diff options
Diffstat (limited to 'indra/newview')
182 files changed, 2858 insertions, 4656 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 355f35c558..c01cd2c34f 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -18,7 +18,6 @@ include(DragDrop) include(EXPAT) include(FMODSTUDIO) include(Hunspell) -include(ICU4C) include(JPEGEncoderBasic) include(JsonCpp) include(LLAppearance) @@ -1617,6 +1616,8 @@ set(viewer_APPSETTINGS_FILES app_settings/anim.ini app_settings/cmd_line.xml app_settings/commands.xml + app_settings/emoji_groups.xml + app_settings/foldertypes.xml app_settings/grass.xml app_settings/ignorable_dialogs.xml app_settings/key_bindings.xml @@ -1932,7 +1933,6 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${LLPHYSICSEXTENSIONS_LIBRARIES} ll::bugsplat ll::tracy - ll::icu4c ) if( TARGET ll::intel_memops ) diff --git a/indra/newview/app_settings/camera/Front.xml b/indra/newview/app_settings/camera/Front.xml index 39f44e11a8..f96d3bc779 100644 --- a/indra/newview/app_settings/camera/Front.xml +++ b/indra/newview/app_settings/camera/Front.xml @@ -1,16 +1,5 @@ <llsd> <map> - <key>AppearanceCameraMovement</key> - <map> - <key>Comment</key> - <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AvatarSitRotation</key> <map> <key>Comment</key> @@ -90,17 +79,6 @@ <key>Value</key> <real>0.90322577953338623</real> </map> - <key>EditCameraMovement</key> - <map> - <key>Comment</key> - <string>When entering build mode, camera moves up above avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FocusOffsetRearView</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/camera/Rear.xml b/indra/newview/app_settings/camera/Rear.xml index 8dc36353ce..7eda566e48 100644 --- a/indra/newview/app_settings/camera/Rear.xml +++ b/indra/newview/app_settings/camera/Rear.xml @@ -1,16 +1,5 @@ <llsd> <map> - <key>AppearanceCameraMovement</key> - <map> - <key>Comment</key> - <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AvatarSitRotation</key> <map> <key>Comment</key> @@ -90,17 +79,6 @@ <key>Value</key> <real>0.90322577953338623</real> </map> - <key>EditCameraMovement</key> - <map> - <key>Comment</key> - <string>When entering build mode, camera moves up above avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FocusOffsetRearView</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/camera/Side.xml b/indra/newview/app_settings/camera/Side.xml index 089ab93a8f..77f73f1df1 100644 --- a/indra/newview/app_settings/camera/Side.xml +++ b/indra/newview/app_settings/camera/Side.xml @@ -1,16 +1,5 @@ <llsd> <map> - <key>AppearanceCameraMovement</key> - <map> - <key>Comment</key> - <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AvatarSitRotation</key> <map> <key>Comment</key> @@ -90,17 +79,6 @@ <key>Value</key> <real>0.90322577953338623</real> </map> - <key>EditCameraMovement</key> - <map> - <key>Comment</key> - <string>When entering build mode, camera moves up above avatar</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FocusOffsetRearView</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2f7c256b49..5e46b478f9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -137,17 +137,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AdvanceOutfitSnapshot</key> - <map> - <key>Comment</key> - <string>Display advanced parameter settings in outfit snaphot interface</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AgentPause</key> <map> <key>Comment</key> @@ -214,17 +203,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AnimationDebug</key> - <map> - <key>Comment</key> - <string>Show active animations in a bubble above avatars head</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>AppearanceCameraMovement</key> <map> <key>Comment</key> @@ -269,17 +247,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AskedAboutCrashReports</key> - <map> - <key>Comment</key> - <string>Turns off dialog asking if you want to enable crash reporting</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>AuctionShowFence</key> <map> <key>Comment</key> @@ -302,17 +269,6 @@ <key>Value</key> <real>0.5</real> </map> - <key>AudioLevelDoppler</key> - <map> - <key>Comment</key> - <string>Scale of doppler effect on moving audio sources (1.0 = normal, <1.0 = diminished doppler effect, >1.0 = enhanced doppler effect)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1.0</real> - </map> <key>AudioLevelMaster</key> <map> <key>Comment</key> @@ -357,28 +313,6 @@ <key>Value</key> <real>0.3</real> </map> - <key>AudioLevelRolloff</key> - <map> - <key>Comment</key> - <string>Controls the distance-based dropoff of audio volume (fraction or multiple of default audio rolloff)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1.0</real> - </map> - <key>AudioLevelUnderwaterRolloff</key> - <map> - <key>Comment</key> - <string>Controls the distance-based dropoff of audio volume underwater(fraction or multiple of default audio rolloff)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>5.0</real> - </map> <key>AudioLevelSFX</key> <map> <key>Comment</key> @@ -412,17 +346,6 @@ <key>Value</key> <real>0.5</real> </map> - <key>AudioLevelWind</key> - <map> - <key>Comment</key> - <string>Audio level of wind noise when standing still</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.5</real> - </map> <key>AudioStreamingMedia</key> <map> <key>Comment</key> @@ -456,7 +379,7 @@ <key>Value</key> <integer>0</integer> </map> - <key>AutoAcceptNewInventory</key> + <key>AutoAcceptNewInventory</key> <map> <key>Comment</key> <string>Automatically accept new notecards/textures/landmarks</string> @@ -478,17 +401,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AutoLoadWebProfiles</key> - <map> - <key>Comment</key> - <string>Automatically load ALL profile webpages without asking first.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>AutoLogin</key> <map> <key>Comment</key> @@ -687,17 +599,6 @@ <key>Value</key> <real>1.0</real> </map> - <key>AvatarBacklight</key> - <map> - <key>Comment</key> - <string>Add rim lighting to avatar rendering to approximate shininess of skin</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AvatarFeathering</key> <map> <key>Comment</key> @@ -709,32 +610,6 @@ <key>Value</key> <real>16.0</real> </map> - <key>AvatarPickerSortOrder</key> - <map> - <key>Comment</key> - <string>Specifies sort key for textures in avatar picker (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>2</integer> - </map> - <key>AvatarPosFinalOffset</key> - <map> - <key>Comment</key> - <string>After-everything-else fixup for avatar position.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>0.0</real> - <real>0.0</real> - <real>0.0</real> - </array> - </map> <key>AvatarPickerURL</key> <map> <key>Comment</key> @@ -746,50 +621,6 @@ <key>Value</key> <string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/avatars.html</string> </map> - <key>AvatarRotateThresholdSlow</key> - <map> - <key>Comment</key> - <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving slowly (degrees)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <integer>60</integer> - </map> - <key>AvatarRotateThresholdFast</key> - <map> - <key>Comment</key> - <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving fast (degrees)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <integer>2</integer> - </map> - <key>AvatarBakedTextureUploadTimeout</key> - <map> - <key>Comment</key> - <string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance. Set to 0 to disable and wait until all baked textures are at highest resolution.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>60</integer> - </map> - <key>AvatarBakedLocalTextureUpdateTimeout</key> - <map> - <key>Comment</key> - <string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>10</integer> - </map> <key>AvatarPhysics</key> <map> <key>Comment</key> @@ -823,28 +654,6 @@ <key>Value</key> <integer>40</integer> </map> - <key>BottomPanelNew</key> - <map> - <key>Comment</key> - <string>Enable the new bottom panel</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>BrowserHomePage</key> - <map> - <key>Comment</key> - <string>[NOT USED]</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>http://www.secondlife.com</string> - </map> <key>BrowserIgnoreSSLCertErrors</key> <map> <key>Comment</key> @@ -878,17 +687,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>BlockSomeAvatarAppearanceVisualParams</key> - <map> - <key>Comment</key> - <string>Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>BrowserProxyAddress</key> <map> <key>Comment</key> @@ -911,17 +709,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>BrowserProxyExclusions</key> - <map> - <key>Comment</key> - <string>[NOT USED]</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> <key>BrowserProxyPort</key> <map> <key>Comment</key> @@ -933,17 +720,6 @@ <key>Value</key> <integer>3128</integer> </map> - <key>BrowserProxySocks45</key> - <map> - <key>Comment</key> - <string>[NOT USED]</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>5</integer> - </map> <key>Socks5ProxyEnabled</key> <map> <key>Comment</key> @@ -1329,39 +1105,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ButtonHPad</key> - <map> - <key>Comment</key> - <string>Default horizontal spacing between buttons (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>4</integer> - </map> - <key>ButtonHeight</key> - <map> - <key>Comment</key> - <string>Default height for normal buttons (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>23</integer> - </map> - <key>ButtonHeightSmall</key> - <map> - <key>Comment</key> - <string>Default height for small buttons (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>23</integer> - </map> <key>EnableDiskCacheDebugInfo</key> <map> <key>Comment</key> @@ -1417,17 +1160,6 @@ <key>Value</key> <string /> </map> - <key>CacheNumberOfRegionsForObjects</key> - <map> - <key>Comment</key> - <string>Controls number of regions to be cached for objects.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>128</integer> - </map> <key>CacheSize</key> <map> <key>Comment</key> @@ -1513,51 +1245,6 @@ <real>0.75</real> </array> </map> - <key>CameraOffsetFrontView</key> - <map> - <key>Comment</key> - <string>Initial camera offset from avatar in Front View</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>2.2</real> - <real>0.0</real> - <real>0.0</real> - </array> - </map> - <key>CameraOffsetGroupView</key> - <map> - <key>Comment</key> - <string>Initial camera offset from avatar in Group View</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>-1.0</real> - <real>0.7</real> - <real>0.5</real> - </array> - </map> - <key>CameraOffsetCustomPreset</key> - <map> - <key>Comment</key> - <string>Initial camera offset from avatar for the custom camera preset</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3</string> - <key>Value</key> - <array> - <real>-3.0</real> - <real>0.0</real> - <real>0.75</real> - </array> - </map> <key>CameraOffsetScale</key> <map> <key>Comment</key> @@ -1712,17 +1399,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ChatBarStealsFocus</key> - <map> - <key>Comment</key> - <string>Whenever keyboard focus is removed from the UI, and the chat bar is visible, the chat bar takes focus</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>LetterKeysFocusChatBar</key> <map> <key>Comment</key> @@ -1767,17 +1443,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ChatHistoryTornOff</key> - <map> - <key>Comment</key> - <string>Show chat history window separately from Communicate window.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>ChatLoadGroupMaxMembers</key> <map> <key>Comment</key> @@ -1789,17 +1454,6 @@ <key>Value</key> <integer>100</integer> </map> - <key>ChatLoadGroupTimeout</key> - <map> - <key>Comment</key> - <string>Time we give the server to send group participants before we hit the server for group info (seconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>10.0</real> - </map> <key>ChatOnlineNotification</key> <map> <key>Comment</key> @@ -1811,28 +1465,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ChatPersistTime</key> - <map> - <key>Comment</key> - <string>Time for which chat stays visible in console (seconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>20.0</real> - </map> - <key>ChatShowTimestamps</key> - <map> - <key>Comment</key> - <string>Show timestamps in chat</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>CheesyBeacon</key> <map> <key>Comment</key> @@ -1855,50 +1487,6 @@ <key>Value</key> <string /> </map> - <key>ContextConeInAlpha</key> - <map> - <key>Comment</key> - <string>Cone In Alpha</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.0</real> - </map> - <key>ContextConeOutAlpha</key> - <map> - <key>Comment</key> - <string>Cone Out Alpha</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1.0</real> - </map> - <key>ContextConeFadeTime</key> - <map> - <key>Comment</key> - <string>Cone Fade Time</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>.08</real> - </map> - <key>ConversationHistoryPageSize</key> - <map> - <key>Comment</key> - <string>Chat history of conversation opened from call log is displayed by pages. So this is number of entries per page.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>100</integer> - </map> <key>ConversationSortOrder</key> <map> <key>Comment</key> @@ -2077,17 +1665,6 @@ <key>Value</key> <integer>40</integer> </map> - <key>ContactsTornOff</key> - <map> - <key>Comment</key> - <string>Show contacts window separately from Communicate window.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>CookiesEnabled</key> <map> <key>Comment</key> @@ -2132,17 +1709,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ChatBarCustomWidth</key> - <map> - <key>Comment</key> - <string>Stores customized width of chat bar.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>CoroutineStackSize</key> <map> <key>Comment</key> @@ -2209,17 +1775,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>CurlMaximumNumberOfHandles</key> - <map> - <key>Comment</key> - <string>Maximum number of handles curl can use (requires restart)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>256</integer> - </map> <key>CurlRequestTimeOut</key> <map> <key>Comment</key> @@ -2231,17 +1786,6 @@ <key>Value</key> <real>120.0</real> </map> - <key>CurlUseMultipleThreads</key> - <map> - <key>Comment</key> - <string>Use background threads for executing curl_multi_perform (requires restart)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>Cursor3D</key> <map> <key>Comment</key> @@ -2264,17 +1808,6 @@ <key>Value</key> <string></string> </map> - <key>CustomServer</key> - <map> - <key>Comment</key> - <string>Specifies IP address or hostname of grid to which you connect</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> <key>DebugAnimatedObjects</key> <map> <key>Comment</key> @@ -2297,17 +1830,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AnimatedObjectsIgnoreLimits</key> - <map> - <key>Comment</key> - <string>Ignore server-enforced limits on animated objects. This is only useful for server testing.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>AnimatedObjectsAllowLeftClick</key> <map> <key>Comment</key> @@ -2319,17 +1841,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AnimatedObjectsGlobalScale</key> - <map> - <key>Comment</key> - <string>Temporary testing: allow an extra scale factor to be forced on animated objects.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1.00</real> - </map> <key>AnimatedObjectsMaxLegalOffset</key> <map> <key>Comment</key> @@ -2352,17 +1863,6 @@ <key>Value</key> <real>64.0</real> </map> - <key>AvatarBoundingBoxComplexity</key> - <map> - <key>Comment</key> - <string>How many aspects to consider for avatar bounding box</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>3</integer> - </map> <key>DebugAvatarAppearanceMessage</key> <map> <key>Comment</key> @@ -2473,17 +1973,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>DebugInventoryFilters</key> - <map> - <key>Comment</key> - <string>Turn on debugging display for inventory filtering</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>DebugPermissions</key> <map> <key>Comment</key> @@ -2550,18 +2039,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>DebugShowPrivateMem</key> - <!-- deprecated (see MAINT-8091) --> - <map> - <key>Comment</key> - <string>(Deprecated) Show Private Mem Info</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>DebugShowRenderInfo</key> <map> <key>Comment</key> @@ -2628,435 +2105,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>DebugSlshareLogTag</key> - <map> - <key>Comment</key> - <string>Request slshare-service debug logging</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string/> - </map> - <key>DebugStatModeFPS</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeBandwidth</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModePacketLoss</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatMode</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeKTrisDrawnFr</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeKTrisDrawnSec</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeTotalObjs</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeNewObjs</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeTextureCount</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeRawCount</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeGLMem</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeFormattedMem</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeRawMem</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeBoundMem</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModePacketsIn</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModePacketsOut</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeObjects</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeTexture</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeAsset</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeLayers</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeActualIn</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeActualOut</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeTimeDialation</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimFPS</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModePhysicsFPS</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModePinnedObjects</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeLowLODObjects</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeMemoryAllocated</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeAgentUpdatesSec</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeMainAgents</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeChildAgents</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimObjects</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimActiveObjects</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimActiveScripts</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimScriptEvents</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimInPPS</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimOutPPS</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> - <key>DebugStatModeSimPendingDownloads</key> - <map> - <key>Comment</key> - <string>Mode of stat in Statistics floater</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>-1</integer> - </map> <key>SimPendingUploads</key> <map> <key>Comment</key> @@ -3277,17 +2325,6 @@ <key>Value</key> <string>Male Shape & Outfit</string> </map> - <key>DefaultUploadCost</key> - <map> - <key>Comment</key> - <string>Default sound/image/file upload cost(in case economy data is not available).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>10</integer> - </map> <key>DestinationGuideURL</key> <map> <key>Comment</key> @@ -3387,94 +2424,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>EnableIMChatPopups</key> - <map> - <key>Comment</key> - <string>Enable Incoming IM Chat Popups</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>DisplayAvatarAgentTarget</key> - <map> - <key>Comment</key> - <string>Show avatar positioning locators (animation debug)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>DisplayChat</key> - <map> - <key>Comment</key> - <string>Display Latest Chat message on LCD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>DisplayDebug</key> - <map> - <key>Comment</key> - <string>Display Network Information on LCD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>DisplayDebugConsole</key> - <map> - <key>Comment</key> - <string>Display Console Debug Information on LCD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>DisplayIM</key> - <map> - <key>Comment</key> - <string>Display Latest IM message on LCD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>DisplayLinden</key> - <map> - <key>Comment</key> - <string>Display Account Information on LCD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>DisplayRegion</key> - <map> - <key>Comment</key> - <string>Display Location information on LCD</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>DisplayTimecode</key> <map> <key>Comment</key> @@ -3508,28 +2457,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ClickActionBuyEnabled</key> - <map> - <key>Comment</key> - <string>Enable click to buy actions in tool pie menu</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>ClickActionPayEnabled</key> - <map> - <key>Comment</key> - <string>Enable click to pay actions in tool pie menu</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>DoubleClickAutoPilot</key> <map> <key>Comment</key> @@ -3563,72 +2490,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>DragAndDropToolTipDelay</key> - <map> - <key>Comment</key> - <string>Seconds before displaying tooltip when performing drag and drop operation</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.10000000149</real> - </map> - <key>DragAndDropDistanceThreshold</key> - <map> - <key>Comment</key> - <string>Number of pixels that mouse should move before triggering drag and drop mode</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>3</integer> - </map> - <key>DropShadowButton</key> - <map> - <key>Comment</key> - <string>Drop shadow width for buttons (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>2</integer> - </map> - <key>DropShadowFloater</key> - <map> - <key>Comment</key> - <string>Drop shadow width for floaters (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>5</integer> - </map> - <key>DropShadowSlider</key> - <map> - <key>Comment</key> - <string>Drop shadow width for sliders (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>3</integer> - </map> - <key>DropShadowTooltip</key> - <map> - <key>Comment</key> - <string>Drop shadow width for tooltips (pixels)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>4</integer> - </map> <key>DynamicCameraStrength</key> <map> <key>Comment</key> @@ -3662,17 +2523,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>IncludeEnhancedSkeleton</key> - <map> - <key>Comment</key> - <string>Include extended skeleton joints when rendering skinned meshes.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>MinObjectsForUnlinkConfirm</key> <map> <key>Comment</key> @@ -3772,39 +2622,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>EnergyFromTop</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>20</integer> - </map> - <key>EnergyHeight</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>40</integer> - </map> - <key>EnergyWidth</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>175</integer> - </map> <key>EventURL</key> <map> <key>Comment</key> @@ -3816,61 +2633,6 @@ <key>Value</key> <string>http://events.[GRID]/viewer/embed/event/[EVENT_ID]</string> </map> - <key>FastCacheFetchEnabled</key> - <map> - <key>Comment</key> - <string>Enable texture fast cache fetching if set</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <string>1</string> - </map> - <key>FeatureManagerHTTPTable</key> - <map> - <key>Comment</key> - <string>Deprecated</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string></string> - </map> - <key>FPSLogFrequency</key> - <map> - <key>Comment</key> - <string>Seconds between display of FPS in log (0 for never)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>10.0</real> - </map> - <key>FilterItemsMaxTimePerFrameVisible</key> - <map> - <key>Comment</key> - <string>Max time devoted to items filtering per frame for visible inventory listings (in milliseconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>10</integer> - </map> - <key>FilterItemsMaxTimePerFrameUnvisible</key> - <map> - <key>Comment</key> - <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>1</integer> - </map> <key>MainWorkTime</key> <map> <key>Comment</key> @@ -3882,72 +2644,6 @@ <key>Value</key> <real>1.0</real> </map> - <key>QueueInventoryFetchTimeout</key> - <map> - <key>Comment</key> - <string>Max time llcompilequeue will wait for inventory fetch to complete (in seconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>300.0</real> - </map> - <key>FindLandArea</key> - <map> - <key>Comment</key> - <string>Enables filtering of land search results by area</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>FindLandPrice</key> - <map> - <key>Comment</key> - <string>Enables filtering of land search results by price</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FindLandType</key> - <map> - <key>Comment</key> - <string>Controls which type of land you are searching for in Find Land interface ("All", "Auction", "For Sale")</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>All</string> - </map> - <key>FindPeopleOnline</key> - <map> - <key>Comment</key> - <string>Limits people search to only users who are logged on</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>FindPlacesPictures</key> - <map> - <key>Comment</key> - <string>Display only results of find places that have pictures</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>FirstName</key> <map> <key>Comment</key> @@ -4339,17 +3035,6 @@ <key>Value</key> <real>16.0</real> </map> - <key>FlycamZoomDirect</key> - <map> - <key>Comment</key> - <string>Map flycam zoom axis directly to camera zoom.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FlyingAtExit</key> <map> <key>Comment</key> @@ -4376,51 +3061,6 @@ <real>1.0</real> </array> </map> - <key>FocusOffsetFrontView</key> - <map> - <key>Comment</key> - <string>Initial focus point offset relative to avatar for the camera preset Front View</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3D</string> - <key>Value</key> - <array> - <real>0.0</real> - <real>0.0</real> - <real>0.0</real> - </array> - </map> - <key>FocusOffsetGroupView</key> - <map> - <key>Comment</key> - <string>Initial focus point offset relative to avatar for the camera preset Group View</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3D</string> - <key>Value</key> - <array> - <real>1.5</real> - <real>0.7</real> - <real>1.0</real> - </array> - </map> - <key>FocusOffsetCustomPreset</key> - <map> - <key>Comment</key> - <string>Initial focus point offset relative to avatar for the custom camera preset (x-axis is forward)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Vector3D</string> - <key>Value</key> - <array> - <real>1.0</real> - <real>0.0</real> - <real>1.0</real> - </array> - </map> <key>AvatarSitRotation</key> <map> <key>Comment</key> @@ -4463,17 +3103,6 @@ <key>Value</key> <real>0.75</real> </map> - <key>FolderLoadingMessageWaitTime</key> - <map> - <key>Comment</key> - <string>Seconds to wait before showing the LOADING... text in folder views</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.5</real> - </map> <key>FontScreenDPI</key> <map> <key>Comment</key> @@ -4529,17 +3158,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>ForceMandatoryUpdate</key> - <map> - <key>Comment</key> - <string>For QA: On next startup, forces the auto-updater to run</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FreezeTime</key> <map> <key>Comment</key> @@ -4661,28 +3279,6 @@ <key>Value</key> <integer>32</integer> </map> - <key>GroupNotifyBoxHeight</key> - <map> - <key>Comment</key> - <string>Height of group notice messages</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>260</integer> - </map> - <key>GroupNotifyBoxWidth</key> - <map> - <key>Comment</key> - <string>Width of group notice messages</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>305</integer> - </map> <key>HelpURLFormat</key> <map> <key>Comment</key> @@ -4771,17 +3367,6 @@ <key>Value</key> <string /> </map> - <key>HtmlHelpLastPage</key> - <map> - <key>Comment</key> - <string>Last URL visited via help system</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string /> - </map> <key>HttpPipelining</key> <map> <key>Comment</key> @@ -4804,17 +3389,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>IMShowTimestamps</key> - <map> - <key>Comment</key> - <string>Show timestamps in IM</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>IMShowControlPanel</key> <map> <key>Comment</key> @@ -4826,17 +3400,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>IMShowContentPanel</key> - <map> - <key>Comment</key> - <string>Show Toolbar and Body Panels</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>IgnoreFOVZoomForLODs</key> <map> <key>Comment</key> @@ -4903,28 +3466,6 @@ <key>Value</key> <real>0.0</real> </map> - <key>InspectorFadeTime</key> - <map> - <key>Comment</key> - <string>Fade out timing for inspectors</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.5</real> - </map> - <key>InspectorShowTime</key> - <map> - <key>Comment</key> - <string>Stay timing for inspectors</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>3.0</real> - </map> <key>InstallLanguage</key> <map> <key>Comment</key> @@ -4991,17 +3532,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>InventoryOutboxDisplayBoth</key> - <map> - <key>Comment</key> - <string>(Deprecated) Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>InventoryOutboxLogging</key> <map> <key>Comment</key> @@ -5251,7 +3781,7 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>String</string> + <string>LLSD</string> <key>Value</key> <string /> </map> @@ -5332,17 +3862,6 @@ <key>Value</key> <real>2.0</real> </map> - <key>LCDDestination</key> - <map> - <key>Comment</key> - <string>Which LCD to use</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>LeapCommand</key> <map> <key>Comment</key> @@ -5564,105 +4083,6 @@ <string>0.0.0</string> </map> - <key>LastSnapshotToProfileHeight</key> - <map> - <key>Comment</key> - <string>The height of the last profile snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>768</integer> - </map> - <key>LastSnapshotToEmailHeight</key> - <map> - <key>Comment</key> - <string>The height of the last email snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>768</integer> - </map> - <key>LastSnapshotToProfileWidth</key> - <map> - <key>Comment</key> - <string>The width of the last profile snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>1024</integer> - </map> - <key>LastSnapshotToEmailWidth</key> - <map> - <key>Comment</key> - <string>The width of the last email snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>1024</integer> - </map> - <key>LastSnapshotToDiskHeight</key> - <map> - <key>Comment</key> - <string>The height of the last disk snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>768</integer> - </map> - <key>LastSnapshotToDiskWidth</key> - <map> - <key>Comment</key> - <string>The width of the last disk snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>1024</integer> - </map> - <key>LastSnapshotToInventoryHeight</key> - <map> - <key>Comment</key> - <string>The height of the last texture snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>512</integer> - </map> - <key>LastSnapshotToInventoryWidth</key> - <map> - <key>Comment</key> - <string>The width of the last texture snapshot, in px</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>512</integer> - </map> - <key>LeftClickShowMenu</key> - <map> - <key>Comment</key> - <string>Unused obsolete setting</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>LimitDragDistance</key> <map> <key>Comment</key> @@ -5829,17 +4249,6 @@ <key>Value</key> <real>40.0</real> </map> - <key>LoginSRVPump</key> - <map> - <key>Comment</key> - <string>(Deprecated) Name of the message pump that handles SRV request)</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>LLAres</string> - </map> <key>LogMessages</key> <map> <key>Comment</key> @@ -5928,17 +4337,6 @@ <key>Value</key> <real>60.0</real> </map> - <key>MapOverlayIndex</key> - <map> - <key>Comment</key> - <string>Currently selected world map type</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>MapScale</key> <map> <key>Comment</key> @@ -6678,28 +5076,6 @@ <key>Value</key> <real>0.25</real> </map> - <key>MenuBarHeight</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>18</integer> - </map> - <key>MenuBarWidth</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>410</integer> - </map> <key>MePanelOpened</key> <map> <key>Comment</key> @@ -7154,28 +5530,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>NotifyBoxHeight</key> - <map> - <key>Comment</key> - <string>Height of notification messages</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>200</integer> - </map> - <key>NotifyBoxWidth</key> - <map> - <key>Comment</key> - <string>Width of notification messages</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>305</integer> - </map> <key>NotificationConferenceIMOptions</key> <map> <key>Comment</key> @@ -7353,17 +5707,6 @@ <key>Value</key> <integer>90</integer> </map> - <key>ChannelBottomPanelMargin</key> - <map> - <key>Comment</key> - <string>Space from a lower toast to the Bottom Tray</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>35</integer> - </map> <key>NotificationChannelRightMargin</key> <map> <key>Comment</key> @@ -8064,17 +6407,6 @@ <key>Value</key> <real>6.0</real> </map> - <key>ClothingLoadingDelay</key> - <map> - <key>Comment</key> - <string>Time to wait for avatar appearance to resolve before showing world (seconds)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>10.0</real> - </map> <key>PreferredMaturity</key> <map> <key>Comment</key> @@ -8517,17 +6849,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>RadioLandBrushSize</key> - <map> - <key>Comment</key> - <string>Size of land modification brush (0 = small, 1 = medium, 2 = large)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>0</integer> - </map> <key>LandBrushForce</key> <map> <key>Comment</key> @@ -8539,17 +6860,6 @@ <key>Value</key> <real>1.0</real> </map> - <key>MediaBrowserWindowLimit</key> - <map> - <key>Comment</key> - <string>Maximum number of media brower windows that can be open at once in the media browser floater (0 for no limit)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>5</integer> - </map> <key>WebContentWindowLimit</key> <map> <key>Comment</key> @@ -8828,17 +7138,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderAvatar</key> - <map> - <key>Comment</key> - <string>Render Avatars</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>RenderAvatarCloth</key> <map> <key>Comment</key> @@ -11565,17 +9864,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>SecondLifeEnterprise</key> - <map> - <key>Comment</key> - <string>Enables Second Life Enterprise features</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>SelectMovableOnly</key> <map> <key>Comment</key> @@ -11851,17 +10139,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>ShowEmptyFoldersWhenSearching</key> - <map> - <key>Comment</key> - <string>Shows folders that do not have any visible contents when applying a filter to inventory</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>ShowEventRecorderMenuItems</key> <map> <key>Comment</key> @@ -12203,136 +10480,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>ShowPGSearchAll</key> - <map> - <key>Comment</key> - <string>Display results of search All that are flagged as general</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>ShowMatureSearchAll</key> - <map> - <key>Comment</key> - <string>Display results of search All that are flagged as moderate</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>ShowAdultSearchAll</key> - <map> - <key>Comment</key> - <string>Display results of search All that are flagged as adult</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>ShowPGGroups</key> - <map> - <key>Comment</key> - <string>Display results of find groups that are flagged as general</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>ShowMatureGroups</key> - <map> - <key>Comment</key> - <string>Display results of find groups that are flagged as moderate</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>ShowAdultGroups</key> - <map> - <key>Comment</key> - <string>Display results of find groups that are flagged as adult</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>ShowPGClassifieds</key> - <map> - <key>Comment</key> - <string>Display results of find classifieds that are flagged as general</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>ShowMatureClassifieds</key> - <map> - <key>Comment</key> - <string>Display results of find classifieds that are flagged as moderate</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>ShowAdultClassifieds</key> - <map> - <key>Comment</key> - <string>Display results of find classifieds that are flagged as adult</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>ShowPGEvents</key> - <map> - <key>Comment</key> - <string>Display results of find events that are flagged as general</string> - <key>Persist</key> - <integer>1</integer> - <key>HideFromEditor</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>ShowMatureEvents</key> <map> <key>Comment</key> @@ -12569,17 +10716,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>ShowToolBar</key> - <map> - <key>Comment</key> - <string>Show toolbar at bottom of screen</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>ShowTutorial</key> <map> <key>Comment</key> @@ -13021,28 +11157,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>TexturePickerShowFolders</key> - <map> - <key>Comment</key> - <string>Show folders with no texures in texture picker</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>TexturePickerSortOrder</key> - <map> - <key>Comment</key> - <string>Specifies sort key for textures in texture picker (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>2</integer> - </map> <key>TextureReverseByteRange</key> <map> <key>Comment</key> @@ -13092,17 +11206,6 @@ <key>Value</key> <real>3000.0</real> </map> - <key>UpdaterMaximumBandwidth</key> - <map> - <key>Comment</key> - <string>Obsolete: this parameter is no longer used.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>500.0</real> - </map> <key>ToolTipDelay</key> <map> <key>Comment</key> @@ -13235,17 +11338,6 @@ <key>Value</key> <string></string> </map> - <key>BingTranslateAPIKey</key> - <map> - <key>Comment</key> - <string>(Deprecated) Bing AppID to use with the Microsoft Translator API</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string></string> - </map> <key>AzureTranslateAPIKey</key> <map> <key>Comment</key> @@ -13312,28 +11404,6 @@ <key>Value</key> <integer>6</integer> </map> - <key>UICheckboxctrlBtnSize</key> - <map> - <key>Comment</key> - <string>UI Checkbox Control Button Size</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>13</integer> - </map> - <key>UICheckboxctrlHeight</key> - <map> - <key>Comment</key> - <string>UI Checkbox Control Height</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>16</integer> - </map> <key>UICheckboxctrlHPad</key> <map> <key>Comment</key> @@ -13565,50 +11635,6 @@ <key>Value</key> <string>5748decc-f629-461c-9a36-a35a221fe21f</string> </map> - <key>StartUpChannelUUID</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>B56AF90D-6684-48E4-B1E4-722D3DEB2CB6</string> - </map> - <key>NearByChatChannelUUID</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>E1158BD6-661C-4981-9DAD-4DCBFF062502</string> - </map> - <key>NotificationChannelUUID</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>AEED3193-8709-4693-8558-7452CCA97AE5</string> - </map> - <key>AlertChannelUUID</key> - <map> - <key>Comment</key> - <string /> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string> - </map> <key>UILineEditorCursorThickness</key> <map> <key>Comment</key> @@ -13785,17 +11811,6 @@ <key>Value</key> <real>1.0</real> </map> - <key>LastSystemUIScaleFactor</key> - <map> - <key>Comment</key> - <string>OBSOLETE: System UI scale factor is now automatically and independently from UIScaleFactor applied</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1.0</real> - </map> <key>UIScrollbarSize</key> <map> <key>Comment</key> @@ -14115,17 +12130,6 @@ <key>Value</key> <integer>16</integer> </map> - <key>UISpinctrlDefaultLabelWidth</key> - <map> - <key>Comment</key> - <string>UI spin control default label width</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>10</integer> - </map> <key>UISpinctrlSpacing</key> <map> <key>Comment</key> @@ -14247,39 +12251,6 @@ <key>Value</key> <integer>3</integer> </map> - <key>UpdaterServiceCheckPeriod</key> - <map> - <key>Comment</key> - <string>Obsolete; no longer used.</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>3600</integer> - </map> - <key>UpdaterServiceURL</key> - <map> - <key>Comment</key> - <string>Obsolete; no longer used.</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>https://update.secondlife.com</string> - </map> - <key>UpdaterServicePath</key> - <map> - <key>Comment</key> - <string>Obsolete: no longer used</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>update</string> - </map> <key>UpdaterWillingToTest</key> <map> <key>Comment</key> @@ -14412,17 +12383,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>UseEnvironmentFromRegion</key> - <map> - <key>Comment</key> - <string>Choose whether to use the region's environment settings, or override them with the local settings.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>EnvironmentPersistAcrossLogin</key> <map> <key>Comment</key> @@ -14434,62 +12394,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>UseDayCycle</key> - <map> - <key>Comment</key> - <string>Whether to use use a day cycle or a fixed sky.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>WaterPresetName</key> - <map> - <key>Comment</key> - <string>Water preset to use. May be superseded by region settings.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>Default</string> - </map> - <key>SkyPresetName</key> - <map> - <key>Comment</key> - <string>Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName).</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>Default</string> - </map> - <key>DayCycleName</key> - <map> - <key>Comment</key> - <string>Day cycle to use. May be superseded by region settings.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>Default</string> - </map> - <key>UseExternalBrowser</key> - <!-- deprecated (see MAINT-4127) --> - <map> - <key>Comment</key> - <string>(Deprecated) Use default browser when opening web pages instead of in-world browser.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <boolean>1</boolean> - </map> <key>PreferredBrowserBehavior</key> <map> <key>Comment</key> @@ -14545,6 +12449,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>RenderDelayVBUpdate</key> + <map> + <key>Comment</key> + <string>Delay vertex buffer updates until just before rendering</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>SocialPhotoResolution</key> <map> <key>Comment</key> @@ -15350,17 +13265,6 @@ <key>Value</key> <real>-1.0</real> </map> - <key>ForcePeriodicRenderingTime</key> - <map> - <key>Comment</key> - <string>Periodically enable all rendering masks for a single frame.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>-1.0</real> - </map> <key>ZoomDirect</key> <map> <key>Comment</key> @@ -15526,17 +13430,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AssetStorageLogFrequency</key> - <map> - <key>Comment</key> - <string>Seconds between display of AssetStorage info in log (0 for never)</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>60.0</real> - </map> <key>LogWearableAssetSave</key> <map> <key>Comment</key> @@ -15774,28 +13667,6 @@ <key>Value</key> <real>120.0</real> </map> - <key>DestinationGuideHintTimeout</key> - <map> - <key>Comment</key> - <string>Number of seconds to wait before telling resident about destination guide.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>1200.0</real> - </map> - <key>SidePanelHintTimeout</key> - <map> - <key>Comment</key> - <string>Number of seconds to wait before telling resident about side panel.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>300.0</real> - </map> <key>GroupMembersSortOrder</key> <map> <key>Comment</key> @@ -15840,17 +13711,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AvatarInspectorTooltipDelay</key> - <map> - <key>Comment</key> - <string>Seconds before displaying avatar inspector tooltip</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>0.35</real> - </map> <key>ObjectInspectorTooltipDelay</key> <map> <key>Comment</key> @@ -15884,17 +13744,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>EnableGroupInfo</key> - <map> - <key>Comment</key> - <string>Enable viewing and editing of group info from web link</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>EnablePlaceProfile</key> <map> <key>Comment</key> @@ -15906,28 +13755,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>EnablePicks</key> - <map> - <key>Comment</key> - <string>Enable editing of picks from web link</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>EnableWorldMap</key> - <map> - <key>Comment</key> - <string>Enable opening world map from web link</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>EnableAvatarPay</key> <map> <key>Comment</key> @@ -15939,17 +13766,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>EnableVoiceCall</key> - <map> - <key>Comment</key> - <string>Enable voice calls from web link</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>EnableAvatarShare</key> <map> <key>Comment</key> @@ -15972,17 +13788,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>EnableSearch</key> - <map> - <key>Comment</key> - <string>Enable opening search from web link</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>EnableAppearance</key> <map> <key>Comment</key> @@ -16060,17 +13865,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>AllowBottomTrayButtonReordering</key> - <map> - <key>Comment</key> - <string>Allow user to move and hide bottom tray buttons</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>AllowSelectAvatar</key> <map> <key>Comment</key> @@ -16929,28 +14723,6 @@ <key>Value</key> <integer>1000</integer> </map> - <key>FMODExStreamBufferSize</key> - <map> - <key>Comment</key> - <string>Sets the streaming buffer size (in milliseconds) for FMOD Ex or FMOD Studio</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>U32</string> - <key>Value</key> - <integer>7000</integer> - </map> - <key>DisablePrecacheDelayAfterTeleporting</key> - <map> - <key>Comment</key> - <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>VersionChannelName</key> <map> <key>Comment</key> diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 63608cdbf8..d1dab94a76 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -397,8 +397,18 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ # Other shortcuts
SetOutPath "$INSTDIR"
-CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
+
+Push $0
+${GetParameters} $COMMANDLINE
+${GetOptionsS} $COMMANDLINE "/marker" $0
+# Returns error if option does not exist
+IfErrors 0 DESKTOP_SHORTCUT_DONE
+ # "/marker" is set by updater, do not recreate desktop shortcut
+ CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
+
+DESKTOP_SHORTCUT_DONE:
+Pop $0
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index d3f988d715..0a558da42b 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -58,16 +58,19 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, try { + LLAccountingCostManager* self = LLAccountingCostManager::getInstance(); uuid_set_t diffSet; - std::set_difference(mObjectList.begin(), mObjectList.end(), - mPendingObjectQuota.begin(), mPendingObjectQuota.end(), - std::inserter(diffSet, diffSet.begin())); + std::set_difference(self->mObjectList.begin(), + self->mObjectList.end(), + self->mPendingObjectQuota.begin(), + self->mPendingObjectQuota.end(), + std::inserter(diffSet, diffSet.begin())); if (diffSet.empty()) return; - mObjectList.clear(); + self->mObjectList.clear(); std::string keystr; if (selectionType == Roots) @@ -91,18 +94,25 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, objectList.append(*it); } - mPendingObjectQuota.insert(diffSet.begin(), diffSet.end()); + self->mPendingObjectQuota.insert(diffSet.begin(), diffSet.end()); LLSD dataToPost = LLSD::emptyMap(); dataToPost[keystr.c_str()] = objectList; - LLAccountingCostObserver* observer = NULL; - LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost); LLSD httpResults = results["http_result"]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + if (LLApp::isQuitting() + || observerHandle.isDead() + || !LLAccountingCostManager::instanceExists()) + { + return; + } + + LLAccountingCostObserver* observer = NULL; + // do/while(false) allows error conditions to break out of following // block while normal flow goes forward once. do @@ -159,7 +169,8 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, throw; } - mPendingObjectQuota.clear(); + // self can be obsolete by this point + LLAccountingCostManager::getInstance()->mPendingObjectQuota.clear(); } //=============================================================================== @@ -172,7 +183,7 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, { std::string coroname = LLCoros::instance().launch("LLAccountingCostManager::accountingCostCoro", - boost::bind(&LLAccountingCostManager::accountingCostCoro, this, url, selectionType, observer_handle)); + boost::bind(accountingCostCoro, url, selectionType, observer_handle)); LL_DEBUGS() << coroname << " with url '" << url << LL_ENDL; } diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h index d133c6437b..9b2ffc7d7c 100644 --- a/indra/newview/llaccountingcostmanager.h +++ b/indra/newview/llaccountingcostmanager.h @@ -70,7 +70,7 @@ private: //a fetch has been instigated. uuid_set_t mPendingObjectQuota; - void accountingCostCoro(std::string url, eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle); + static void accountingCostCoro(std::string url, eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle); }; //=============================================================================== diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 8977b145d1..b51bf132f4 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1932,7 +1932,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit) } else { - target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f; + LLCachedControl<F32> dynamic_camera_strength(gSavedSettings, "DynamicCameraStrength"); + target_lag = vel * dynamic_camera_strength / 30.f; } mCameraLag = lerp(mCameraLag, target_lag, lag_interp); diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp index 799060eeab..0b72f1ee4d 100644 --- a/indra/newview/llagentpicksinfo.cpp +++ b/indra/newview/llagentpicksinfo.cpp @@ -49,10 +49,10 @@ public: void sendAgentPicksRequest() { - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(gAgent.getID()); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgent.getID()); } - typedef boost::function<void(LLAvatarPicks*)> server_respond_callback_t; + typedef boost::function<void(LLAvatarData*)> server_respond_callback_t; void setServerRespondCallback(const server_respond_callback_t& cb) { @@ -61,10 +61,10 @@ public: virtual void processProperties(void* data, EAvatarProcessorType type) { - if(APT_PICKS == type) + if(APT_PROPERTIES == type) { - LLAvatarPicks* picks = static_cast<LLAvatarPicks*>(data); - if(picks && gAgent.getID() == picks->target_id) + LLAvatarData* picks = static_cast<LLAvatarData*>(data); + if(picks && gAgent.getID() == picks->avatar_id) { if(mServerRespondCallback) { @@ -115,7 +115,7 @@ bool LLAgentPicksInfo::isPickLimitReached() return getNumberOfPicks() >= getMaxNumberOfPicks(); } -void LLAgentPicksInfo::onServerRespond(LLAvatarPicks* picks) +void LLAgentPicksInfo::onServerRespond(LLAvatarData* picks) { if(!picks) { diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h index 21df036cb7..56e7bd0775 100644 --- a/indra/newview/llagentpicksinfo.h +++ b/indra/newview/llagentpicksinfo.h @@ -29,7 +29,7 @@ #include "llsingleton.h" -struct LLAvatarPicks; +struct LLAvatarData; /** * Class that provides information about Agent Picks @@ -74,7 +74,7 @@ public: void decrementNumberOfPicks() { --mNumberOfPicks; } - void onServerRespond(LLAvatarPicks* picks); + void onServerRespond(LLAvatarData* picks); private: diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 4c3a9229d2..fa0dee3ef9 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1399,7 +1399,7 @@ const std::string LLAppearanceMgr::sExpectedTextureName = "OutfitPreview"; const LLUUID LLAppearanceMgr::getCOF() const { - return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + return mCOFID; } S32 LLAppearanceMgr::getCOFVersion() const @@ -1415,6 +1415,11 @@ S32 LLAppearanceMgr::getCOFVersion() const } } +void LLAppearanceMgr::initCOFID() +{ + mCOFID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); +} + const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink() { const LLUUID& current_outfit_cat = getCOF(); @@ -3763,6 +3768,14 @@ LLSD LLAppearanceMgr::dumpCOF() const return result; } +void LLAppearanceMgr::cleanup() +{ + mIsInUpdateAppearanceFromCOF = false; + mOutstandingAppearanceBakeRequest = false; + mRerequestAppearanceBake = false; + mCOFID.setNull(); +} + // static void LLAppearanceMgr::onIdle(void *) { @@ -4131,7 +4144,7 @@ void LLAppearanceMgr::wearBaseOutfit() updateCOF(base_outfit_id); } -void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) +void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, nullary_func_t post_update_func) { LL_DEBUGS("UIUsage") << "removeItemsFromAvatar" << LL_ENDL; LLUIUsage::instance().logCommand("Avatar.RemoveItem"); @@ -4141,7 +4154,7 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL; return; } - LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy; + LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy(true, true, post_update_func); for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) { const LLUUID& id_to_remove = *it; @@ -4160,11 +4173,11 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) } } -void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) +void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove, nullary_func_t post_update_func) { uuid_vec_t ids_to_remove; ids_to_remove.push_back(id_to_remove); - removeItemsFromAvatar(ids_to_remove); + removeItemsFromAvatar(ids_to_remove, post_update_func); } @@ -4401,20 +4414,45 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const return FALSE; } -BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const +bool LLAppearanceMgr::getIsInCOF(const LLInventoryObject* obj) const +{ + const LLUUID& cof = getCOF(); + if (obj->getUUID() == cof) + return true; + if (obj && obj->getParentUUID() == cof) + return true; + return false; +} + +bool LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const { - if (!getIsInCOF(obj_id)) return FALSE; + if (!getIsInCOF(obj_id)) return false; // If a non-link somehow ended up in COF, allow deletion. const LLInventoryObject *obj = gInventory.getObject(obj_id); if (obj && !obj->getIsLinkType()) { - return FALSE; + return false; } // For now, don't allow direct deletion from the COF. Instead, force users // to choose "Detach" or "Take Off". - return TRUE; + return true; +} + +bool LLAppearanceMgr::getIsProtectedCOFItem(const LLInventoryObject* obj) const +{ + if (!getIsInCOF(obj)) return false; + + // If a non-link somehow ended up in COF, allow deletion. + if (obj && !obj->getIsLinkType()) + { + return false; + } + + // For now, don't allow direct deletion from the COF. Instead, force users + // to choose "Detach" or "Take Off". + return true; } class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index da29ceee3a..551185e33f 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -111,9 +111,11 @@ public: // Find the Current Outfit folder. const LLUUID getCOF() const; S32 getCOFVersion() const; + void initCOFID(); // Debugging - get truncated LLSD summary of COF contents. LLSD dumpCOF() const; + void cleanup(); // Finds the folder link to the currently worn outfit const LLViewerInventoryItem *getBaseOutfitLink(); @@ -195,8 +197,8 @@ public: bool updateBaseOutfit(); //Remove clothing or detach an object from the agent (a bodypart cannot be removed) - void removeItemsFromAvatar(const uuid_vec_t& item_ids); - void removeItemFromAvatar(const LLUUID& item_id); + void removeItemsFromAvatar(const uuid_vec_t& item_ids, nullary_func_t post_update_func = no_op); + void removeItemFromAvatar(const LLUUID& item_id, nullary_func_t post_update_func = no_op); void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel); @@ -276,6 +278,7 @@ private: attachments_changed_signal_t mAttachmentsChangeSignal; LLUUID mCOFImageID; + LLUUID mCOFID; std::unique_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; @@ -290,8 +293,10 @@ private: public: // Is this in the COF? BOOL getIsInCOF(const LLUUID& obj_id) const; - // Is this in the COF and can the user delete it from the COF? - BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const; + bool getIsInCOF(const LLInventoryObject* obj) const; + // Is this in the COF and can the user delete it from the COF? + bool getIsProtectedCOFItem(const LLUUID& obj_id) const; + bool getIsProtectedCOFItem(const LLInventoryObject* obj) const; // Outfits will prioritize textures with such name to use for preview in gallery static const std::string sExpectedTextureName; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 6e176183d8..fc6153defd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -526,13 +526,6 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) // or for things that are performance critical. JC static void settings_to_globals() { - LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad"); - BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall"); - BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight"); - - MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight"); - MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth"); - LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); #if LL_DARWIN @@ -4308,7 +4301,8 @@ bool LLAppViewer::initCache() LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); - LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); + const U32 CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS = 128; + LLVOCache::getInstance()->initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS, getObjectCacheVersion()); return true; } diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 44bf698caa..52bec5d434 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -245,7 +245,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) // messages. People API already hits the user table. LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI); app->addObserver(mAvatarId, this); - app->sendAvatarPropertiesRequest(mAvatarId); + app->sendAvatarLegacyPropertiesRequest(mAvatarId); } else if (gAgentID == mAvatarId) { @@ -299,9 +299,15 @@ bool LLAvatarIconCtrl::updateFromCache() //virtual void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) { - if (APT_PROPERTIES == type) + // Both APT_PROPERTIES_LEGACY and APT_PROPERTIES have icon data. + // 'Legacy' is cheaper to request so LLAvatarIconCtrl issues that, + // but own icon should track any source for the sake of timely updates. + // + // If this needs to change, make sure to update onCommitProfileImage + // to issue right kind of request + if (APT_PROPERTIES_LEGACY == type) { - LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + LLAvatarLegacyData* avatar_data = static_cast<LLAvatarLegacyData*>(data); if (avatar_data) { if (avatar_data->avatar_id != mAvatarId) @@ -313,6 +319,20 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) updateFromCache(); } } + else if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data) + { + if (avatar_data->avatar_id != mAvatarId) + { + return; + } + + LLAvatarIconIDCache::getInstance()->add(mAvatarId, avatar_data->image_id); + updateFromCache(); + } + } } void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index dd0d06a8c8..bed8887ce1 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -52,24 +52,23 @@ LLAvatarPropertiesProcessor::~LLAvatarPropertiesProcessor() void LLAvatarPropertiesProcessor::addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer) { + if (!observer) + return; + // Check if that observer is already in mObservers for that avatar_id - observer_multimap_t::iterator it; + using pair = std::pair<LLUUID, LLAvatarPropertiesObserver*>; + observer_multimap_t::iterator begin = mObservers.begin(); + observer_multimap_t::iterator end = mObservers.end(); + observer_multimap_t::iterator it = std::find_if(begin, end, [&](const pair& p) + { + return p.first == avatar_id && p.second == observer; + }); // IAN BUG this should update the observer's UUID if this is a dupe - sent to PE - it = mObservers.find(avatar_id); - while (it != mObservers.end()) + if (it == end) { - if (it->second == observer) - { - return; - } - else - { - ++it; - } + mObservers.emplace(avatar_id, observer); } - - mObservers.insert(std::pair<LLUUID, LLAvatarPropertiesObserver*>(avatar_id, observer)); } void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer) @@ -79,19 +78,18 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat return; } - observer_multimap_t::iterator it; - it = mObservers.find(avatar_id); - while (it != mObservers.end()) - { - if (it->second == observer) - { - mObservers.erase(it); - break; - } - else + // Check if that observer is in mObservers for that avatar_id + using pair = std::pair<LLUUID, LLAvatarPropertiesObserver*>; + observer_multimap_t::iterator begin = mObservers.begin(); + observer_multimap_t::iterator end = mObservers.end(); + observer_multimap_t::iterator it = std::find_if(begin, end, [&](const pair& p) { - ++it; - } + return p.first == avatar_id && p.second == observer; + }); + + if (it != end) + { + mObservers.erase(it); } } @@ -116,32 +114,30 @@ void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarPr return; } - std::string cap; - - switch (type) + // Try to send HTTP request if cap_url is available + if (type == APT_PROPERTIES) { - case APT_PROPERTIES: - // indicate we're going to make a request - sendAvatarPropertiesRequestMessage(avatar_id); - // can use getRegionCapability("AgentProfile"), but it is heavy - // initAgentProfileCapRequest(avatar_id, cap); - break; - case APT_PICKS: - case APT_GROUPS: - case APT_NOTES: - if (cap.empty()) + std::string cap_url = gAgent.getRegionCapability("AgentProfile"); + if (!cap_url.empty()) { - // indicate we're going to make a request - sendGenericRequest(avatar_id, type, method); + initAgentProfileCapRequest(avatar_id, cap_url, type); } else { - initAgentProfileCapRequest(avatar_id, cap); + // Don't sent UDP request for APT_PROPERTIES + LL_WARNS() << "No cap_url for APT_PROPERTIES, request for " << avatar_id << " is not sent" << LL_ENDL; } - break; - default: + return; + } + + // Send UDP request + if (type == APT_PROPERTIES_LEGACY) + { + sendAvatarPropertiesRequestMessage(avatar_id); + } + else + { sendGenericRequest(avatar_id, type, method); - break; } } @@ -150,33 +146,29 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA // indicate we're going to make a request addPendingRequest(avatar_id, type); - std::vector<std::string> strings; - strings.push_back(avatar_id.asString()); + std::vector<std::string> strings{ avatar_id.asString() }; send_generic_message(method, strings); } void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id) { - addPendingRequest(avatar_id, APT_PROPERTIES); + addPendingRequest(avatar_id, APT_PROPERTIES_LEGACY); LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_AvatarPropertiesRequest); msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); msg->addUUIDFast(_PREHASH_AvatarID, avatar_id); gAgent.sendReliableMessage(); } -void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url) +void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url, EAvatarProcessorType type) { - addPendingRequest(avatar_id, APT_PROPERTIES); - addPendingRequest(avatar_id, APT_PICKS); - addPendingRequest(avatar_id, APT_GROUPS); - addPendingRequest(avatar_id, APT_NOTES); + addPendingRequest(avatar_id, type); LLCoros::instance().launch("requestAgentUserInfoCoro", - boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id)); + [cap_url, avatar_id, type]() { requestAvatarPropertiesCoro(cap_url, avatar_id, type); }); } void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) @@ -184,19 +176,9 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avat sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); } -void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id) +void LLAvatarPropertiesProcessor::sendAvatarLegacyPropertiesRequest(const LLUUID& avatar_id) { - sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest"); -} - -void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id) -{ - sendGenericRequest(avatar_id, APT_NOTES, "avatarnotesrequest"); -} - -void LLAvatarPropertiesProcessor::sendAvatarGroupsRequest(const LLUUID& avatar_id) -{ - sendGenericRequest(avatar_id, APT_GROUPS, "avatargroupsrequest"); + sendRequest(avatar_id, APT_PROPERTIES_LEGACY, "AvatarPropertiesRequest"); } void LLAvatarPropertiesProcessor::sendAvatarTexturesRequest(const LLUUID& avatar_id) @@ -211,42 +193,6 @@ void LLAvatarPropertiesProcessor::sendAvatarClassifiedsRequest(const LLUUID& ava sendGenericRequest(avatar_id, APT_CLASSIFIEDS, "avatarclassifiedsrequest"); } -void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props) -{ - if (!gAgent.isInitialized() || (gAgent.getID() == LLUUID::null)) - { - LL_WARNS() << "Sending avatarinfo update DENIED - invalid agent" << LL_ENDL; - return; - } - - LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL; - - // This value is required by sendAvatarPropertiesUpdate method. - //A profile should never be mature. (From the original code) - BOOL mature = FALSE; - - LLMessageSystem *msg = gMessageSystem; - - msg->newMessageFast (_PREHASH_AvatarPropertiesUpdate); - msg->nextBlockFast (_PREHASH_AgentData); - msg->addUUIDFast (_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast (_PREHASH_SessionID, gAgent.getSessionID() ); - msg->nextBlockFast (_PREHASH_PropertiesData); - - msg->addUUIDFast (_PREHASH_ImageID, avatar_props->image_id); - msg->addUUIDFast (_PREHASH_FLImageID, avatar_props->fl_image_id); - msg->addStringFast (_PREHASH_AboutText, avatar_props->about_text); - msg->addStringFast (_PREHASH_FLAboutText, avatar_props->fl_about_text); - - msg->addBOOL(_PREHASH_AllowPublish, avatar_props->allow_publish); - msg->addBOOL(_PREHASH_MaturePublish, mature); - msg->addString(_PREHASH_ProfileURL, avatar_props->profile_url); - - gAgent.sendReliableMessage(); -} - - - //static std::string LLAvatarPropertiesProcessor::accountType(const LLAvatarData* avatar_data) { @@ -271,19 +217,21 @@ std::string LLAvatarPropertiesProcessor::accountType(const LLAvatarData* avatar_ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_data) { // Special accounts like M Linden don't have payment info revealed. - if (!avatar_data->caption_text.empty()) return ""; + if (!avatar_data->caption_text.empty()) + return ""; // Linden employees don't have payment info revealed - const S32 LINDEN_EMPLOYEE_INDEX = 3; - if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return ""; + constexpr S32 LINDEN_EMPLOYEE_INDEX = 3; + if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) + return ""; - BOOL transacted = (avatar_data->flags & AVATAR_TRANSACTED); - BOOL identified = (avatar_data->flags & AVATAR_IDENTIFIED); + bool transacted = (avatar_data->flags & AVATAR_TRANSACTED); + bool identified = (avatar_data->flags & AVATAR_IDENTIFIED); // Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations //BOOL age_verified = (avatar_data->flags & AVATAR_AGEVERIFIED); const char* payment_text; - if(transacted) + if (transacted) { payment_text = "PaymentInfoUsed"; } @@ -302,18 +250,22 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data) { // Special accounts like M Linden don't have payment info revealed. - if (!avatar_data->caption_text.empty()) return true; + if (!avatar_data->caption_text.empty()) + return true; // Linden employees don't have payment info revealed - const S32 LINDEN_EMPLOYEE_INDEX = 3; - if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true; + constexpr S32 LINDEN_EMPLOYEE_INDEX = 3; + if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) + return true; return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED)); } // static -void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id) +void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID avatar_id, EAvatarProcessorType type) { + LLAvatarPropertiesProcessor& inst = instance(); + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy)); @@ -323,104 +275,104 @@ void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_ur LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); httpOpts->setFollowRedirects(true); - std::string finalUrl = cap_url + "/" + agent_id.asString(); + std::string finalUrl = cap_url + "/" + avatar_id.asString(); LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders); + // Response is being processed, no longer pending is required + inst.removePendingRequest(avatar_id, type); + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); if (!status || !result.has("id") - || agent_id != result["id"].asUUID()) + || avatar_id != result["id"].asUUID()) { - LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; - LLAvatarPropertiesProcessor* self = getInstance(); - self->removePendingRequest(agent_id, APT_PROPERTIES); - self->removePendingRequest(agent_id, APT_PICKS); - self->removePendingRequest(agent_id, APT_GROUPS); - self->removePendingRequest(agent_id, APT_NOTES); + LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << avatar_id + << (!status ? " (no HTTP status)" : !result.has("id") ? " (no result.id)" : + std::string(" (result.id=") + result["id"].asUUID().asString() + ")") + << LL_ENDL; return; } - // Avatar Data - LLAvatarData avatar_data; + std::string birth_date; - avatar_data.agent_id = agent_id; - avatar_data.avatar_id = agent_id; + avatar_data.agent_id = gAgentID; + avatar_data.avatar_id = avatar_id; avatar_data.image_id = result["sl_image_id"].asUUID(); avatar_data.fl_image_id = result["fl_image_id"].asUUID(); avatar_data.partner_id = result["partner_id"].asUUID(); avatar_data.about_text = result["sl_about_text"].asString(); avatar_data.fl_about_text = result["fl_about_text"].asString(); avatar_data.born_on = result["member_since"].asDate(); - avatar_data.profile_url = getProfileURL(agent_id.asString()); + // TODO: SL-20163 Remove the "has" check when SRV-684 is done + // and the field "hide_age" is included to the http response + inst.mIsHideAgeSupportedByServer = result.has("hide_age"); + avatar_data.hide_age = inst.isHideAgeSupportedByServer() && result["hide_age"].asBoolean(); + avatar_data.profile_url = getProfileURL(avatar_id.asString()); + avatar_data.customer_type = result["customer_type"].asString(); + avatar_data.notes = result["notes"].asString(); avatar_data.flags = 0; - avatar_data.caption_index = 0; - - LLAvatarPropertiesProcessor* self = getInstance(); - // Request processed, no longer pending - self->removePendingRequest(agent_id, APT_PROPERTIES); - self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES); - - // Picks - - LLSD picks_array = result["picks"]; - LLAvatarPicks avatar_picks; - avatar_picks.agent_id = agent_id; // Not in use? - avatar_picks.target_id = agent_id; - - for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it) + if (result["online"].asBoolean()) { - const LLSD& pick_data = *it; - avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); + avatar_data.flags |= AVATAR_ONLINE; + } + if (result["allow_publish"].asBoolean()) + { + avatar_data.flags |= AVATAR_ALLOW_PUBLISH; + } + if (result["identified"].asBoolean()) + { + avatar_data.flags |= AVATAR_IDENTIFIED; + } + if (result["transacted"].asBoolean()) + { + avatar_data.flags |= AVATAR_TRANSACTED; } - // Request processed, no longer pending - self->removePendingRequest(agent_id, APT_PICKS); - self->notifyObservers(agent_id, &avatar_picks, APT_PICKS); + avatar_data.caption_index = 0; + if (result.has("charter_member")) // won't be present if "caption" is set + { + avatar_data.caption_index = result["charter_member"].asInteger(); + } + else if (result.has("caption")) + { + avatar_data.caption_text = result["caption"].asString(); + } // Groups - LLSD groups_array = result["groups"]; - LLAvatarGroups avatar_groups; - avatar_groups.agent_id = agent_id; // Not in use? - avatar_groups.avatar_id = agent_id; // target_id - for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it) { const LLSD& group_info = *it; - LLAvatarGroups::LLGroupData group_data; + LLAvatarData::LLGroupData group_data; group_data.group_powers = 0; // Not in use? group_data.group_title = group_info["name"].asString(); // Missing data, not in use? group_data.group_id = group_info["id"].asUUID(); group_data.group_name = group_info["name"].asString(); group_data.group_insignia_id = group_info["image_id"].asUUID(); - avatar_groups.group_list.push_back(group_data); + avatar_data.group_list.push_back(group_data); } - self->removePendingRequest(agent_id, APT_GROUPS); - self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS); - - // Notes - LLAvatarNotes avatar_notes; - - avatar_notes.agent_id = agent_id; - avatar_notes.target_id = agent_id; - avatar_notes.notes = result["notes"].asString(); + // Picks + LLSD picks_array = result["picks"]; + for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it) + { + const LLSD& pick_data = *it; + avatar_data.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); + } - // Request processed, no longer pending - self->removePendingRequest(agent_id, APT_NOTES); - self->notifyObservers(agent_id, &avatar_notes, APT_NOTES); + inst.notifyObservers(avatar_id, &avatar_data, type); } -void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**) +void LLAvatarPropertiesProcessor::processAvatarLegacyPropertiesReply(LLMessageSystem* msg, void**) { - LLAvatarData avatar_data; + LLAvatarLegacyData avatar_data; std::string birth_date; msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, avatar_data.agent_id); @@ -434,51 +386,23 @@ void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg->getString( _PREHASH_PropertiesData, _PREHASH_ProfileURL, avatar_data.profile_url); msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_Flags, avatar_data.flags); - LLDateUtil::dateFromPDTString(avatar_data.born_on, birth_date); avatar_data.caption_index = 0; S32 charter_member_size = 0; charter_member_size = msg->getSize(_PREHASH_PropertiesData, _PREHASH_CharterMember); - if(1 == charter_member_size) + if (1 == charter_member_size) { msg->getBinaryData(_PREHASH_PropertiesData, _PREHASH_CharterMember, &avatar_data.caption_index, 1); } - else if(1 < charter_member_size) + else if (1 < charter_member_size) { msg->getString(_PREHASH_PropertiesData, _PREHASH_CharterMember, avatar_data.caption_text); } LLAvatarPropertiesProcessor* self = getInstance(); // Request processed, no longer pending - self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES); - self->notifyObservers(avatar_data.avatar_id,&avatar_data,APT_PROPERTIES); -} - -void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* msg, void**) -{ -/* - AvatarInterestsReply is automatically sent by the server in response to the - AvatarPropertiesRequest sent when the panel is opened (in addition to the AvatarPropertiesReply message). - If the interests panel is no longer part of the design (?) we should just register the message - to a handler function that does nothing. - That will suppress the warnings and be compatible with old server versions. - WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply -*/ - - LLInterestsData interests_data; - - msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id ); - msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id ); - msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask ); - msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text ); - msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask ); - msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text ); - msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text ); - - LLAvatarPropertiesProcessor* self = getInstance(); - // Request processed, no longer pending - self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO); - self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO); + self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES_LEGACY); + self->notifyObservers(avatar_data.avatar_id, &avatar_data, APT_PROPERTIES_LEGACY); } void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**) @@ -497,7 +421,7 @@ void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, data.classified_id, n); msg->getString(_PREHASH_Data, _PREHASH_Name, data.name, n); - classifieds.classifieds_list.push_back(data); + classifieds.classifieds_list.emplace_back(data); } LLAvatarPropertiesProcessor* self = getInstance(); @@ -534,44 +458,6 @@ void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* ms self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO); } - -void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void**) -{ - LLAvatarNotes avatar_notes; - - msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_notes.agent_id); - msg->getUUID(_PREHASH_Data, _PREHASH_TargetID, avatar_notes.target_id); - msg->getString(_PREHASH_Data, _PREHASH_Notes, avatar_notes.notes); - - LLAvatarPropertiesProcessor* self = getInstance(); - // Request processed, no longer pending - self->removePendingRequest(avatar_notes.target_id, APT_NOTES); - self->notifyObservers(avatar_notes.target_id,&avatar_notes,APT_NOTES); -} - -void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**) -{ - LLAvatarPicks avatar_picks; - msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id); - msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id); - - S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data); - for (int block = 0; block < block_count; ++block) - { - LLUUID pick_id; - std::string pick_name; - - msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block); - msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block); - - avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name)); - } - LLAvatarPropertiesProcessor* self = getInstance(); - // Request processed, no longer pending - self->removePendingRequest(avatar_picks.target_id, APT_PICKS); - self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS); -} - void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**) { LLPickData pick_data; @@ -602,46 +488,18 @@ void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, voi self->notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO); } -void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, void**) -{ - LLAvatarGroups avatar_groups; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_groups.agent_id ); - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_groups.avatar_id ); - - S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData); - for(S32 i = 0; i < group_count; ++i) - { - LLAvatarGroups::LLGroupData group_data; - - msg->getU64( _PREHASH_GroupData, _PREHASH_GroupPowers, group_data.group_powers, i ); - msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupTitle, group_data.group_title, i ); - msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupID, group_data.group_id, i); - msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group_data.group_name, i ); - msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupInsigniaID, group_data.group_insignia_id, i ); - - avatar_groups.group_list.push_back(group_data); - } - - LLAvatarPropertiesProcessor* self = getInstance(); - self->removePendingRequest(avatar_groups.avatar_id, APT_GROUPS); - self->notifyObservers(avatar_groups.avatar_id,&avatar_groups,APT_GROUPS); -} - -void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type) +void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id, void* data, EAvatarProcessorType type) { // Copy the map (because observers may delete themselves when updated?) LLAvatarPropertiesProcessor::observer_multimap_t observers = mObservers; - observer_multimap_t::iterator oi = observers.begin(); - observer_multimap_t::iterator end = observers.end(); - for (; oi != end; ++oi) + for (const auto& [agent_id, observer] : observers) { // only notify observers for the same agent, or if the observer // didn't know the agent ID and passed a NULL id. - const LLUUID &agent_id = oi->first; if (agent_id == id || agent_id.isNull()) { - oi->second->processProperties(data,type); + observer->processProperties(data, type); } } } @@ -655,8 +513,8 @@ void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32 // setup message header msg->newMessageFast(_PREHASH_GrantUserRights); msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID(_PREHASH_AgentID, gAgentID); + msg->addUUID(_PREHASH_SessionID, gAgentSessionID); msg->nextBlockFast(_PREHASH_Rights); msg->addUUID(_PREHASH_AgentRelated, avatar_id); @@ -666,34 +524,13 @@ void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32 } } -void LLAvatarPropertiesProcessor::sendNotes(const LLUUID& avatar_id, const std::string notes) -{ - if(!avatar_id.isNull()) - { - LLMessageSystem* msg = gMessageSystem; - - // setup message header - msg->newMessageFast(_PREHASH_AvatarNotesUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); - - msg->nextBlockFast(_PREHASH_Data); - msg->addUUID(_PREHASH_TargetID, avatar_id); - msg->addString(_PREHASH_Notes, notes); - - gAgent.sendReliableMessage(); - } -} - - void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id ) { LLMessageSystem* msg = gMessageSystem; msg->newMessage(_PREHASH_PickDelete); msg->nextBlock(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID(_PREHASH_AgentID, gAgentID); + msg->addUUID(_PREHASH_SessionID, gAgentSessionID); msg->nextBlock(_PREHASH_Data); msg->addUUID(_PREHASH_PickID, pick_id); gAgent.sendReliableMessage(); @@ -709,8 +546,8 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_ msg->newMessage(_PREHASH_ClassifiedDelete); msg->nextBlock(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID(_PREHASH_AgentID, gAgentID); + msg->addUUID(_PREHASH_SessionID, gAgentSessionID); msg->nextBlock(_PREHASH_Data); msg->addUUID(_PREHASH_ClassifiedID, classified_id); @@ -718,39 +555,17 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_ gAgent.sendReliableMessage(); } -void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data) -{ - if(!interests_data) - { - return; - } - - LLMessageSystem* msg = gMessageSystem; - - msg->newMessage(_PREHASH_AvatarInterestsUpdate); - msg->nextBlockFast( _PREHASH_AgentData); - msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() ); - msg->nextBlockFast( _PREHASH_PropertiesData); - msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask); - msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text); - msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask); - msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text); - msg->addString( _PREHASH_LanguagesText, interests_data->languages_text); - - gAgent.sendReliableMessage(); -} - void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick) { - if (!new_pick) return; + if (!new_pick) + return; LLMessageSystem* msg = gMessageSystem; msg->newMessage(_PREHASH_PickInfoUpdate); msg->nextBlock(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID(_PREHASH_AgentID, gAgentID); + msg->addUUID(_PREHASH_SessionID, gAgentSessionID); msg->nextBlock(_PREHASH_Data); msg->addUUID(_PREHASH_PickID, new_pick->pick_id); @@ -787,8 +602,8 @@ void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassif msg->newMessage(_PREHASH_ClassifiedInfoUpdate); msg->nextBlock(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID(_PREHASH_AgentID, gAgentID); + msg->addUUID(_PREHASH_SessionID, gAgentSessionID); msg->nextBlock(_PREHASH_Data); msg->addUUID(_PREHASH_ClassifiedID, c_data->classified_id); @@ -809,9 +624,7 @@ void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id, { // Must ask for a pick based on the creator id because // the pick database is distributed to the inventory cluster. JC - std::vector<std::string> request_params; - request_params.push_back(creator_id.asString() ); - request_params.push_back(pick_id.asString() ); + std::vector<std::string> request_params{ creator_id.asString(), pick_id.asString() }; send_generic_message("pickinforequest", request_params); } @@ -822,8 +635,8 @@ void LLAvatarPropertiesProcessor::sendClassifiedInfoRequest(const LLUUID& classi msg->newMessage(_PREHASH_ClassifiedInfoRequest); msg->nextBlock(_PREHASH_AgentData); - msg->addUUID(_PREHASH_AgentID, gAgent.getID()); - msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUID(_PREHASH_AgentID, gAgentID); + msg->addUUID(_PREHASH_SessionID, gAgentSessionID); msg->nextBlock(_PREHASH_Data); msg->addUUID(_PREHASH_ClassifiedID, classified_id); @@ -840,7 +653,7 @@ bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAva if (it == mRequestTimestamps.end()) return false; // We found a request, check if it has timed out - U32 now = time(NULL); + U32 now = time(nullptr); const U32 REQUEST_EXPIRE_SECS = 5; U32 expires = it->second + REQUEST_EXPIRE_SECS; @@ -854,7 +667,7 @@ bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAva void LLAvatarPropertiesProcessor::addPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type) { timestamp_map_t::key_type key = std::make_pair(avatar_id, type); - U32 now = time(NULL); + U32 now = time(nullptr); // Add or update existing (expired) request mRequestTimestamps[ key ] = now; } diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 10cde35f9c..99ed110487 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -50,54 +50,71 @@ class LLMessageSystem; enum EAvatarProcessorType { - APT_PROPERTIES, - APT_NOTES, - APT_GROUPS, - APT_PICKS, + APT_PROPERTIES_LEGACY, // APT_PROPERTIES via udp request (Truncates data!!!) + APT_PROPERTIES, // APT_PROPERTIES via http request APT_PICK_INFO, APT_TEXTURES, - APT_INTERESTS_INFO, APT_CLASSIFIEDS, APT_CLASSIFIED_INFO }; -struct LLInterestsData +// legacy data is supposed to match AvatarPropertiesReply, +// but it is obsolete, fields like about_text will truncate +// data, if you need them, use AgenProfile cap. +// Todo: remove it once once icon ids get moved elsewhere, +// since AgentProfile is too large for bulk icon requests +struct LLAvatarLegacyData { - LLUUID agent_id; - LLUUID avatar_id; //target id - U32 want_to_mask; - std::string want_to_text; - U32 skills_mask; - std::string skills_text; - std::string languages_text; + LLUUID agent_id; + LLUUID avatar_id; //target id + LLUUID image_id; + LLUUID fl_image_id; + LLUUID partner_id; + std::string about_text; + std::string fl_about_text; + LLDate born_on; + std::string profile_url; + U8 caption_index; + std::string caption_text; + std::string customer_type; + U32 flags; }; struct LLAvatarData { - LLUUID agent_id; - LLUUID avatar_id; //target id - LLUUID image_id; - LLUUID fl_image_id; - LLUUID partner_id; - std::string about_text; - std::string fl_about_text; - LLDate born_on; - std::string profile_url; - U8 caption_index; - std::string caption_text; + LLUUID agent_id; + LLUUID avatar_id; //target id + LLUUID image_id; + LLUUID fl_image_id; + LLUUID partner_id; + std::string about_text; + std::string fl_about_text; + LLDate born_on; + std::string profile_url; + U8 caption_index; + std::string caption_text; std::string customer_type; - U32 flags; - BOOL allow_publish; + U32 flags; + bool hide_age; + std::string notes; + + struct LLGroupData; + typedef std::list<LLGroupData> group_list_t; + group_list_t group_list; + + typedef std::pair<LLUUID, std::string> pick_data_t; + typedef std::list< pick_data_t> picks_list_t; + picks_list_t picks_list; }; -struct LLAvatarPicks +struct LLAvatarData::LLGroupData { - LLUUID agent_id; - LLUUID target_id; //target id - - typedef std::pair<LLUUID,std::string> pick_data_t; - typedef std::list< pick_data_t> picks_list_t; - picks_list_t picks_list; + U64 group_powers; + BOOL accept_notices; + std::string group_title; + LLUUID group_id; + std::string group_name; + LLUUID group_insignia_id; }; struct LLPickData @@ -121,36 +138,6 @@ struct LLPickData //used only in write (update) requests LLUUID session_id; - -}; - -struct LLAvatarNotes -{ - LLUUID agent_id; - LLUUID target_id; //target id - std::string notes; -}; - -struct LLAvatarGroups -{ - LLUUID agent_id; - LLUUID avatar_id; //target id - BOOL list_in_profile; - - struct LLGroupData; - typedef std::list<LLGroupData> group_list_t; - - group_list_t group_list; - - struct LLGroupData - { - U64 group_powers; - BOOL accept_notices; - std::string group_title; - LLUUID group_id; - std::string group_name; - LLUUID group_insignia_id; - }; }; struct LLAvatarClassifieds @@ -211,9 +198,7 @@ public: // Request various types of avatar data. Duplicate requests will be // suppressed while waiting for a response from the network. void sendAvatarPropertiesRequest(const LLUUID& avatar_id); - void sendAvatarPicksRequest(const LLUUID& avatar_id); - void sendAvatarNotesRequest(const LLUUID& avatar_id); - void sendAvatarGroupsRequest(const LLUUID& avatar_id); + void sendAvatarLegacyPropertiesRequest(const LLUUID& avatar_id); void sendAvatarTexturesRequest(const LLUUID& avatar_id); void sendAvatarClassifiedsRequest(const LLUUID& avatar_id); @@ -222,21 +207,17 @@ public: void sendClassifiedInfoRequest(const LLUUID& classified_id); - void sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props); - void sendPickInfoUpdate(const LLPickData* new_pick); void sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data); void sendFriendRights(const LLUUID& avatar_id, S32 rights); - void sendNotes(const LLUUID& avatar_id, const std::string notes); - void sendPickDelete(const LLUUID& pick_id); void sendClassifiedDelete(const LLUUID& classified_id); - void sendInterestsInfoUpdate(const LLInterestsData* interests_data); + bool isHideAgeSupportedByServer() { return mIsHideAgeSupportedByServer; } // Returns translated, human readable string for account type, such // as "Resident" or "Linden Employee". Used for profiles, inspectors. @@ -249,30 +230,23 @@ public: static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data); - static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id); - - static void processAvatarPropertiesReply(LLMessageSystem* msg, void**); + static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID avatar_id, EAvatarProcessorType type); - static void processAvatarInterestsReply(LLMessageSystem* msg, void**); + // Processing of UDP variant of properties, truncates certain fields! + static void processAvatarLegacyPropertiesReply(LLMessageSystem* msg, void**); static void processAvatarClassifiedsReply(LLMessageSystem* msg, void**); static void processClassifiedInfoReply(LLMessageSystem* msg, void**); - static void processAvatarGroupsReply(LLMessageSystem* msg, void**); - - static void processAvatarNotesReply(LLMessageSystem* msg, void**); - - static void processAvatarPicksReply(LLMessageSystem* msg, void**); - static void processPickInfoReply(LLMessageSystem* msg, void**); protected: - void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method); + void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method); void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method); void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id); - void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url); + void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url, EAvatarProcessorType type); void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type); @@ -302,6 +276,9 @@ protected: // Map avatar_id+request_type -> U32 timestamp in seconds typedef std::map< std::pair<LLUUID, EAvatarProcessorType>, U32> timestamp_map_t; timestamp_map_t mRequestTimestamps; + + // Is returned by isHideAgeSupportedByServer() + bool mIsHideAgeSupportedByServer { false }; }; #endif // LL_LLAVATARPROPERTIESPROCESSOR_H diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp index 9e7a8ba95c..934b852a41 100644 --- a/indra/newview/llchannelmanager.cpp +++ b/indra/newview/llchannelmanager.cpp @@ -88,7 +88,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel() { // creating params for a channel LLScreenChannelBase::Params p; - p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID")); + p.id = NOTIFICATION_CHANNEL_UUID; p.channel_align = CA_RIGHT; p.toast_align = NA_TOP; @@ -108,7 +108,7 @@ void LLChannelManager::onLoginCompleted() if (!channel) continue; // don't calc notifications for Nearby Chat - if(channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))) + if(channel->getChannelID() == NEARBY_CHAT_CHANNEL_UUID) { continue; } @@ -130,7 +130,7 @@ void LLChannelManager::onLoginCompleted() { // create a channel for the StartUp Toast LLScreenChannelBase::Params p; - p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID")); + p.id = STARTUP_CHANNEL_UUID; p.channel_align = CA_RIGHT; mStartUpChannel = createChannel(p); @@ -143,9 +143,8 @@ void LLChannelManager::onLoginCompleted() gViewerWindow->getRootView()->addChild(mStartUpChannel); // init channel's position and size - S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); - S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound); + S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + mStartUpChannel->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound); mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4)); mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this)); @@ -164,7 +163,7 @@ void LLChannelManager::onStartUpToastClose() { mStartUpChannel->setVisible(FALSE); mStartUpChannel->closeStartUpToast(); - removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID"))); + removeChannelByID(STARTUP_CHANNEL_UUID); mStartUpChannel = NULL; } @@ -258,12 +257,12 @@ LLNotificationsUI::LLScreenChannel* LLChannelManager::getNotificationScreenChann { LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + findChannelByID(NOTIFICATION_CHANNEL_UUID)); if (channel == NULL) { - LL_WARNS() << "Can't find screen channel by NotificationChannelUUID" << LL_ENDL; - llassert(!"Can't find screen channel by NotificationChannelUUID"); + LL_WARNS() << "Can't find screen channel by Notification Channel UUID" << LL_ENDL; + llassert(!"Can't find screen channel by Notification Channel UUID"); } return channel; diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index aa2ba752b7..b138db48b5 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -142,7 +142,7 @@ protected: registrar.add("Attachment.Touch", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs)); registrar.add("Attachment.Edit", boost::bind(handleMultiple, handle_item_edit, mUUIDs)); - registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs)); + registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; enable_registrar.add("Attachment.OnEnable", boost::bind(&CofAttachmentContextMenu::onEnable, this, _2)); @@ -195,7 +195,7 @@ protected: LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; LLUUID selected_id = mUUIDs.back(); - registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs)); + registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id)); registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id)); diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index eb2c156ca5..320806d78d 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -66,6 +66,7 @@ namespace { const std::string QUEUE_EVENTPUMP_NAME("ScriptActionQueue"); + const F32 QUEUE_INVENTORY_FETCH_TIMEOUT = 300.f; // ObjectIventoryFetcher is an adapter between the LLVOInventoryListener::inventoryChanged // callback mechanism and the LLEventPump coroutine architecture allowing the @@ -359,8 +360,6 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. // which is caught in objectScriptProcessingQueueCoro bool monocompile = floater->mMono; - F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout"); - // Initial test to see if we can (or should) attempt to compile the script. LLInventoryItem *item = dynamic_cast<LLInventoryItem *>(inventory); @@ -385,7 +384,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat LLExperienceCache::instance().fetchAssociatedExperience(inventory->getParentUUID(), inventory->getUUID(), boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _1)); - result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, + result = llcoro::suspendUntilEventOnWithTimeout(pump, QUEUE_INVENTORY_FETCH_TIMEOUT, LLSDMap("timeout", LLSD::Boolean(true))); floater.check(); @@ -435,7 +434,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat &LLFloaterCompileQueue::handleScriptRetrieval, &userData); - result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, + result = llcoro::suspendUntilEventOnWithTimeout(pump, QUEUE_INVENTORY_FETCH_TIMEOUT, LLSDMap("timeout", LLSD::Boolean(true))); } @@ -481,7 +480,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } - result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true))); + result = llcoro::suspendUntilEventOnWithTimeout(pump, QUEUE_INVENTORY_FETCH_TIMEOUT, LLSDMap("timeout", LLSD::Boolean(true))); floater.check(); @@ -736,8 +735,6 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. // This is expected if the dialog closes. LLEventMailDrop maildrop(QUEUE_EVENTPUMP_NAME, true); - F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout"); - try { @@ -759,7 +756,7 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L args["[OBJECT_NAME]"] = (*itObj).mObjectName; floater->addStringMessage(floater->getString("LoadingObjInv", args)); - LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, fetch_timeout, + LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, QUEUE_INVENTORY_FETCH_TIMEOUT, LLSDMap("timeout", LLSD::Boolean(true))); if (result.has("timeout")) diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index d764f64c79..7848ad5a63 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -137,9 +137,9 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_ { LLVector3 pos_box_offset = point_to_box_offset(vol_pos, unshift_extents); F32 offset_dist = pos_box_offset.length(); - if (offset_dist > max_legal_offset && offset_dist > 0.f) + if (offset_dist > MAX_LEGAL_OFFSET && offset_dist > 0.f) { - F32 target_dist = (offset_dist - max_legal_offset); + F32 target_dist = (offset_dist - MAX_LEGAL_OFFSET); new_pos_fixup = (target_dist/offset_dist)*pos_box_offset; } if (new_pos_fixup != mPositionConstraintFixup) @@ -152,11 +152,11 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_ } } - if (box_size/mScaleConstraintFixup > max_legal_size) + if (box_size/mScaleConstraintFixup > MAX_LEGAL_SIZE) { - new_scale_fixup = mScaleConstraintFixup*max_legal_size/box_size; + new_scale_fixup = mScaleConstraintFixup* MAX_LEGAL_SIZE /box_size; LL_DEBUGS("ConstraintFix") << getFullname() << " scale fix, box_size " << box_size << " fixup " - << mScaleConstraintFixup << " max legal " << max_legal_size + << mScaleConstraintFixup << " max legal " << MAX_LEGAL_SIZE << " -> new scale " << new_scale_fixup << LL_ENDL; } } @@ -201,8 +201,7 @@ void LLControlAvatar::matchVolumeTransform() mRoot->setWorldRotation(obj_rot * joint_rot); setRotation(mRoot->getRotation()); - F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale"); - setGlobalScale(global_scale * mScaleConstraintFixup); + setGlobalScale(mScaleConstraintFixup); } else { @@ -252,8 +251,7 @@ void LLControlAvatar::matchVolumeTransform() } mRoot->setPosition(vol_pos + mPositionConstraintFixup); - F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale"); - setGlobalScale(global_scale * mScaleConstraintFixup); + setGlobalScale(mScaleConstraintFixup); } } } diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 436c9c00ab..6065f6558c 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -82,7 +82,7 @@ public: virtual BOOL isItemRenameable() const { return TRUE; } virtual BOOL renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return TRUE; } virtual BOOL isItemMovable( void ) const { return FALSE; } - virtual BOOL isItemRemovable( void ) const { return FALSE; } + virtual BOOL isItemRemovable(bool check_worn = true) const { return FALSE; } virtual BOOL isItemInTrash( void) const { return FALSE; } virtual BOOL removeItem() { return FALSE; } virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { } diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 48c7df40df..84e5e2fe44 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -106,6 +106,8 @@ LLConversationViewSession::~LLConversationViewSession() } mFlashTimer->unset(); + delete mFlashTimer; + mFlashStateOn = false; } void LLConversationViewSession::destroyView() diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 60c2682078..5af629a3e0 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2112,7 +2112,7 @@ void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environ { LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL; } - else if (LLApp::isExiting()) + else if (LLApp::isExiting() || gDisconnected) { return; } diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 2d332f75f5..8b7593e169 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -243,6 +243,12 @@ LLExpandableTextBox::LLExpandableTextBox(const Params& p) mTextBox->setCommitCallback(boost::bind(&LLExpandableTextBox::onExpandClicked, this)); } + +LLExpandableTextBox::~LLExpandableTextBox() +{ + gViewerWindow->removePopup(this); +} + void LLExpandableTextBox::draw() { if(mBGVisible && !mExpanded) diff --git a/indra/newview/llexpandabletextbox.h b/indra/newview/llexpandabletextbox.h index aaf393277f..8094036081 100644 --- a/indra/newview/llexpandabletextbox.h +++ b/indra/newview/llexpandabletextbox.h @@ -121,7 +121,7 @@ public: /** * Returns text */ - virtual std::string getText() const { return mText; } + virtual const std::string& getText() const { return mText; } /** * Sets text @@ -154,6 +154,8 @@ public: */ /*virtual*/ void draw(); + virtual ~LLExpandableTextBox(); + protected: LLExpandableTextBox(const Params& p); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 4ad136e13a..27b28681e0 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -627,6 +627,9 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF switch(filter) { case FFLOAD_ALL: + case FFLOAD_EXE: + allowedv->push_back("app"); + allowedv->push_back("exe"); allowedv->push_back("wav"); allowedv->push_back("bvh"); allowedv->push_back("anim"); @@ -647,9 +650,6 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF allowedv->push_back("tpic"); allowedv->push_back("png"); break; - case FFLOAD_EXE: - allowedv->push_back("app"); - allowedv->push_back("exe"); break; case FFLOAD_WAV: allowedv->push_back("wav"); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 42ef41017a..e8ce4aa42a 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -107,15 +107,11 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) mCloseOnSelect(FALSE), mExcludeAgentFromSearchResults(FALSE), mContextConeOpacity (0.f), - mContextConeInAlpha(0.f), - mContextConeOutAlpha(0.f), - mContextConeFadeTime(0.f) + mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA), + mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA), + mContextConeFadeTime(CONTEXT_CONE_FADE_TIME) { mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this)); - - mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); - mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); - mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); } BOOL LLFloaterAvatarPicker::postBuild() diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index ba91277c79..1672969e82 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -102,9 +102,9 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show mActive ( TRUE ), mCanApplyImmediately ( show_apply_immediate ), mContextConeOpacity ( 0.f ), - mContextConeInAlpha ( 0.f ), - mContextConeOutAlpha ( 0.f ), - mContextConeFadeTime ( 0.f ) + mContextConeInAlpha (CONTEXT_CONE_IN_ALPHA), + mContextConeOutAlpha (CONTEXT_CONE_OUT_ALPHA), + mContextConeFadeTime (CONTEXT_CONE_FADE_TIME) { buildFromFile ( "floater_color_picker.xml"); @@ -116,10 +116,6 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show mApplyImmediateCheck->setEnabled(FALSE); mApplyImmediateCheck->set(FALSE); } - - mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); - mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); - mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); } LLFloaterColorPicker::~LLFloaterColorPicker() diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index 580a3f2610..97327da81a 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -37,13 +37,14 @@ const std::string LL_FCP_COMPLETE_NAME("complete_name"); const std::string LL_FCP_ACCOUNT_NAME("user_name"); +const S32 CONVERSATION_HISTORY_PAGE_SIZE = 100; LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id) : LLFloater(session_id), mChatHistory(NULL), mSessionID(session_id.asUUID()), mCurrentPage(0), - mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")), + mPageSize(CONVERSATION_HISTORY_PAGE_SIZE), mAccountName(session_id[LL_FCP_ACCOUNT_NAME]), mCompleteName(session_id[LL_FCP_COMPLETE_NAME]), mMutex(), diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp index 1578caa39c..51b31a72ca 100644 --- a/indra/newview/llfloateremojipicker.cpp +++ b/indra/newview/llfloateremojipicker.cpp @@ -40,6 +40,7 @@ #include "llscrolllistitem.h" #include "llsdserialize.h" #include "lltextbox.h" +#include "lltrans.h" #include "llviewerchat.h" namespace { @@ -128,7 +129,7 @@ public: , const LLEmojiSearchResult& emoji) : LLScrollingPanel(panel_params) , mData(emoji) - , mText(LLWString(1, emoji.Character)) + , mChar(LLWString(1, emoji.Character)) { } @@ -138,8 +139,8 @@ public: F32 x = getRect().getWidth() / 2; F32 y = getRect().getHeight() / 2; - LLFontGL::getFontEmoji()->render( - mText, // wstr + LLFontGL::getFontEmojiLarge()->render( + mChar, // wstr 0, // begin_offset x, // x y, // y @@ -154,11 +155,11 @@ public: virtual void updatePanel(BOOL allow_modify) override {} const LLEmojiSearchResult& getData() const { return mData; } - LLWString getText() const { return mText; } + const LLWString& getChar() const { return mChar; } private: const LLEmojiSearchResult mData; - const LLWString mText; + const LLWString mChar; }; class LLEmojiPreviewPanel : public LLPanel @@ -229,7 +230,7 @@ protected: { F32 x0 = x; F32 x1 = max_pixels; - LLFontGL* font = LLFontGL::getFontEmoji(); + LLFontGL* font = LLFontGL::getFontEmojiLarge(); if (mBegin) { std::string text = mTitle.substr(0, mBegin); @@ -388,9 +389,12 @@ void LLFloaterEmojiPicker::initialize() } else { - const std::string prompt("No emoji found for "); - std::string title(prompt + '"' + mFilterPattern.substr(1) + '"'); - mPreview->setData(EMPTY_LIST_IMAGE_INDEX, title, prompt.size() + 1, title.size() - 1); + std::size_t begin, end; + LLStringUtil::format_map_t args; + args["[FILTER]"] = mFilterPattern.substr(1); + std::string title(getString("text_no_emoji_for_filter", args)); + LLEmojiDictionary::searchInShortCode(begin, end, title, mFilterPattern); + mPreview->setData(EMPTY_LIST_IMAGE_INDEX, title, begin, end); showPreview(true); } return; @@ -423,7 +427,7 @@ void LLFloaterEmojiPicker::fillGroups() mGroupButtons.clear(); LLButton::Params params; - params.font = LLFontGL::getFontEmoji(); + params.font = LLFontGL::getFontEmojiLarge(); LLRect rect; rect.mTop = mGroups->getRect().getHeight(); @@ -485,10 +489,12 @@ void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::map<std::string, std::v auto e2d = emoji2descr.find(emoji); if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty()) { - const std::string shortcode(e2d->second->ShortCodes.front()); - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + for (const std::string& shortcode : e2d->second->ShortCodes) { - emojis.emplace_back(emoji, shortcode, begin, end); + if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + { + emojis.emplace_back(emoji, shortcode, begin, end); + } } } } @@ -517,10 +523,12 @@ void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std: auto e2d = emoji2descr.find(emoji.first); if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty()) { - const std::string shortcode(e2d->second->ShortCodes.front()); - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + for (const std::string& shortcode : e2d->second->ShortCodes) { - emojis.emplace_back(emoji.first, shortcode, begin, end); + if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + { + emojis.emplace_back(emoji.first, shortcode, begin, end); + } } } } @@ -553,10 +561,12 @@ void LLFloaterEmojiPicker::fillGroupEmojis(std::map<std::string, std::vector<LLE { if (!descr->ShortCodes.empty()) { - const std::string shortcode(descr->ShortCodes.front()); - if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + for (const std::string& shortcode : descr->ShortCodes) { - emojis.emplace_back(descr->Character, shortcode, begin, end); + if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern)) + { + emojis.emplace_back(descr->Character, shortcode, begin, end); + } } } } @@ -924,7 +934,7 @@ void LLFloaterEmojiPicker::onEmojiMouseUp(LLUICtrl* ctrl) if (LLEmojiGridIcon* icon = dynamic_cast<LLEmojiGridIcon*>(ctrl)) { - LLSD value(wstring_to_utf8str(icon->getText())); + LLSD value(wstring_to_utf8str(icon->getChar())); setValue(value); onCommit(); diff --git a/indra/newview/llfloaterexperiencepicker.cpp b/indra/newview/llfloaterexperiencepicker.cpp index c642da7b83..fe7854b3a5 100644 --- a/indra/newview/llfloaterexperiencepicker.cpp +++ b/indra/newview/llfloaterexperiencepicker.cpp @@ -88,13 +88,10 @@ LLFloaterExperiencePicker::LLFloaterExperiencePicker( const LLSD& key ) :LLFloater(key) ,mSearchPanel(NULL) ,mContextConeOpacity(0.f) - ,mContextConeInAlpha(0.f) - ,mContextConeOutAlpha(0.f) - ,mContextConeFadeTime(0.f) + ,mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA) + ,mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA) + ,mContextConeFadeTime(CONTEXT_CONE_FADE_TIME) { - mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); - mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); - mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); } LLFloaterExperiencePicker::~LLFloaterExperiencePicker() diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 40bdf14deb..c934fdad63 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -261,7 +261,8 @@ void LLFloaterIMNearbyChat::loadHistory() void LLFloaterIMNearbyChat::removeScreenChat() { - LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID"))); + LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID( + LLNotificationsUI::NEARBY_CHAT_CHANNEL_UUID); if(chat_channel) { chat_channel->removeToastsFromChannel(); diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp index eb7bd843d3..76bb10d149 100644 --- a/indra/newview/llfloaterimnearbychathandler.cpp +++ b/indra/newview/llfloaterimnearbychathandler.cpp @@ -459,7 +459,7 @@ LLFloaterIMNearbyChatHandler::LLFloaterIMNearbyChatHandler() { // Getting a Channel for our notifications LLFloaterIMNearbyChatScreenChannel::Params p; - p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID")); + p.id = NEARBY_CHAT_CHANNEL_UUID; LLFloaterIMNearbyChatScreenChannel* channel = new LLFloaterIMNearbyChatScreenChannel(p); LLFloaterIMNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel; diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index ed2a2807b5..dc756deab1 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -653,7 +653,7 @@ void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock) // update notification channel state LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID)); if(!isChatMultiTab()) { @@ -689,7 +689,7 @@ void LLFloaterIMSession::setVisible(BOOL visible) { LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID)); LLFloaterIMSessionTab::setVisible(visible); @@ -867,7 +867,7 @@ void LLFloaterIMSession::updateMessages() // remove embedded notification from channel LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*> (LLNotificationsUI::LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID)); if (getVisible()) { // toast will be automatically closed since it is not storable toast diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 24cc398f3b..e174dad77d 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -267,9 +267,13 @@ BOOL LLFloaterIMSessionTab::postBuild() mEmojiRecentEmptyText->setToolTip(mEmojiRecentEmptyText->getText()); mEmojiRecentEmptyText->setVisible(false); + mEmojiRecentContainer = getChild<LLPanel>("emoji_recent_container"); + mEmojiRecentContainer->setVisible(false); + mEmojiRecentIconsCtrl = getChild<LLPanelEmojiComplete>("emoji_recent_icons_ctrl"); + mEmojiRecentIconsCtrl->setFocusReceivedCallback([this](LLFocusableElement*) { onEmojiRecentPanelFocusReceived(); }); + mEmojiRecentIconsCtrl->setFocusLostCallback([this](LLFocusableElement*) { onEmojiRecentPanelFocusLost(); }); mEmojiRecentIconsCtrl->setCommitCallback([this](LLUICtrl*, const LLSD& value) { onRecentEmojiPicked(value); }); - mEmojiRecentIconsCtrl->setVisible(false); mEmojiPickerShowBtn = getChild<LLButton>("emoji_picker_show_btn"); mEmojiPickerShowBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerShowBtnClicked(); }); @@ -475,7 +479,7 @@ void LLFloaterIMSessionTab::initEmojiRecentPanel() if (recentlyUsed.empty()) { mEmojiRecentEmptyText->setVisible(TRUE); - mEmojiRecentIconsCtrl->setVisible(FALSE); + mEmojiRecentContainer->setVisible(FALSE); } else { @@ -486,10 +490,22 @@ void LLFloaterIMSessionTab::initEmojiRecentPanel() } mEmojiRecentIconsCtrl->setEmojis(emojis); mEmojiRecentEmptyText->setVisible(FALSE); - mEmojiRecentIconsCtrl->setVisible(TRUE); + mEmojiRecentContainer->setVisible(TRUE); } } +// static +void LLFloaterIMSessionTab::onEmojiRecentPanelFocusReceived() +{ + mEmojiRecentContainer->addBorder(); +} + +// static +void LLFloaterIMSessionTab::onEmojiRecentPanelFocusLost() +{ + mEmojiRecentContainer->removeBorder(); +} + void LLFloaterIMSessionTab::onRecentEmojiPicked(const LLSD& value) { LLSD::String str = value.asString(); diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index cc985b2753..58bfa04dba 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -173,6 +173,7 @@ protected: LLLayoutPanel* mInputButtonPanel; LLLayoutPanel* mEmojiRecentPanel; LLTextBox* mEmojiRecentEmptyText; + LLPanel* mEmojiRecentContainer; LLPanelEmojiComplete* mEmojiRecentIconsCtrl; LLParticipantList* getParticipantList(); conversations_widgets_map mConversationsWidgets; @@ -218,6 +219,8 @@ private: void onEmojiRecentPanelToggleBtnClicked(); void onEmojiPickerShowBtnClicked(); void initEmojiRecentPanel(); + void onEmojiRecentPanelFocusReceived(); + void onEmojiRecentPanelFocusLost(); void onRecentEmojiPicked(const LLSD& value); bool checkIfTornOff(); diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index 558b14bba7..d3add020cf 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -250,6 +250,13 @@ void LLFloaterJoystick::refresh() initFromSettings(); } +bool LLFloaterJoystick::addDeviceCallback(std::string &name, LLSD& value, void* userdata) +{ + LLFloaterJoystick * floater = (LLFloaterJoystick*)userdata; + floater->mJoysticksCombo->add(name, value, ADD_BOTTOM, 1); + return false; // keep searching +} + void LLFloaterJoystick::addDevice(std::string &name, LLSD& value) { mJoysticksCombo->add(name, value, ADD_BOTTOM, 1); @@ -264,19 +271,21 @@ void LLFloaterJoystick::refreshListOfDevices() mHasDeviceList = false; + void* win_calback = nullptr; // di8_devices_callback callback is immediate and happens in scope of getInputDevices() #if LL_WINDOWS && !LL_MESA_HEADLESS // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib U32 device_type = DI8DEVCLASS_GAMECTRL; - void* callback = &di8_list_devices_callback; + win_calback = di8_list_devices_callback; +#elif LL_DARWIN + U32 device_type = 0; #else - // MAC doesn't support device search yet - // On MAC there is an ndof_idsearch and it is possible to specify product - // and manufacturer in NDOF_Device for ndof_init_first to pick specific one + // On MAC it is possible to specify product + // and manufacturer in NDOF_Device for + // ndof_init_first to pick specific device U32 device_type = 0; - void* callback = NULL; #endif - if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this)) + if (gViewerWindow->getWindow()->getInputDevices(device_type, addDeviceCallback, win_calback, this)) { mHasDeviceList = true; } @@ -418,10 +427,11 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) joystick->toggleFlycam(); } } - - std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString(); - gSavedSettings.setString("JoystickDeviceUUID", device_id); - LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL; + + LLViewerJoystick::getInstance()->saveDeviceIdToSettings(); + + std::string device_string = LLViewerJoystick::getInstance()->getDeviceUUIDString(); + LL_DEBUGS("Joystick") << "Selected " << device_string << " as joystick." << LL_ENDL; self->refreshListOfDevices(); } diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index 1d46efd3f6..ff889c804b 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -46,6 +46,7 @@ public: virtual void draw(); static void setSNDefaults(); + static bool addDeviceCallback(std::string &name, LLSD& value, void* userdata); void addDevice(std::string &name, LLSD& value); protected: diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp index d1679fd936..2ff6c5618c 100644 --- a/indra/newview/llfloaternotificationstabbed.cpp +++ b/indra/newview/llfloaternotificationstabbed.cpp @@ -154,7 +154,7 @@ LLPanel * LLFloaterNotificationsTabbed::findItemByID(const LLUUID& id, std::stri void LLFloaterNotificationsTabbed::initChannel() { LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID( - LLUUID(gSavedSettings.getString("NotificationChannelUUID"))); + LLNotificationsUI::NOTIFICATION_CHANNEL_UUID); mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel); if(NULL == mChannel) { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index b65d727948..168106f1d2 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -368,9 +368,9 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) { - if ( APT_PROPERTIES == type ) + if ( APT_PROPERTIES_LEGACY == type ) { - const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData ); + const LLAvatarLegacyData* pAvatarData = static_cast<const LLAvatarLegacyData*>( pData ); if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null)) { mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH); @@ -510,9 +510,7 @@ BOOL LLFloaterPreference::postBuild() void LLFloaterPreference::updateDeleteTranscriptsButton() { - std::vector<std::string> list_of_transcriptions_file_names; - LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names); - getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0); + getChild<LLButton>("delete_transcripts")->setEnabled(LLLogChat::transcriptFilesExist()); } void LLFloaterPreference::onDoNotDisturbResponseChanged() @@ -677,7 +675,6 @@ void LLFloaterPreference::cancel() void LLFloaterPreference::onOpen(const LLSD& key) { - // this variable and if that follows it are used to properly handle do not disturb mode response message static bool initialized = FALSE; // if user is logged in and we haven't initialized do not disturb mode response yet, do it @@ -704,7 +701,7 @@ void LLFloaterPreference::onOpen(const LLSD& key) (gAgent.isMature() || gAgent.isGodlike()); LLComboBox* maturity_combo = getChild<LLComboBox>("maturity_desired_combobox"); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest( gAgent.getID() ); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarLegacyPropertiesRequest( gAgent.getID() ); if (can_choose_maturity) { // if they're not adult or a god, they shouldn't see the adult selection, so delete it diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp index ec2e627165..a46548f29a 100644 --- a/indra/newview/llfloaterprofiletexture.cpp +++ b/indra/newview/llfloaterprofiletexture.cpp @@ -33,39 +33,173 @@ #include "llpreview.h" // fors constants #include "lltrans.h" #include "llviewercontrol.h" -#include "lltextureview.h" #include "llviewertexture.h" #include "llviewertexturelist.h" + ////////////////////////////////////////////////////////////////////////// + // LLProfileImageCtrl + ////////////////////////////////////////////////////////////////////////// -LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner) - : LLFloater(LLSD()) - , mUpdateDimensions(TRUE) - , mLastHeight(0) - , mLastWidth(0) +static LLDefaultChildRegistry::Register<LLProfileImageCtrl> r("profile_image"); + +LLProfileImageCtrl::LLProfileImageCtrl(const LLProfileImageCtrl::Params& p) + : LLIconCtrl(p) , mImage(NULL) , mImageOldBoostLevel(LLGLTexture::BOOST_NONE) - , mOwnerHandle(owner->getHandle()) + , mWasNoDelete(false) + , mImageLoadedSignal(NULL) { - buildFromFile("floater_profile_texture.xml"); } -LLFloaterProfileTexture::~LLFloaterProfileTexture() +LLProfileImageCtrl::~LLProfileImageCtrl() +{ + LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList); + releaseTexture(); + + delete mImageLoadedSignal; +} + +void LLProfileImageCtrl::releaseTexture() { if (mImage.notNull()) { mImage->setBoostLevel(mImageOldBoostLevel); + if (!mWasNoDelete) + { + // In most cases setBoostLevel marks images as NO_DELETE + mImage->forceActive(); + } mImage = NULL; } +} + +void LLProfileImageCtrl::setValue(const LLSD& value) +{ + LLUUID id = value.asUUID(); + setImageAssetId(id); + if (id.isNull()) + { + LLIconCtrl::setValue("Generic_Person_Large", LLGLTexture::BOOST_UI); + } + else + { + // called second to not change priority before it gets saved to mImageOldBoostLevel + LLIconCtrl::setValue(value, LLGLTexture::BOOST_PREVIEW); + } +} + +void LLProfileImageCtrl::draw() +{ + if (mImage.notNull()) + { + // Pump the texture priority + mImage->addTextureStats(MAX_IMAGE_AREA); + mImage->setKnownDrawSize(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT, LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); + } + LLIconCtrl::draw(); +} - LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList); +boost::signals2::connection LLProfileImageCtrl::setImageLoadedCallback(const image_loaded_signal_t::slot_type& cb) +{ + if (!mImageLoadedSignal) mImageLoadedSignal = new image_loaded_signal_t(); + + return mImageLoadedSignal->connect(cb); +} + +void LLProfileImageCtrl::setImageAssetId(const LLUUID& asset_id) +{ + if (mImageID == asset_id) + { + return; + } + + releaseTexture(); + + mImageID = asset_id; + if (mImageID.notNull()) + { + mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + mWasNoDelete = mImage->getTextureState() == LLGLTexture::NO_DELETE; + mImageOldBoostLevel = mImage->getBoostLevel(); + mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); + mImage->setKnownDrawSize(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT, LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); + mImage->forceToSaveRawImage(0); + + if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) + { + mImage->setLoadedCallback(LLProfileImageCtrl::onImageLoaded, + 0, TRUE, FALSE, new LLHandle<LLUICtrl>(getHandle()), &mCallbackTextureList); + } + else + { + onImageLoaded(true, mImage); + } + } +} + +void LLProfileImageCtrl::onImageLoaded(bool success, LLViewerFetchedTexture* img) +{ + if (mImageLoadedSignal) + { + (*mImageLoadedSignal)(success, img); + } +} + +// static +void LLProfileImageCtrl::onImageLoaded(BOOL success, + LLViewerFetchedTexture* src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata) +{ + if (!userdata) return; + + LLHandle<LLUICtrl>* handle = (LLHandle<LLUICtrl>*)userdata; + + if (!handle->isDead()) + { + LLProfileImageCtrl* caller = static_cast<LLProfileImageCtrl*>(handle->get()); + if (caller && caller->mImageLoadedSignal) + { + (*caller->mImageLoadedSignal)(success, src_vi); + } + } + + if (final || !success) + { + delete handle; + } +} + + +////////////////////////////////////////////////////////////////////////// +// LLFloaterProfileTexture + ////////////////////////////////////////////////////////////////////////// + +LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner) + : LLFloater(LLSD()) + , mLastHeight(0) + , mLastWidth(0) + , mOwnerHandle(owner->getHandle()) + , mContextConeOpacity(0.f) + , mCloseButton(NULL) + , mProfileIcon(NULL) +{ + buildFromFile("floater_profile_texture.xml"); +} + +LLFloaterProfileTexture::~LLFloaterProfileTexture() +{ } // virtual BOOL LLFloaterProfileTexture::postBuild() { - mProfileIcon = getChild<LLIconCtrl>("profile_pic"); + mProfileIcon = getChild<LLProfileImageCtrl>("profile_pic"); + mProfileIcon->setImageLoadedCallback([this](BOOL success, LLViewerFetchedTexture* imagep) {onImageLoaded(success, imagep); }); mCloseButton = getChild<LLButton>("close_btn"); mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr); @@ -83,55 +217,41 @@ void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_pa // When we receive it, reshape the window accordingly. void LLFloaterProfileTexture::updateDimensions() { - if (mImage.isNull()) + LLPointer<LLViewerFetchedTexture> image = mProfileIcon->getImage(); + if (image.isNull()) { return; } - if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) + if ((image->getFullWidth() * image->getFullHeight()) == 0) { return; } - S32 img_width = mImage->getFullWidth(); - S32 img_height = mImage->getFullHeight(); - - if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED - || mLastWidth != img_width - || mLastHeight != img_height) - { - mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED; - // Asset has been fully loaded - mUpdateDimensions = TRUE; - } + S32 img_width = image->getFullWidth(); + S32 img_height = image->getFullHeight(); mLastHeight = img_height; mLastWidth = img_width; - // Reshape the floater only when required - if (mUpdateDimensions) - { - mUpdateDimensions = FALSE; - - LLRect old_floater_rect = getRect(); - LLRect old_image_rect = mProfileIcon->getRect(); - S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth; - S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight; + LLRect old_floater_rect = getRect(); + LLRect old_image_rect = mProfileIcon->getRect(); + S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth; + S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight; - const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256 + const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256 - S32 biggest_dim = llmax(width, height); - if (biggest_dim > MAX_DIMENTIONS) - { - F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim; - width *= scale_down; - height *= scale_down; - } + S32 biggest_dim = llmax(width, height); + if (biggest_dim > MAX_DIMENTIONS) + { + F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim; + width *= scale_down; + height *= scale_down; + } - //reshape floater - reshape(width, height); + //reshape floater + reshape(width, height); - gFloaterView->adjustToFitScreen(this, FALSE); - } + gFloaterView->adjustToFitScreen(this, FALSE); } void LLFloaterProfileTexture::draw() @@ -151,75 +271,18 @@ void LLFloaterProfileTexture::onOpen(const LLSD& key) void LLFloaterProfileTexture::resetAsset() { - mProfileIcon->setValue("Generic_Person_Large"); - mImageID = LLUUID::null; - if (mImage.notNull()) - { - mImage->setBoostLevel(mImageOldBoostLevel); - mImage = NULL; - } + mProfileIcon->setValue(LLUUID::null); } void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id) { - if (mImageID != image_id) - { - if (mImage.notNull()) - { - mImage->setBoostLevel(mImageOldBoostLevel); - mImage = NULL; - } - } - else - { - return; - } - mProfileIcon->setValue(image_id); - mImageID = image_id; - mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - mImageOldBoostLevel = mImage->getBoostLevel(); - - if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0) - { - mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded, - 0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList); - - mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW); - mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING; - } - else - { - mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED; - } - - mUpdateDimensions = TRUE; updateDimensions(); } -// static -void LLFloaterProfileTexture::onTextureLoaded( - BOOL success, - LLViewerFetchedTexture *src_vi, - LLImageRaw* src, - LLImageRaw* aux_src, - S32 discard_level, - BOOL final, - void* userdata) +void LLFloaterProfileTexture::onImageLoaded(BOOL success, LLViewerFetchedTexture* imagep) { - LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata; - - if (!handle->isDead()) - { - LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get()); - if (floater && success) - { - floater->mUpdateDimensions = TRUE; - floater->updateDimensions(); - } - } - - if (final || !success) + if (success) { - delete handle; + updateDimensions(); } } diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h index 66a61213dd..12efbab572 100644 --- a/indra/newview/llfloaterprofiletexture.h +++ b/indra/newview/llfloaterprofiletexture.h @@ -28,11 +28,50 @@ #define LL_LLFLOATERPROFILETEXTURE_H #include "llfloater.h" +#include "lliconctrl.h" #include "llviewertexture.h" class LLButton; class LLImageRaw; -class LLIconCtrl; + +class LLProfileImageCtrl: public LLIconCtrl +{ +public: + struct Params: public LLInitParam::Block<Params, LLIconCtrl::Params> + { + }; + + LLProfileImageCtrl(const Params& p); + virtual ~LLProfileImageCtrl(); + + + virtual void setValue(const LLSD& value) override; + LLUUID getImageAssetId() { return mImageID; } + LLPointer<LLViewerFetchedTexture> getImage() {return mImage;} + void draw() override; + + typedef boost::signals2::signal<void(bool success, LLViewerFetchedTexture* imagep)> image_loaded_signal_t; + boost::signals2::connection setImageLoadedCallback(const image_loaded_signal_t::slot_type& cb); +private: + void onImageLoaded(bool success, LLViewerFetchedTexture* src_vi); + static void onImageLoaded(BOOL success, + LLViewerFetchedTexture* src_vi, + LLImageRaw* src, + LLImageRaw* aux_src, + S32 discard_level, + BOOL final, + void* userdata); + void releaseTexture(); + + void setImageAssetId(const LLUUID& asset_id); +private: + LLPointer<LLViewerFetchedTexture> mImage; + LLUUID mImageID; + S32 mImageOldBoostLevel; + bool mWasNoDelete; + image_loaded_signal_t* mImageLoadedSignal; + LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList; +}; class LLFloaterProfileTexture : public LLFloater { @@ -46,36 +85,23 @@ public: void resetAsset(); void loadAsset(const LLUUID &image_id); - - static void onTextureLoaded( - BOOL success, - LLViewerFetchedTexture *src_vi, - LLImageRaw* src, - LLImageRaw* aux_src, - S32 discard_level, - BOOL final, - void* userdata); + void onImageLoaded(BOOL success, LLViewerFetchedTexture* imagep); void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + + LLHandle<LLFloater> getHandle() const { return LLFloater::getHandle(); } protected: BOOL postBuild() override; private: void updateDimensions(); - LLUUID mImageID; - LLPointer<LLViewerFetchedTexture> mImage; - S32 mImageOldBoostLevel; - S32 mAssetStatus; F32 mContextConeOpacity; S32 mLastHeight; S32 mLastWidth; - BOOL mUpdateDimensions; LLHandle<LLView> mOwnerHandle; - LLIconCtrl* mProfileIcon; + LLProfileImageCtrl* mProfileIcon; LLButton* mCloseButton; - - LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList; }; #endif // LL_LLFLOATERPROFILETEXTURE_H diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 37ae80fa8f..a6ab61cbb9 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -48,12 +48,6 @@ public: LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { } bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) { - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch")) - { - LLNotificationsUtil::add("NoSearch", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - const size_t parts = tokens.size(); // get the (optional) category for the search diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index b139e5daf5..7e7bebf968 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -283,9 +283,7 @@ void LLFloaterSellLandUI::refreshUI() getChild<LLUICtrl>("info_size")->setTextArg("[AREA]", llformat("%d", mParcelActualArea)); std::string price_str = getChild<LLUICtrl>("price")->getValue().asString(); - bool valid_price = false; - valid_price = (price_str != "") && LLTextValidate::validateNonNegativeS32(utf8str_to_wstring(price_str)); - + bool valid_price = !price_str.empty() && LLTextValidate::validateNonNegativeS32.validate(price_str); if (valid_price && mParcelActualArea > 0) { F32 per_meter_price = 0; @@ -299,7 +297,7 @@ void LLFloaterSellLandUI::refreshUI() { getChildView("price_per_m")->setVisible(FALSE); - if ("" == price_str) + if (price_str.empty()) { setBadge("step_price", BADGE_NOTE); } @@ -331,9 +329,7 @@ void LLFloaterSellLandUI::refreshUI() // Must select Sell To: Anybody, or User (with a specified username) std::string sell_to = getChild<LLUICtrl>("sell_to")->getValue().asString(); - bool valid_sell_to = "select" != sell_to && - ("user" != sell_to || mAuthorizedBuyer.notNull()); - + bool valid_sell_to = "select" != sell_to && ("user" != sell_to || mAuthorizedBuyer.notNull()); if (!valid_sell_to) { setBadge("step_sell_to", BADGE_NOTE); @@ -344,7 +340,6 @@ void LLFloaterSellLandUI::refreshUI() } bool valid_sell_objects = ("none" != getChild<LLUICtrl>("sell_objects")->getValue().asString()); - if (!valid_sell_objects) { setBadge("step_sell_objects", BADGE_NOTE); diff --git a/indra/newview/llfloatersimplesnapshot.cpp b/indra/newview/llfloatersimplesnapshot.cpp index 58604c5628..40d5a5ed84 100644 --- a/indra/newview/llfloatersimplesnapshot.cpp +++ b/indra/newview/llfloatersimplesnapshot.cpp @@ -370,7 +370,7 @@ void LLFloaterSimpleSnapshot::onSend() else { LLSD notif_args; - notif_args["REASON"] = LLImage::getLastError().c_str(); + notif_args["REASON"] = LLImage::getLastThreadError().c_str(); LLNotificationsUtil::add("CannotUploadTexture", notif_args); } } @@ -389,7 +389,7 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(const std::string &file_path, cons if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN, true)) { LLSD notif_args; - notif_args["REASON"] = LLImage::getLastError().c_str(); + notif_args["REASON"] = LLImage::getLastThreadError().c_str(); LLNotificationsUtil::add("CannotUploadTexture", notif_args); LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; return; @@ -404,7 +404,7 @@ void LLFloaterSimpleSnapshot::uploadThumbnail(LLPointer<LLImageRaw> raw_image, c if (!LLViewerTextureList::createUploadFile(raw_image, temp_file, THUMBNAIL_SNAPSHOT_DIM_MAX, THUMBNAIL_SNAPSHOT_DIM_MIN)) { LLSD notif_args; - notif_args["REASON"] = LLImage::getLastError().c_str(); + notif_args["REASON"] = LLImage::getLastThreadError().c_str(); LLNotificationsUtil::add("CannotUploadTexture", notif_args); LL_WARNS("Thumbnail") << "Failed to upload thumbnail for " << inventory_id << " " << task_id << ", reason: " << notif_args["REASON"].asString() << LL_ENDL; return; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index c8559fc9d3..5d72f8e3bf 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -146,12 +146,6 @@ public: const std::string& grid, LLMediaCtrl* web) { - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableWorldMap")) - { - LLNotificationsUtil::add("NoWorldMap", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - if (params.size() == 0) { // support the secondlife:///app/worldmap SLapp @@ -207,12 +201,6 @@ public: const std::string& grid, LLMediaCtrl* web) { - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableWorldMap")) - { - LLNotificationsUtil::add("NoWorldMap", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - //Make sure we have some parameters if (params.size() == 0) { diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index c0f773968d..6c6d302599 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -58,6 +58,9 @@ // Longest time, in seconds, to wait for all animations to stop playing const F32 MAX_WAIT_ANIM_SECS = 30.f; +// Longest time, in seconds, to wait for a key release. +// This should be relatively long, but not too long. 10 minutes is enough +const F32 MAX_WAIT_KEY_SECS = 60.f * 10.f; // Lightweight constructor. // init() does the heavy lifting. @@ -528,12 +531,13 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset LLGestureMgr::instance().replaceGesture(base_item_id, gesture, new_asset_id); } -void LLGestureMgr::playGesture(LLMultiGesture* gesture) +void LLGestureMgr::playGesture(LLMultiGesture* gesture, bool fromKeyPress) { if (!gesture) return; // Reset gesture to first step gesture->mCurrentStep = 0; + gesture->mTriggeredByKey = fromKeyPress; // Add to list of playing gesture->mPlaying = TRUE; @@ -731,7 +735,8 @@ BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask) if (!gesture) continue; if (gesture->mKey == key - && gesture->mMask == mask) + && gesture->mMask == mask + && gesture->mWaitingKeyRelease == FALSE) { matching.push_back(gesture); } @@ -744,13 +749,38 @@ BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask) LLMultiGesture* gesture = matching[random]; - playGesture(gesture); + playGesture(gesture, TRUE); return TRUE; } return FALSE; } +BOOL LLGestureMgr::triggerGestureRelease(KEY key, MASK mask) +{ + std::vector <LLMultiGesture *> matching; + item_map_t::iterator it; + + // collect matching gestures + for (it = mActive.begin(); it != mActive.end(); ++it) + { + LLMultiGesture* gesture = (*it).second; + + // asset data might not have arrived yet + if (!gesture) continue; + + if (gesture->mKey == key + && gesture->mMask == mask) + { + gesture->mKeyReleased = TRUE; + } + } + + //If we found one, block. Otherwise tell them it's free to go. + return matching.size() > 0; +} + + S32 LLGestureMgr::getPlayingCount() const { return mPlaying.size(); @@ -899,6 +929,32 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture) continue; } + // If we're waiting a fixed amount of time, check for timer + // expiration. + if (gesture->mWaitingKeyRelease) + { + // We're waiting for a certain amount of time to pass + if (gesture->mKeyReleased) + { + // wait is done, continue execution + gesture->mWaitingKeyRelease = FALSE; + gesture->mCurrentStep++; + } + else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_KEY_SECS) + { + LL_INFOS("GestureMgr") << "Waited too long for key release, continuing gesture." + << LL_ENDL; + gesture->mWaitingKeyRelease = FALSE; + gesture->mCurrentStep++; + } + else + { + // we're waiting, so execution is done for now + waiting = TRUE; + } + continue; + } + // If we're waiting on our animations to stop, poll for // completion. if (gesture->mWaitingAnimations) @@ -1015,7 +1071,17 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step) case STEP_WAIT: { LLGestureStepWait* wait_step = (LLGestureStepWait*)step; - if (wait_step->mFlags & WAIT_FLAG_TIME) + if (gesture->mTriggeredByKey // Only wait here IF we were triggered by a key! + && gesture->mWaitingKeyRelease == FALSE // We can only do this once! Prevent gestures infinitely running + && wait_step->mFlags & WAIT_FLAG_KEY_RELEASE) + { + // Lets wait for the key release first so we don't hold up re-presses + gesture->mWaitingKeyRelease = TRUE; + gesture->mKeyReleased = FALSE; + // Use the wait timer as a deadlock breaker for key release waits. + gesture->mWaitTimer.reset(); + } + else if (wait_step->mFlags & WAIT_FLAG_TIME) { gesture->mWaitingTimer = TRUE; gesture->mWaitTimer.reset(); @@ -1023,8 +1089,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step) else if (wait_step->mFlags & WAIT_FLAG_ALL_ANIM) { gesture->mWaitingAnimations = TRUE; - // Use the wait timer as a deadlock breaker for animation - // waits. + // Use the wait timer as a deadlock breaker for animation waits. gesture->mWaitTimer.reset(); } else diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 7bb60f00e2..030e7db6dd 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -102,7 +102,10 @@ public: const item_map_t& getActiveGestures() const { return mActive; } // Force a gesture to be played, for example, if it is being // previewed. - void playGesture(LLMultiGesture* gesture); + void playGesture(LLMultiGesture* gesture, bool fromKeyPress); + void playGesture(LLMultiGesture* gesture) { + playGesture(gesture, FALSE); + } void playGesture(const LLUUID& item_id); // Stop all requested or playing anims for this gesture @@ -118,10 +121,14 @@ public: { mCallbackMap[inv_item_id] = cb; } - // Trigger the first gesture that matches this key. + // Trigger a random gesture that matches this key. // Returns TRUE if it finds a gesture bound to that key. BOOL triggerGesture(KEY key, MASK mask); + // Trigger release wait on all gestures that matches this key. + // Returns TRUE if it finds a gesture bound to that key. + BOOL triggerGestureRelease(KEY key, MASK mask); + // Trigger all gestures referenced as substrings in this string BOOL triggerAndReviseString(const std::string &str, std::string *revised_string = NULL); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 380e49c320..00d472215f 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -89,12 +89,6 @@ public: return true; } - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo")) - { - LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - if (tokens.size() < 1) { return false; @@ -373,7 +367,16 @@ void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id) args["GROUP"] = gdatap->mName; LLSD payload; payload["group_id"] = group_id; - LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup); + if (gdatap->mMembershipFee > 0) + { + args["COST"] = gdatap->mMembershipFee; + LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup); + } + else + { + LLNotificationsUtil::add("GroupLeaveConfirmMemberNoFee", args, payload, onLeaveGroup); + } + } // static @@ -405,7 +408,7 @@ void LLGroupActions::inspect(const LLUUID& group_id) } // static -void LLGroupActions::show(const LLUUID& group_id) +void LLGroupActions::show(const LLUUID &group_id, bool expand_notices_tab) { if (group_id.isNull()) return; @@ -413,6 +416,10 @@ void LLGroupActions::show(const LLUUID& group_id) LLSD params; params["group_id"] = group_id; params["open_tab_name"] = "panel_group_info_sidetray"; + if (expand_notices_tab) + { + params["action"] = "show_notices"; + } LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params); LLFloater *floater = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("people"); diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index afc4686dd7..44513199c1 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -57,7 +57,7 @@ public: /** * Show group information panel. */ - static void show(const LLUUID& group_id); + static void show(const LLUUID& group_id, bool expand_notices_tab = false); /** * Show group inspector floater. diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 32af2592d3..14310536b2 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -303,6 +303,7 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL item->getChildView("info_btn")->setVisible( false); item->getChildView("profile_btn")->setVisible( false); + item->getChildView("notices_btn")->setVisible(false); item->setGroupIconVisible(mShowIcons); if (!mShowIcons) { @@ -403,6 +404,7 @@ mGroupIcon(NULL), mGroupNameBox(NULL), mInfoBtn(NULL), mProfileBtn(NULL), +mNoticesBtn(NULL), mVisibilityHideBtn(NULL), mVisibilityShowBtn(NULL), mGroupID(LLUUID::null), @@ -435,6 +437,9 @@ BOOL LLGroupListItem::postBuild() mProfileBtn = getChild<LLButton>("profile_btn"); mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); }); + mNoticesBtn = getChild<LLButton>("notices_btn"); + mNoticesBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onNoticesBtnClick(); }); + mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn"); if (mVisibilityHideBtn) { @@ -470,13 +475,17 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask) { mInfoBtn->setVisible(true); mProfileBtn->setVisible(true); - if (mForAgent && mVisibilityHideBtn) + if (mForAgent) { LLGroupData agent_gdatap; if (gAgent.getGroupData(mGroupID, agent_gdatap)) { - mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile); - mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile); + if (mVisibilityHideBtn) + { + mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile); + mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile); + } + mNoticesBtn->setVisible(true); } } } @@ -489,6 +498,7 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask) getChildView("hovered_icon")->setVisible( false); mInfoBtn->setVisible(false); mProfileBtn->setVisible(false); + mNoticesBtn->setVisible(false); if (mVisibilityHideBtn) { mVisibilityHideBtn->setVisible(false); @@ -583,6 +593,11 @@ void LLGroupListItem::onProfileBtnClick() LLGroupActions::show(mGroupID); } +void LLGroupListItem::onNoticesBtnClick() +{ + LLGroupActions::show(mGroupID, true); +} + void LLGroupListItem::onVisibilityBtnClick(bool new_visibility) { LLGroupData agent_gdatap; diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h index 5cbabb712f..1bc2caff33 100644 --- a/indra/newview/llgrouplist.h +++ b/indra/newview/llgrouplist.h @@ -123,6 +123,7 @@ private: void setBold(bool bold); void onInfoBtnClick(); void onProfileBtnClick(); + void onNoticesBtnClick(); void onVisibilityBtnClick(bool new_visibility); LLTextBox* mGroupNameBox; @@ -130,6 +131,7 @@ private: LLGroupIconCtrl* mGroupIcon; LLButton* mInfoBtn; LLButton* mProfileBtn; + LLButton* mNoticesBtn; LLButton* mVisibilityHideBtn; LLButton* mVisibilityShowBtn; diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp index 0fa3dc1110..99be4dc92b 100644 --- a/indra/newview/llimhandler.cpp +++ b/indra/newview/llimhandler.cpp @@ -54,9 +54,8 @@ LLIMHandler::~LLIMHandler() //-------------------------------------------------------------------------- void LLIMHandler::initChannel() { - S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); - S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); + S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 61a01d7418..17a28e84bb 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -581,6 +581,12 @@ void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from, return; } + if (LLApp::isExiting() || gDisconnected) + { + LL_DEBUGS("ChatHistory") << "Ignoring chat history response, shutting down" << LL_ENDL; + return; + } + // Add history to IM session LLSD history = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT]; @@ -3915,6 +3921,12 @@ public: const LLSD& context, const LLSD& input) const { + if (LLApp::isExiting() || gDisconnected) + { + LL_DEBUGS("ChatHistory") << "Ignoring ChatterBox session, Shutting down" << LL_ENDL; + return; + } + LLSD body; LLUUID temp_session_id; LLUUID session_id; diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp index f382b5985f..0da0609ff7 100644 --- a/indra/newview/llinspect.cpp +++ b/indra/newview/llinspect.cpp @@ -45,8 +45,8 @@ LLInspect::~LLInspect() // virtual void LLInspect::draw() { - static LLCachedControl<F32> FADE_TIME(*LLUI::getInstance()->mSettingGroups["config"], "InspectorFadeTime", 1.f); - static LLCachedControl<F32> STAY_TIME(*LLUI::getInstance()->mSettingGroups["config"], "InspectorShowTime", 1.f); + const F32 FADE_TIME = 0.5f; + const F32 STAY_TIME = 3.f; if (mOpenTimer.getStarted()) { LLFloater::draw(); @@ -59,7 +59,7 @@ void LLInspect::draw() } else if (mCloseTimer.getStarted()) { - F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME(), 1.f, 0.f); + F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 1.f, 0.f); LLViewDrawContext context(alpha); LLFloater::draw(); if (mCloseTimer.getElapsedTimeF32() > FADE_TIME) diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index b11c440015..ca18dc343d 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -261,12 +261,15 @@ void LLInspectAvatar::requestUpdate() void LLInspectAvatar::processAvatarData(LLAvatarData* data) { LLStringUtil::format_map_t args; - { - std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); - LLStringUtil::format(birth_date, LLSD().with("datetime", (S32) data->born_on.secondsSinceEpoch())); - args["[BORN_ON]"] = birth_date; - } - args["[AGE]"] = LLDateUtil::ageFromDate(data->born_on, LLDate::now()); + + std::string birth_date = LLTrans::getString(data->hide_age ? + "AvatarBirthDateFormatShort" : + "AvatarBirthDateFormatFull"); + LLStringUtil::format(birth_date, LLSD().with("datetime", (S32)data->born_on.secondsSinceEpoch())); + args["[BORN_ON]"] = birth_date; + args["[AGE]"] = data->hide_age ? + LLStringUtilBase<char>::null : + LLDateUtil::ageFromDate(data->born_on, LLDate::now()); args["[SL_PROFILE]"] = data->about_text; args["[RW_PROFILE"] = data->fl_about_text; args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(data); diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp index 6f93a78ca6..21cdde0bea 100644 --- a/indra/newview/llinspecttoast.cpp +++ b/indra/newview/llinspecttoast.cpp @@ -60,8 +60,8 @@ private: LLInspectToast::LLInspectToast(const LLSD& notification_id) : LLInspect(LLSD()), mPanel(NULL) { - LLScreenChannelBase* channel = LLChannelManager::getInstance()->findChannelByID( - LLUUID(gSavedSettings.getString("NotificationChannelUUID"))); + LLScreenChannelBase* channel = LLChannelManager::getInstance()->findChannelByID( + LLNotificationsUI::NOTIFICATION_CHANNEL_UUID); mScreenChannel = dynamic_cast<LLScreenChannel*>(channel); if(NULL == mScreenChannel) { diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7a9d0ff7a7..988dffc8a5 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -90,6 +90,7 @@ void copy_slurl_to_clipboard_callback_inv(const std::string& slurl); const F32 SOUND_GAIN = 1.0f; +const F32 FOLDER_LOADING_MESSAGE_DELAY = 0.5f; // Seconds to wait before showing the LOADING... text in folder views using namespace LLOldEvents; @@ -308,9 +309,9 @@ void LLInvFVBridge::setCreationDate(time_t creation_date_utc) // Can be destroyed (or moved to trash) -BOOL LLInvFVBridge::isItemRemovable() const +BOOL LLInvFVBridge::isItemRemovable(bool check_worn) const { - return get_is_item_removable(getInventoryModel(), mUUID); + return get_is_item_removable(getInventoryModel(), mUUID, check_worn); } // Can be moved to another folder @@ -772,9 +773,6 @@ void hide_context_entries(LLMenuGL& menu, bool found = false; - std::string myinput; - std::vector<std::string> mylist{ "a", "b", "c" }; - menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name); if (itor2 != entries_to_show.end()) { @@ -874,7 +872,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } items.push_back(std::string("Cut")); - if (!isItemMovable() || !isItemRemovable()) + if (!isItemMovable() || !canMenuCut()) { disabled_items.push_back(std::string("Cut")); } @@ -923,7 +921,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if(!single_folder_root) { items.push_back(std::string("Cut")); - if (!isItemMovable() || !isItemRemovable()) + if (!isItemMovable() || !canMenuCut()) { disabled_items.push_back(std::string("Cut")); } @@ -1068,7 +1066,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, items.push_back(std::string("Delete")); - if (!isItemRemovable() || isPanelActive("Favorite Items")) + if (isPanelActive("Favorite Items") || !canMenuDelete()) { disabled_items.push_back(std::string("Delete")); } @@ -1224,6 +1222,16 @@ void LLInvFVBridge::addLinkReplaceMenuOption(menuentry_vec_t& items, menuentry_v } } +bool LLInvFVBridge::canMenuDelete() +{ + return isItemRemovable(false); +} + +bool LLInvFVBridge::canMenuCut() +{ + return isItemRemovable(true); +} + // *TODO: remove this BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const { @@ -2412,48 +2420,19 @@ void LLFolderBridge::update() } } - -// Iterate through a folder's children to determine if -// all the children are removable. -class LLIsItemRemovable : public LLFolderViewFunctor -{ -public: - LLIsItemRemovable() : mPassed(TRUE) {} - virtual void doFolder(LLFolderViewFolder* folder) - { - mPassed &= folder->getViewModelItem()->isItemRemovable(); - } - virtual void doItem(LLFolderViewItem* item) - { - mPassed &= item->getViewModelItem()->isItemRemovable(); - } - BOOL mPassed; -}; - // Can be destroyed (or moved to trash) -BOOL LLFolderBridge::isItemRemovable() const +BOOL LLFolderBridge::isItemRemovable(bool check_worn) const { - if (!get_is_category_removable(getInventoryModel(), mUUID)) + if (!get_is_category_and_children_removable(getInventoryModel(), mUUID, check_worn)) { return FALSE; } - LLInventoryPanel* panel = mInventoryPanel.get(); - LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL); - if (folderp) - { - LLIsItemRemovable folder_test; - folderp->applyFunctorToChildren(folder_test); - if (!folder_test.mPassed) - { - return FALSE; - } - } - - if (isMarketplaceListingsFolder() && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID))) - { - return FALSE; - } + if (isMarketplaceListingsFolder() + && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID))) + { + return FALSE; + } return TRUE; } @@ -4383,6 +4362,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back("New Settings"); } } + else + { + items.push_back(std::string("New Listing Folder")); + } if (menu_items_added) { items.push_back(std::string("Create Separator")); @@ -4524,7 +4507,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& return; } - if (!isItemRemovable()) + if (!canMenuDelete()) { disabled_items.push_back(std::string("Delete")); } @@ -4895,6 +4878,192 @@ void LLFolderBridge::modifyOutfit(BOOL append) } } +//static +void LLFolderBridge::onCanDeleteIdle(void* user_data) +{ + LLFolderBridge* self = (LLFolderBridge*)user_data; + + // we really need proper onidle mechanics that returns available time + const F32 EXPIRY_SECONDS = 0.008f; + LLTimer timer; + timer.setTimerExpirySec(EXPIRY_SECONDS); + + LLInventoryModel* model = self->getInventoryModel(); + if (model) + { + switch (self->mCanDeleteFolderState) + { + case CDS_INIT_FOLDER_CHECK: + // Can still be expensive, split it further? + model->collectDescendents( + self->mUUID, + self->mFoldersToCheck, + self->mItemsToCheck, + LLInventoryModel::EXCLUDE_TRASH); + self->mCanDeleteFolderState = CDS_PROCESSING_ITEMS; + break; + + case CDS_PROCESSING_ITEMS: + while (!timer.hasExpired() && !self->mItemsToCheck.empty()) + { + LLViewerInventoryItem* item = self->mItemsToCheck.back().get(); + if (item) + { + if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item)) + { + if (get_is_item_worn(item)) + { + // At the moment we disable 'cut' if category has worn items (do we need to?) + // but allow 'delete' to happen since it will prompt user to detach + self->mCanCut = false; + } + } + + if (!item->getIsLinkType() && get_is_item_worn(item)) + { + self->mCanCut = false; + } + } + self->mItemsToCheck.pop_back(); + } + self->mCanDeleteFolderState = CDS_PROCESSING_FOLDERS; + break; + case CDS_PROCESSING_FOLDERS: + { + const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); + LLViewerInventoryCategory* outfit_linked_category = base_outfit_link ? base_outfit_link->getLinkedCategory() : nullptr; + + while (!timer.hasExpired() && !self->mFoldersToCheck.empty()) + { + LLViewerInventoryCategory* cat = self->mFoldersToCheck.back().get(); + if (cat) + { + const LLFolderType::EType folder_type = cat->getPreferredType(); + if (LLFolderType::lookupIsProtectedType(folder_type)) + { + self->mCanCut = false; + self->mCanDelete = false; + self->completeDeleteProcessing(); + break; + } + + // Can't delete the outfit that is currently being worn. + if (folder_type == LLFolderType::FT_OUTFIT) + { + if (cat == outfit_linked_category) + { + self->mCanCut = false; + self->mCanDelete = false; + self->completeDeleteProcessing(); + break; + } + } + } + self->mFoldersToCheck.pop_back(); + } + } + self->mCanDeleteFolderState = CDS_DONE; + break; + case CDS_DONE: + self->completeDeleteProcessing(); + break; + } + } +} + +bool LLFolderBridge::canMenuDelete() +{ + LLInventoryModel* model = getInventoryModel(); + if (!model) return false; + LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); + if (!category) + { + return false; + } + + S32 version = category->getVersion(); + if (mLastCheckedVersion == version) + { + return mCanDelete; + } + + initCanDeleteProcessing(model, version); + return false; +} + +bool LLFolderBridge::canMenuCut() +{ + LLInventoryModel* model = getInventoryModel(); + if (!model) return false; + LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID); + if (!category) + { + return false; + } + + S32 version = category->getVersion(); + if (mLastCheckedVersion == version) + { + return mCanCut; + } + + initCanDeleteProcessing(model, version); + return false; +} + +void LLFolderBridge::initCanDeleteProcessing(LLInventoryModel* model, S32 version) +{ + if (mCanDeleteFolderState == CDS_DONE + || mInProgressVersion != version) + { + if (get_is_category_removable(model, mUUID)) + { + // init recursive check of content + mInProgressVersion = version; + mCanCut = true; + mCanDelete = true; + mCanDeleteFolderState = CDS_INIT_FOLDER_CHECK; + mFoldersToCheck.clear(); + mItemsToCheck.clear(); + gIdleCallbacks.addFunction(onCanDeleteIdle, this); + } + else + { + // no check needed + mCanDelete = false; + mCanCut = false; + mLastCheckedVersion = version; + mCanDeleteFolderState = CDS_DONE; + mFoldersToCheck.clear(); + mItemsToCheck.clear(); + } + } +} + +void LLFolderBridge::completeDeleteProcessing() +{ + LLInventoryModel* model = getInventoryModel(); + LLViewerInventoryCategory* category = model ? (LLViewerInventoryCategory*)model->getCategory(mUUID) : nullptr; + if (model && category && category->getVersion() == mInProgressVersion) + { + mLastCheckedVersion = mInProgressVersion; + mCanDeleteFolderState = CDS_DONE; + gIdleCallbacks.deleteFunction(onCanDeleteIdle, this); + } + else + { + mCanDelete = false; + mCanCut = false; + mLastCheckedVersion = LLViewerInventoryCategory::VERSION_UNKNOWN; + mCanDeleteFolderState = CDS_DONE; + } + + if (mRoot) + { + mRoot->updateMenu(); + } +} + // +=================================================+ // | LLMarketplaceFolderBridge | @@ -4938,9 +5107,7 @@ LLUIImagePtr LLMarketplaceFolderBridge::getMarketplaceFolderIcon(BOOL is_open) c std::string LLMarketplaceFolderBridge::getLabelSuffix() const { - static LLCachedControl<F32> folder_loading_message_delay(gSavedSettings, "FolderLoadingMessageWaitTime", 0.5f); - - if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= folder_loading_message_delay()) + if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= FOLDER_LOADING_MESSAGE_DELAY) { return llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str()); } @@ -5058,6 +5225,27 @@ void drop_to_favorites_cb(const LLUUID& id, LLPointer<LLInventoryCallback> cb1, cb2->fire(id); } +LLFolderBridge::LLFolderBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid) + : LLInvFVBridge(inventory, root, uuid) + , mCallingCards(FALSE) + , mWearables(FALSE) + , mIsLoading(false) + , mShowDescendantsCount(false) + , mCanDeleteFolderState(CDS_DONE) + , mLastCheckedVersion(S32_MIN) + , mInProgressVersion(S32_MIN) + , mCanDelete(false) + , mCanCut(false) +{ +} + +LLFolderBridge::~LLFolderBridge() +{ + gIdleCallbacks.deleteFunction(onCanDeleteIdle, this); +} + void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb) { // use callback to rearrange favorite landmarks after adding @@ -6651,6 +6839,26 @@ LLInventoryObject* LLObjectBridge::getObject() const return object; } +LLViewerInventoryItem* LLObjectBridge::getItem() const +{ + LLInventoryModel* model = getInventoryModel(); + if (model) + { + return model->getItem(mUUID); + } + return NULL; +} + +LLViewerInventoryCategory* LLObjectBridge::getCategory() const +{ + LLInventoryModel* model = getInventoryModel(); + if (model) + { + return model->getCategory(mUUID); + } + return NULL; +} + // virtual void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) { diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 3cbbd68e51..8bdb76cdef 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -114,7 +114,7 @@ public: virtual BOOL isItemRenameable() const { return TRUE; } virtual BOOL isMultiPreviewAllowed() { return TRUE; } //virtual BOOL renameItem(const std::string& new_name) {} - virtual BOOL isItemRemovable() const; + virtual BOOL isItemRemovable(bool check_worn = true) const; virtual BOOL isItemMovable() const; virtual BOOL isItemInTrash() const; virtual bool isItemInOutfits() const; @@ -162,6 +162,9 @@ protected: virtual void addLinkReplaceMenuOption(menuentry_vec_t& items, menuentry_vec_t& disabled_items); + virtual bool canMenuDelete(); + virtual bool canMenuCut(); + protected: LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid); @@ -272,14 +275,10 @@ class LLFolderBridge : public LLInvFVBridge public: LLFolderBridge(LLInventoryPanel* inventory, LLFolderView* root, - const LLUUID& uuid) - : LLInvFVBridge(inventory, root, uuid), - mCallingCards(FALSE), - mWearables(FALSE), - mIsLoading(false), - mShowDescendantsCount(false) - {} - + const LLUUID& uuid); + + ~LLFolderBridge(); + BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL); BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL); void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item); @@ -321,7 +320,7 @@ public: void* cargo_data, std::string& tooltip_msg); - virtual BOOL isItemRemovable() const; + virtual BOOL isItemRemovable(bool check_worn = true) const; virtual BOOL isItemMovable() const ; virtual BOOL isUpToDate() const; virtual bool isItemCopyable(bool can_copy_as_link = true) const; @@ -392,6 +391,31 @@ protected: LLTimer mTimeSinceRequestStart; std::string mMessage; LLRootHandle<LLFolderBridge> mHandle; + +private: + // checking if folder is cutable or deletable is expensive, + // cache values and split check over frames + static void onCanDeleteIdle(void* user_data); + void initCanDeleteProcessing(LLInventoryModel* model, S32 version); + void completeDeleteProcessing(); + bool canMenuDelete(); + bool canMenuCut(); + + enum ECanDeleteState + { + CDS_INIT_FOLDER_CHECK, + CDS_PROCESSING_ITEMS, + CDS_PROCESSING_FOLDERS, + CDS_DONE, + }; + + ECanDeleteState mCanDeleteFolderState; + LLInventoryModel::cat_array_t mFoldersToCheck; + LLInventoryModel::item_array_t mItemsToCheck; + S32 mLastCheckedVersion; + S32 mInProgressVersion; + bool mCanDelete; + bool mCanCut; }; class LLTextureBridge : public LLItemBridge @@ -524,6 +548,8 @@ public: virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual BOOL renameItem(const std::string& new_name); LLInventoryObject* getObject() const; + LLViewerInventoryItem* getItem() const; + LLViewerInventoryCategory* getCategory() const; protected: static LLUUID sContextMenuItemID; // Only valid while the context menu is open. U32 mAttachPt; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7ddc0c18b2..8a15281e78 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -579,9 +579,8 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id) return FALSE; } -BOOL get_is_item_worn(const LLUUID& id) +BOOL get_is_item_worn(const LLUUID& id, const LLViewerInventoryItem* item) { - const LLViewerInventoryItem* item = gInventory.getItem(id); if (!item) return FALSE; @@ -619,6 +618,21 @@ BOOL get_is_item_worn(const LLUUID& id) return FALSE; } +BOOL get_is_item_worn(const LLUUID& id) +{ + const LLViewerInventoryItem* item = gInventory.getItem(id); + return get_is_item_worn(id, item); +} + +BOOL get_is_item_worn(const LLViewerInventoryItem* item) +{ + if (!item) + { + return FALSE; + } + return get_is_item_worn(item->getUUID(), item); +} + BOOL get_can_item_be_worn(const LLUUID& id) { const LLViewerInventoryItem* item = gInventory.getItem(id); @@ -682,39 +696,39 @@ BOOL get_can_item_be_worn(const LLUUID& id) return FALSE; } -BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id) +bool get_is_item_removable(const LLInventoryModel* model, const LLUUID& id, bool check_worn) { if (!model) { - return FALSE; + return false; } // Can't delete an item that's in the library. if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID())) { - return FALSE; + return false; } // Disable delete from COF folder; have users explicitly choose "detach/take off", // unless the item is not worn but in the COF (i.e. is bugged). - if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id)) + const LLViewerInventoryItem* obj = model->getItem(id); + if (LLAppearanceMgr::instance().getIsProtectedCOFItem(obj)) { - if (get_is_item_worn(id)) + if (get_is_item_worn(id, obj)) { - return FALSE; + return false; } } - const LLInventoryObject *obj = model->getItem(id); if (obj && obj->getIsLinkType()) { - return TRUE; + return true; } - if (get_is_item_worn(id)) + if (check_worn && get_is_item_worn(id, obj)) { - return FALSE; + return false; } - return TRUE; + return true; } bool get_is_item_editable(const LLUUID& inv_item_id) @@ -805,6 +819,74 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id) return TRUE; } +bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUID& folder_id, bool check_worn) +{ + if (!get_is_category_removable(model, folder_id)) + { + return false; + } + + const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id)) + { + return false; + } + + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + model->collectDescendents( + folder_id, + cat_array, + item_array, + LLInventoryModel::EXCLUDE_TRASH); + + if (check_worn) + { + for (LLInventoryModel::item_array_t::value_type& item : item_array) + { + // Disable delete/cut from COF folder; have users explicitly choose "detach/take off", + // unless the item is not worn but in the COF (i.e. is bugged). + if (item) + { + if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item)) + { + if (get_is_item_worn(item)) + { + return false; + } + } + + if (!item->getIsLinkType() && get_is_item_worn(item)) + { + return false; + } + } + } + } + + const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); + LLViewerInventoryCategory* outfit_linked_category = base_outfit_link ? base_outfit_link->getLinkedCategory() : nullptr; + for (LLInventoryModel::cat_array_t::value_type& cat : cat_array) + { + const LLFolderType::EType folder_type = cat->getPreferredType(); + if (LLFolderType::lookupIsProtectedType(folder_type)) + { + return false; + } + + // Can't delete the outfit that is currently being worn. + if (folder_type == LLFolderType::FT_OUTFIT) + { + if (cat == outfit_linked_category) + { + return false; + } + } + } + + return true; +} + BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id) { if (!model) @@ -2783,7 +2865,7 @@ bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventory { if (item) { - return !get_is_item_removable(&gInventory, item->getUUID()); + return !get_is_item_removable(&gInventory, item->getUUID(), true); } if (cat) { @@ -3048,6 +3130,8 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root { const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); bool marketplacelistings_item = false; + bool has_worn = false; + bool needs_replacement = false; LLAllDescendentsPassedFilter f; for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(); (it != selected_items.end()) && (f.allDescendentsPassedFilter()); ++it) { @@ -3056,14 +3140,69 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root folder->applyFunctorRecursively(f); } LLFolderViewModelItemInventory * viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem()); - if (viewModel && gInventory.isObjectDescendentOf(viewModel->getUUID(), marketplacelistings_id)) + LLUUID obj_id = viewModel->getUUID(); + if (viewModel && gInventory.isObjectDescendentOf(obj_id, marketplacelistings_id)) { marketplacelistings_item = true; break; } + + LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id); + if (cat) + { + LLInventoryModel::cat_array_t categories; + LLInventoryModel::item_array_t items; + + gInventory.collectDescendents(obj_id, categories, items, FALSE); + + for (LLInventoryModel::item_array_t::value_type& item : items) + { + if (get_is_item_worn(item)) + { + has_worn = true; + LLWearableType::EType type = item->getWearableType(); + if (type == LLWearableType::WT_SHAPE + || type == LLWearableType::WT_SKIN + || type == LLWearableType::WT_HAIR + || type == LLWearableType::WT_EYES) + { + needs_replacement = true; + break; + } + } + } + if (needs_replacement) + { + break; + } + } + LLViewerInventoryItem* item = gInventory.getItem(obj_id); + if (item && get_is_item_worn(item)) + { + has_worn = true; + LLWearableType::EType type = item->getWearableType(); + if (type == LLWearableType::WT_SHAPE + || type == LLWearableType::WT_SKIN + || type == LLWearableType::WT_HAIR + || type == LLWearableType::WT_EYES) + { + needs_replacement = true; + break; + } + } } // Fall through to the generic confirmation if the user choose to ignore the specialized one - if ( (!f.allDescendentsPassedFilter()) && !marketplacelistings_item && (!LLNotifications::instance().getIgnored("DeleteFilteredItems")) ) + if (needs_replacement) + { + LLNotificationsUtil::add("CantDeleteRequiredClothing"); + } + else if (has_worn) + { + LLSD payload; + payload["has_worn"] = true; + LLNotificationsUtil::add("DeleteWornItems", LLSD(), payload, boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle())); + } + else if ( (!f.allDescendentsPassedFilter()) && !marketplacelistings_item && (!LLNotifications::instance().getIgnored("DeleteFilteredItems")) ) { LLNotificationsUtil::add("DeleteFilteredItems", LLSD(), LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle())); } @@ -3386,11 +3525,81 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0 && !root.isDead() && !root.get()->isDead()) { + bool has_worn = notification["payload"]["has_worn"].asBoolean(); LLFolderView* folder_root = root.get(); //Need to remove item from DND before item is removed from root folder view //because once removed from root folder view the item is no longer a selected item removeItemFromDND(folder_root); - folder_root->removeSelectedItems(); + + // removeSelectedItems will change selection, collect worn items beforehand + uuid_vec_t worn; + uuid_vec_t item_deletion_list; + uuid_vec_t cat_deletion_list; + if (has_worn) + { + //Get selected items + LLFolderView::selected_items_t selectedItems = folder_root->getSelectedItems(); + + //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification + //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification. + for (LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it) + { + LLFolderViewModelItemInventory* viewModel = dynamic_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem()); + + LLUUID obj_id = viewModel->getUUID(); + LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id); + bool cat_has_worn = false; + if (cat) + { + LLInventoryModel::cat_array_t categories; + LLInventoryModel::item_array_t items; + + gInventory.collectDescendents(obj_id, categories, items, FALSE); + + for (LLInventoryModel::item_array_t::value_type& item : items) + { + if (get_is_item_worn(item)) + { + worn.push_back(item->getUUID()); + cat_has_worn = true; + } + } + if (cat_has_worn) + { + cat_deletion_list.push_back(obj_id); + } + } + LLViewerInventoryItem* item = gInventory.getItem(obj_id); + if (item && get_is_item_worn(item)) + { + worn.push_back(obj_id); + item_deletion_list.push_back(obj_id); + } + } + } + + // removeSelectedItems will check if items are worn before deletion, + // don't 'unwear' yet to prevent race conditions from unwearing + // and removing simultaneously + folder_root->removeSelectedItems(); + + // unwear then delete the rest + if (!worn.empty()) + { + // should fire once after every item gets detached + LLAppearanceMgr::instance().removeItemsFromAvatar(worn, + [item_deletion_list, cat_deletion_list]() + { + for (const LLUUID& id : item_deletion_list) + { + remove_inventory_item(id, NULL); + } + for (const LLUUID& id : cat_deletion_list) + { + remove_inventory_category(id, NULL); + } + }); + } // Update the marketplace listings that have been affected by the operation updateMarketplaceFolders(); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 5a833eab8c..1163139762 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -47,17 +47,19 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id); // Is this item or its baseitem is worn, attached, etc... BOOL get_is_item_worn(const LLUUID& id); +BOOL get_is_item_worn(const LLViewerInventoryItem* item); // Could this item be worn (correct type + not already being worn) BOOL get_can_item_be_worn(const LLUUID& id); -BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id); +bool get_is_item_removable(const LLInventoryModel* model, const LLUUID& id, bool check_worn); // Performs the appropiate edit action (if one exists) for this item bool get_is_item_editable(const LLUUID& inv_item_id); void handle_item_edit(const LLUUID& inv_item_id); BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id); +bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUID& folder_id, bool check_worn); BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id); diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index d4ca58f778..3c3da253d3 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -1435,7 +1435,7 @@ void LLInventoryGallery::onFocusReceived() LLInventoryGalleryItem* focus_item = NULL; for (const LLUUID& id : mSelectedItemIDs) { - if (mItemMap[id]) + if (mItemMap[id] && !mItemMap[id]->isHidden()) { focus_item = mItemMap[id]; focus_item->setSelected(true); @@ -1668,6 +1668,45 @@ void LLInventoryGallery::cut() mFilterSubString.clear(); } + + +bool is_category_removable(const LLUUID& folder_id, bool check_worn) +{ + if (!get_is_category_removable(&gInventory, folder_id)) + { + return false; + } + + // check children + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(folder_id, cat_array, item_array); + + for (LLInventoryModel::item_array_t::value_type& item : *item_array) + { + if (!get_is_item_removable(&gInventory, item->getUUID(), check_worn)) + { + return false; + } + } + + for (LLInventoryModel::cat_array_t::value_type& cat : *cat_array) + { + if (!is_category_removable(cat->getUUID(), check_worn)) + { + return false; + } + } + + const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS); + if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id)) + { + return false; + } + + return true; +} + BOOL LLInventoryGallery::canCut() const { if (!getVisible() || !getEnabled() || mSelectedItemIDs.empty()) @@ -1680,12 +1719,12 @@ BOOL LLInventoryGallery::canCut() const LLViewerInventoryCategory* cat = gInventory.getCategory(id); if (cat) { - if (!get_is_category_removable(&gInventory, id)) + if (!get_is_category_and_children_removable(&gInventory, id, true)) { return FALSE; } } - else if (!get_is_item_removable(&gInventory, id)) + else if (!get_is_item_removable(&gInventory, id, true)) { return FALSE; } @@ -1864,42 +1903,149 @@ void LLInventoryGallery::onDelete(const LLSD& notification, const LLSD& response S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { - for (const LLUUID& id : selected_ids) + bool has_worn = notification["payload"]["has_worn"].asBoolean(); + uuid_vec_t worn; + uuid_vec_t item_deletion_list; + uuid_vec_t cat_deletion_list; + for (const LLUUID& obj_id : selected_ids) { - LLInventoryObject* obj = gInventory.getObject(id); - if (!obj) - { - return; - } - if (obj->getType() == LLAssetType::AT_CATEGORY) + LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id); + if (cat) { - if (get_is_category_removable(&gInventory, id)) + bool cat_has_worn = false; + if (has_worn) { - gInventory.removeCategory(id); + LLInventoryModel::cat_array_t categories; + LLInventoryModel::item_array_t items; + + gInventory.collectDescendents(obj_id, categories, items, FALSE); + + for (LLInventoryModel::item_array_t::value_type& item : items) + { + if (get_is_item_worn(item)) + { + worn.push_back(item->getUUID()); + cat_has_worn = true; + } + } + } + if (cat_has_worn) + { + cat_deletion_list.push_back(obj_id); + } + else + { + gInventory.removeCategory(obj_id); } } - else + LLViewerInventoryItem* item = gInventory.getItem(obj_id); + if (item) { - if (get_is_item_removable(&gInventory, id)) + if (has_worn && get_is_item_worn(item)) + { + worn.push_back(item->getUUID()); + item_deletion_list.push_back(item->getUUID()); + } + else { - gInventory.removeItem(id); + gInventory.removeItem(obj_id); } } } + + if (!worn.empty()) + { + // should fire once after every item gets detached + LLAppearanceMgr::instance().removeItemsFromAvatar(worn, + [item_deletion_list, cat_deletion_list]() + { + for (const LLUUID& id : item_deletion_list) + { + remove_inventory_item(id, NULL); + } + for (const LLUUID& id : cat_deletion_list) + { + remove_inventory_category(id, NULL); + } + }); + } } } void LLInventoryGallery::deleteSelection() { - if (!LLInventoryAction::sDeleteConfirmationDisplayed) // ask for the confirmation at least once per session + bool has_worn = false; + bool needs_replacement = false; + for (const LLUUID& id : mSelectedItemIDs) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(id); + if (cat) + { + LLInventoryModel::cat_array_t categories; + LLInventoryModel::item_array_t items; + + gInventory.collectDescendents(id, categories, items, FALSE); + + for (LLInventoryModel::item_array_t::value_type& item : items) + { + if (get_is_item_worn(item)) + { + has_worn = true; + LLWearableType::EType type = item->getWearableType(); + if (type == LLWearableType::WT_SHAPE + || type == LLWearableType::WT_SKIN + || type == LLWearableType::WT_HAIR + || type == LLWearableType::WT_EYES) + { + needs_replacement = true; + break; + } + } + } + if (needs_replacement) + { + break; + } + } + + LLViewerInventoryItem* item = gInventory.getItem(id); + if (item && get_is_item_worn(item)) + { + has_worn = true; + LLWearableType::EType type = item->getWearableType(); + if (type == LLWearableType::WT_SHAPE + || type == LLWearableType::WT_SKIN + || type == LLWearableType::WT_HAIR + || type == LLWearableType::WT_EYES) + { + needs_replacement = true; + break; + } + } + } + + if (needs_replacement) + { + LLNotificationsUtil::add("CantDeleteRequiredClothing"); + } + else if (has_worn) { - LLNotifications::instance().setIgnored("DeleteItems", false); - LLInventoryAction::sDeleteConfirmationDisplayed = true; + LLSD payload; + payload["has_worn"] = true; + LLNotificationsUtil::add("DeleteWornItems", LLSD(), payload, boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs)); } + else + { + if (!LLInventoryAction::sDeleteConfirmationDisplayed) // ask for the confirmation at least once per session + { + LLNotifications::instance().setIgnored("DeleteItems", false); + LLInventoryAction::sDeleteConfirmationDisplayed = true; + } - LLSD args; - args["QUESTION"] = LLTrans::getString("DeleteItem"); - LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs)); + LLSD args; + args["QUESTION"] = LLTrans::getString("DeleteItem"); + LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs)); + } } bool LLInventoryGallery::canDeleteSelection() @@ -1925,7 +2071,7 @@ bool LLInventoryGallery::canDeleteSelection() return false; } } - else if (!get_is_item_removable(&gInventory, id)) + else if (!get_is_item_removable(&gInventory, id, true)) { return false; } diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 5f4b816b99..4b47346473 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -495,7 +495,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } } items.push_back(std::string("Purge Item")); - if (is_folder && !get_is_category_removable(&gInventory, selected_id)) + if (is_folder && !get_is_category_and_children_removable(&gInventory, selected_id, true)) { disabled_items.push_back(std::string("Purge Item")); } @@ -542,11 +542,16 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } items.push_back(std::string("Cut")); items.push_back(std::string("Delete")); - if(!get_is_category_removable(&gInventory, selected_id)) + + if(!get_is_category_and_children_removable(&gInventory, selected_id, false)) { disabled_items.push_back(std::string("Delete")); disabled_items.push_back(std::string("Cut")); } + else if (!get_is_category_and_children_removable(&gInventory, selected_id, true)) + { + disabled_items.push_back(std::string("Cut")); + } if(!is_inbox) { @@ -577,11 +582,15 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men { items.push_back(std::string("Delete")); } - if(!get_is_item_removable(&gInventory, selected_id)) + if (!get_is_item_removable(&gInventory, selected_id, false)) { disabled_items.push_back(std::string("Delete")); disabled_items.push_back(std::string("Cut")); } + else if(!get_is_item_removable(&gInventory, selected_id, true)) + { + disabled_items.push_back(std::string("Cut")); + } if (selected_item && (selected_item->getInventoryType() != LLInventoryType::IT_CALLINGCARD) && !is_inbox && selected_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 05aa2e423f..10feb16346 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1744,12 +1744,10 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item, << " from " << make_inventory_info(item->getParentUUID()) << " to " << make_inventory_info(new_parent_id) << LL_ENDL; - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - accountForUpdate(update); + LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(), -1); + accountForUpdate(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1, false); + accountForUpdate(new_folder); LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->setParent(new_parent_id); @@ -1779,12 +1777,10 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat, << " from " << make_inventory_info(cat->getParentUUID()) << " to " << make_inventory_info(new_parent_id) << LL_ENDL; - LLInventoryModel::update_list_t update; LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - accountForUpdate(update); + accountForUpdate(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1, false); + accountForUpdate(new_folder); LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat); new_cat->setParent(new_parent_id); @@ -2542,7 +2538,10 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const { descendents_actual += update.mDescendentDelta; cat->setDescendentCount(descendents_actual); - cat->setVersion(++version); + if (update.mChangeVersion) + { + cat->setVersion(++version); + } LL_DEBUGS(LOG_INV) << "accounted: '" << cat->getName() << "' " << version << " with " << descendents_actual << " descendents." << LL_ENDL; @@ -2570,7 +2569,7 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const } void LLInventoryModel::accountForUpdate( - const LLInventoryModel::update_list_t& update) + const LLInventoryModel::update_list_t& update) const { update_list_t::const_iterator it = update.begin(); update_list_t::const_iterator end = update.end(); @@ -2581,7 +2580,7 @@ void LLInventoryModel::accountForUpdate( } void LLInventoryModel::accountForUpdate( - const LLInventoryModel::update_map_t& update) + const LLInventoryModel::update_map_t& update) const { LLCategoryUpdate up; update_map_t::const_iterator it = update.begin(); @@ -2706,6 +2705,17 @@ bool LLInventoryModel::loadSkeleton( gzip_filename.append(".gz"); LLFILE* fp = LLFile::fopen(gzip_filename, "rb"); bool remove_inventory_file = false; + if (LLAppViewer::instance()->isSecondInstance()) + { + // Safeguard viewer against trying to unpack file twice + // ex: user logs into two accounts simultaneously, so two + // viewers are trying to unpack library into same file + // + // Would be better to do it in gunzip_file, but it doesn't + // have access to llfilesystem + inventory_filename = gDirUtilp->getTempFilename(); + remove_inventory_file = true; + } if(fp) { fclose(fp); @@ -2914,7 +2924,7 @@ bool LLInventoryModel::loadSkeleton( // clean up the gunzipped file. LLFile::remove(inventory_filename); } - if(is_cache_obsolete) + if(is_cache_obsolete && !LLAppViewer::instance()->isSecondInstance()) { // If out of date, remove the gzipped file too. LL_WARNS(LOG_INV) << "Inv cache out of date, removing" << LL_ENDL; diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 69d987cabd..41faafa6bb 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -511,12 +511,14 @@ public: // Represents the number of items added or removed from a category. struct LLCategoryUpdate { - LLCategoryUpdate() : mDescendentDelta(0) {} - LLCategoryUpdate(const LLUUID& category_id, S32 delta) : + LLCategoryUpdate() : mDescendentDelta(0), mChangeVersion(true) {} + LLCategoryUpdate(const LLUUID& category_id, S32 delta, bool change_version = true) : mCategoryID(category_id), - mDescendentDelta(delta) {} + mDescendentDelta(delta), + mChangeVersion(change_version) {} LLUUID mCategoryID; S32 mDescendentDelta; + bool mChangeVersion; }; typedef std::vector<LLCategoryUpdate> update_list_t; @@ -534,8 +536,8 @@ public: // Call when there are category updates. Call them *before* the // actual update so the method can do descendent accounting correctly. void accountForUpdate(const LLCategoryUpdate& update) const; - void accountForUpdate(const update_list_t& updates); - void accountForUpdate(const update_map_t& updates); + void accountForUpdate(const update_list_t& updates) const; + void accountForUpdate(const update_map_t& updates) const; // Return (yes/no/maybe) child status of category children. EHasChildren categoryHasChildren(const LLUUID& cat_id) const; diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 9fa35e3bd9..eb1bb9aca4 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -230,10 +230,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) // Can't access old mTextEntry fields as they are protected, so lets build new params // That is C&P from LLComboBox::createLineEditor function - static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0); S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0; LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0); - text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button; + text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * BTN_DROP_SHADOW; LLLineEditor::Params params = p.combo_editor; params.rect(text_entry_rect); @@ -708,7 +707,7 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data) value["item_type"] = LANDMARK; value["AssetUUID"] = landmark_items[i]->getAssetUUID(); - add(landmark_items[i]->getName(), value); + addLocationHistoryEntry(landmark_items[i]->getName(), value); } //Let's add teleport history items @@ -733,7 +732,7 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data) std::string region_name = result->mTitle.substr(0, result->mTitle.find(',')); //TODO*: add Surl to teleportitem or parse region name from title value["tooltip"] = LLSLURL(region_name, result->mGlobalPos).getSLURLString(); - add(result->getTitle(), value); + addLocationHistoryEntry(result->getTitle(), value); } result = std::find_if(result + 1, th_items.end(), boost::bind( &LLLocationInputCtrl::findTeleportItemsByTitle, this, @@ -986,6 +985,17 @@ void LLLocationInputCtrl::positionMaturityButton() mMaturityButton->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad); } +void LLLocationInputCtrl::addLocationHistoryEntry(const std::string& title, const LLSD& value) +{ + // SL-20286 : Duplication of autocomplete results occurs when entering some search queries in the navigation bar + // Exclude visual duplicates (items with the same titles) in the dropdown list + LLScrollListItem* item = mList->getItemByLabel(title); + if (!item) + { + add(title, value); + } +} + void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter) { LLLocationHistory::location_list_t filtered_items; @@ -1010,7 +1020,7 @@ void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter) //location history can contain only typed locations value["item_type"] = TYPED_REGION_SLURL; value["global_pos"] = it->mGlobalPos.getValue(); - add(it->getLocation(), value); + addLocationHistoryEntry(it->getLocation(), value); } } diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index af2a9f6afd..cbc05602ce 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -145,6 +145,7 @@ private: void refreshMaturityButton(); void positionMaturityButton(); + void addLocationHistoryEntry(const std::string& title, const LLSD& value); void rebuildLocationHistory(const std::string& filter = LLStringUtil::null); bool findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter); void setText(const LLStringExplicit& text); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 052ac50185..5f3ad7c58f 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -651,6 +651,27 @@ std::string LLLogChat::oldLogFileName(std::string filename) return scanResult; } +bool LLLogChat::transcriptFilesExist() +{ + std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION; + // get Users log directory + std::string dirname = gDirUtilp->getPerAccountChatLogsDir(); + + // add final OS dependent delimiter + dirname += gDirUtilp->getDirDelimiter(); + + LLDirIterator iter(dirname, pattern); + std::string filename; + while (iter.next(filename)) + { + std::string fullname = gDirUtilp->add(dirname, filename); + if (isTranscriptFileFound(fullname)) + { + return true; + } + } + return false; +} // static void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions) { diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 5dce8ab1d2..9e2e060de2 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -103,6 +103,7 @@ public: const std::string& from, const LLUUID& from_id, const std::string& line); + static bool transcriptFilesExist(); static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions); static void getListOfTranscriptFiles(std::vector<std::string>& list); static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions); diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 8fbcf8e18d..ddfaa9b23f 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -441,13 +441,13 @@ void LLModelPreview::rebuildUploadData() // That's ok, but might not what they wanted. Use default_physics_shape if found. std::ostringstream out; out << "No physics model specified for " << instance.mLabel; - if (mDefaultPhysicsShapeP) + if (mDefaultPhysicsShapeP.notNull()) { out << " - using: " << DEFAULT_PHYSICS_MESH_NAME; lod_model = mDefaultPhysicsShapeP; } LL_WARNS() << out.str() << LL_ENDL; - LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default. + LLFloaterModelPreview::addStringToLog(out, mDefaultPhysicsShapeP.isNull()); // Flash log tab if no default. } if (lod_model) @@ -1078,8 +1078,9 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) if (loaded_lod == LLModel::LOD_PHYSICS) { // Explicitly loading physics. See if there is a default mesh. LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own. - mDefaultPhysicsShapeP = nullptr; - FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform); + LLModel* out_model = nullptr; + FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), out_model, ignored_transform); + mDefaultPhysicsShapeP = out_model; mWarnOfUnmatchedPhyicsMeshes = true; } BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching"); diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index df7320768c..f68cec4441 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -240,7 +240,7 @@ private: /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME. /// It is reset when such a name is not found, and when resetting the modelpreview. /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true. - LLModel* mDefaultPhysicsShapeP{}; + LLPointer<LLModel> mDefaultPhysicsShapeP; typedef enum { diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index f5ee1171d9..61448828d1 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -352,10 +352,9 @@ void LLNavigationBar::draw() { if (isBackgroundVisible()) { - static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0); static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow"); gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, - color_drop_shadow, drop_shadow_floater ); + color_drop_shadow, DROP_SHADOW_FLOATER); } LLPanel::draw(); diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp index 90b9cdc133..df8ab84663 100644 --- a/indra/newview/llnotificationalerthandler.cpp +++ b/indra/newview/llnotificationalerthandler.cpp @@ -46,7 +46,7 @@ LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notif mIsModal(is_modal) { LLScreenChannelBase::Params p; - p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID")); + p.id = ALERT_CHANNEL_UUID; p.display_toasts_always = true; p.toast_align = NA_CENTRE; p.channel_align = CA_CENTRE; diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp index f87ebf219b..3c3d96f72c 100644 --- a/indra/newview/llnotificationgrouphandler.cpp +++ b/indra/newview/llnotificationgrouphandler.cpp @@ -56,9 +56,8 @@ LLGroupHandler::~LLGroupHandler() //-------------------------------------------------------------------------- void LLGroupHandler::initChannel() { - S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); - S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); + S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 3f22467544..0e7222838d 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -63,8 +63,7 @@ LLOfferHandler::~LLOfferHandler() void LLOfferHandler::initChannel() { S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); - S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); + mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index bb39d8f362..2f7dfa8e77 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -61,9 +61,8 @@ LLScriptHandler::~LLScriptHandler() //-------------------------------------------------------------------------- void LLScriptHandler::initChannel() { - S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); - S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); + S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp index 91f93067de..dc24e651cb 100644 --- a/indra/newview/llnotificationtiphandler.cpp +++ b/indra/newview/llnotificationtiphandler.cpp @@ -60,9 +60,8 @@ LLTipHandler::~LLTipHandler() //-------------------------------------------------------------------------- void LLTipHandler::initChannel() { - S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); - S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth"); - mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound); + S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin"); + mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound); } //-------------------------------------------------------------------------- diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 27d73fc4ae..352d59a9c2 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -790,7 +790,7 @@ void LLOutfitListBase::onOpen(const LLSD& info) // Start observing changes in "My Outfits" category. mCategoriesObserver->addCategory(outfits, - boost::bind(&LLOutfitListBase::refreshList, this, outfits)); + boost::bind(&LLOutfitListBase::observerCallback, this, outfits)); //const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); // Start observing changes in Current Outfit category. @@ -810,6 +810,13 @@ void LLOutfitListBase::onOpen(const LLSD& info) } } +void LLOutfitListBase::observerCallback(const LLUUID& category_id) +{ + const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); + mChangedItems.insert(changed_items.begin(), changed_items.end()); + refreshList(category_id); +} + void LLOutfitListBase::refreshList(const LLUUID& category_id) { bool wasNull = mRefreshListState.CategoryUUID.isNull(); @@ -905,24 +912,22 @@ void LLOutfitListBase::onIdleRefreshList() // Get changed items from inventory model and update outfit tabs // which might have been renamed. - const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); - for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin(); - items_iter != changed_items.end(); - ++items_iter) + while (!mChangedItems.empty()) { + std::set<LLUUID>::const_iterator items_iter = mChangedItems.begin(); LLViewerInventoryCategory *cat = gInventory.getCategory(*items_iter); - if (!cat) + mChangedItems.erase(items_iter); + + // Links aren't supposed to be allowed here, check only cats + if (cat) { - LLInventoryObject* obj = gInventory.getObject(*items_iter); - if (!obj || (obj->getType() != LLAssetType::AT_CATEGORY)) - { - break; - } - cat = (LLViewerInventoryCategory*)obj; + std::string name = cat->getName(); + updateChangedCategoryName(cat, name); } - std::string name = cat->getName(); - updateChangedCategoryName(cat, name); + curent_time = LLTimer::getTotalSeconds(); + if (curent_time >= end_time) + return; } sortOutfits(); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index 43c3ba75b5..980b9c3970 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -109,6 +109,7 @@ public: virtual bool getHasExpandableFolders() = 0; protected: + void observerCallback(const LLUUID& category_id); virtual LLOutfitListGearMenuBase* createGearMenu() = 0; virtual void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) = 0; virtual void onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) = 0; @@ -127,6 +128,7 @@ protected: uuid_vec_t::const_iterator AddedIterator; uuid_vec_t::const_iterator RemovedIterator; } mRefreshListState; + std::set<LLUUID> mChangedItems; bool mIsInitialized; LLInventoryCategoriesObserver* mCategoriesObserver; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index ff33efe4aa..3f2dc5a415 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -127,6 +127,54 @@ void LLPanelProfileTab::setApplyProgress(bool started) } } +static void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data, std::function<void(bool)> callback) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpHeaders::ptr_t httpHeaders; + + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + httpOpts->setFollowRedirects(true); + + std::string finalUrl = cap_url + "/" + agent_id.asString(); + + LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; + } + else + { + LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; + } + + if (callback) + { + callback(status); + } +} + +bool LLPanelProfileTab::saveAgentUserInfoCoro(std::string name, LLSD value, std::function<void(bool)> callback) const +{ + std::string cap_url = gAgent.getRegionCapability("AgentProfile"); + if (cap_url.empty()) + { + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; + return false; + } + + LLCoros::instance().launch("putAgentUserInfoCoro", + boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with(name, value), callback)); + + return true; +} + LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab() : LLPanelProfileTab() { @@ -152,3 +200,13 @@ void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id) LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this); } } + +void LLPanelProfilePropertiesProcessorTab::updateData() +{ + LLUUID avatar_id = getAvatarId(); + if (!getStarted() && avatar_id.notNull()) + { + setIsLoading(); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(getAvatarId()); + } +} diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h index f182660c8e..ec620b39e1 100644 --- a/indra/newview/llpanelavatar.h +++ b/indra/newview/llpanelavatar.h @@ -92,17 +92,17 @@ public: /** * Returns avatar ID. */ - virtual const LLUUID& getAvatarId() { return mAvatarId; } + virtual const LLUUID& getAvatarId() const { return mAvatarId; } /** * Sends update data request to server. */ - virtual void updateData() {}; + virtual void updateData(){}; /** * Clears panel data if viewing avatar info for first time and sends update data request. */ - virtual void onOpen(const LLSD& key); + virtual void onOpen(const LLSD& key) override; /** * Clears all data received from server. @@ -133,6 +133,8 @@ protected: const bool getSelfProfile() const { return mSelfProfile; } + bool saveAgentUserInfoCoro(std::string name, LLSD value, std::function<void(bool)> callback = nullptr) const; + public: void setIsLoading() { mLoadingState = PROFILE_LOADING; } void resetLoading() { mLoadingState = PROFILE_INIT; } @@ -158,12 +160,14 @@ public: LLPanelProfilePropertiesProcessorTab(); ~LLPanelProfilePropertiesProcessorTab(); - /*virtual*/ void setAvatarId(const LLUUID& avatar_id); + void setAvatarId(const LLUUID& avatar_id) override; + + void updateData() override; /** * Processes data received from server via LLAvatarPropertiesObserver. */ - virtual void processProperties(void* data, EAvatarProcessorType type) = 0; + virtual void processProperties(void* data, EAvatarProcessorType type) override = 0; }; #endif // LL_LLPANELAVATAR_H diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 183000ceac..e926ed2b3c 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -104,6 +104,11 @@ LLPanelClassifiedInfo::LLPanelClassifiedInfo() LLPanelClassifiedInfo::~LLPanelClassifiedInfo() { sAllPanels.remove(this); + + if (getAvatarId().notNull()) + { + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this); + } } BOOL LLPanelClassifiedInfo::postBuild() diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index ab255d5215..0ab0d85c78 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -134,6 +134,15 @@ void LLPanelGroup::onOpen(const LLSD& key) if(panel_notices) panel_notices->refreshNotices(); } + if (str_action == "show_notices") + { + setGroupID(group_id); + + LLAccordionCtrl *tab_ctrl = getChild<LLAccordionCtrl>("groups_accordion"); + tab_ctrl->collapseAllTabs(); + getChild<LLAccordionCtrlTab>("group_notices_tab")->setDisplayChildren(true); + tab_ctrl->arrange(); + } } @@ -264,8 +273,15 @@ void LLPanelGroup::onBtnGroupChatClicked(void* user_data) void LLPanelGroup::onBtnJoin() { - LL_DEBUGS() << "joining group: " << mID << LL_ENDL; - LLGroupActions::join(mID); + if (LLGroupActions::isInGroup(mID)) + { + LLGroupActions::leave(mID); + } + else + { + LL_DEBUGS() << "joining group: " << mID << LL_ENDL; + LLGroupActions::join(mID); + } } void LLPanelGroup::changed(LLGroupChange gc) @@ -303,12 +319,17 @@ void LLPanelGroup::update(LLGroupChange gc) LLGroupData agent_gdatap; bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlikeWithoutAdminMenuFakery(); - bool join_btn_visible = !is_member && gdatap->mOpenEnrollment; + bool join_btn_visible = is_member || gdatap->mOpenEnrollment; mButtonJoin->setVisible(join_btn_visible); mJoinText->setVisible(join_btn_visible); - if(join_btn_visible) + if (is_member) + { + mJoinText->setValue(getString("group_member")); + mButtonJoin->setLabel(getString("leave_txt")); + } + else if(join_btn_visible) { LLStringUtil::format_map_t string_args; std::string fee_buff; @@ -323,6 +344,7 @@ void LLPanelGroup::update(LLGroupChange gc) fee_buff = getString("group_join_free", string_args); } mJoinText->setValue(fee_buff); + mButtonJoin->setLabel(getString("join_txt")); } } } diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 82f880c9ee..a38e27b16b 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -250,6 +250,7 @@ BOOL LLPanelGroupNotices::postBuild() mNoticesList = getChild<LLScrollListCtrl>("notice_list",recurse); mNoticesList->setCommitOnSelectionChange(TRUE); mNoticesList->setCommitCallback(onSelectNotice, this); + mNoticesList->sortByColumn("date", false); mBtnNewMessage = getChild<LLButton>("create_new_notice",recurse); mBtnNewMessage->setClickedCallback(onClickNewMessage, this); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0704fc881d..94f1b252dd 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -244,7 +244,7 @@ BOOL LLPanelObject::postBuild() mCtrlSculptTexture = getChild<LLTextureCtrl>("sculpt texture control"); if (mCtrlSculptTexture) { - mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE)); + mCtrlSculptTexture->setDefaultImageAssetID(SCULPT_DEFAULT_TEXTURE); mCtrlSculptTexture->setCommitCallback( boost::bind(&LLPanelObject::onCommitSculpt, this, _2 )); mCtrlSculptTexture->setOnCancelCallback( boost::bind(&LLPanelObject::onCancelSculpt, this, _2 )); mCtrlSculptTexture->setOnSelectCallback( boost::bind(&LLPanelObject::onSelectSculpt, this, _2 )); @@ -2024,7 +2024,7 @@ void LLPanelObject::onCancelSculpt(const LLSD& data) if(mSculptTextureRevert == LLUUID::null) { - mSculptTextureRevert = LLUUID(SCULPT_DEFAULT_TEXTURE); + mSculptTextureRevert = SCULPT_DEFAULT_TEXTURE; } mTextureCtrl->setImageAssetID(mSculptTextureRevert); @@ -2267,7 +2267,7 @@ void LLPanelObject::onCopyParams() } else { - mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE); + mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE; } mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType(); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 632e902d70..90f8ae12c1 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -130,7 +130,7 @@ public: virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL isItemMovable() const; - virtual BOOL isItemRemovable() const; + virtual BOOL isItemRemovable(bool check_worn = true) const; virtual BOOL removeItem(); virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); virtual void move(LLFolderViewModelItem* parent_listener); @@ -336,7 +336,7 @@ BOOL LLTaskInvFVBridge::isItemMovable() const return TRUE; } -BOOL LLTaskInvFVBridge::isItemRemovable() const +BOOL LLTaskInvFVBridge::isItemRemovable(bool check_worn) const { const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); if(object @@ -588,7 +588,7 @@ public: virtual BOOL isItemRenameable() const; // virtual BOOL isItemCopyable() const { return FALSE; } virtual BOOL renameItem(const std::string& new_name); - virtual BOOL isItemRemovable() const; + virtual BOOL isItemRemovable(bool check_worn = true) const; virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual bool hasChildren() const; virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const; @@ -648,7 +648,7 @@ BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name) return FALSE; } -BOOL LLTaskCategoryBridge::isItemRemovable() const +BOOL LLTaskCategoryBridge::isItemRemovable(bool check_worn) const { return FALSE; } diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 8114e05a94..3d75fc56b5 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -71,7 +71,6 @@ #include "llpanelblockedlist.h" #include "llpanelprofileclassifieds.h" #include "llpanelprofilepicks.h" -#include "llthumbnailctrl.h" #include "lltrans.h" #include "llviewercontrol.h" #include "llviewermenu.h" //is_agent_mappable @@ -102,216 +101,6 @@ static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage"; ////////////////////////////////////////////////////////////////////////// -void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t httpHeaders; - - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - httpOpts->setFollowRedirects(true); - - std::string finalUrl = cap_url + "/" + agent_id.asString(); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL; - - if (!status - || !result.has("id") - || agent_id != result["id"].asUUID()) - { - LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL; - return; - } - - LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)); - if (!floater_profile) - { - // floater is dead, so panels are dead as well - return; - } - - LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE); - LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel); - if (!panel_profile) - { - LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; - return; - } - - - // Avatar Data - - LLAvatarData *avatar_data = &panel_profile->mAvatarData; - std::string birth_date; - - avatar_data->agent_id = agent_id; - avatar_data->avatar_id = agent_id; - avatar_data->image_id = result["sl_image_id"].asUUID(); - avatar_data->fl_image_id = result["fl_image_id"].asUUID(); - avatar_data->partner_id = result["partner_id"].asUUID(); - avatar_data->about_text = result["sl_about_text"].asString(); - avatar_data->fl_about_text = result["fl_about_text"].asString(); - avatar_data->born_on = result["member_since"].asDate(); - avatar_data->profile_url = getProfileURL(agent_id.asString()); - avatar_data->customer_type = result["customer_type"].asString(); - - avatar_data->flags = 0; - - if (result["online"].asBoolean()) - { - avatar_data->flags |= AVATAR_ONLINE; - } - if (result["allow_publish"].asBoolean()) - { - avatar_data->flags |= AVATAR_ALLOW_PUBLISH; - } - if (result["identified"].asBoolean()) - { - avatar_data->flags |= AVATAR_IDENTIFIED; - } - if (result["transacted"].asBoolean()) - { - avatar_data->flags |= AVATAR_TRANSACTED; - } - - avatar_data->caption_index = 0; - if (result.has("charter_member")) // won't be present if "caption" is set - { - avatar_data->caption_index = result["charter_member"].asInteger(); - } - else if (result.has("caption")) - { - avatar_data->caption_text = result["caption"].asString(); - } - - panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE); - LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel); - if (panel_sl) - { - panel_sl->processProfileProperties(avatar_data); - } - - panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE); - LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel); - if (panel_web) - { - panel_web->setLoaded(); - } - - panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE); - LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel); - if (panel_first) - { - panel_first->processProperties(avatar_data); - } - - // Picks - - LLSD picks_array = result["picks"]; - LLAvatarPicks avatar_picks; - avatar_picks.agent_id = agent_id; // Not in use? - avatar_picks.target_id = agent_id; - - for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it) - { - const LLSD& pick_data = *it; - avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); - } - - panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE); - LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel); - if (panel_picks) - { - // Refresh pick limit before processing - LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks); - panel_picks->processProperties(&avatar_picks); - } - - // Groups - - LLSD groups_array = result["groups"]; - LLAvatarGroups avatar_groups; - avatar_groups.agent_id = agent_id; // Not in use? - avatar_groups.avatar_id = agent_id; // target_id - - for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it) - { - const LLSD& group_info = *it; - LLAvatarGroups::LLGroupData group_data; - group_data.group_powers = 0; // Not in use? - group_data.group_title = group_info["name"].asString(); // Missing data, not in use? - group_data.group_id = group_info["id"].asUUID(); - group_data.group_name = group_info["name"].asString(); - group_data.group_insignia_id = group_info["image_id"].asUUID(); - - avatar_groups.group_list.push_back(group_data); - } - - if (panel_sl) - { - panel_sl->processGroupProperties(&avatar_groups); - } - - // Notes - LLAvatarNotes avatar_notes; - - avatar_notes.agent_id = agent_id; - avatar_notes.target_id = agent_id; - avatar_notes.notes = result["notes"].asString(); - - panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE); - LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel); - if (panel_notes) - { - panel_notes->processProperties(&avatar_notes); - } -} - -//TODO: changes take two minutes to propagate! -// Add some storage that holds updated data for two minutes -// for new instances to reuse the data -// Profile data is only relevant to own avatar, but notes -// are for everybody (no onger an issue?) -void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data, std::function<void(bool)> callback) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t httpHeaders; - - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - httpOpts->setFollowRedirects(true); - - std::string finalUrl = cap_url + "/" + agent_id.asString(); - - LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL; - } - else - { - LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL; - } - - if (callback) - { - callback(status); - } -} - LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); @@ -348,7 +137,6 @@ LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::stri } // Upload the image - LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest); LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders); LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions); @@ -898,11 +686,12 @@ void LLFloaterProfilePermissions::onCancel() // LLPanelProfileSecondLife LLPanelProfileSecondLife::LLPanelProfileSecondLife() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() , mAvatarNameCacheConnection() , mHasUnsavedDescriptionChanges(false) , mWaitingForImageUpload(false) , mAllowPublish(false) + , mHideAge(false) { } @@ -928,7 +717,8 @@ BOOL LLPanelProfileSecondLife::postBuild() { mGroupList = getChild<LLGroupList>("group_list"); mShowInSearchCombo = getChild<LLComboBox>("show_in_search"); - mSecondLifePic = getChild<LLThumbnailCtrl>("2nd_life_pic"); + mHideAgeCombo = getChild<LLComboBox>("hide_age"); + mSecondLifePic = getChild<LLProfileImageCtrl>("2nd_life_pic"); mSecondLifePicLayout = getChild<LLPanel>("image_panel"); mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit"); mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu"); @@ -942,6 +732,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects"); mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr); + mHideAgeCombo->setCommitCallback([this](LLUICtrl*, void*) { onHideAgeCallback(); }, nullptr); mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); }); mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); }); mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); @@ -1012,26 +803,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); } -void LLPanelProfileSecondLife::updateData() -{ - LLUUID avatar_id = getAvatarId(); - if (!getStarted() && avatar_id.notNull()) - { - setIsLoading(); - - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("requestAgentUserInfoCoro", - boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); - } - else - { - LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; - } - } -} - void LLPanelProfileSecondLife::refreshName() { if (!mAvatarNameCacheConnection.connected()) @@ -1046,10 +817,9 @@ void LLPanelProfileSecondLife::resetData() // Set default image and 1:1 dimensions for it mSecondLifePic->setValue("Generic_Person_Large"); - mImageId = LLUUID::null; LLRect imageRect = mSecondLifePicLayout->getRect(); - mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight()); + mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth()); setDescriptionText(LLStringUtil::null); mGroups.clear(); @@ -1075,6 +845,18 @@ void LLPanelProfileSecondLife::resetData() childSetVisible("partner_spacer_layout", TRUE); } +void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProfileProperties(avatar_data); + } + } +} + void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) { const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); @@ -1094,22 +876,18 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat fillAccountStatus(avatar_data); - setLoaded(); -} - -void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups) -{ - - LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin(); - const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end(); + LLAvatarData::group_list_t::const_iterator it = avatar_data->group_list.begin(); + const LLAvatarData::group_list_t::const_iterator it_end = avatar_data->group_list.end(); for (; it_end != it; ++it) { - LLAvatarGroups::LLGroupData group_data = *it; + LLAvatarData::LLGroupData group_data = *it; mGroups[group_data.group_name] = group_data.group_id; } mGroupList->setGroups(mGroups); + + setLoaded(); } void LLPanelProfileSecondLife::openGroupProfile() @@ -1143,36 +921,12 @@ void LLPanelProfileSecondLife::setProfileImageUploading(bool loading) void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id) { mSecondLifePic->setValue(image_asset_id); - mImageId = image_asset_id; - - LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id); - if (imagep->getFullHeight()) - { - onImageLoaded(true, imagep); - } - else - { - imagep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, - FALSE, - FALSE, - new LLHandle<LLPanel>(getHandle()), - NULL, - FALSE); - } LLFloater *floater = mFloaterProfileTextureHandle.get(); if (floater) { LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); - if (mImageId.notNull()) - { - texture_view->loadAsset(mImageId); - } - else - { - texture_view->resetAsset(); - } + texture_view->loadAsset(mSecondLifePic->getImageAssetId()); } setProfileImageUploading(false); @@ -1216,42 +970,16 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data) // and to make sure icons in text will be up to date LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id); - fillAgeData(avatar_data->born_on); + fillAgeData(avatar_data); setDescriptionText(avatar_data->about_text); - if (avatar_data->image_id.notNull()) - { - mSecondLifePic->setValue(avatar_data->image_id); - mImageId = avatar_data->image_id; - } - else - { - mSecondLifePic->setValue("Generic_Person_Large"); - mImageId = LLUUID::null; - } - - // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic - LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id); - if (imagep->getFullHeight()) - { - onImageLoaded(true, imagep); - } - else - { - imagep->setLoadedCallback(onImageLoaded, - MAX_DISCARD_LEVEL, - FALSE, - FALSE, - new LLHandle<LLPanel>(getHandle()), - NULL, - FALSE); - } + mSecondLifePic->setValue(avatar_data->image_id); if (getSelfProfile()) { mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH; - mShowInSearchCombo->setValue((BOOL)mAllowPublish); + mShowInSearchCombo->setValue(mAllowPublish ? TRUE : FALSE); } } @@ -1376,21 +1104,47 @@ void LLPanelProfileSecondLife::fillRightsData() } } -void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) +void LLPanelProfileSecondLife::fillAgeData(const LLAvatarData* avatar_data) { // Date from server comes already converted to stl timezone, // so display it as an UTC + 0 - std::string name_and_date = getString("date_format"); + bool hide_age = avatar_data->hide_age && !getSelfProfile(); + std::string name_and_date = getString(hide_age ? "date_format_short" : "date_format_full"); LLSD args_name; - args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); + args_name["datetime"] = (S32)avatar_data->born_on.secondsSinceEpoch(); LLStringUtil::format(name_and_date, args_name); getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date); - std::string register_date = getString("age_format"); - LLSD args_age; - args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now()); - LLStringUtil::format(register_date, args_age); - getChild<LLUICtrl>("user_age")->setValue(register_date); + LLUICtrl* userAgeCtrl = getChild<LLUICtrl>("user_age"); + if (hide_age) + { + userAgeCtrl->setVisible(FALSE); + } + else + { + std::string register_date = getString("age_format"); + LLSD args_age; + args_age["[AGE]"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now()); + LLStringUtil::format(register_date, args_age); + userAgeCtrl->setValue(register_date); + } + + BOOL showHideAgeCombo = FALSE; + if (getSelfProfile()) + { + if (LLAvatarPropertiesProcessor::getInstance()->isHideAgeSupportedByServer()) + { + F64 birth = avatar_data->born_on.secondsSinceEpoch(); + F64 now = LLDate::now().secondsSinceEpoch(); + if (now - birth > 365 * 24 * 60 * 60) + { + mHideAge = avatar_data->hide_age; + mHideAgeCombo->setValue(mHideAge ? TRUE : FALSE); + showHideAgeCombo = TRUE; + } + } + } + mHideAgeCombo->setVisible(showHideAgeCombo); } void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep) @@ -1407,34 +1161,6 @@ void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTextur } } -//static -void LLPanelProfileSecondLife::onImageLoaded(BOOL success, - LLViewerFetchedTexture *src_vi, - LLImageRaw* src, - LLImageRaw* aux_src, - S32 discard_level, - BOOL final, - void* userdata) -{ - if (!userdata) return; - - LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata; - - if (!handle->isDead()) - { - LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get()); - if (panel) - { - panel->onImageLoaded(success, src_vi); - } - } - - if (final || !success) - { - delete handle; - } -} - // virtual, called by LLAvatarTracker void LLPanelProfileSecondLife::changed(U32 mask) { @@ -1465,7 +1191,7 @@ void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); } - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); if (LLAvatarActions::isFriend(getAvatarId())) { @@ -1507,6 +1233,10 @@ void LLPanelProfileSecondLife::setLoaded() if (getSelfProfile()) { mShowInSearchCombo->setEnabled(TRUE); + if (mHideAgeCombo->getVisible()) + { + mHideAgeCombo->setEnabled(TRUE); + } mDescriptionEdit->setEnabled(TRUE); } } @@ -1559,7 +1289,7 @@ void LLProfileImagePicker::notify(const std::vector<std::string>& filenames) if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM)) { LLSD notif_args; - notif_args["REASON"] = LLImage::getLastError().c_str(); + notif_args["REASON"] = LLImage::getLastThreadError().c_str(); LLNotificationsUtil::add("CannotUploadTexture", notif_args); LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)mType << ", " << notif_args["REASON"].asString() << LL_ENDL; return; @@ -1695,7 +1425,7 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) } else if (item_name == "upload_photo") { - (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile(); + (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(LLPanel::getHandle())))->getFile(); LLFloater* floaterp = mFloaterTexturePickerHandle.get(); if (floaterp) @@ -1770,7 +1500,7 @@ bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata) else if (item_name == "remove_photo") { std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); + return mSecondLifePic->getImageAssetId().notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded(); } return false; @@ -1834,39 +1564,28 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty() void LLPanelProfileSecondLife::onShowInSearchCallback() { - S32 value = mShowInSearchCombo->getValue().asInteger(); - if (mAllowPublish == (bool)value) - { + bool value = mShowInSearchCombo->getValue().asInteger(); + if (value == mAllowPublish) return; - } - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - mAllowPublish = value; - LLSD data; - data["allow_publish"] = mAllowPublish; - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data, nullptr)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + + mAllowPublish = value; + saveAgentUserInfoCoro("allow_publish", value); +} + +void LLPanelProfileSecondLife::onHideAgeCallback() +{ + bool value = mHideAgeCombo->getValue().asInteger(); + if (value == mHideAge) + return; + + mHideAge = value; + saveAgentUserInfoCoro("hide_age", value); } void LLPanelProfileSecondLife::onSaveDescriptionChanges() { mDescriptionText = mDescriptionEdit->getValue().asString(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText), nullptr)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + saveAgentUserInfoCoro("sl_about_text", mDescriptionText); mSaveDescriptionChanges->setEnabled(FALSE); mDiscardDescriptionChanges->setEnabled(FALSE); @@ -1916,9 +1635,9 @@ void LLPanelProfileSecondLife::onShowAgentProfileTexture() { LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater); mFloaterProfileTextureHandle = texture_view->getHandle(); - if (mImageId.notNull()) + if (mSecondLifePic->getImageAssetId().notNull()) { - texture_view->loadAsset(mImageId); + texture_view->loadAsset(mSecondLifePic->getImageAssetId()); } else { @@ -1935,9 +1654,9 @@ void LLPanelProfileSecondLife::onShowAgentProfileTexture() LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); texture_view->setMinimized(FALSE); texture_view->setVisibleAndFrontmost(TRUE); - if (mImageId.notNull()) + if (mSecondLifePic->getImageAssetId().notNull()) { - texture_view->loadAsset(mImageId); + texture_view->loadAsset(mSecondLifePic->getImageAssetId()); } else { @@ -1960,9 +1679,9 @@ void LLPanelProfileSecondLife::onShowTexturePicker() getWindow()->setCursor(UI_CURSOR_WAIT); LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( this, - mImageId, + mSecondLifePic->getImageAssetId(), LLUUID::null, - mImageId, + mSecondLifePic->getImageAssetId(), FALSE, FALSE, "SELECT PHOTO", @@ -2000,55 +1719,36 @@ void LLPanelProfileSecondLife::onShowTexturePicker() void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) { - if (mImageId == id) - { + if (mSecondLifePic->getImageAssetId() == id) return; - } - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) + std::function<void(bool)> callback = [id](bool result) { - std::function<void(bool)> callback = [id](bool result) + if (result) { - if (result) - { - LLAvatarIconIDCache::getInstance()->add(gAgentID, id); - // Should trigger callbacks in icon controls - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID); - } - }; - LLSD params; - params["sl_image_id"] = id; - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params, callback)); - - mImageId = id; - if (mImageId == LLUUID::null) + LLAvatarIconIDCache::getInstance()->add(gAgentID, id); + // Should trigger callbacks in icon controls (or request Legacy) + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID); + } + }; + + if (!saveAgentUserInfoCoro("sl_image_id", id, callback)) + return; + + mSecondLifePic->setValue(id); + + LLFloater *floater = mFloaterProfileTextureHandle.get(); + if (floater) + { + LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); + if (id == LLUUID::null) { - mSecondLifePic->setValue("Generic_Person_Large"); + texture_view->resetAsset(); } else { - mSecondLifePic->setValue(mImageId); + texture_view->loadAsset(id); } - - LLFloater *floater = mFloaterProfileTextureHandle.get(); - if (floater) - { - LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater); - if (mImageId == LLUUID::null) - { - texture_view->resetAsset(); - } - else - { - texture_view->loadAsset(mImageId); - } - } - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -2180,6 +1880,8 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e LLStringUtil::format_map_t args; args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32()); childSetValue("status_text", LLSD( getString("LoadTime", args)) ); + + setLoaded(); } break; @@ -2195,7 +1897,7 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e ////////////////////////////////////////////////////////////////////////// LLPanelProfileFirstLife::LLPanelProfileFirstLife() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() , mHasUnsavedChanges(false) { } @@ -2207,7 +1909,7 @@ LLPanelProfileFirstLife::~LLPanelProfileFirstLife() BOOL LLPanelProfileFirstLife::postBuild() { mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit"); - mPicture = getChild<LLThumbnailCtrl>("real_world_pic"); + mPicture = getChild<LLProfileImageCtrl>("real_world_pic"); mUploadPhoto = getChild<LLButton>("fl_upload_image"); mChangePhoto = getChild<LLButton>("fl_change_image"); @@ -2242,7 +1944,7 @@ void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) { mUploadPhoto->setEnabled(!loading); mChangePhoto->setEnabled(!loading); - mRemovePhoto->setEnabled(!loading && mImageId.notNull()); + mRemovePhoto->setEnabled(!loading && mPicture->getImageAssetId().notNull()); LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator"); indicator->setVisible(loading); @@ -2259,7 +1961,6 @@ void LLPanelProfileFirstLife::setProfileImageUploading(bool loading) void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id) { mPicture->setValue(image_asset_id); - mImageId = image_asset_id; setProfileImageUploading(false); } @@ -2273,7 +1974,7 @@ void LLPanelProfileFirstLife::commitUnsavedChanges() void LLPanelProfileFirstLife::onUploadPhoto() { - (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile(); + (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(LLPanel::getHandle())))->getFile(); LLFloater* floaterp = mFloaterTexturePickerHandle.get(); if (floaterp) @@ -2296,9 +1997,9 @@ void LLPanelProfileFirstLife::onChangePhoto() getWindow()->setCursor(UI_CURSOR_WAIT); LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker( this, - mImageId, + mPicture->getImageAssetId(), LLUUID::null, - mImageId, + mPicture->getImageAssetId(), FALSE, FALSE, "SELECT PHOTO", @@ -2346,35 +2047,15 @@ void LLPanelProfileFirstLife::onRemovePhoto() void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) { - if (mImageId == id) - { + if (mPicture->getImageAssetId() == id) return; - } - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLSD params; - params["fl_image_id"] = id; - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params, nullptr)); + if (!saveAgentUserInfoCoro("fl_image_id", id)) + return; - mImageId = id; - if (mImageId.notNull()) - { - mPicture->setValue(mImageId); - } - else - { - mPicture->setValue("Generic_Person_Large"); - } + mPicture->setValue(id); - mRemovePhoto->setEnabled(mImageId.notNull()); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + mRemovePhoto->setEnabled(id.notNull()); } void LLPanelProfileFirstLife::setDescriptionText(const std::string &text) @@ -2397,16 +2078,7 @@ void LLPanelProfileFirstLife::onSetDescriptionDirty() void LLPanelProfileFirstLife::onSaveDescriptionChanges() { mCurrentDescription = mDescriptionEdit->getValue().asString(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription), nullptr)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + saveAgentUserInfoCoro("fl_about_text", mCurrentDescription); mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); @@ -2418,20 +2090,23 @@ void LLPanelProfileFirstLife::onDiscardDescriptionChanges() setDescriptionText(mCurrentDescription); } +void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProperties(avatar_data); + } + } +} + void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { setDescriptionText(avatar_data->fl_about_text); - mImageId = avatar_data->fl_image_id; - - if (mImageId.notNull()) - { - mPicture->setValue(mImageId); - } - else - { - mPicture->setValue("Generic_Person_Large"); - } + mPicture->setValue(avatar_data->fl_image_id); setLoaded(); } @@ -2439,8 +2114,7 @@ void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) void LLPanelProfileFirstLife::resetData() { setDescriptionText(std::string()); - mPicture->setValue("Generic_Person_Large"); - mImageId = LLUUID::null; + mPicture->setValue(LLUUID::null); mUploadPhoto->setVisible(getSelfProfile()); mChangePhoto->setVisible(getSelfProfile()); @@ -2457,7 +2131,7 @@ void LLPanelProfileFirstLife::setLoaded() { mDescriptionEdit->setEnabled(TRUE); mPicture->setEnabled(TRUE); - mRemovePhoto->setEnabled(mImageId.notNull()); + mRemovePhoto->setEnabled(mPicture->getImageAssetId().notNull()); } } @@ -2466,7 +2140,7 @@ void LLPanelProfileFirstLife::setLoaded() ////////////////////////////////////////////////////////////////////////// LLPanelProfileNotes::LLPanelProfileNotes() -: LLPanelProfileTab() +: LLPanelProfilePropertiesProcessorTab() , mHasUnsavedChanges(false) { @@ -2476,22 +2150,6 @@ LLPanelProfileNotes::~LLPanelProfileNotes() { } -void LLPanelProfileNotes::updateData() -{ - LLUUID avatar_id = getAvatarId(); - if (!getStarted() && avatar_id.notNull()) - { - setIsLoading(); - - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("requestAgentUserInfoCoro", - boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); - } - } -} - void LLPanelProfileNotes::commitUnsavedChanges() { if (mHasUnsavedChanges) @@ -2540,16 +2198,7 @@ void LLPanelProfileNotes::onSetNotesDirty() void LLPanelProfileNotes::onSaveNotesChanges() { mCurrentNotes = mNotesEditor->getValue().asString(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("putAgentUserInfoCoro", - boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes), nullptr)); - } - else - { - LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; - } + saveAgentUserInfoCoro("notes", mCurrentNotes); mSaveChanges->setEnabled(FALSE); mDiscardChanges->setEnabled(FALSE); @@ -2561,9 +2210,21 @@ void LLPanelProfileNotes::onDiscardNotesChanges() setNotesText(mCurrentNotes); } -void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) +void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); + if (avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProperties(avatar_data); + } + } +} + +void LLPanelProfileNotes::processProperties(const LLAvatarData* avatar_data) { - setNotesText(avatar_notes->notes); + setNotesText(avatar_data->notes); mNotesEditor->setEnabled(TRUE); setLoaded(); } @@ -2574,14 +2235,6 @@ void LLPanelProfileNotes::resetData() setNotesText(std::string()); } -void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) -{ - if (avatar_id.notNull()) - { - LLPanelProfileTab::setAvatarId(avatar_id); - } -} - ////////////////////////////////////////////////////////////////////////// // LLPanelProfile @@ -2658,12 +2311,7 @@ void LLPanelProfile::updateData() mPanelFirstlife->setIsLoading(); mPanelNotes->setIsLoading(); - std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); - if (!cap_url.empty()) - { - LLCoros::instance().launch("requestAgentUserInfoCoro", - boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); - } + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(getAvatarId()); } } diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 11632a10ae..3760fe11d7 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -58,9 +58,9 @@ class LLTextBase; class LLMenuButton; class LLLineEditor; class LLTextEditor; -class LLThumbnailCtrl; class LLPanelProfileClassifieds; class LLPanelProfilePicks; +class LLProfileImageCtrl; class LLViewerFetchedTexture; @@ -68,7 +68,7 @@ class LLViewerFetchedTexture; * Panel for displaying Avatar's second life related info. */ class LLPanelProfileSecondLife - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab , public LLFriendObserver , public LLVoiceClientStatusObserver { @@ -93,10 +93,6 @@ public: void resetData() override; - /** - * Sends update data request to server. - */ - void updateData() override; void refreshName(); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); @@ -107,7 +103,7 @@ public: bool hasUnsavedChanges() override; void commitUnsavedChanges() override; - friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + void processProperties(void* data, EAvatarProcessorType type) override; protected: /** @@ -116,11 +112,6 @@ protected: void processProfileProperties(const LLAvatarData* avatar_data); /** - * Processes group related data received from server. - */ - void processGroupProperties(const LLAvatarGroups* avatar_groups); - - /** * Fills common for Avatar profile and My Profile fields. */ void fillCommonData(const LLAvatarData* avatar_data); @@ -143,16 +134,9 @@ protected: /** * Fills user name, display name, age. */ - void fillAgeData(const LLDate &born_on); + void fillAgeData(const LLAvatarData* avatar_data); void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep); - static void onImageLoaded(BOOL success, - LLViewerFetchedTexture *src_vi, - LLImageRaw* src, - LLImageRaw* aux_src, - S32 discard_level, - BOOL final, - void* userdata); /** * Displays avatar's online status if possible. @@ -179,6 +163,7 @@ private: void setDescriptionText(const std::string &text); void onSetDescriptionDirty(); void onShowInSearchCallback(); + void onHideAgeCallback(); void onSaveDescriptionChanges(); void onDiscardDescriptionChanges(); void onShowAgentPermissionsDialog(); @@ -193,7 +178,8 @@ private: LLGroupList* mGroupList; LLComboBox* mShowInSearchCombo; - LLThumbnailCtrl* mSecondLifePic; + LLComboBox* mHideAgeCombo; + LLProfileImageCtrl* mSecondLifePic; LLPanel* mSecondLifePicLayout; LLTextEditor* mDescriptionEdit; LLMenuButton* mAgentActionMenuButton; @@ -214,9 +200,8 @@ private: bool mVoiceStatus; bool mWaitingForImageUpload; bool mAllowPublish; + bool mHideAge; std::string mDescriptionText; - LLUUID mImageId; - boost::signals2::connection mAvatarNameCacheConnection; }; @@ -247,8 +232,6 @@ public: void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); - friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); - protected: void onCommitLoad(LLUICtrl* ctrl); @@ -267,7 +250,7 @@ private: * Panel for displaying Avatar's first life related info. */ class LLPanelProfileFirstLife - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileFirstLife(); @@ -277,6 +260,7 @@ public: BOOL postBuild() override; + void processProperties(void* data, EAvatarProcessorType type) override; void processProperties(const LLAvatarData* avatar_data); void resetData() override; @@ -287,8 +271,6 @@ public: bool hasUnsavedChanges() override { return mHasUnsavedChanges; } void commitUnsavedChanges() override; - friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); - protected: void setLoaded() override; @@ -302,7 +284,7 @@ protected: void onDiscardDescriptionChanges(); LLTextEditor* mDescriptionEdit; - LLThumbnailCtrl* mPicture; + LLProfileImageCtrl* mPicture; LLButton* mUploadPhoto; LLButton* mChangePhoto; LLButton* mRemovePhoto; @@ -312,7 +294,6 @@ protected: LLHandle<LLFloater> mFloaterTexturePickerHandle; std::string mCurrentDescription; - LLUUID mImageId; bool mHasUnsavedChanges; }; @@ -320,24 +301,21 @@ protected: * Panel for displaying Avatar's notes and modifying friend's rights. */ class LLPanelProfileNotes - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileNotes(); /*virtual*/ ~LLPanelProfileNotes(); - void setAvatarId(const LLUUID& avatar_id) override; - void onOpen(const LLSD& key) override; BOOL postBuild() override; - void processProperties(LLAvatarNotes* avatar_notes); + void processProperties(void* data, EAvatarProcessorType type) override; + void processProperties(const LLAvatarData* avatar_data); void resetData() override; - void updateData() override; - bool hasUnsavedChanges() override { return mHasUnsavedChanges; } void commitUnsavedChanges() override; @@ -384,10 +362,6 @@ public: void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false); void createClassified(); - LLAvatarData getAvatarData() { return mAvatarData; }; - - friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); - private: void onTabChange(); @@ -398,13 +372,6 @@ private: LLPanelProfileFirstLife* mPanelFirstlife; LLPanelProfileNotes* mPanelNotes; LLTabContainer* mTabContainer; - - // Todo: due to server taking minutes to update this needs a more long term storage - // to reuse recently saved values if user opens floater again - // Storage implementation depends onto how a cap will be implemented, if cap will be - // enought to fully update LLAvatarPropertiesProcessor, then this storage can be - // implemented there. - LLAvatarData mAvatarData; }; #endif //LL_LLPANELPROFILE_H diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 75b02fdf20..9a228a1f40 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -98,12 +98,6 @@ public: return true; } - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks")) - { - LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - // handle app/pick/create urls first if (params.size() == 1 && params[0].asString() == "create") { @@ -296,17 +290,21 @@ void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLS void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type) { - if (APT_PICKS == type) + if (APT_PROPERTIES == type) { - LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); - if (avatar_picks && getAvatarId() == avatar_picks->target_id) + LLAvatarData* avatar_picks = static_cast<LLAvatarData*>(data); + if (avatar_picks && getAvatarId() == avatar_picks->avatar_id) { + if (getSelfProfile()) + { + LLAgentPicksInfo::getInstance()->onServerRespond(avatar_picks); + } processProperties(avatar_picks); } } } -void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks) +void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks) { LLUUID selected_id = mPickToSelectOnLoad; bool has_selection = false; @@ -324,7 +322,7 @@ void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks) mTabContainer->deleteAllTabs(); - LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); + LLAvatarData::picks_list_t::const_iterator it = avatar_picks->picks_list.begin(); for (; avatar_picks->picks_list.end() != it; ++it) { LLUUID pick_id = it->first; @@ -428,7 +426,7 @@ void LLPanelProfilePicks::updateData() { setIsLoading(); - LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); } if (!getIsLoaded()) { diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index 228dfd5958..956b4c7850 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -58,7 +58,7 @@ public: void selectPick(const LLUUID& pick_id); void processProperties(void* data, EAvatarProcessorType type) override; - void processProperties(const LLAvatarPicks* avatar_picks); + void processProperties(const LLAvatarData* avatar_picks); void resetData() override; @@ -77,8 +77,6 @@ public: bool hasUnsavedChanges() override; void commitUnsavedChanges() override; - friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); - private: void onClickNewBtn(); void onClickDelete(); diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index bfdb0fbc88..35eba16afe 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -110,9 +110,9 @@ protected: registrar.add("Wearing.EditOutfit", boost::bind(&edit_outfit)); registrar.add("Wearing.ShowOriginal", boost::bind(show_item_original, mUUIDs.front())); registrar.add("Wearing.TakeOff", - boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs)); + boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); registrar.add("Wearing.Detach", - boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs)); + boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); LLContextMenu* menu = createFromFile("menu_wearing_tab.xml"); updateMenuItemsVisibility(menu); diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 9bf771db8a..ec537e216b 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -115,7 +115,7 @@ void LLPersistentNotificationStorage::loadNotifications() using namespace LLNotificationsUI; LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()-> - findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID)); LLNotifications& instance = LLNotifications::instance(); S32 processed_notifications = 0; diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp index d1a9ca229f..aadef9a308 100644 --- a/indra/newview/llpopupview.cpp +++ b/indra/newview/llpopupview.cpp @@ -256,16 +256,16 @@ void LLPopupView::removePopup(LLView* popup) void LLPopupView::clearPopups() { - for (popup_list_t::iterator popup_it = mPopups.begin(); - popup_it != mPopups.end();) + while (!mPopups.empty()) { - LLView* popup = popup_it->get(); - - popup_list_t::iterator cur_popup_it = popup_it; - ++popup_it; - - mPopups.erase(cur_popup_it); - popup->onTopLost(); + popup_list_t::iterator popup_it = mPopups.begin(); + LLView* popup = popup_it->get(); + // Remove before notifying in case it will cause removePopup + mPopups.erase(popup_it); + if (popup) + { + popup->onTopLost(); + } } } diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index 30d0a22ef0..1fcc456d62 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -254,8 +254,6 @@ void LLPresetsManager::getControlNames(std::vector<std::string>& names) // From panel_preferences_move.xml ("CameraAngle") ("CameraOffsetScale") - ("EditCameraMovement") - ("AppearanceCameraMovement") // From llagentcamera.cpp ("CameraOffsetBuild") ("TrackFocusObject") @@ -460,6 +458,9 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n LL_DEBUGS() << "attempting to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL; + bool appearance_camera_movement = gSavedSettings.getBOOL("AppearanceCameraMovement"); + bool edit_camera_movement = gSavedSettings.getBOOL("EditCameraMovement"); + mIgnoreChangedSignal = true; if(gSavedSettings.loadFromFile(full_path, false, true) > 0) { @@ -479,6 +480,16 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n { gSavedSettings.setString("PresetCameraActive", name); triggerChangeCameraSignal(); + + //SL-20277 old preset files may contain settings that should be ignored when loading camera presets + if (appearance_camera_movement != (bool)gSavedSettings.getBOOL("AppearanceCameraMovement")) + { + gSavedSettings.setBOOL("AppearanceCameraMovement", appearance_camera_movement); + } + if (edit_camera_movement != (bool)gSavedSettings.getBOOL("EditCameraMovement")) + { + gSavedSettings.setBOOL("EditCameraMovement", edit_camera_movement); + } } } else diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 544ff8b5dc..0b0d5d10cd 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -433,6 +433,11 @@ BOOL LLPreviewGesture::postBuild() edit->setIgnoreTab(TRUE); mChatEditor = edit; + check = getChild<LLCheckBoxCtrl>( "wait_key_release_check"); + check->setVisible(FALSE); + check->setCommitCallback(onCommitWait, this); + mWaitKeyReleaseCheck = check; + check = getChild<LLCheckBoxCtrl>( "wait_anim_check"); check->setVisible(FALSE); check->setCommitCallback(onCommitWait, this); @@ -638,6 +643,7 @@ void LLPreviewGesture::refresh() mAnimationRadio->setEnabled(FALSE); mSoundCombo->setEnabled(FALSE); mChatEditor->setEnabled(FALSE); + mWaitKeyReleaseCheck->setEnabled(FALSE); mWaitAnimCheck->setEnabled(FALSE); mWaitTimeCheck->setEnabled(FALSE); mWaitTimeEditor->setEnabled(FALSE); @@ -660,6 +666,7 @@ void LLPreviewGesture::refresh() mAnimationRadio->setEnabled(modifiable); mSoundCombo->setEnabled(modifiable); mChatEditor->setEnabled(modifiable); + mWaitKeyReleaseCheck->setEnabled(modifiable); mWaitAnimCheck->setEnabled(modifiable); mWaitTimeCheck->setEnabled(modifiable); mWaitTimeEditor->setEnabled(modifiable); @@ -695,6 +702,7 @@ void LLPreviewGesture::refresh() mAnimationRadio->setVisible(FALSE); mSoundCombo->setVisible(FALSE); mChatEditor->setVisible(FALSE); + mWaitKeyReleaseCheck->setVisible(FALSE); mWaitAnimCheck->setVisible(FALSE); mWaitTimeCheck->setVisible(FALSE); mWaitTimeEditor->setVisible(FALSE); @@ -739,6 +747,8 @@ void LLPreviewGesture::refresh() { LLGestureStepWait* wait_step = (LLGestureStepWait*)step; optionstext = getString("step_wait"); + mWaitKeyReleaseCheck->setVisible(TRUE); + mWaitKeyReleaseCheck->set(wait_step->mFlags & WAIT_FLAG_KEY_RELEASE); mWaitAnimCheck->setVisible(TRUE); mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM); mWaitTimeCheck->setVisible(TRUE); @@ -1518,6 +1528,7 @@ void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data) LLGestureStepWait* wait_step = (LLGestureStepWait*)step; U32 flags = 0x0; + if (self->mWaitKeyReleaseCheck->get()) flags |= WAIT_FLAG_KEY_RELEASE; if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM; if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME; wait_step->mFlags = flags; diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h index f5c47d71b8..d0fddaf49a 100644 --- a/indra/newview/llpreviewgesture.h +++ b/indra/newview/llpreviewgesture.h @@ -154,6 +154,7 @@ private: LLComboBox* mAnimationCombo; LLComboBox* mSoundCombo; LLLineEditor* mChatEditor; + LLCheckBoxCtrl* mWaitKeyReleaseCheck; LLCheckBoxCtrl* mWaitAnimCheck; LLCheckBoxCtrl* mWaitTimeCheck; LLLineEditor* mWaitTimeEditor; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index a26445b4bc..2e5aaa997d 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -74,8 +74,9 @@ void LLReflectionMap::autoAdjustOrigin() { const LLVector4a* bounds = mGroup->getBounds(); auto* node = mGroup->getOctreeNode(); + LLSpatialPartition* part = mGroup->getSpatialPartition(); - if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME) + if (part && part->mPartitionType == LLViewerRegion::PARTITION_VOLUME) { mPriority = 0; // cast a ray towards 8 corners of bounding box diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 17f2970f99..ea3aa58f94 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -170,8 +170,9 @@ void LLScreenChannelBase::init(S32 channel_left, S32 channel_right) void LLScreenChannelBase::updateRect() { + const S32 CHANNEL_BOTTOM_PANEL_MARGIN = 35; S32 channel_top = getChannelRect().mTop; - S32 channel_bottom = getChannelRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin"); + S32 channel_bottom = getChannelRect().mBottom + CHANNEL_BOTTOM_PANEL_MARGIN; S32 channel_left = getRect().mLeft; S32 channel_right = getRect().mRight; setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom)); diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index e5f4807ab7..d66c8afc22 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -34,6 +34,12 @@ namespace LLNotificationsUI { + const LLUUID ALERT_CHANNEL_UUID("F3E07BC8-A973-476D-8C7F-F3B7293975D1"); + const LLUUID NOTIFICATION_CHANNEL_UUID("AEED3193-8709-4693-8558-7452CCA97AE5"); + const LLUUID NEARBY_CHAT_CHANNEL_UUID("E1158BD6-661C-4981-9DAD-4DCBFF062502"); + const LLUUID STARTUP_CHANNEL_UUID("B56AF90D-6684-48E4-B1E4-722D3DEB2CB6"); + + const S32 NOTIFY_BOX_WIDTH = 305; typedef enum e_notification_toast_alignment { diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index 6a27ff3047..66ee016191 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -335,7 +335,7 @@ void LLScriptFloater::hideToastsIfNeeded() // find channel LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID( - LLUUID(gSavedSettings.getString("NotificationChannelUUID")))); + LLNotificationsUI::NOTIFICATION_CHANNEL_UUID)); // update notification channel state if(channel) { diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp index 74844a80e8..dbab7e53b6 100644 --- a/indra/newview/llsetkeybinddialog.cpp +++ b/indra/newview/llsetkeybinddialog.cpp @@ -74,13 +74,10 @@ LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key) pUpdater(NULL), mLastMaskKey(0), mContextConeOpacity(0.f), - mContextConeInAlpha(0.f), - mContextConeOutAlpha(0.f), - mContextConeFadeTime(0.f) + mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA), + mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA), + mContextConeFadeTime(CONTEXT_CONE_FADE_TIME) { - mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha"); - mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha"); - mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime"); } LLSetKeyBindDialog::~LLSetKeyBindDialog() diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index fe61b7a02a..ad8e1a6506 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -74,6 +74,32 @@ LLSidepanelTaskInfo* LLSidepanelTaskInfo::sActivePanel = NULL; static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info"); +static std::string click_action_to_string_value(U8 click_action) +{ + switch (click_action) + { + case CLICK_ACTION_TOUCH: + return "Touch"; + case CLICK_ACTION_SIT: + return "Sit"; + case CLICK_ACTION_BUY: + return "Buy"; + case CLICK_ACTION_PAY: + return "Pay"; + case CLICK_ACTION_OPEN: + return "Open"; + case CLICK_ACTION_ZOOM: + return "Zoom"; + case CLICK_ACTION_DISABLED: + return "None"; + case CLICK_ACTION_IGNORE: + return "Ignore"; + default: + return "Touch"; + } + return "Touch"; +} + // Default constructor LLSidepanelTaskInfo::LLSidepanelTaskInfo() : mVisibleDebugPermissions(true) // space was allocated by default @@ -891,11 +917,7 @@ void LLSidepanelTaskInfo::refresh() U8 click_action = 0; if (LLSelectMgr::getInstance()->selectionGetClickAction(&click_action)) { - LLComboBox* ComboClickAction = getChild<LLComboBox>("clickaction"); - if (ComboClickAction) - { - ComboClickAction->setCurrentByIndex((S32)click_action); - } + getChild<LLComboBox>("clickaction")->setValue(click_action_to_string_value(click_action)); } getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume); @@ -1152,6 +1174,8 @@ static U8 string_value_to_click_action(std::string p_value) return CLICK_ACTION_ZOOM; if (p_value == "None") return CLICK_ACTION_DISABLED; + if (p_value == "Ignore") + return CLICK_ACTION_IGNORE; return CLICK_ACTION_TOUCH; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index faf6f15015..f7c15dde1a 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1597,6 +1597,8 @@ bool check_rigged_group(LLDrawable* drawable) if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group) { + LL_WARNS() << "[root->isState(LLDrawable::RIGGED) and root->getSpatialGroup() != group] is true" + " (" << root->getSpatialGroup() << " != " << group << ")" << LL_ENDL; llassert(false); return false; } @@ -1606,8 +1608,10 @@ bool check_rigged_group(LLDrawable* drawable) { for (auto& face : root->getFaces()) { - if ((S32) face->getDrawOrderIndex() <= last_draw_index) + if ((S32)face->getDrawOrderIndex() <= last_draw_index) { + LL_WARNS() << "[(S32)face->getDrawOrderIndex() <= last_draw_index] is true" + " (" << (S32)face->getDrawOrderIndex() << " <= " << last_draw_index << ")" << LL_ENDL; llassert(false); return false; } @@ -1621,17 +1625,21 @@ bool check_rigged_group(LLDrawable* drawable) { for (auto& face : child->mDrawable->getFaces()) { - if ((S32) face->getDrawOrderIndex() <= last_draw_index) + if ((S32)face->getDrawOrderIndex() <= last_draw_index) { + LL_WARNS() << "[(S32)face->getDrawOrderIndex() <= last_draw_index] is true" + " (" << (S32)face->getDrawOrderIndex() << " <= " << last_draw_index << ")" << LL_ENDL; llassert(false); return false; } last_draw_index = face->getDrawOrderIndex(); } } - + if (child->mDrawable->getSpatialGroup() != group) { + LL_WARNS() << "[child->mDrawable->getSpatialGroup() != group] is true" + " (" << child->mDrawable->getSpatialGroup() << " != " << group << ")" << LL_ENDL; llassert(false); return false; } diff --git a/indra/newview/llsplitbutton.cpp b/indra/newview/llsplitbutton.cpp index 790305103d..c216319e76 100644 --- a/indra/newview/llsplitbutton.cpp +++ b/indra/newview/llsplitbutton.cpp @@ -243,7 +243,14 @@ LLSplitButton::LLSplitButton(const LLSplitButton::Params& p) item_top -= (rc.getHeight() + BUTTON_PAD); } - setTopLostCallback(boost::bind(&LLSplitButton::hideButtons, this)); + mTopLostSignalConnection = setTopLostCallback(boost::bind(&LLSplitButton::hideButtons, this)); +} + +LLSplitButton::~LLSplitButton() +{ + // explicitly disconect to avoid hideButtons with + // dead pointers being called on destruction + mTopLostSignalConnection.disconnect(); } diff --git a/indra/newview/llsplitbutton.h b/indra/newview/llsplitbutton.h index 4f20c8b379..dbb18c0c62 100644 --- a/indra/newview/llsplitbutton.h +++ b/indra/newview/llsplitbutton.h @@ -67,7 +67,7 @@ public: }; - virtual ~LLSplitButton() {}; + virtual ~LLSplitButton(); //Overridden virtual void onFocusLost(); @@ -99,6 +99,8 @@ protected: LLButton* mShownItem; EArrowPosition mArrowPosition; + boost::signals2::connection mTopLostSignalConnection; + commit_callback_t mSelectionCallback; }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a0324ca82a..e2530ed5e9 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1961,8 +1961,10 @@ bool idle_startup() display_startup(); return FALSE; } + LLInventoryModelBackgroundFetch::instance().start(); - LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); + LLAppearanceMgr::instance().initCOFID(); + LLUUID cof_id = LLAppearanceMgr::instance().getCOF(); LLViewerInventoryCategory* cof = gInventory.getCategory(cof_id); if (cof && cof->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) @@ -2273,7 +2275,7 @@ bool idle_startup() static LLFrameTimer wearables_timer; const F32 wearables_time = wearables_timer.getElapsedTimeF32(); - static LLCachedControl<F32> max_wearables_time(gSavedSettings, "ClothingLoadingDelay"); + const F32 MAX_WEARABLES_TIME = 10.f; if (!gAgent.isOutfitChosen() && isAgentAvatarValid()) { @@ -2292,7 +2294,7 @@ bool idle_startup() display_startup(); - if (gAgent.isOutfitChosen() && (wearables_time > max_wearables_time)) + if (gAgent.isOutfitChosen() && (wearables_time > MAX_WEARABLES_TIME)) { if (gInventory.isInventoryUsable()) { @@ -2710,18 +2712,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) LLViewerParcelMgr::processParcelDwellReply); msg->setHandlerFunc("AvatarPropertiesReply", - &LLAvatarPropertiesProcessor::processAvatarPropertiesReply); - msg->setHandlerFunc("AvatarInterestsReply", - &LLAvatarPropertiesProcessor::processAvatarInterestsReply); - msg->setHandlerFunc("AvatarGroupsReply", - &LLAvatarPropertiesProcessor::processAvatarGroupsReply); - // ratings deprecated - //msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply, - // LLPanelAvatar::processAvatarStatisticsReply); - msg->setHandlerFunc("AvatarNotesReply", - &LLAvatarPropertiesProcessor::processAvatarNotesReply); - msg->setHandlerFunc("AvatarPicksReply", - &LLAvatarPropertiesProcessor::processAvatarPicksReply); + &LLAvatarPropertiesProcessor::processAvatarLegacyPropertiesReply); msg->setHandlerFunc("AvatarClassifiedReply", &LLAvatarPropertiesProcessor::processAvatarClassifiedsReply); @@ -2878,6 +2869,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true); // Initiate creation of COF, since we're also bypassing that. gInventory.ensureCategoryForTypeExists(LLFolderType::FT_CURRENT_OUTFIT); + LLAppearanceMgr::getInstance()->initCOFID(); ESex gender; if (gender_name == "male") @@ -2990,7 +2982,9 @@ std::string LLStartUp::startupStateToString(EStartupState state) RTNENUM( STATE_AGENT_SEND ); RTNENUM( STATE_AGENT_WAIT ); RTNENUM( STATE_INVENTORY_SEND ); - RTNENUM(STATE_INVENTORY_CALLBACKS ); + RTNENUM( STATE_INVENTORY_CALLBACKS ); + RTNENUM( STATE_INVENTORY_SKEL ); + RTNENUM( STATE_INVENTORY_SEND2 ); RTNENUM( STATE_MISC ); RTNENUM( STATE_PRECACHE ); RTNENUM( STATE_WEARABLES_WAIT ); @@ -3033,6 +3027,7 @@ void reset_login() gAgent.cleanup(); gSky.cleanup(); // mVOSkyp is an inworld object. LLWorld::getInstance()->resetClass(); + LLAppearanceMgr::getInstance()->cleanup(); if ( gViewerWindow ) { // Hide menus and normal buttons diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 8f64cff47c..db6d822186 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -127,8 +127,8 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id) //--------------------------------------------------------------------------------- void LLSysWellWindow::initChannel() { - LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID( - LLUUID(gSavedSettings.getString("NotificationChannelUUID"))); + LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID( + LLNotificationsUI::NOTIFICATION_CHANNEL_UUID); mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel); if(NULL == mChannel) { diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 40bbe2b934..feffebdae3 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -348,13 +348,13 @@ private: } // Threads: Tid - virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) + virtual void completed(bool success, const std::string& error_message, LLImageRaw* raw, LLImageRaw* aux, U32 request_id) { LL_PROFILE_ZONE_SCOPED; LLTextureFetchWorker* worker = mFetcher->getWorker(mID); if (worker) { - worker->callbackDecoded(success, raw, aux, request_id); + worker->callbackDecoded(success, error_message, raw, aux, request_id); } } private: @@ -398,7 +398,7 @@ public: void callbackCacheWrite(bool success); // Threads: Tid - void callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id); + void callbackDecoded(bool success, const std::string& error_message, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id); // Threads: T* void setGetStatus(LLCore::HttpStatus status, const std::string& reason) @@ -2319,7 +2319,7 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success) ////////////////////////////////////////////////////////////////////////////// // Threads: Tid -void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id) +void LLTextureFetchWorker::callbackDecoded(bool success, const std::string &error_message, LLImageRaw* raw, LLImageRaw* aux, S32 decode_id) { LLMutexLock lock(&mWorkMutex); // +Mw if (mDecodeHandle == 0) @@ -2354,7 +2354,7 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag } else { - LL_WARNS(LOG_TXT) << "DECODE FAILED: " << mID << " Discard: " << (S32)mFormattedImage->getDiscardLevel() << LL_ENDL; + LL_WARNS(LOG_TXT) << "DECODE FAILED: " << mID << " Discard: " << (S32)mFormattedImage->getDiscardLevel() << ", reason: " << error_message << LL_ENDL; removeFromCache(); mDecodedDiscard = -1; // Redundant, here for clarity and paranoia } diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 84cd6e2da7..f31762c341 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -424,14 +424,12 @@ void LLAvatarTexBar::draw() text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT); line_num++; } - const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout"); const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); LLColor4 header_color(1.f, 1.f, 1.f, 0.9f); - const std::string texture_timeout_str = texture_timeout ? llformat("%d",texture_timeout) : "Disabled"; const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled"; - std::string header_text = llformat("[ Timeout('AvatarBakedTextureUploadTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str()); + std::string header_text = llformat("[ Timeout:60 ] [ LOD_Override('TextureDiscardLevel'):%s ]", override_tex_discard_level_str.c_str()); LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, l_offset, v_offset + line_height*line_num, header_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT); line_num++; diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 8bf078477a..27208e05f1 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -90,6 +90,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal std::string edit_text_contents; S32 edit_text_max_chars = 0; bool is_password = false; + bool allow_emoji = false; LLToastPanel::setBackgroundVisible(FALSE); LLToastPanel::setBackgroundOpaque(TRUE); @@ -134,6 +135,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal edit_text_contents = (*it)["value"].asString(); edit_text_name = (*it)["name"].asString(); edit_text_max_chars = (*it)["max_length_chars"].asInteger(); + allow_emoji = (*it)["allow_emoji"].asBoolean(); } else if (type == "password") { @@ -292,6 +294,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight()); mLineEditor->setRect(leditor_rect); mLineEditor->setMaxTextChars(edit_text_max_chars); + mLineEditor->setAllowEmoji(allow_emoji); mLineEditor->setText(edit_text_contents); std::string notif_name = mNotification->getName(); @@ -497,10 +500,9 @@ void LLToastAlertPanel::draw() } static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow"); - static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 5); gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0, - shadow_color, shadow_lines); + shadow_color, DROP_SHADOW_FLOATER); LLToastPanel::draw(); } diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index bf3f4c1e88..9db4bc4d3f 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -50,8 +50,8 @@ S32 BUTTON_WIDTH = 90; //static -const LLFontGL* LLToastNotifyPanel::sFont = NULL; -const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL; +const std::string LLToastNotifyPanel::sFontDefault("Emoji"); +const std::string LLToastNotifyPanel::sFontScript("SansSerif"); LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal; @@ -85,11 +85,15 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt mBtnCallbackData.push_back(userdata); LLButton::Params p; - bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2; - const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog - p.name = form_element["name"].asString(); - p.label = form_element["text"].asString(); - p.tool_tip = form_element["text"].asString(); + S32 index = form_element["index"].asInteger(); + std::string name = form_element["name"].asString(); + std::string text = form_element["text"].asString(); + bool make_small_btn = index == -1 || index == -2; // for block and ignore buttons in script dialog + const LLFontGL* font = LLFontGL::getFont(LLFontDescriptor( + mIsScriptDialog ? sFontScript : sFontDefault, make_small_btn ? "Small" : "Medium", 0)); + p.name = name; + p.label = text; + p.tool_tip = text; p.font = font; p.rect.height = BTN_HEIGHT; p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); @@ -256,19 +260,12 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) { deleteAllChildren(); - mTextBox = NULL; - mInfoPanel = NULL; - mControlPanel = NULL; - mNumOptions = 0; - mNumButtons = 0; - mAddedDefaultBtn = false; - LLRect current_rect = getRect(); setXMLFilename(""); buildFromFile("panel_notification.xml"); - if(rect != LLRect::null) + if (rect != LLRect::null) { this->setShape(rect); } @@ -295,12 +292,6 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) // setup parameters // get a notification message mMessage = mNotification->getMessage(); - // init font variables - if (!sFont) - { - sFont = LLFontGL::getFontSansSerif(); - sFontSmall = LLFontGL::getFontSansSerifSmall(); - } // initialize setFocusRoot(!mIsTip); // get a form for the notification @@ -318,15 +309,18 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) if (mIsCaution && !mIsTip) { mTextBox = getChild<LLTextBox>("caution_text_box"); + mTextBox->setFont(LLFontGL::getFont(LLFontDescriptor(mIsScriptDialog ? sFontScript : sFontDefault, "Medium", LLFontGL::BOLD))); } else { mTextBox = getChild<LLTextEditor>("text_editor_box"); + mTextBox->setFont(LLFontGL::getFont(LLFontDescriptor(mIsScriptDialog ? sFontScript : sFontDefault, "Medium", 0))); } mTextBox->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH); mTextBox->setVisible(TRUE); mTextBox->setPlainText(!show_images); + mTextBox->setUseEmoji(!mIsScriptDialog); mTextBox->setContentTrusted(is_content_trusted); mTextBox->setValue(mNotification->getMessage()); mTextBox->setIsFriendCallback(LLAvatarActions::isFriend); diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h index a5a637c6fa..4a6c2ada8a 100644 --- a/indra/newview/lltoastnotifypanel.h +++ b/indra/newview/lltoastnotifypanel.h @@ -102,9 +102,9 @@ protected: //std::vector<index_button_pair_t> mButtons; // panel elements - LLTextBase* mTextBox; - LLPanel* mInfoPanel; // a panel, that contains an information - LLPanel* mControlPanel; // a panel, that contains buttons (if present) + LLTextBase* mTextBox { nullptr }; + LLPanel* mInfoPanel { nullptr }; // panel for text information + LLPanel* mControlPanel { nullptr }; // panel for buttons (if present) // internal handler for button being clicked static void onClickButton(void* data); @@ -124,17 +124,17 @@ protected: */ //void disableRespondedOptions(const LLNotificationPtr& notification); - bool mIsTip; - bool mAddedDefaultBtn; - bool mIsScriptDialog; - bool mIsCaution; + bool mIsTip { false }; + bool mAddedDefaultBtn { false }; + bool mIsScriptDialog { false }; + bool mIsCaution { false }; std::string mMessage; - S32 mNumOptions; - S32 mNumButtons; + S32 mNumOptions { 0 }; + S32 mNumButtons { 0 }; - static const LLFontGL* sFont; - static const LLFontGL* sFontSmall; + static const std::string sFontDefault; + static const std::string sFontScript; }; class LLIMToastNotifyPanel : public LLToastNotifyPanel diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index bfa9386cd4..2619c277ab 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -301,12 +301,10 @@ void LLToolDragAndDrop::setDragStart(S32 x, S32 y) BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y) { - static LLCachedControl<S32> drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3); - S32 mouse_delta_x = x - mDragStartX; S32 mouse_delta_y = y - mDragStartY; - return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold; + return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > DRAG_N_DROP_DISTANCE_THRESHOLD * DRAG_N_DROP_DISTANCE_THRESHOLD; } void LLToolDragAndDrop::beginDrag(EDragAndDropType type, @@ -569,12 +567,13 @@ BOOL LLToolDragAndDrop::handleKey(KEY key, MASK mask) BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask) { + const F32 DRAG_N_DROP_TOOLTIP_DELAY = 0.10000000149f; if (!mToolTipMsg.empty()) { LLToolTipMgr::instance().unblockToolTips(); LLToolTipMgr::instance().show(LLToolTip::Params() .message(mToolTipMsg) - .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" ))); + .delay_time(DRAG_N_DROP_TOOLTIP_DELAY)); return TRUE; } return FALSE; diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index d99c0ba2a6..e937c499ae 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -223,6 +223,13 @@ BOOL LLVisualParamHint::render() LLVector3 target_pos = target_joint_pos + (target_offset * avatar_rotation); F32 cam_angle_radians = mVisualParam->getCameraAngle() * DEG_TO_RAD; + + static LLCachedControl<bool> auto_camera_position(gSavedSettings, "AppearanceCameraMovement"); + if (!auto_camera_position) + { + cam_angle_radians += F_PI; + } + LLVector3 camera_snapshot_offset( mVisualParam->getCameraDistance() * cosf( cam_angle_radians ), mVisualParam->getCameraDistance() * sinf( cam_angle_radians ), diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 83a707472e..cf3b714c49 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -86,8 +86,8 @@ LLToolPie::LLToolPie() mMouseSteerX(-1), mMouseSteerY(-1), mClickAction(0), - mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ), - mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ), + mClickActionBuyEnabled( TRUE ), + mClickActionPayEnabled( TRUE ), mDoubleClickTimer() { } @@ -756,8 +756,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask) { S32 delta_x = x - mMouseDownX; S32 delta_y = y - mMouseDownY; - S32 threshold = gSavedSettings.getS32("DragAndDropDistanceThreshold"); - if (delta_x * delta_x + delta_y * delta_y > threshold * threshold) + if (delta_x * delta_x + delta_y * delta_y > DRAG_N_DROP_DISTANCE_THRESHOLD * DRAG_N_DROP_DISTANCE_THRESHOLD) { startCameraSteering(); steerCameraWithMouse(x, y); @@ -1089,6 +1088,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l final_name = LLTrans::getString("TooltipPerson");; } + const F32 INSPECTOR_TOOLTIP_DELAY = 0.35f; + LLInspector::Params p; p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); p.message(final_name); @@ -1096,7 +1097,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l p.click_callback(boost::bind(showAvatarInspector, hover_object->getID())); p.visible_time_near(6.f); p.visible_time_far(3.f); - p.delay_time(gSavedSettings.getF32("AvatarInspectorTooltipDelay")); + p.delay_time(INSPECTOR_TOOLTIP_DELAY); p.wrap(false); LLToolTipMgr::instance().show(p); diff --git a/indra/newview/lluploaddialog.cpp b/indra/newview/lluploaddialog.cpp index e59064c074..b8bf70fc62 100644 --- a/indra/newview/lluploaddialog.cpp +++ b/indra/newview/lluploaddialog.cpp @@ -149,6 +149,7 @@ void LLUploadDialog::setMessage( const std::string& msg) LLUploadDialog::~LLUploadDialog() { + gViewerWindow->removePopup(this); gFocusMgr.releaseFocusIfNeeded( this ); // LLFilePicker::instance().reset(); diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp index 2b7e598a59..081f4dcf23 100644 --- a/indra/newview/llurllineeditorctrl.cpp +++ b/indra/newview/llurllineeditorctrl.cpp @@ -62,7 +62,7 @@ void LLURLLineEditor::cut() deleteSelection(); // Validate new string and rollback the if needed. - BOOL need_to_rollback = ( mPrevalidateFunc && !mPrevalidateFunc( mText.getWString() ) ); + bool need_to_rollback = mPrevalidator && !mPrevalidator.validate(mText.getWString()); if( need_to_rollback ) { rollback.doRollback( this ); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index e2e321af0d..9d95c8d054 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -417,7 +417,7 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() if (!LLViewerTextureList::createUploadFile(getFileName(), filename, codec)) { errorMessage = llformat("Problem with file %s:\n\n%s\n", - getFileName().c_str(), LLImage::getLastError().c_str()); + getFileName().c_str(), LLImage::getLastThreadError().c_str()); errorLabel = "ProblemWithFile"; error = true; } diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 6a0edbecb1..48499f0da8 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -48,6 +48,8 @@ #include "llstreamingaudio.h" ///////////////////////////////////////////////////////// +const U32 FMODEX_DECODE_BUFFER_SIZE = 1000; // in milliseconds +const U32 FMODEX_STREAM_BUFFER_SIZE = 7000; // in milliseconds LLViewerAudio::LLViewerAudio() : mDone(true), @@ -116,7 +118,7 @@ void LLViewerAudio::startInternetStreamWithAutoFade(const std::string &streamURI LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); if (stream && stream->supportsAdjustableBufferSizes()) - stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"), gSavedSettings.getU32("FMODExDecodeBufferSize")); + stream->setBufferSizes(FMODEX_STREAM_BUFFER_SIZE, FMODEX_DECODE_BUFFER_SIZE); gAudiop->startInternetStream(mNextStreamURI); } @@ -183,7 +185,7 @@ bool LLViewerAudio::onIdleUpdate() LL_DEBUGS("AudioEngine") << "Audio fade in: " << mNextStreamURI << LL_ENDL; LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl(); if(stream && stream->supportsAdjustableBufferSizes()) - stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize")); + stream->setBufferSizes(FMODEX_STREAM_BUFFER_SIZE, FMODEX_DECODE_BUFFER_SIZE); gAudiop->startInternetStream(mNextStreamURI); } @@ -418,12 +420,19 @@ void audio_update_volume(bool force_update) gAudiop->setMasterGain ( master_volume ); - gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); + const F32 AUDIO_LEVEL_DOPPLER = 1.f; + gAudiop->setDopplerFactor(AUDIO_LEVEL_DOPPLER); - if(!LLViewerCamera::getInstance()->cameraUnderWater()) - gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); + if(!LLViewerCamera::getInstance()->cameraUnderWater()) + { + const F32 AUDIO_LEVEL_ROLLOFF = 1.f; + gAudiop->setRolloffFactor(AUDIO_LEVEL_ROLLOFF); + } else - gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff")); + { + const F32 AUDIO_LEVEL_UNDERWATER_ROLLOFF = 5.f; + gAudiop->setRolloffFactor(AUDIO_LEVEL_UNDERWATER_ROLLOFF); + } gAudiop->setMuted(mute_audio || progress_view_visible); @@ -532,8 +541,8 @@ void audio_update_wind(bool force_update) // whereas steady-state avatar walk velocity is only 3.2 m/s. // Without this the world feels desolate on first login when you are // standing still. - static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f); - LLVector3 scaled_wind_vec = gWindVec * wind_level; + const F32 WIND_LEVEL = 0.5f; + LLVector3 scaled_wind_vec = gWindVec * WIND_LEVEL; // Mix in the avatar's motion, subtract because when you walk north, // the apparent wind moves south. diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 7738cb904e..4f83f2cc9f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -345,15 +345,6 @@ static bool handleChatFontSizeChanged(const LLSD& newvalue) return true; } -static bool handleChatPersistTimeChanged(const LLSD& newvalue) -{ - if(gConsole) - { - gConsole->setLinePersistTime((F32) newvalue.asReal()); - } - return true; -} - static bool handleConsoleMaxLinesChanged(const LLSD& newvalue) { if(gConsole) @@ -630,6 +621,18 @@ void handleUserTargetDrawDistanceChanged(const LLSD& newValue) LLPerfStats::tunables.userTargetDrawDistance = newval; } +void handleUserMinDrawDistanceChanged(const LLSD &newValue) +{ + const auto newval = gSavedSettings.getF32("AutoTuneRenderFarClipMin"); + LLPerfStats::tunables.userMinDrawDistance = newval; +} + +void handleUserTargetReflectionsChanged(const LLSD& newValue) +{ + const auto newval = gSavedSettings.getS32("UserTargetReflections"); + LLPerfStats::tunables.userTargetReflections = newval; +} + void handlePerformanceStatsEnabledChanged(const LLSD& newValue) { const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled"); @@ -728,7 +731,6 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); - setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); @@ -739,9 +741,6 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); - setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); - setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); - setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); @@ -827,6 +826,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderAvatarMaxART", handleRenderAvatarMaxARTChanged); setting_setup_signal_listener(gSavedSettings, "PerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged); setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged); + setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipMin", handleUserMinDrawDistanceChanged); setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged); setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged); setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged); @@ -853,8 +853,6 @@ DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"]; DECL_LLCC(LLSD, test_llsd); -static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment"); - void test_cached_control() { #define do { TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL; } while(0) @@ -871,8 +869,6 @@ void test_cached_control() TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); //There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); - - if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL; } #endif // TEST_CACHED_CONTROL diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index e1d6f71cce..9ddb4e0174 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -214,11 +214,11 @@ void display_update_camera() void display_stats() { LL_PROFILE_ZONE_SCOPED - F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); - if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) + const F32 FPS_LOG_FREQUENCY = 10.f; + if (gRecentFPSTime.getElapsedTimeF32() >= FPS_LOG_FREQUENCY) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS"); - F32 fps = gRecentFrameCount / fps_log_freq; + F32 fps = gRecentFrameCount / FPS_LOG_FREQUENCY; LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL; gRecentFrameCount = 0; gRecentFPSTime.reset(); @@ -233,8 +233,8 @@ void display_stats() LLMemory::logMemoryInfo(TRUE) ; gRecentMemoryTime.reset(); } - F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency"); - if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq) + const F32 ASSET_STORAGE_LOG_FREQUENCY = 60.f; + if (gAssetStorageLogTime.getElapsedTimeF32() >= ASSET_STORAGE_LOG_FREQUENCY) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage"); gAssetStorageLogTime.reset(); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index e35cb26ce1..4577f71061 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -227,8 +227,18 @@ std::string string_from_guid(const GUID &guid) return res; } +#elif LL_DARWIN + +bool macos_devices_callback(std::string &product_name, LLSD &data, void* userdata) +{ + std::string product = data["product"].asString(); + + return LLViewerJoystick::getInstance()->initDevice(nullptr, product, data); +} + #endif + // ----------------------------------------------------------------------------- void LLViewerJoystick::updateEnabled(bool autoenable) { @@ -365,25 +375,48 @@ void LLViewerJoystick::init(bool autoenable) { if (mNdofDev) { + U32 device_type = 0; + void* win_callback = nullptr; + std::function<bool(std::string&, LLSD&, void*)> osx_callback; // di8_devices_callback callback is immediate and happens in scope of getInputDevices() #if LL_WINDOWS && !LL_MESA_HEADLESS // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib - U32 device_type = DI8DEVCLASS_GAMECTRL; - void* callback = &di8_devices_callback; -#else - // MAC doesn't support device search yet - // On MAC there is an ndof_idsearch and it is possible to specify product - // and manufacturer in NDOF_Device for ndof_init_first to pick specific one - U32 device_type = 0; - void* callback = NULL; + device_type = DI8DEVCLASS_GAMECTRL; + win_callback = &di8_devices_callback; +#elif LL_DARWIN + osx_callback = macos_devices_callback; + + if (mLastDeviceUUID.isMap()) + { + std::string manufacturer = mLastDeviceUUID["manufacturer"].asString(); + std::string product = mLastDeviceUUID["product"].asString(); + + strncpy(mNdofDev->manufacturer, manufacturer.c_str(), sizeof(mNdofDev->manufacturer)); + strncpy(mNdofDev->product, product.c_str(), sizeof(mNdofDev->product)); + + if (ndof_init_first(mNdofDev, nullptr)) + { + mDriverState = JDS_INITIALIZING; + // Saved device no longer exist + // No device found + LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL; + } + else + { + mDriverState = JDS_INITIALIZED; + } + } #endif - if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL)) + if (mDriverState != JDS_INITIALIZED) { - LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL; - // Failed to gather devices from windows, init first suitable one - mLastDeviceUUID = LLSD(); - void *preffered_device = NULL; - initDevice(preffered_device); + if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL)) + { + LL_INFOS("Joystick") << "Failed to gather input devices. Falling back to ndof's init" << LL_ENDL; + // Failed to gather devices, init first suitable one + mLastDeviceUUID = LLSD(); + void *preffered_device = NULL; + initDevice(preffered_device); + } } if (mDriverState == JDS_INITIALIZING) @@ -438,27 +471,49 @@ void LLViewerJoystick::initDevice(LLSD &guid) { #if LIB_NDOF mLastDeviceUUID = guid; - + U32 device_type = 0; + void* win_callback = nullptr; + std::function<bool(std::string&, LLSD&, void*)> osx_callback; + mDriverState = JDS_INITIALIZING; + #if LL_WINDOWS && !LL_MESA_HEADLESS // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib - U32 device_type = DI8DEVCLASS_GAMECTRL; - void* callback = &di8_devices_callback; -#else - // MAC doesn't support device search yet - // On MAC there is an ndof_idsearch and it is possible to specify product - // and manufacturer in NDOF_Device for ndof_init_first to pick specific one - U32 device_type = 0; - void* callback = NULL; + device_type = DI8DEVCLASS_GAMECTRL; + win_callback = &di8_devices_callback; +#elif LL_DARWIN + osx_callback = macos_devices_callback; + if (mLastDeviceUUID.isMap()) + { + std::string manufacturer = mLastDeviceUUID["manufacturer"].asString(); + std::string product = mLastDeviceUUID["product"].asString(); + + strncpy(mNdofDev->manufacturer, manufacturer.c_str(), sizeof(mNdofDev->manufacturer)); + strncpy(mNdofDev->product, product.c_str(), sizeof(mNdofDev->product)); + + if (ndof_init_first(mNdofDev, nullptr)) + { + mDriverState = JDS_INITIALIZING; + // Saved device no longer exist + // Np other device present + LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL; + } + else + { + mDriverState = JDS_INITIALIZED; + } + } #endif - mDriverState = JDS_INITIALIZING; - if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL)) + if (mDriverState != JDS_INITIALIZED) { - LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL; - // Failed to gather devices from windows, init first suitable one - void *preffered_device = NULL; - mLastDeviceUUID = LLSD(); - initDevice(preffered_device); + if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL)) + { + LL_INFOS("Joystick") << "Failed to gather input devices. Falling back to ndof's init" << LL_ENDL; + // Failed to gather devices from window, init first suitable one + void *preffered_device = NULL; + mLastDeviceUUID = LLSD(); + initDevice(preffered_device); + } } if (mDriverState == JDS_INITIALIZING) @@ -469,19 +524,37 @@ void LLViewerJoystick::initDevice(LLSD &guid) #endif } -void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid) +bool LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid) { #if LIB_NDOF mLastDeviceUUID = guid; - + +#if LL_DARWIN + if (guid.isMap()) + { + std::string manufacturer = mLastDeviceUUID["manufacturer"].asString(); + std::string product = mLastDeviceUUID["product"].asString(); + + strncpy(mNdofDev->manufacturer, manufacturer.c_str(), sizeof(mNdofDev->manufacturer)); + strncpy(mNdofDev->product, product.c_str(), sizeof(mNdofDev->product)); + } + else + { + mNdofDev->product[0] = '\0'; + mNdofDev->manufacturer[0] = '\0'; + } +#else strncpy(mNdofDev->product, name.c_str(), sizeof(mNdofDev->product)); mNdofDev->manufacturer[0] = '\0'; +#endif - initDevice(preffered_device); + return initDevice(preffered_device); +#else + return false; #endif } -void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */) +bool LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */) { #if LIB_NDOF // Different joysticks will return different ranges of raw values. @@ -511,8 +584,10 @@ void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE else { mDriverState = JDS_INITIALIZED; + return true; } #endif + return false; } // ----------------------------------------------------------------------------- @@ -1320,6 +1395,8 @@ bool LLViewerJoystick::isDeviceUUIDSet() #if LL_WINDOWS && !LL_MESA_HEADLESS // for ease of comparison and to dial less with platform specific variables, we store id as LLSD binary return mLastDeviceUUID.isBinary(); +#elif LL_DARWIN + return mLastDeviceUUID.isMap(); #else return false; #endif @@ -1346,19 +1423,48 @@ std::string LLViewerJoystick::getDeviceUUIDString() { return std::string(); } +#elif LL_DARWIN + if (mLastDeviceUUID.isMap()) + { + std::string manufacturer = mLastDeviceUUID["manufacturer"].asString(); + std::string product = mLastDeviceUUID["product"].asString(); + return manufacturer + ":" + product; + } + else + { + return std::string(); + } #else return std::string(); - // return mLastDeviceUUID; +#endif +} + +void LLViewerJoystick::saveDeviceIdToSettings() +{ +#if LL_WINDOWS && !LL_MESA_HEADLESS + // can't save as binary directly, + // someone editing the xml will corrupt it + // so convert to string first + std::string device_string = getDeviceUUIDString(); + gSavedSettings.setLLSD("JoystickDeviceUUID", LLSD(device_string)); +#else + LLSD device_id = getDeviceUUID(); + gSavedSettings.setLLSD("JoystickDeviceUUID", device_id); #endif } void LLViewerJoystick::loadDeviceIdFromSettings() { + LLSD dev_id = gSavedSettings.getLLSD("JoystickDeviceUUID"); #if LL_WINDOWS && !LL_MESA_HEADLESS // We can't save binary data to gSavedSettings, somebody editing the file will corrupt it, // so _GUID data gets converted to string (we probably can convert it to LLUUID with memcpy) // and here we need to convert it back to binary from string - std::string device_string = gSavedSettings.getString("JoystickDeviceUUID"); + std::string device_string; + if (dev_id.isString()) + { + device_string = dev_id.asString(); + } if (device_string.empty()) { mLastDeviceUUID = LLSD(); @@ -1372,10 +1478,22 @@ void LLViewerJoystick::loadDeviceIdFromSettings() LLSD::Binary data; //just an std::vector data.resize(size); memcpy(&data[0], &guid /*POD _GUID*/, size); - // We store this data in LLSD since LLSD is versatile and will be able to handle both GUID2 - // and any data MAC will need for device selection + // We store this data in LLSD since it can handle both GUID2 and long mLastDeviceUUID = LLSD(data); } +#elif LL_DARWIN + if (!dev_id.isMap()) + { + mLastDeviceUUID = LLSD(); + } + else + { + std::string manufacturer = mLastDeviceUUID["manufacturer"].asString(); + std::string product = mLastDeviceUUID["product"].asString(); + LL_DEBUGS("Joystick") << "Looking for device by manufacturer: " << manufacturer << " and product: " << product << LL_ENDL; + // We store this data in LLSD since it can handle both GUID2 and long + mLastDeviceUUID = dev_id; + } #else mLastDeviceUUID = LLSD(); //mLastDeviceUUID = gSavedSettings.getLLSD("JoystickDeviceUUID"); diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index 3b4f898710..33579f544c 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -30,6 +30,9 @@ #include "stdtypes.h" #if LIB_NDOF +#if LL_DARWIN +#define TARGET_OS_MAC 1 +#endif #include "ndofdev_external.h" #else #define NDOF_Device void @@ -52,8 +55,8 @@ class LLViewerJoystick : public LLSingleton<LLViewerJoystick> public: void init(bool autoenable); void initDevice(LLSD &guid); - void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/); - void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid); + bool initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/); + bool initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid); void terminate(); void updateStatus(); @@ -76,6 +79,7 @@ public: LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search std::string getDeviceUUIDString(); // converted readable value for settings std::string getDescription(); + void saveDeviceIdToSettings(); protected: void updateEnabled(bool autoenable); @@ -103,7 +107,11 @@ private: bool mCameraUpdated; bool mOverrideCamera; U32 mJoystickRun; - LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device + + // Windows: _GUID as U8 binary map + // MacOS: long as an U8 binary map + // Else: integer 1 for no device/ndof's default device + LLSD mLastDeviceUUID; static F32 sLastDelta[7]; static F32 sDelta[7]; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 94efab3f4b..c8dd65941a 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7309,37 +7309,70 @@ class LLAttachmentDetach : public view_listener_t { // Called when the user clicked on an object attached to them // and selected "Detach". - LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + LLViewerObject *object = selection->getPrimaryObject(); if (!object) { LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; return true; } - LLViewerObject *parent = (LLViewerObject*)object->getParent(); - while (parent) - { - if(parent->isAvatar()) - { - break; - } - object = parent; - parent = (LLViewerObject*)parent->getParent(); - } + struct f: public LLSelectedObjectFunctor + { + f() : mAvatarsInSelection(false) {} + virtual bool apply(LLViewerObject* objectp) + { + if (!objectp) + { + return false; + } - if (!object) - { - LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL; - return true; - } + if (objectp->isAvatar()) + { + mAvatarsInSelection = true; + return false; + } - if (object->isAvatar()) - { - LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL; - return true; - } + LLViewerObject* parent = (LLViewerObject*)objectp->getParent(); + while (parent) + { + if (parent->isAvatar()) + { + break; + } + objectp = parent; + parent = (LLViewerObject*)parent->getParent(); + } + + // std::set to avoid dupplicate 'roots' from linksets + mRemoveSet.insert(objectp->getAttachmentItemID()); + + return true; + } + bool mAvatarsInSelection; + uuid_set_t mRemoveSet; + } func; + // Probbly can run applyToRootObjects instead, + // but previous version of this code worked for any selected object + selection->applyToObjects(&func); + + if (func.mAvatarsInSelection) + { + // Not possible under normal circumstances + // Either avatar selection is ON or has to do with animeshes + // Better stop this than mess something + LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL; + return true; + } + + if (func.mRemoveSet.empty()) + { + LL_WARNS() << "handle_detach() - no valid attachments in selection to detach" << LL_ENDL; + return true; + } - LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID()); + uuid_vec_t detach_list(func.mRemoveSet.begin(), func.mRemoveSet.end()); + LLAppearanceMgr::instance().removeItemsFromAvatar(detach_list); return true; } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 5461e0f362..fe5fee6ee6 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -947,7 +947,7 @@ void handle_compress_image(void*) } else { - LL_INFOS() << "Compression failed: " << LLImage::getLastError() << LL_ENDL; + LL_INFOS() << "Compression failed: " << LLImage::getLastThreadError() << LL_ENDL; } infile = picker.getNextFile(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c50365db2a..ed96e11c6b 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1654,8 +1654,9 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, const LLUUID& blocked_id; }; - LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID( - gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id)); + LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel( + LLNotificationsUI::NOTIFICATION_CHANNEL_UUID, + OfferMatcher(blocked_id)); } @@ -4165,6 +4166,12 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.find(object_id); for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it) { + if (anim_it->first != object_id) + { + // elements with the same key are always contiguous, bail if we went past the + // end of this object's animations + break; + } if (anim_it->second == animation_id) { anim_found = TRUE; @@ -5775,8 +5782,9 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name) const LLUUID& blocked_id; }; - LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID( - gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(task_id)); + LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel( + LLNotificationsUI::NOTIFICATION_CHANNEL_UUID, + OfferMatcher(task_id)); } static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f1fac106c7..ea28d2d0a3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3971,20 +3971,13 @@ F32 LLViewerObject::recursiveGetEstTrianglesMax() const S32 LLViewerObject::getAnimatedObjectMaxTris() const { S32 max_tris = 0; - if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) + if (gAgent.getRegion()) { - max_tris = S32_MAX; - } - else - { - if (gAgent.getRegion()) + LLSD features; + gAgent.getRegion()->getSimulatorFeatures(features); + if (features.has("AnimatedObjects")) { - LLSD features; - gAgent.getRegion()->getSimulatorFeatures(features); - if (features.has("AnimatedObjects")) - { - max_tris = features["AnimatedObjects"]["AnimatedObjectMaxTris"].asInteger(); - } + max_tris = features["AnimatedObjects"]["AnimatedObjectMaxTris"].asInteger(); } } return max_tris; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 15accd0547..c5426c9382 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1526,6 +1526,12 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user) // static void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user) { + if (LLApp::isExiting() || gDisconnected) + { + LL_DEBUGS("ParcelMgr") << "Ignoring parcel properties, shutting down" << LL_ENDL; + return; + } + S32 request_result; S32 sequence_id; BOOL snap_selection = FALSE; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 785c84c38d..5a2b7e4c2f 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -50,18 +50,15 @@ #include "pipeline.h" -const U8 OVERLAY_IMG_COMPONENTS = 4; +static const U8 OVERLAY_IMG_COMPONENTS = 4; +static const F32 LINE_WIDTH = 0.0625f; LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters) : mRegion( region ), mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ), mDirty( FALSE ), mTimeSinceLastUpdate(), - mOverlayTextureIdx(-1), - mVertexCount(0), - mVertexArray(NULL), - mColorArray(NULL) -// mTexCoordArray(NULL), + mOverlayTextureIdx(-1) { // Create a texture to hold color information. // 4 components @@ -99,17 +96,6 @@ LLViewerParcelOverlay::~LLViewerParcelOverlay() { delete[] mOwnership; mOwnership = NULL; - - delete[] mVertexArray; - mVertexArray = NULL; - - delete[] mColorArray; - mColorArray = NULL; - -// JC No textures. -// delete mTexCoordArray; -// mTexCoordArray = NULL; - mImageRaw = NULL; } @@ -312,7 +298,6 @@ F32 LLViewerParcelOverlay::getOwnedRatio() const } return (F32)total / (F32)size; - } //--------------------------------------------------------------------------- @@ -329,14 +314,13 @@ F32 LLViewerParcelOverlay::getOwnedRatio() const // Note: Assumes that the ownership array and void LLViewerParcelOverlay::updateOverlayTexture() { - if (mOverlayTextureIdx < 0 && mDirty) - { - mOverlayTextureIdx = 0; - } if (mOverlayTextureIdx < 0) { - return; + if (!mDirty) + return; + mOverlayTextureIdx = 0; } + const LLColor4U avail = LLUIColorTable::instance().getColor("PropertyColorAvail").get(); const LLColor4U owned = LLUIColorTable::instance().getColor("PropertyColorOther").get(); const LLColor4U group = LLUIColorTable::instance().getColor("PropertyColorGroup").get(); @@ -441,38 +425,44 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay) setDirty(); } - void LLViewerParcelOverlay::updatePropertyLines() { - if (!gSavedSettings.getBOOL("ShowPropertyLines")) + static LLCachedControl<bool> show(gSavedSettings, "ShowPropertyLines"); + + if (!show) return; - - S32 row, col; - - const LLColor4U self_coloru = LLUIColorTable::instance().getColor("PropertyColorSelf").get(); - const LLColor4U other_coloru = LLUIColorTable::instance().getColor("PropertyColorOther").get(); - const LLColor4U group_coloru = LLUIColorTable::instance().getColor("PropertyColorGroup").get(); - const LLColor4U for_sale_coloru = LLUIColorTable::instance().getColor("PropertyColorForSale").get(); - const LLColor4U auction_coloru = LLUIColorTable::instance().getColor("PropertyColorAuction").get(); - - // Build into dynamic arrays, then copy into static arrays. - std::vector<LLVector3> new_vertex_array; - new_vertex_array.reserve(256); - std::vector<LLColor4U> new_color_array; - new_color_array.reserve(256); - std::vector<LLVector2> new_coord_array; - new_coord_array.reserve(256); - - U8 overlay = 0; - BOOL add_edge = FALSE; + + LLColor4U colors[PARCEL_COLOR_MASK + 1]; + colors[PARCEL_SELF] = LLUIColorTable::instance().getColor("PropertyColorSelf").get(); + colors[PARCEL_OWNED] = LLUIColorTable::instance().getColor("PropertyColorOther").get(); + colors[PARCEL_GROUP] = LLUIColorTable::instance().getColor("PropertyColorGroup").get(); + colors[PARCEL_FOR_SALE] = LLUIColorTable::instance().getColor("PropertyColorForSale").get(); + colors[PARCEL_AUCTION] = LLUIColorTable::instance().getColor("PropertyColorAuction").get(); + + mEdges.clear(); + const F32 GRID_STEP = PARCEL_GRID_STEP_METERS; const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; - for (row = 0; row < GRIDS_PER_EDGE; row++) + for (S32 row = 0; row < GRIDS_PER_EDGE; row++) { - for (col = 0; col < GRIDS_PER_EDGE; col++) + for (S32 col = 0; col < GRIDS_PER_EDGE; col++) { - overlay = mOwnership[row*GRIDS_PER_EDGE+col]; + U8 overlay = mOwnership[row*GRIDS_PER_EDGE+col]; + S32 colorIndex = overlay & PARCEL_COLOR_MASK; + switch(colorIndex) + { + case PARCEL_SELF: + case PARCEL_GROUP: + case PARCEL_OWNED: + case PARCEL_FOR_SALE: + case PARCEL_AUCTION: + break; + default: + continue; + } + + const LLColor4U& color = colors[colorIndex]; F32 left = col*GRID_STEP; F32 right = left+GRID_STEP; @@ -483,259 +473,41 @@ void LLViewerParcelOverlay::updatePropertyLines() // West edge if (overlay & PARCEL_WEST_LINE) { - switch(overlay & PARCEL_COLOR_MASK) - { - case PARCEL_SELF: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, WEST, self_coloru); - break; - case PARCEL_GROUP: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, WEST, group_coloru); - break; - case PARCEL_OWNED: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, WEST, other_coloru); - break; - case PARCEL_FOR_SALE: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, WEST, for_sale_coloru); - break; - case PARCEL_AUCTION: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, WEST, auction_coloru); - break; - default: - break; - } + addPropertyLine(left, bottom, 0, 1, LINE_WIDTH, 0, color); } // East edge - if (col < GRIDS_PER_EDGE-1) - { - U8 east_overlay = mOwnership[row*GRIDS_PER_EDGE+col+1]; - add_edge = east_overlay & PARCEL_WEST_LINE; - } - else - { - add_edge = TRUE; - } - - if (add_edge) + if (col == GRIDS_PER_EDGE - 1 || mOwnership[row * GRIDS_PER_EDGE + col + 1] & PARCEL_WEST_LINE) { - switch(overlay & PARCEL_COLOR_MASK) - { - case PARCEL_SELF: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - right, bottom, EAST, self_coloru); - break; - case PARCEL_GROUP: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - right, bottom, EAST, group_coloru); - break; - case PARCEL_OWNED: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - right, bottom, EAST, other_coloru); - break; - case PARCEL_FOR_SALE: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - right, bottom, EAST, for_sale_coloru); - break; - case PARCEL_AUCTION: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - right, bottom, EAST, auction_coloru); - break; - default: - break; - } + addPropertyLine(right, bottom, 0, 1, -LINE_WIDTH, 0, color); } // South edge if (overlay & PARCEL_SOUTH_LINE) { - switch(overlay & PARCEL_COLOR_MASK) - { - case PARCEL_SELF: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, SOUTH, self_coloru); - break; - case PARCEL_GROUP: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, SOUTH, group_coloru); - break; - case PARCEL_OWNED: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, SOUTH, other_coloru); - break; - case PARCEL_FOR_SALE: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, SOUTH, for_sale_coloru); - break; - case PARCEL_AUCTION: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, bottom, SOUTH, auction_coloru); - break; - default: - break; - } + addPropertyLine(left, bottom, 1, 0, 0, LINE_WIDTH, color); } - // North edge - if (row < GRIDS_PER_EDGE-1) - { - U8 north_overlay = mOwnership[(row+1)*GRIDS_PER_EDGE+col]; - add_edge = north_overlay & PARCEL_SOUTH_LINE; - } - else + if (row == GRIDS_PER_EDGE - 1 || mOwnership[(row + 1) * GRIDS_PER_EDGE + col] & PARCEL_SOUTH_LINE) { - add_edge = TRUE; + addPropertyLine(left, top, 1, 0, 0, -LINE_WIDTH, color); } - - if (add_edge) - { - switch(overlay & PARCEL_COLOR_MASK) - { - case PARCEL_SELF: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, top, NORTH, self_coloru); - break; - case PARCEL_GROUP: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, top, NORTH, group_coloru); - break; - case PARCEL_OWNED: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, top, NORTH, other_coloru); - break; - case PARCEL_FOR_SALE: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, top, NORTH, for_sale_coloru); - break; - case PARCEL_AUCTION: - addPropertyLine(new_vertex_array, new_color_array, new_coord_array, - left, top, NORTH, auction_coloru); - break; - default: - break; - } - } - } - } - - // Now copy into static arrays for faster rendering. - // Attempt to recycle old arrays if possible to avoid memory - // shuffling. - S32 new_vertex_count = new_vertex_array.size(); - - if (!(mVertexArray && mColorArray && new_vertex_count == mVertexCount)) - { - // ...need new arrays - delete[] mVertexArray; - mVertexArray = NULL; - delete[] mColorArray; - mColorArray = NULL; - - mVertexCount = new_vertex_count; - - if (new_vertex_count > 0) - { - mVertexArray = new F32[3 * mVertexCount]; - mColorArray = new U8 [4 * mVertexCount]; } } - - // Copy the new data into the arrays - S32 i; - F32* vertex = mVertexArray; - for (i = 0; i < mVertexCount; i++) - { - const LLVector3& point = new_vertex_array.at(i); - *vertex = point.mV[VX]; - vertex++; - *vertex = point.mV[VY]; - vertex++; - *vertex = point.mV[VZ]; - vertex++; - } - - U8* colorp = mColorArray; - for (i = 0; i < mVertexCount; i++) - { - const LLColor4U& color = new_color_array.at(i); - *colorp = color.mV[VRED]; - colorp++; - *colorp = color.mV[VGREEN]; - colorp++; - *colorp = color.mV[VBLUE]; - colorp++; - *colorp = color.mV[VALPHA]; - colorp++; - } // Everything's clean now mDirty = FALSE; } - -void LLViewerParcelOverlay::addPropertyLine( - std::vector<LLVector3>& vertex_array, - std::vector<LLColor4U>& color_array, - std::vector<LLVector2>& coord_array, - const F32 start_x, const F32 start_y, - const U32 edge, - const LLColor4U& color) +void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F32 dy, F32 tick_dx, F32 tick_dy, const LLColor4U& color) { - LLColor4U underwater( color ); - underwater.mV[VALPHA] /= 2; - - vertex_array.reserve(16); - color_array.reserve(16); - coord_array.reserve(16); - LLSurface& land = mRegion->getLand(); + F32 water_z = land.getWaterHeight(); - F32 dx; - F32 dy; - F32 tick_dx; - F32 tick_dy; - //const F32 LINE_WIDTH = 0.125f; - const F32 LINE_WIDTH = 0.0625f; - - switch(edge) - { - case WEST: - dx = 0.f; - dy = 1.f; - tick_dx = LINE_WIDTH; - tick_dy = 0.f; - break; - - case EAST: - dx = 0.f; - dy = 1.f; - tick_dx = -LINE_WIDTH; - tick_dy = 0.f; - break; - - case NORTH: - dx = 1.f; - dy = 0.f; - tick_dx = 0.f; - tick_dy = -LINE_WIDTH; - break; - - case SOUTH: - dx = 1.f; - dy = 0.f; - tick_dx = 0.f; - tick_dy = LINE_WIDTH; - break; - - default: - LL_ERRS() << "Invalid edge in addPropertyLine" << LL_ENDL; - return; - } + mEdges.resize(mEdges.size() + 1); + Edge& edge = mEdges.back(); + edge.color = color; F32 outside_x = start_x; F32 outside_y = start_y; @@ -744,14 +516,31 @@ void LLViewerParcelOverlay::addPropertyLine( F32 inside_y = start_y + tick_dy; F32 inside_z = 0.f; + auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part) + { + F32 new_x = start.mV[0] + (x - start.mV[0]) * part; + F32 new_y = start.mV[1] + (y - start.mV[1]) * part; + F32 new_z = start.mV[2] + (z - start.mV[2]) * part; + edge.vertices.emplace_back(new_x, new_y, new_z); + }; + + auto checkForSplit = [&]() + { + const LLVector3& last_outside = edge.vertices.back(); + F32 z0 = last_outside.mV[2]; + F32 z1 = outside_z; + if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z)) + return; + F32 part = (water_z - z0) / (z1 - z0); + const LLVector3& last_inside = edge.vertices[edge.vertices.size() - 2]; + split(last_inside, inside_x, inside_y, inside_z, part); + split(last_outside, outside_x, outside_y, outside_z, part); + }; + // First part, only one vertex outside_z = land.resolveHeightRegion( outside_x, outside_y ); - if (outside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) ); - coord_array.push_back( LLVector2(outside_x - start_x, 0.f) ); + edge.vertices.emplace_back(outside_x, outside_y, outside_z); inside_x += dx * LINE_WIDTH; inside_y += dy * LINE_WIDTH; @@ -763,17 +552,8 @@ void LLViewerParcelOverlay::addPropertyLine( inside_z = land.resolveHeightRegion( inside_x, inside_y ); outside_z = land.resolveHeightRegion( outside_x, outside_y ); - if (inside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - if (outside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) ); - vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) ); - - coord_array.push_back( LLVector2(outside_x - start_x, 1.f) ); - coord_array.push_back( LLVector2(outside_x - start_x, 0.f) ); + edge.vertices.emplace_back(inside_x, inside_y, inside_z); + edge.vertices.emplace_back(outside_x, outside_y, outside_z); inside_x += dx * (dx - LINE_WIDTH); inside_y += dy * (dy - LINE_WIDTH); @@ -782,24 +562,16 @@ void LLViewerParcelOverlay::addPropertyLine( outside_y += dy * (dy - LINE_WIDTH); // Middle part, full width - S32 i; const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS ); - for (i = 1; i < GRID_STEP; i++) + for (S32 i = 1; i < GRID_STEP; i++) { inside_z = land.resolveHeightRegion( inside_x, inside_y ); outside_z = land.resolveHeightRegion( outside_x, outside_y ); - if (inside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - if (outside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) ); - vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) ); + checkForSplit(); - coord_array.push_back( LLVector2(outside_x - start_x, 1.f) ); - coord_array.push_back( LLVector2(outside_x - start_x, 0.f) ); + edge.vertices.emplace_back(inside_x, inside_y, inside_z); + edge.vertices.emplace_back(outside_x, outside_y, outside_z); inside_x += dx; inside_y += dy; @@ -818,20 +590,10 @@ void LLViewerParcelOverlay::addPropertyLine( inside_z = land.resolveHeightRegion( inside_x, inside_y ); outside_z = land.resolveHeightRegion( outside_x, outside_y ); - if (inside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - if (outside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) ); - vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) ); - - coord_array.push_back( LLVector2(outside_x - start_x, 1.f) ); - coord_array.push_back( LLVector2(outside_x - start_x, 0.f) ); + checkForSplit(); - inside_x += dx * LINE_WIDTH; - inside_y += dy * LINE_WIDTH; + edge.vertices.emplace_back(inside_x, inside_y, inside_z); + edge.vertices.emplace_back(outside_x, outside_y, outside_z); outside_x += dx * LINE_WIDTH; outside_y += dy * LINE_WIDTH; @@ -839,14 +601,9 @@ void LLViewerParcelOverlay::addPropertyLine( // Last edge is not drawn to the edge outside_z = land.resolveHeightRegion( outside_x, outside_y ); - if (outside_z > 20.f) color_array.push_back( color ); - else color_array.push_back( underwater ); - - vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) ); - coord_array.push_back( LLVector2(outside_x - start_x, 0.f) ); + edge.vertices.emplace_back(outside_x, outside_y, outside_z); } - void LLViewerParcelOverlay::setDirty() { mDirty = TRUE; @@ -882,18 +639,15 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update) } } -S32 LLViewerParcelOverlay::renderPropertyLines () +void LLViewerParcelOverlay::renderPropertyLines() { - if (!gSavedSettings.getBOOL("ShowPropertyLines")) - { - return 0; - } - if (!mVertexArray || !mColorArray) - { - return 0; - } + static LLCachedControl<bool> show(gSavedSettings, "ShowPropertyLines"); + + if (!show) + return; LLSurface& land = mRegion->getLand(); + F32 water_z = land.getWaterHeight() + 0.01f; LLGLSUIDefault gls_ui; // called from pipeline gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -920,16 +674,11 @@ S32 LLViewerParcelOverlay::renderPropertyLines () // Move to appropriate region coords LLVector3 origin = mRegion->getOriginAgent(); - gGL.translatef( origin.mV[VX], origin.mV[VY], origin.mV[VZ] ); + gGL.translatef(origin.mV[VX], origin.mV[VY], origin.mV[VZ]); gGL.translatef(pull_toward_camera.mV[VX], pull_toward_camera.mV[VY], pull_toward_camera.mV[VZ]); - // Include +1 because vertices are fenceposts. - // *2 because it's a quad strip - const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS ); - const S32 vertex_per_edge = 3 + 2 * (GRID_STEP-1) + 3; - // Stomp the camera into two dimensions LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() ); @@ -939,91 +688,68 @@ S32 LLViewerParcelOverlay::renderPropertyLines () cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS; cull_plane_point += camera_region; - LLVector3 vertex; - - const S32 BYTES_PER_COLOR = 4; - const S32 FLOATS_PER_VERTEX = 3; - //const S32 FLOATS_PER_TEX_COORD = 2; - S32 i, j; - S32 drawn = 0; - F32* vertexp; - U8* colorp; bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build"); const F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f; - for (i = 0; i < mVertexCount; i += vertex_per_edge) + for (const Edge& edge : mEdges) { - colorp = mColorArray + BYTES_PER_COLOR * i; - vertexp = mVertexArray + FLOATS_PER_VERTEX * i; - - vertex.mV[VX] = *(vertexp); - vertex.mV[VY] = *(vertexp+1); - vertex.mV[VZ] = *(vertexp+2); + LLVector3 center = edge.vertices[edge.vertices.size() >> 1]; - if (dist_vec_squared2D(vertex, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED) + if (dist_vec_squared2D(center, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED) { continue; } // Destroy vertex, transform to plane-local. - vertex -= cull_plane_point; + center -= cull_plane_point; - // negative dot product means it is in back of the plane - if ( vertex * CAMERA_AT < 0.f ) + // Negative dot product means it is in back of the plane + if (center * CAMERA_AT < 0.f) { continue; } gGL.begin(LLRender::TRIANGLE_STRIP); - for (j = 0; j < vertex_per_edge; j++) - { - gGL.color4ubv(colorp); - gGL.vertex3fv(vertexp); + gGL.color4ubv(edge.color.mV); - colorp += BYTES_PER_COLOR; - vertexp += FLOATS_PER_VERTEX; + for (const LLVector3& vertex : edge.vertices) + { + if (render_hidden || camera_z < water_z || vertex.mV[2] >= water_z) + { + gGL.vertex3fv(vertex.mV); + } + else + { + LLVector3 visible = vertex; + visible.mV[2] = water_z; + gGL.vertex3fv(visible.mV); + } } - drawn += vertex_per_edge; - gGL.end(); - + if (render_hidden) { LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); - - colorp = mColorArray + BYTES_PER_COLOR * i; - vertexp = mVertexArray + FLOATS_PER_VERTEX * i; gGL.begin(LLRender::TRIANGLE_STRIP); - for (j = 0; j < vertex_per_edge; j++) - { - U8 color[4]; - color[0] = colorp[0]; - color[1] = colorp[1]; - color[2] = colorp[2]; - color[3] = colorp[3]/4; + LLColor4U color = edge.color; + color.mV[3] /= 4; + gGL.color4ubv(color.mV); - gGL.color4ubv(color); - gGL.vertex3fv(vertexp); - - colorp += BYTES_PER_COLOR; - vertexp += FLOATS_PER_VERTEX; + for (const LLVector3& vertex : edge.vertices) + { + gGL.vertex3fv(vertex.mV); } - drawn += vertex_per_edge; - gGL.end(); } - } gGL.popMatrix(); - - return drawn; } // Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top @@ -1047,11 +773,9 @@ void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F3 void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) { - if (!mOwnership) - { - return; - } - if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + static LLCachedControl<bool> show(gSavedSettings, "MiniMapShowPropertyLines"); + + if (!mOwnership || !show) { return; } @@ -1066,11 +790,11 @@ void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_me gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glLineWidth(1.0f); gGL.color4fv(parcel_outline_color); - for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++) + for (S32 i = 0; i <= GRIDS_PER_EDGE; i++) { const F32 bottom = region_bottom + (i * map_parcel_width); const F32 top = bottom + map_parcel_width; - for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++) + for (S32 j = 0; j <= GRIDS_PER_EDGE; j++) { const F32 left = region_left + (j * map_parcel_width); const F32 right = left + map_parcel_width; diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index c466cc3b6b..c0d7e2a466 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -68,8 +68,8 @@ public: F32 getOwnedRatio() const; // Returns the number of vertices drawn - S32 renderPropertyLines(); - void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); + void renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); U8 ownership( const LLVector3& pos) const; U8 parcelLineFlags( const LLVector3& pos) const; @@ -83,7 +83,7 @@ public: void idleUpdate(bool update_now = false); void updateGL(); - + private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. @@ -92,12 +92,7 @@ private: U8 parcelFlags(S32 row, S32 col, U8 flags) const; - void addPropertyLine(std::vector<LLVector3>& vertex_array, - std::vector<LLColor4U>& color_array, - std::vector<LLVector2>& coord_array, - const F32 start_x, const F32 start_y, - const U32 edge, - const LLColor4U& color); + void addPropertyLine(F32 start_x, F32 start_y, F32 dx, F32 dy, F32 tick_dx, F32 tick_dy, const LLColor4U& color); void updateOverlayTexture(); void updatePropertyLines(); @@ -120,10 +115,14 @@ private: BOOL mDirty; LLFrameTimer mTimeSinceLastUpdate; S32 mOverlayTextureIdx; - - S32 mVertexCount; - F32* mVertexArray; - U8* mColorArray; + + struct Edge + { + std::vector<LLVector3> vertices; + LLColor4U color; + }; + + std::vector<Edge> mEdges; }; #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index eba7189a82..f5d47df82c 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1081,15 +1081,11 @@ void LLViewerRegion::setCacheID(const LLUUID& id) mImpl->mCacheID = id; } -S32 LLViewerRegion::renderPropertyLines() +void LLViewerRegion::renderPropertyLines() { if (mParcelOverlay) { - return mParcelOverlay->renderPropertyLines(); - } - else - { - return 0; + mParcelOverlay->renderPropertyLines(); } } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 622490c881..5735889361 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -156,7 +156,7 @@ public: // Draw lines in the dirt showing ownership. Return number of // vertices drawn. - S32 renderPropertyLines(); + void renderPropertyLines(); void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 4c2fbcf837..ae8163beec 100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -186,11 +186,11 @@ BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const // Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small // since render unnecessarily doesn't cost much. - const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout"); - if (texture_timeout != 0) + const U32 TEXTURE_TIMEOUT = 10; + if (TEXTURE_TIMEOUT != 0) { // If we hit our timeout and have textures available at even lower resolution, then update. - const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout; + const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= TEXTURE_TIMEOUT; const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable(); if (has_lower_lod && is_update_textures_timeout) return TRUE; } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 8731be6e97..4536012674 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -586,7 +586,6 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, LLHost request_from_host) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true); LLPointer<LLViewerFetchedTexture> imagep ; switch(texture_type) @@ -632,11 +631,9 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, imagep->forceActive() ; } - if(fast_cache_fetching_enabled) - { - mFastCacheList.insert(imagep); - imagep->setInFastCacheList(true); - } + mFastCacheList.insert(imagep); + imagep->setInFastCacheList(true); + return imagep ; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 37e64dfc17..183fdab609 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2096,13 +2096,15 @@ void LLViewerWindow::initBase() gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle()); gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View"); + const F32 CHAT_PERSIST_TIME = 20.f; + // Console llassert( !gConsole ); LLConsole::Params cp; cp.name("console"); cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize")); cp.rect(getChatConsoleRect()); - cp.persist_time(gSavedSettings.getF32("ChatPersistTime")); + cp.persist_time(CHAT_PERSIST_TIME); cp.font_size_index(gSavedSettings.getS32("ChatFontSize")); cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM); gConsole = LLUICtrlFactory::create<LLConsole>(cp); @@ -2814,6 +2816,15 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) } } + // Try for a new-format gesture + if (LLGestureMgr::instance().triggerGestureRelease(key, mask)) + { + LL_DEBUGS() << "LLviewerWindow::handleKey new gesture release feature" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key,mask); + return TRUE; + } + //Old format gestures do not support this, so no need to implement it. + // don't pass keys on to world when something in ui has focus return gFocusMgr.childHasKeyboardFocus(mRootView) || LLMenuGL::getKeyboardMode() @@ -3320,11 +3331,13 @@ void LLViewerWindow::updateUI() if (gLoggedInTime.getStarted()) { - if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout")) + const F32 DESTINATION_GUIDE_HINT_TIMEOUT = 1200.f; + const F32 SIDE_PANEL_HINT_TIMEOUT = 300.f; + if (gLoggedInTime.getElapsedTimeF32() > DESTINATION_GUIDE_HINT_TIMEOUT) { LLFirstUse::notUsingDestinationGuide(); } - if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout")) + if (gLoggedInTime.getElapsedTimeF32() > SIDE_PANEL_HINT_TIMEOUT) { LLFirstUse::notUsingSidePanel(); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9579a5e4b1..957ce32302 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1351,8 +1351,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - static LLCachedControl<S32> box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity"); - S32 box_detail = box_detail_cache; + const S32 BOX_DETAIL_DEFAULT = 3; + S32 box_detail = BOX_DETAIL_DEFAULT; if (getOverallAppearance() != AOA_NORMAL) { if (isControlAvatar()) @@ -4262,10 +4262,10 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time) LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); - static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0); - static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); + const F32 AVATAR_PELVIS_ROTATE_THRESHOLD_SLOW = 60.0f; + const F32 AVATAR_PELVIS_ROTATE_THRESHOLD_FAST = 2.0f; - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); + F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, AVATAR_PELVIS_ROTATE_THRESHOLD_SLOW, AVATAR_PELVIS_ROTATE_THRESHOLD_FAST); if (self_in_mouselook) { @@ -9290,9 +9290,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe // Parse visual params, if any. S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); - static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams"); - bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing - if( num_blocks > 1 && !drop_visual_params_debug) + if( num_blocks > 1) { //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL; @@ -9337,14 +9335,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe } else { - if (drop_visual_params_debug) - { - LL_INFOS() << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << LL_ENDL; - } - else - { - LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL; - } + LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL; } LLVisualParam* appearance_version_param = getVisualParam(11000); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 7b24b9ee02..f12fc3babc 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -834,7 +834,11 @@ void LLVOAvatarSelf::stopMotionFromSource(const LLUUID& source_id) for (AnimSourceIterator motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end(); ) { gAgent.sendAnimationRequest(motion_it->second, ANIM_REQUEST_STOP); - mAnimationSources.erase(motion_it++); + mAnimationSources.erase(motion_it); + // Must find() after each erase() to deal with potential iterator invalidation + // This also ensures that we don't go past the end of this source's animations + // into those of another source. + motion_it = mAnimationSources.find(source_id); } diff --git a/indra/newview/llvoicecallhandler.cpp b/indra/newview/llvoicecallhandler.cpp index 95e11abd82..c245399622 100644 --- a/indra/newview/llvoicecallhandler.cpp +++ b/indra/newview/llvoicecallhandler.cpp @@ -40,12 +40,6 @@ public: bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) { - if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableVoiceCall")) - { - LLNotificationsUtil::add("NoVoiceCall", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); - return true; - } - //Make sure we have some parameters if (params.size() == 0) { diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 948fe55e0d..49c35c7ad5 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -925,17 +925,17 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id)); registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); registrar.add("Wearable.TakeOffDetach", - boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids)); + boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); // Register handlers for clothing. registrar.add("Clothing.TakeOff", - boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids)); + boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); // Register handlers for body parts. // Register handlers for attachments. registrar.add("Attachment.Detach", - boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids)); + boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); registrar.add("Attachment.Touch", boost::bind(handle_attachment_touch, selected_id)); registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id)); registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2)); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f5f2ba52bf..5ab044d585 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -5143,7 +5143,7 @@ void LLPipeline::setupAvatarLights(bool for_edit) light->setSpotExponent(0.f); light->setSpotCutoff(180.f); } - else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) + else if (gAvatarBacklight) { LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir); LLVector3 opposite_pos = -light_dir; diff --git a/indra/newview/skins/default/textures/icons/Group_Notices.png b/indra/newview/skins/default/textures/icons/Group_Notices.png Binary files differnew file mode 100644 index 0000000000..601502d374 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Group_Notices.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index c733d3feaf..97468c3b2e 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -241,6 +241,8 @@ with the same filename but different name <texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" /> <texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" /> + <texture name="Group_Notices" file_name="icons/Group_Notices.png" preload="false" /> + <texture name="Hand" file_name="icons/hand.png" preload="false" /> <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/da/emoji_categories.xml b/indra/newview/skins/default/xui/da/emoji_categories.xml index 456b18e4e2..f2a7f7a3aa 100644 --- a/indra/newview/skins/default/xui/da/emoji_categories.xml +++ b/indra/newview/skins/default/xui/da/emoji_categories.xml @@ -5,13 +5,13 @@ <key>Name</key> <string>smileys and emotion</string> <key>Category</key> - <string>smileys and følelser</string> + <string>smileys & følelser</string> </map> <map> <key>Name</key> <string>people and body</string> <key>Category</key> - <string>mennesker and krop</string> + <string>mennesker & krop</string> </map> <map> <key>Name</key> @@ -23,19 +23,19 @@ <key>Name</key> <string>animals and nature</string> <key>Category</key> - <string>dyr and natur</string> + <string>dyr & natur</string> </map> <map> <key>Name</key> <string>food and drink</string> <key>Category</key> - <string>mad and drikke</string> + <string>mad & drikke</string> </map> <map> <key>Name</key> <string>travel and places</string> <key>Category</key> - <string>rejser and steder</string> + <string>rejser & steder</string> </map> <map> <key>Name</key> diff --git a/indra/newview/skins/default/xui/de/emoji_categories.xml b/indra/newview/skins/default/xui/de/emoji_categories.xml index ed63d0bac9..ff9e4aec63 100644 --- a/indra/newview/skins/default/xui/de/emoji_categories.xml +++ b/indra/newview/skins/default/xui/de/emoji_categories.xml @@ -5,13 +5,13 @@ <key>Name</key> <string>smileys and emotion</string> <key>Category</key> - <string>Smileys and Emotionen</string> + <string>Smileys & Emotionen</string> </map> <map> <key>Name</key> <string>people and body</string> <key>Category</key> - <string>Menschen and Körper</string> + <string>Menschen & Körper</string> </map> <map> <key>Name</key> @@ -23,19 +23,19 @@ <key>Name</key> <string>animals and nature</string> <key>Category</key> - <string>Tiere and Natur</string> + <string>Tiere & Natur</string> </map> <map> <key>Name</key> <string>food and drink</string> <key>Category</key> - <string>Essen and Trinken</string> + <string>Essen & Trinken</string> </map> <map> <key>Name</key> <string>travel and places</string> <key>Category</key> - <string>Reisen and Orte</string> + <string>Reisen & Orte</string> </map> <map> <key>Name</key> diff --git a/indra/newview/skins/default/xui/en/emoji_categories.xml b/indra/newview/skins/default/xui/en/emoji_categories.xml index 0315d0c43a..5e7700da33 100644 --- a/indra/newview/skins/default/xui/en/emoji_categories.xml +++ b/indra/newview/skins/default/xui/en/emoji_categories.xml @@ -1,17 +1,21 @@ <?xml version="1.0" ?> <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="llsd.xsd"> + <!-- WARNING: This file isn't directly localizable at the moment, + translated variants Must match values provided by + 3p_emoji_shortcodes via emoji_characters for categories + to work correctly--> <array> <map> <key>Name</key> <string>smileys and emotion</string> <key>Category</key> - <string>smileys and emotion</string> + <string>smileys & emotion</string> </map> <map> <key>Name</key> <string>people and body</string> <key>Category</key> - <string>people and body</string> + <string>people & body</string> </map> <map> <key>Name</key> @@ -23,19 +27,19 @@ <key>Name</key> <string>animals and nature</string> <key>Category</key> - <string>animals and nature</string> + <string>animals & nature</string> </map> <map> <key>Name</key> <string>food and drink</string> <key>Category</key> - <string>food and drink</string> + <string>food & drink</string> </map> <map> <key>Name</key> <string>travel and places</string> <key>Category</key> - <string>travel and places</string> + <string>travel & places</string> </map> <map> <key>Name</key> diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml index ba2527e550..abe8344097 100644 --- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -39,7 +39,7 @@ layout="topleft" max_length_bytes="63" name="title_editor" - prevalidate_callback="ascii" + prevalidator="ascii" text_readonly_color="white" top_pad="5" width="290" /> @@ -87,7 +87,7 @@ name="notes_editor" spellcheck="true" text_readonly_color="white" - text_type="ascii_with_newline" + prevalidator="ascii_with_newline" commit_on_focus_lost="true" top_pad="5" width="290" diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index 2eacc8150e..1500c96b8d 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -60,7 +60,7 @@ left_pad="10" max_length_bytes="100" name="day_cycle_name" - prevalidate_callback="ascii" + prevalidator="ascii" top="5" width="200" height="21" /> diff --git a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml index d21f8c82bc..e4b8f13df7 100644 --- a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml @@ -15,6 +15,7 @@ width="304"> <floater.string name="title_for_recently_used" value="Recently used"/> <floater.string name="title_for_frequently_used" value="Frequently used"/> + <floater.string name="text_no_emoji_for_filter" value="No emoji found for '[FILTER]'"/> <scroll_container name="EmojiGridContainer" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml index f424f67df0..5c31bf8ba0 100644 --- a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml +++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml @@ -44,7 +44,7 @@ left_delta="45" width="250" name="settings_name" - prevalidate_callback="ascii" + prevalidator="ascii" max_length_chars="63" height="20"/> <button diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index a54c28af80..738d448f00 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -335,7 +335,7 @@ </layout_panel> <layout_panel name="emoji_recent_layout_panel" - height="30" + height="36" auto_resize="false"> <text name="emoji_recent_empty_text" @@ -345,19 +345,28 @@ h_pad="20" v_pad="10" top="0" - left="1" + left="2" right="-65" - height="30" + height="34" >Recently used emojis will appear here</text> - <emoji_complete - name="emoji_recent_icons_ctrl" + <panel + name="emoji_recent_container" follows="top|left|right" layout="topleft" - max_visible="20" top="0" - left="1" + left="2" right="-65" - height="30"/> + height="34"> + <emoji_complete + name="emoji_recent_icons_ctrl" + follows="top|left|right" + layout="topleft" + max_visible="20" + top="2" + left="2" + right="-2" + height="30"/> + </panel> <button name="emoji_picker_show_btn" label="More" diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml index 5ea751dc7c..e5ec9cc97d 100644 --- a/indra/newview/skins/default/xui/en/floater_media_browser.xml +++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml @@ -211,22 +211,12 @@ <button.commit_callback function="MediaBrowser.OpenWebBrowser" /> </button> - <check_box - control_name="UseExternalBrowser" - follows="bottom|left" - height="20" - label="Always open in my web browser" - layout="topleft" - left_pad="5" - name="open_always" - top_delta="0" - width="200" /> <button follows="bottom|right" height="20" label="Close" layout="topleft" - left_pad="80" + left_pad="285" name="close" top_delta="0" width="70"> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 5dcac85b4f..90223fcda8 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -93,7 +93,7 @@ height="19" max_length_bytes="63" name="description_form" - prevalidate_callback="ascii" + prevalidator="ascii" top_pad="5" width="290" /> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml index 615dbdb025..c94ad6fc9a 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater legacy_header_height="18" - height="460" - min_height="460" + height="475" + min_height="475" layout="topleft" name="gesture_preview" help_topic="gesture_preview" @@ -297,11 +297,20 @@ <check_box follows="top|left" height="20" + label="until key is released" + layout="topleft" + left="28" + name="wait_key_release_check" + top="330" + width="100" /> + <check_box + follows="top|left" + height="20" label="until animations are done" layout="topleft" left="28" name="wait_anim_check" - top="330" + top_delta="20" width="100" /> <check_box follows="top|left" diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml index 5da14b75ab..7f906ff21f 100644 --- a/indra/newview/skins/default/xui/en/floater_profile_texture.xml +++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml @@ -27,7 +27,7 @@ follows="left|top" auto_resize="true" layout="topleft"> - <icon + <profile_image name="profile_pic" image_name="Generic_Person_Large" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_region_info.xml b/indra/newview/skins/default/xui/en/floater_region_info.xml index a7bbfc9842..2d45d08857 100644 --- a/indra/newview/skins/default/xui/en/floater_region_info.xml +++ b/indra/newview/skins/default/xui/en/floater_region_info.xml @@ -7,14 +7,16 @@ name="regioninfo" save_rect="true" title="REGION/ESTATE" - width="530"> + width="637"> <tab_container bottom="555" follows="left|right|top|bottom" layout="topleft" - left="1" + left="0" name="region_panels" - right="-1" - tab_position="top" + tab_padding_right="3" + tab_position="left" + halign="left" + tab_width="110" top="20"/> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml index 2eea5c361f..226cb671f8 100644 --- a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml @@ -23,7 +23,7 @@ layout="topleft" left_delta="0" name="ascii_line_editor" - prevalidate_callback="ascii" + prevalidator="ascii" tool_tip="ascii line editor" top_pad="10" width="200"> diff --git a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml index ab3b819e34..1cf89a8f94 100644 --- a/indra/newview/skins/default/xui/en/floater_test_text_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_test_text_editor.xml @@ -38,7 +38,7 @@ name="numeric_text_editor" tool_tip="text editor for numeric text entry only" top_pad="10" - text_type="int" + prevalidator="int" width="200"> This is text that is NOT a number, so shouldn't appear </text_editor> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 488b39de06..d5c0a427fb 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -144,6 +144,14 @@ parameter="rename" /> </menu_item_call> <menu_item_call + label="New Folder" + layout="topleft" + name="New Listing Folder"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="category" /> + </menu_item_call> + <menu_item_call label="New Outfit" layout="topleft" name="New Outfit"> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index d580369ab2..3bf4015bc5 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -399,6 +399,16 @@ function="Self.EnableRemoveAllAttachments" /> </menu_item_call> </menu> + <menu_item_call + label="Remove selected attachments" + layout="topleft" + name="Remove Selected Attachments" + shortcut="alt|shift|R"> + <menu_item_call.on_click + function="Attachment.Detach" /> + <menu_item_call.on_enable + function="Attachment.EnableDetach" /> + </menu_item_call> <menu_item_separator/> <menu_item_call label="Complete avatars..." @@ -750,6 +760,33 @@ function="Floater.Show" parameter="360capture" /> </menu_item_call> + <menu + create_jump_keys="true" + label="Zoom level" + name="Zoom menu" + tear_off="true"> + <menu_item_call + label="Zoom out" + name="Zoom Out" + shortcut="control|8"> + <menu_item_call.on_click + function="View.ZoomOut" /> + </menu_item_call> + <menu_item_call + label="Default" + name="Zoom Default" + shortcut="control|9"> + <menu_item_call.on_click + function="View.ZoomDefault" /> + </menu_item_call> + <menu_item_call + label="Zoom in" + name="Zoom In" + shortcut="control|0"> + <menu_item_call.on_click + function="View.ZoomIn" /> + </menu_item_call> + </menu> <menu_item_separator/> <menu_item_call label="Place profile" @@ -2391,29 +2428,6 @@ function="World.EnvPreset" function="View.EnableLastChatter" /> </menu_item_call> - <menu_item_separator/> - - <menu_item_call - label="Zoom In" - name="Zoom In" - shortcut="control|0"> - <menu_item_call.on_click - function="View.ZoomIn" /> - </menu_item_call> - <menu_item_call - label="Zoom Default" - name="Zoom Default" - shortcut="control|9"> - <menu_item_call.on_click - function="View.ZoomDefault" /> - </menu_item_call> - <menu_item_call - label="Zoom Out" - name="Zoom Out" - shortcut="control|8"> - <menu_item_call.on_click - function="View.ZoomOut" /> - </menu_item_call> </menu> <!--Shortcuts--> <menu_item_separator/> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3ca284b0fa..a9d13dfd06 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -415,6 +415,15 @@ Initialization with the Marketplace failed because of a system or network error. </notification> <notification + icon="notifytip.tga" + name="InvalidKeystroke" + type="notifytip"> +There was an invalid keystroke entered. +[REASON]. +Please input a valid text. + </notification> + + <notification icon="alertmodal.tga" name="MerchantForceValidateListing" type="alertmodal"> @@ -4400,14 +4409,28 @@ Are you sure you want to return the selected objects to their owners? Transferab icon="alert.tga" name="GroupLeaveConfirmMember" type="alert"> -You are currently a member of the group <nolink>[GROUP]</nolink>. -Leave Group? +Leave the group '<nolink>[GROUP]</nolink>'? +Currently, the fee to join this "group" is L$ [COST]. <tag>group</tag> <tag>confirm</tag> <usetemplate name="okcancelbuttons" notext="Cancel" - yestext="OK"/> + yestext="Leave"/> + </notification> + + <notification + icon="alert.tga" + name="GroupLeaveConfirmMemberNoFee" + type="alert"> +Leave the group '<nolink>[GROUP]</nolink>'? +There is currently no fee to join this group. + <tag>group</tag> + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="Leave"/> </notification> @@ -6170,6 +6193,33 @@ Are you sure you want to delete them? notext="Cancel" yestext="OK"/> </notification> + + <notification + icon="alertmodal.tga" + name="DeleteWornItems" + type="alertmodal"> + <unique/> +Some item(s) you wish to delete are being worn on your avatar. +Remove these items from your avatar? + <tag>confirm</tag> + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="Remove item(s) and delete"/> + </notification> + + <notification + icon="alertmodal.tga" + name="CantDeleteRequiredClothing" + type="alertmodal"> + <unique/> +Some item(s) you wish to delete are required clothing layers (skin, shape, hair, eyes). +You must replace those layers before deleting them. + <tag>confirm</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> <notification icon="alertmodal.tga" @@ -6458,14 +6508,6 @@ Your trash is overflowing. This may cause problems logging in. </notification> <notification - icon="notifytip.tga" - name="InventoryLimitReachedAIS" - type="notifytip"> -Your inventory is experiencing issues. Please, contact support. - <tag>fail</tag> - </notification> - - <notification icon="alertmodal.tga" name="InventoryLimitReachedAISAlert" type="alertmodal"> diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 347efa50da..4d2069c9fe 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -260,7 +260,7 @@ left="10" max_length_bytes="63" name="description" - prevalidate_callback="ascii" + prevalidator="ascii" select_on_focus="true" text_color="Black" top_pad="3" diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 3043a30dcb..7290cbb5c6 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -65,7 +65,7 @@ Hover your mouse over the options for more help. width="168" /> <text font="SansSerifMedium" - text_color="EmphasisColor" + text_color="white" type="string" follows="left|top" height="16" @@ -75,14 +75,14 @@ Hover your mouse over the options for more help. top_pad="10" visible="true" width="190"> - Free + No charge to join </text> <button follows="left|top" left_delta="0" top_pad="6" height="23" - label="JOIN NOW!" + label="Join group" name="btn_join" visible="true" width="120" /> diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index cc50c6202f..ad9dbd1156 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -22,10 +22,10 @@ background_visible="true" name="group_join_btn"> Join (L$[AMOUNT]) </panel.string> - <panel.string - name="group_join_free"> - Free - </panel.string> + <panel.string name="group_join_free">No charge to join</panel.string> + <panel.string name="group_member">You are a member</panel.string> + <panel.string name="join_txt">Join group</panel.string> + <panel.string name="leave_txt">Leave</panel.string> <panel name="group_info_top" follows="top|left" diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml index 9e31ff604a..ff6af88707 100644 --- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml @@ -49,6 +49,18 @@ value="Unknown" width="242" /> <button + name="notices_btn" + tool_tip="Group Notices" + top_delta="-4" + left_pad="3" + right="-53" + height="20" + width="20" + follows="right" + image_pressed="Group_Notices" + image_unselected="Group_Notices" + tab_stop="false"/> + <button follows="right" height="16" image_pressed="Info_Press" @@ -58,7 +70,7 @@ name="info_btn" tool_tip="More info" tab_stop="false" - top_delta="-2" + top_delta="2" width="16" /> <!--*TODO: Should only appear on rollover--> <button @@ -71,6 +83,6 @@ name="profile_btn" tab_stop="false" tool_tip="View profile" - top_delta="-2" + top_delta="0" width="20" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml index 6a1466867d..c33c9659cf 100644 --- a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml +++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml @@ -54,9 +54,22 @@ use_ellipses="true" /> <button + name="notices_btn" + tool_tip="Group Notices" + top_delta="-4" + left_pad="3" + right="-80" + height="20" + width="20" + follows="right" + image_pressed="Group_Notices" + image_unselected="Group_Notices" + tab_stop="false" + visible="false"/> + <button name="visibility_hide_btn" tool_tip="Hide group on my profile" - top_delta="-3" + top_delta="0" left_pad="3" right="-53" height="20" diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 0131f1d97d..1162dcf20d 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -141,7 +141,7 @@ Maximum 200 per group daily left_pad="3" max_length_bytes="63" name="create_subject" - prevalidate_callback="ascii" + prevalidator="ascii" spellcheck="true" width="218" /> <text diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 2fbf322019..af68bd7fee 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -308,7 +308,7 @@ left="0" max_length_bytes="63" name="title_editor" - prevalidate_callback="ascii" + prevalidator="ascii" text_readonly_color="white" top_delta="1" width="290"/> @@ -332,7 +332,7 @@ read_only="true" spellcheck="true" text_readonly_color="white" - text_type="ascii_with_newline" + prevalidator="ascii_with_newline" top_pad="5" width="290" wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 2088a443fd..1801ae1f49 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -55,7 +55,7 @@ combo_editor.font="SansSerifLarge" max_chars="128" combo_editor.commit_on_focus_lost="false" - combo_editor.prevalidate_callback="ascii" + combo_editor.prevalidator="ascii" tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" name="username_combo" width="206"> diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index d002e24782..c906e2f96c 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -112,7 +112,7 @@ combo_editor.font="SansSerifLarge" max_chars="128" top="0" - combo_editor.prevalidate_callback="ascii" + combo_editor.prevalidator="ascii" tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" name="username_combo" width="232"> diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 190ff4ef28..498dab1ef3 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -219,6 +219,7 @@ tab_height="30" tab_position="top" tab_min_width="100" + use_tab_offset="true" top="0"> <inventory_panel bg_opaque_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml index 56d8714064..bfe738f472 100644 --- a/indra/newview/skins/default/xui/en/panel_notification.xml +++ b/indra/newview/skins/default/xui/en/panel_notification.xml @@ -32,21 +32,6 @@ <text border_visible="false" follows="left|right|top|bottom" - font="SansSerif" - height="85" - layout="topleft" - left="10" - name="text_box" - read_only="true" - text_color="White" - top="10" - visible="false" - width="285" - wrap="true"/> - <text - border_visible="false" - follows="left|right|top|bottom" - font="SansSerifBold" height="85" layout="topleft" left="10" @@ -57,14 +42,13 @@ width="285" wrap="true"/> <text_editor - h_pad="0" - v_pad="0" + h_pad="0" + v_pad="0" bg_readonly_color="Transparent" border_visible="false" embedded_items="false" enabled="false" follows="left|right|top|bottom" - font="SansSerif" height="85" layout="topleft" left="10" diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml index 3d61eecf86..1c42a9ed33 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml @@ -483,7 +483,7 @@ layout="topleft" font="SansSerif" max_length_bytes="30" - prevalidate_callback="ascii" + prevalidator="ascii" commit_on_focus_lost="false" text_color="black" /> diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml index f596b876ab..6554dd0952 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml @@ -19,9 +19,10 @@ layout="topleft" visible="false" /> - <thumbnail + <profile_image name="real_world_pic" image_name="Generic_Person_Large" + show_loading="false" follows="top|left" layout="topleft" top="10" diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index dd9a146265..e361a0f28c 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -5,7 +5,7 @@ top="0" left="0" height="480" - width="420" + width="440" follows="all" layout="topleft" > @@ -14,8 +14,11 @@ so display it as an UTC+0 --> <string - name="date_format" + name="date_format_full" value="SL birthdate: [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]" /> + <string + name="date_format_short" + value="SL birthdate: [mth,datetime,utc] [day,datetime,utc]" /> <string name="age_format" value="[AGE]" /> @@ -53,7 +56,7 @@ Account: [ACCTTYPE] top="8" left="6" bottom="-1" - width="160" + width="180" border_size="0" follows="left|top|bottom" layout="topleft" @@ -68,9 +71,10 @@ Account: [ACCTTYPE] auto_resize="false" user_resize="false"> - <thumbnail + <profile_image name="2nd_life_pic" image_name="Generic_Person_Large" + show_loading="false" layout="topleft" follows="all" interactable="true" @@ -322,74 +326,81 @@ Account: [ACCTTYPE] visible="true"/> </layout_panel> <layout_panel + name="menu_panel" + follows="all" + layout="topleft" + height="55" + auto_resize="false" + user_resize="false"> + <menu_button + layout="topleft" + follows="left|top" + left="1" + top="25" + height="25" + width="176" + label="Actions" + halign="left" + image_unselected="DropDown_Off" + image_selected="DropDown_On" + image_pressed="DropDown_Press" + image_pressed_selected="DropDown_Press" + image_disabled="DropDown_Disabled" + name="agent_actions_menu"/> + </layout_panel> + <layout_panel name="settings_panel" follows="all" layout="topleft" - height="50" + height="70" auto_resize="false" user_resize="false"> <!-- only for self --> - <text - name="search_label" - value="Show my profile in search:" - top="1" - left="6" - right="-1" - height="16" - follows="left|top|right" - layout="topleft"/> <combo_box name="show_in_search" tool_tip="Let people see you in search results" left="1" - top="18" - height="23" - width="140" + top="5" + height="25" + width="176" follows="left|top" layout="topleft" - visible="true" enabled="false"> <combo_box.item - name="Hide" - label="Hide" - value="0" /> - <combo_box.item name="Show" - label="Show" + label="Show me in search" value="1" /> + <combo_box.item + name="Hide" + label="Don't show me in search" + value="0" /> </combo_box> - </layout_panel> - - <layout_panel - name="menu_panel" - follows="all" - layout="topleft" - height="55" - auto_resize="false" - user_resize="false" - > - <menu_button - layout="topleft" - follows="left|top" + <combo_box + name="hide_age" + tool_tip="Let people see your SL age" left="1" - top="25" + top="40" height="25" - width="140" - label="Actions" - halign="left" - image_unselected="DropDown_Off" - image_selected="DropDown_On" - image_pressed="DropDown_Press" - image_pressed_selected="DropDown_Press" - image_disabled="DropDown_Disabled" - name="agent_actions_menu" /> + width="176" + follows="left|top" + layout="topleft" + enabled="false"> + <combo_box.item + name="Show" + label="Show birthdate + SL age" + value="0"/> + <combo_box.item + name="Hide" + label="Show month + day only" + value="1"/> + </combo_box> </layout_panel> </layout_stack> <layout_stack name="main_stack" top="8" - left="168" + left="188" bottom="-1" right="-1" follows="all" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index bdb4b545c1..1cb3eca2eb 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -208,7 +208,7 @@ TestString PleaseIgnore Description: </text> <text_editor - text_type="ascii_printable_no_pipe" + prevalidator="ascii_printable_no_pipe" commit_on_focus_lost="true" border_style="line" border_thickness="1" diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 1276f3bad3..45bc73a0b7 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -286,13 +286,13 @@ name="Zoom" value="Zoom" /> <combo_box.item - label="Ignore object" - name="Ignoreobject" - value="Ignore" /> - <combo_box.item label="None" name="None" value="None" /> + <combo_box.item + label="Ignore object" + name="Ignoreobject" + value="Ignore" /> </combo_box> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index b1feb7368f..bee58da6b0 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -580,7 +580,21 @@ http://secondlife.com/support for help fixing this problem. <string name="script_files">Scripts</string> <string name="dictionary_files">Dictionaries</string> - <!-- LSL Usage Hover Tips --> + <!-- Text validator error messages --> + <string name="Validator_InvalidNumericString">Invalid numeric string: "[STR]"</string> + <string name="Validator_ShouldNotBeMinus">Invalid initial character: '[CH]' (shouldn't be a minus)</string> + <string name="Validator_ShouldNotBeMinusOrZero">Invalid initial character: '[CH]' (shouldn't be either a minus or a zero)</string> + <string name="Validator_ShouldBeDigit">Invalid character [NR]: '[CH]' (should only be a digit)</string> + <string name="Validator_ShouldBeDigitOrDot">Invalid character [NR]: '[CH]' (should only be a digit or a decimal point)</string> + <string name="Validator_ShouldBeDigitOrAlpha">Invalid character [NR]: '[CH]' (should only be a digit or an alpha-numeric ASCII character)</string> + <string name="Validator_ShouldBeDigitOrAlphaOrSpace">Invalid character [NR]: '[CH]' (should only be a digit or an alpha-numeric ASCII character or a space)</string> + <string name="Validator_ShouldBeDigitOrAlphaOrPunct">Invalid character [NR]: '[CH]' (should only be a digit or an alpha-numeric ASCII character or a punctuation)</string> + <string name="Validator_ShouldBeDigitOrAlphaOrPunctNotSpace">Invalid character [NR]: '[CH]' (should only be a digit or an alpha-numeric ASCII character or a punctuation with no space)</string> + <string name="Validator_ShouldBeDigitNotSpace">Invalid character [NR]: '[CH]' (should only be a digit with no space)</string> + <string name="Validator_ShouldBeASCII">Invalid character [NR]: '[CH]' (should only be an ASCII character)</string> + <string name="Validator_ShouldBeNewLineOrASCII">Invalid character [NR]: '[CH]' (should only be an ASCII character or a new line)</string> + + <!-- LSL Usage Hover Tips --> <!-- NOTE: For now these are set as translate="false", until DEV-40761 is implemented (to internationalize the rest of tooltips in the same window). This has no effect on viewer code, but prevents Linden Lab internal localization tool from scraping these strings. --> <string name="LSLTipSleepTime" translate="false"> @@ -3946,7 +3960,8 @@ Abuse Report</string> <string name="dance8">dance8</string> <!-- birth date format shared by avatar inspector and profile panels --> - <string name="AvatarBirthDateFormat">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string> + <string name="AvatarBirthDateFormatFull">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string> + <string name="AvatarBirthDateFormatShort">[mthnum,datetime,slt]/[day,datetime,slt]</string> <string name="DefaultMimeType">none/none</string> <string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string> @@ -4013,7 +4028,8 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <string name="EmptyOutfitText">There are no items in this outfit</string> <!-- External editor status codes --> - <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.</string> + <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting. +See https://wiki.secondlife.com/wiki/LSL_Alternate_Editors</string> <string name="ExternalEditorNotFound">Cannot find the external editor you specified. Try enclosing path to the editor with double quotes. (e.g. "/path to my/editor" "%s")</string> diff --git a/indra/newview/skins/default/xui/en/widgets/line_editor.xml b/indra/newview/skins/default/xui/en/widgets/line_editor.xml index d37bee27ba..ae642e1da5 100644 --- a/indra/newview/skins/default/xui/en/widgets/line_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/line_editor.xml @@ -15,5 +15,5 @@ preedit_bg_color="White" mouse_opaque="true" name="line_editor" - font="SansSerifSmall"> + font="EmojiSmall"> </line_editor> diff --git a/indra/newview/skins/default/xui/it/emoji_categories.xml b/indra/newview/skins/default/xui/it/emoji_categories.xml index a4782e60a6..b447a5b78b 100644 --- a/indra/newview/skins/default/xui/it/emoji_categories.xml +++ b/indra/newview/skins/default/xui/it/emoji_categories.xml @@ -5,7 +5,7 @@ <key>Name</key> <string>smileys and emotion</string> <key>Category</key> - <string>smileys and emozione</string> + <string>smileys & emozione</string> </map> <map> <key>Name</key> @@ -23,7 +23,7 @@ <key>Name</key> <string>animals and nature</string> <key>Category</key> - <string>animali and natura</string> + <string>animali & natura</string> </map> <map> <key>Name</key> @@ -35,7 +35,7 @@ <key>Name</key> <string>travel and places</string> <key>Category</key> - <string>viaggi and luoghi</string> + <string>viaggi & luoghi</string> </map> <map> <key>Name</key> diff --git a/indra/newview/skins/default/xui/pl/emoji_categories.xml b/indra/newview/skins/default/xui/pl/emoji_categories.xml index 9aad7af794..42f8e2eb4a 100644 --- a/indra/newview/skins/default/xui/pl/emoji_categories.xml +++ b/indra/newview/skins/default/xui/pl/emoji_categories.xml @@ -5,13 +5,13 @@ <key>Name</key> <string>smileys and emotion</string> <key>Category</key> - <string>buźki and emocje</string> + <string>buźki & emocje</string> </map> <map> <key>Name</key> <string>people and body</string> <key>Category</key> - <string>ludzie and ciało</string> + <string>ludzie & ciało</string> </map> <map> <key>Name</key> @@ -23,7 +23,7 @@ <key>Name</key> <string>animals and nature</string> <key>Category</key> - <string>zwierzęta and przyroda</string> + <string>zwierzęta & przyroda</string> </map> <map> <key>Name</key> @@ -35,7 +35,7 @@ <key>Name</key> <string>travel and places</string> <key>Category</key> - <string>podróże and miejsca</string> + <string>podróże & miejsca</string> </map> <map> <key>Name</key> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index c7f32d0da9..3efd88964d 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -559,10 +559,6 @@ class Windows_x86_64_Manifest(ViewerManifest): self.path("OpenAL32.dll") self.path("alut.dll") - # For ICU4C - self.path("icudt48.dll") - self.path("icuuc48.dll") - # For textures self.path("openjp2.dll") |