summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml465
-rwxr-xr-xindra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl4
-rwxr-xr-xindra/newview/installers/windows/installer_template.nsi187
-rwxr-xr-xindra/newview/installers/windows/lang_da.nsibin7108 -> 8026 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsibin8260 -> 9346 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_en-us.nsibin7542 -> 8120 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_es.nsibin7846 -> 8764 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_fr.nsibin8114 -> 9030 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_it.nsibin7438 -> 8372 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ja.nsibin6302 -> 7288 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pl.nsibin7450 -> 8426 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pt-br.nsibin7832 -> 8788 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ru.nsibin7598 -> 8144 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_tr.nsibin7722 -> 8266 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_zh.nsibin5824 -> 6798 bytes
-rwxr-xr-xindra/newview/llagent.cpp1
-rwxr-xr-xindra/newview/llagentwearables.cpp61
-rwxr-xr-xindra/newview/llappearancemgr.cpp13
-rwxr-xr-xindra/newview/llappviewer.cpp4
-rwxr-xr-xindra/newview/llappviewer.h1
-rw-r--r--indra/newview/llappviewerwin32.cpp2
-rwxr-xr-xindra/newview/llavataractions.cpp4
-rwxr-xr-xindra/newview/llfloaterbvhpreview.cpp2
-rwxr-xr-xindra/newview/llfloatergesture.cpp26
-rwxr-xr-xindra/newview/llfloaternamedesc.cpp6
-rwxr-xr-xindra/newview/llfloateroutbox.cpp252
-rwxr-xr-xindra/newview/llfloateroutbox.h6
-rwxr-xr-xindra/newview/llfloaterperms.cpp229
-rwxr-xr-xindra/newview/llfloaterperms.h55
-rwxr-xr-xindra/newview/llfloaterpreference.cpp9
-rwxr-xr-xindra/newview/llfloaterpreference.h1
-rwxr-xr-xindra/newview/llfolderviewmodelinventory.cpp20
-rwxr-xr-xindra/newview/llimview.cpp2
-rwxr-xr-xindra/newview/llinventorymodel.cpp79
-rwxr-xr-xindra/newview/llinventorymodel.h5
-rwxr-xr-xindra/newview/llinventoryobserver.cpp19
-rwxr-xr-xindra/newview/llinventorypanel.cpp194
-rwxr-xr-xindra/newview/llinventorypanel.h11
-rwxr-xr-xindra/newview/llmaniprotate.cpp29
-rwxr-xr-xindra/newview/llmanipscale.cpp698
-rwxr-xr-xindra/newview/llmanipscale.h47
-rwxr-xr-xindra/newview/llmaniptranslate.cpp11
-rwxr-xr-xindra/newview/llmaniptranslate.h2
-rwxr-xr-xindra/newview/llmarketplacefunctions.cpp88
-rwxr-xr-xindra/newview/llmarketplacefunctions.h20
-rwxr-xr-xindra/newview/llmeshrepository.cpp6
-rwxr-xr-xindra/newview/llnamelistctrl.cpp33
-rwxr-xr-xindra/newview/llnamelistctrl.h13
-rwxr-xr-xindra/newview/llpanelcontents.cpp11
-rwxr-xr-xindra/newview/llpanelgrouproles.cpp35
-rwxr-xr-xindra/newview/llpanelgrouproles.h5
-rwxr-xr-xindra/newview/llpanelmarketplaceinboxinventory.cpp4
-rwxr-xr-xindra/newview/llplacesinventorypanel.cpp12
-rwxr-xr-xindra/newview/llsidepanelinventory.cpp32
-rwxr-xr-xindra/newview/llsidepanelinventory.h4
-rwxr-xr-xindra/newview/lltoastnotifypanel.cpp2
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewerfoldertype.cpp8
-rwxr-xr-xindra/newview/llviewerinventory.cpp129
-rwxr-xr-xindra/newview/llviewerinventory.h2
-rwxr-xr-xindra/newview/llviewermedia.cpp2
-rwxr-xr-xindra/newview/llviewermenufile.cpp12
-rwxr-xr-xindra/newview/llviewermessage.cpp69
-rwxr-xr-xindra/newview/llviewerobject.cpp2
-rwxr-xr-xindra/newview/llviewerobjectlist.cpp1
-rwxr-xr-xindra/newview/llviewerregion.cpp4
-rwxr-xr-xindra/newview/pipeline.cpp61
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_buy_object.xml4
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_perm_prefs.xml108
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml503
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_inventory_add.xml7
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml27
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml15
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_preferences_advanced.xml11
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml12
76 files changed, 2557 insertions, 1134 deletions
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 897e56be0b..d2577d9756 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.7.6
+3.7.7
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d39bf6c3c2..778ab4983a 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3533,17 +3533,6 @@
<key>Value</key>
<string>http://events.secondlife.com/viewer/embed/event/</string>
</map>
- <key>EveryoneCopy</key>
- <map>
- <key>Comment</key>
- <string>Everyone can copy the newly created objects</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FastCacheFetchEnabled</key>
<map>
<key>Comment</key>
@@ -4655,6 +4644,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>InventoryOutboxMakeVisible</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable making the Merchant Outbox and Inbox visible in the inventory for debug purposes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>InventoryOutboxMaxFolderCount</key>
<map>
<key>Comment</key>
@@ -6426,39 +6426,6 @@
<key>Value</key>
<integer>130</integer>
</map>
- <key>NextOwnerCopy</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects can be copied by next owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>NextOwnerModify</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects can be modified by next owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>NextOwnerTransfer</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects can be resold or given away by next owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>NewCacheLocation</key>
<map>
<key>Comment</key>
@@ -8908,7 +8875,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>384</real>
+ <real>368.0</real>
</map>
<key>RenderDeferred</key>
@@ -10332,17 +10299,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShareWithGroup</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects are shared with the currently active group</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowAdvancedGraphicsSettings</key>
<map>
<key>Comment</key>
@@ -14594,6 +14550,347 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>ObjectsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ObjectsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ObjectsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ObjectsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created object</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ObjectsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>UploadsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly uploaded item</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ScriptsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created script</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NotecardsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotecardsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotecardsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotecardsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created notecard</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NotecardsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>GesturesNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>GesturesNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>GesturesNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>GesturesEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created gesture</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>GesturesShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>WearablesEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created clothing or body part</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part is shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DefaultUploadPermissionsConverted</key>
+ <map>
+ <key>Comment</key>
+ <string>Default upload permissions have been converted to default creation permissions</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>PathfindingRetrieveNeighboringRegion</key>
<map>
<key>Comment</key>
@@ -14981,6 +15278,62 @@
<key>Value</key>
<string />
</map>
+ <key>EveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Everyone can copy the newly created objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index c98e7d1cd3..bc63d07d72 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -33,8 +33,8 @@ mat4 getSkinnedTransform()
mat4 ret;
int i = int(floor(weight.x));
float x = fract(weight.x);
-
- ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
+
+ ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);
ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);
ret[3] = vec4(0,0,0,1);
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index c4f503ef4e..8b3a9a8372 100755
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -116,11 +116,14 @@ Var DO_UNINSTALL_V2 ; If non-null, path to a previous Viewer 2 installation
!include "FileFunc.nsh" ; For GetParameters, GetOptions
!insertmacro GetParameters
!insertmacro GetOptions
+!include WinVer.nsh ; For OS and SP detection
+!include x64.nsh ; For 64bit OS detection
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; After install completes, launch app
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function .onInstSuccess
+Call CheckWindowsServPack ; Warn if not on the latest SP before asking to launch.
Push $R0 # Option value, unused
StrCmp $SKIP_DIALOGS "true" label_launch
@@ -152,26 +155,67 @@ Function dirPre
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Make sure we're not on Windows 98 / ME
+; Make sure this computer meets the minimum system requirements.
+; Currently: Windows 32bit XP SP3, 64bit XP SP2 and Server 2003 SP2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CheckWindowsVersion
- DetailPrint "Checking Windows version..."
- Call GetWindowsVersion
- Pop $R0
- ; Just get first two characters, ignore 4.0 part of "NT 4.0"
- StrCpy $R0 $R0 2
- ; Blacklist certain OS versions
- StrCmp $R0 "95" win_ver_bad
- StrCmp $R0 "98" win_ver_bad
- StrCmp $R0 "ME" win_ver_bad
- StrCmp $R0 "NT" win_ver_bad
- Return
-win_ver_bad:
- StrCmp $SKIP_DIALOGS "true" +2 ; If skip_dialogs is set just install
- MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort
- Return
-win_ver_abort:
- Quit
+ ${If} ${AtMostWin2000}
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+
+ ${If} ${IsWinXP}
+ ${AndIfNot} ${RunningX64}
+ ${AndIfNot} ${IsServicePack} 3
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+
+ ${If} ${IsWinXP}
+ ${AndIf} ${RunningX64}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+
+ ${If} ${IsWin2003}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;Recommend Upgrading Service Pack
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function CheckWindowsServPack
+ ${If} ${IsWinVista}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
+
+ ${If} ${IsWin2008}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
+
+ ${If} ${IsWin7}
+ ${AndIfNot} ${IsServicePack} 1
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
+
+ ${If} ${IsWin2008R2}
+ ${AndIfNot} ${IsServicePack} 1
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -222,17 +266,13 @@ FunctionEnd
; Checks for CPU valid (must have SSE2 support)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CheckCPUFlags
- Call GetWindowsVersion
- Pop $R0
- StrCmp $R0 "2000" OK_SSE ; sse check not available on win2k.
-
Push $1
System::Call 'kernel32::IsProcessorFeaturePresent(i) i(10) .r1'
- IntCmp $1 1 OK_SSE
- MessageBox MB_OKCANCEL $(MissingSSE2) /SD IDOK IDOK OK_SSE
+ IntCmp $1 1 OK_SSE2
+ MessageBox MB_OKCANCEL $(MissingSSE2) /SD IDOK IDOK OK_SSE2
Quit
- OK_SSE:
+ OK_SSE2:
Pop $1
Return
FunctionEnd
@@ -768,103 +808,13 @@ Call un.ProgramFiles
SectionEnd ; end of uninstall section
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; (From the NSIS documentation, JC)
-; GetWindowsVersion
-;
-; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/
-; Updated by Joost Verburg
-;
-; Returns on top of stack
-;
-; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003)
-; or
-; '' (Unknown Windows Version)
-;
-; Usage:
-; Call GetWindowsVersion
-; Pop $R0
-; ; at this point $R0 is "NT 4.0" or whatnot
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Function GetWindowsVersion
-
- Push $R0
- Push $R1
-
- ReadRegStr $R0 HKLM \
- "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
-
- IfErrors 0 lbl_winnt
-
- ; we are not NT
- ReadRegStr $R0 HKLM \
- "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber
-
- StrCpy $R1 $R0 1
- StrCmp $R1 '4' 0 lbl_error
-
- StrCpy $R1 $R0 3
-
- StrCmp $R1 '4.0' lbl_win32_95
- StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98
-
- lbl_win32_95:
- StrCpy $R0 '95'
- Goto lbl_done
-
- lbl_win32_98:
- StrCpy $R0 '98'
- Goto lbl_done
-
- lbl_win32_ME:
- StrCpy $R0 'ME'
- Goto lbl_done
-
- lbl_winnt:
-
- StrCpy $R1 $R0 1
-
- StrCmp $R1 '3' lbl_winnt_x
- StrCmp $R1 '4' lbl_winnt_x
-
- StrCpy $R1 $R0 3
-
- StrCmp $R1 '5.0' lbl_winnt_2000
- StrCmp $R1 '5.1' lbl_winnt_XP
- StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error
-
- lbl_winnt_x:
- StrCpy $R0 "NT $R0" 6
- Goto lbl_done
-
- lbl_winnt_2000:
- Strcpy $R0 '2000'
- Goto lbl_done
-
- lbl_winnt_XP:
- Strcpy $R0 'XP'
- Goto lbl_done
-
- lbl_winnt_2003:
- Strcpy $R0 '2003'
- Goto lbl_done
-
- lbl_error:
- Strcpy $R0 ''
- lbl_done:
-
- Pop $R1
- Exch $R0
-
-FunctionEnd
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Note: to add new languages, add a language file include to the list
;; at the top of this file, add an entry to the menu and then add an
;; entry to the language ID selector below
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function .onInit
+Call CheckWindowsVersion ; Don't install On unsupported systems
Push $0
${GetParameters} $COMMANDLINE ; get our command line
@@ -933,13 +883,12 @@ StrCpy $INSTPROG "${INSTNAME}"
StrCpy $INSTEXE "${INSTEXE}"
StrCpy $INSTSHORTCUT "${SHORTCUT}"
-Call CheckWindowsVersion ; warn if on Windows 98/ME
-Call CheckCPUFlags ; Make sure we have SSE2 support
+Call CheckCPUFlags ; Make sure we have SSE2 support
Call CheckIfAdministrator ; Make sure the user can install/uninstall
Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this version
Call CloseSecondLife ; Make sure we're not running
Call CheckNetworkConnection ; ping secondlife.com
-Call CheckWillUninstallV2 ; See if a V2 install exists and will be removed.
+Call CheckWillUninstallV2 ; See if a V2 install exists and will be removed.
Call CheckOldExeName ; Clean up a previous version of the exe
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 0c832e8ba9..2352649b4b 100755
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index b717a4d3a5..397262afe1 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index da0d7f54d2..df0d55d9e0 100755
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index c6a7f38f3f..32967a0dfa 100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 008c240ed7..7c75e25360 100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index eccd965a92..ce66b61f9f 100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index f564291f7d..e68830123a 100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 191bae4755..7883819190 100755
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index da56a3c336..eb3fb2386c 100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index de7affe08a..3b0042fbf5 100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index 5e7e3d797b..b9be1eab08 100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index ecf1185fbb..3c6f6fd289 100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f150ceda67..54e0375a2b 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -47,6 +47,7 @@
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterimcontainer.h"
+#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llgroupactions.h"
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index fa810aac76..9c36e54928 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -49,6 +49,7 @@
#include "llvoavatarself.h"
#include "llviewerwearable.h"
#include "llwearablelist.h"
+#include "llfloaterperms.h"
#include <boost/scoped_ptr.hpp>
@@ -65,6 +66,19 @@ void wear_and_edit_cb(const LLUUID& inv_item)
{
if (inv_item.isNull()) return;
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (!item) return;
+
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+
// Request editing the item after it gets worn.
gAgentWearables.requestEditingWearable(inv_item);
@@ -72,6 +86,26 @@ void wear_and_edit_cb(const LLUUID& inv_item)
LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
}
+void wear_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
// HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look"
@@ -204,7 +238,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
*
* Would like to pass the agent in here, but we can't safely
* count on it being around later. Just use gAgent directly.
- * @param cb callback to execute on completion (??? unused ???)
+ * @param cb callback to execute on completion (? unused ?)
* @param type Type for the wearable in the agent
* @param wearable The wearable data.
* @param todo Bitmask of actions to take on completion.
@@ -482,6 +516,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(
old_wearable,
trunc_name);
+
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
@@ -1804,7 +1839,16 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
- LLPointer<LLInventoryCallback> cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;
+ LLPointer<LLInventoryCallback> cb;
+ if(wear)
+ {
+ cb = new LLBoostFuncInventoryCallback(wear_and_edit_cb);
+ }
+ else
+ {
+ cb = new LLBoostFuncInventoryCallback(wear_cb);
+ }
+
LLUUID folder_id;
if (parent_id.notNull())
@@ -1817,10 +1861,15 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
folder_id = gInventory.findCategoryUUIDForType(folder_type);
}
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, wearable->getTransactionID(), wearable->getName(),
- wearable->getDescription(), asset_type, inv_type, wearable->getType(),
- wearable->getPermissions().getMaskNextOwner(),
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ folder_id,
+ wearable->getTransactionID(),
+ wearable->getName(),
+ wearable->getDescription(),
+ asset_type, inv_type,
+ wearable->getType(),
+ LLFloaterPerms::getNextOwnerPerms("Wearables"),
cb);
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index da1609297e..c5e98915fc 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1431,6 +1431,18 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
uuids_to_remove.push_back(item->getUUID());
}
removeItemsFromAvatar(uuids_to_remove);
+
+ // deactivate all gestures in the outfit folder
+ LLInventoryModel::item_array_t gest_items;
+ getDescendentsOfAssetType(cat_id, gest_items, LLAssetType::AT_GESTURE, false);
+ for(S32 i = 0; i < gest_items.count(); ++i)
+ {
+ LLViewerInventoryItem *gest_item = gest_items.get(i);
+ if ( LLGestureMgr::instance().isGestureActive( gest_item->getLinkedUUID()) )
+ {
+ LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
+ }
+ }
}
// Create a copy of src_id + contents as a subfolder of dst_id.
@@ -3414,6 +3426,7 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
llwarns << "called with empty list, nothing to do" << llendl;
}
+
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
const LLUUID& id_to_remove = *it;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ebdb52c565..cecbf907f2 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -740,7 +740,7 @@ public:
bool LLAppViewer::init()
{
- setupErrorHandling();
+ setupErrorHandling(mSecondInstance);
//
// Start of the application
@@ -4785,7 +4785,7 @@ void LLAppViewer::idle()
static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
// Update session stats every large chunk of time
- // *FIX: (???) SAMANTHA
+ // *FIX: (?) SAMANTHA
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
llinfos << "Transmitting sessions stats" << llendl;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index cbaa7bc4c2..25b5c90bb0 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -80,6 +80,7 @@ public:
bool quitRequested() { return mQuitRequested; }
bool logoutRequestSent() { return mLogoutRequestSent; }
+ bool isSecondInstance() { return mSecondInstance; }
void writeDebugInfo(bool isStatic=true);
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index d9a0eb25e4..5585bd914c 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -674,6 +674,8 @@ bool LLAppViewerWin32::restoreErrorTrap()
void LLAppViewerWin32::initCrashReporting(bool reportFreeze)
{
+ if (isSecondInstance()) return; //BUG-5707 do not start another crash reporter for second instance.
+
const char* logger_name = "win_crash_logger.exe";
std::string exe_path = gDirUtilp->getExecutableDir();
exe_path += gDirUtilp->getDirDelimiter();
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 70cc48f12b..307e72fe18 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -868,6 +868,10 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
// check selection in the panel
LLFolderView* root_folder = inv_panel->getRootFolder();
+ if (!root_folder)
+ {
+ return false;
+ }
const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
if (inventory_selected.empty()) return false; // nothing selected
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index f2deb6a805..a992443ce1 100755
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1002,7 +1002,7 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_ANIMATION,
- LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
name,
callback, expected_upload_cost, userdata);
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 56051ff684..59f5b2b346 100755
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -48,6 +48,7 @@
#include "llviewermenu.h"
#include "llviewerinventory.h"
#include "llviewercontrol.h"
+#include "llfloaterperms.h"
BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
{
@@ -74,6 +75,17 @@ public:
void fire(const LLUUID &inv_item)
{
LLPreviewGesture::show(inv_item, LLUUID::null);
+
+ LLInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Gestures"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+ item->setPermissions(perm);
+ item->updateServer(FALSE);
+ }
}
};
@@ -449,9 +461,17 @@ void LLFloaterGesture::onClickPlay()
void LLFloaterGesture::onClickNew()
{
LLPointer<LLInventoryCallback> cb = new GestureShowCallback();
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- LLUUID::null, LLTransactionID::tnull, "New Gesture", "", LLAssetType::AT_GESTURE,
- LLInventoryType::IT_GESTURE, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ LLUUID::null,
+ LLTransactionID::tnull,
+ "New Gesture",
+ "",
+ LLAssetType::AT_GESTURE,
+ LLInventoryType::IT_GESTURE,
+ NOT_WEARABLE,
+ PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Gestures"),
+ cb);
}
void LLFloaterGesture::onActivateBtnClick()
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 27b1c3b9cd..ee7f413a59 100755
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -45,6 +45,7 @@
#include "lluictrlfactory.h"
#include "llstring.h"
#include "lleconomy.h"
+#include "llpermissions.h"
// linden includes
#include "llassetstorage.h"
@@ -167,11 +168,14 @@ void LLFloaterNameDesc::onBtnOK( )
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
void *nruserdata = NULL;
std::string display_name = LLStringUtil::null;
+
upload_new_resource(mFilenameAndPath, // file
getChild<LLUICtrl>("name_form")->getValue().asString(),
getChild<LLUICtrl>("description_form")->getValue().asString(),
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
display_name, callback, expected_upload_cost, nruserdata);
closeFloater(false);
}
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 29a3e6ac3a..de96f75602 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -95,7 +95,7 @@ public:
if (added_category_type == LLFolderType::FT_OUTBOX)
{
- mOutboxFloater->setupOutbox(added_category->getUUID());
+ mOutboxFloater->initializeMarketPlace();
}
}
}
@@ -120,7 +120,6 @@ LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)
, mInventoryText(NULL)
, mInventoryTitle(NULL)
, mOutboxId(LLUUID::null)
- , mOutboxInventoryPanel(NULL)
, mOutboxItemCount(0)
, mOutboxTopLevelDropZone(NULL)
, mWindowShade(NULL)
@@ -157,9 +156,24 @@ BOOL LLFloaterOutbox::postBuild()
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this));
+ // Observe category creation to catch outbox creation (moot if already existing)
+ mCategoryAddedObserver = new LLOutboxAddedObserver(this);
+ gInventory.addObserver(mCategoryAddedObserver);
+
return TRUE;
}
+void LLFloaterOutbox::cleanOutbox()
+{
+ // Note: we cannot delete the mOutboxInventoryPanel as that point
+ // as this is called through callback observers of the panel itself.
+ // Doing so would crash rapidly.
+
+ // Invalidate the outbox data
+ mOutboxId.setNull();
+ mOutboxItemCount = 0;
+}
+
void LLFloaterOutbox::onClose(bool app_quitting)
{
if (mWindowShade)
@@ -173,33 +187,25 @@ void LLFloaterOutbox::onClose(bool app_quitting)
void LLFloaterOutbox::onOpen(const LLSD& key)
{
//
- // Look for an outbox and set up the inventory API
+ // Initialize the Market Place or go update the outbox
//
-
- if (mOutboxId.isNull())
+ if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
- const bool do_not_create_folder = false;
-
- const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder);
-
- if (outbox_id.isNull())
- {
- // Observe category creation to catch outbox creation
- mCategoryAddedObserver = new LLOutboxAddedObserver(this);
- gInventory.addObserver(mCategoryAddedObserver);
- }
- else
- {
- setupOutbox(outbox_id);
- }
+ initializeMarketPlace();
+ }
+ else
+ {
+ setupOutbox();
}
+ //
+ // Update the floater view
+ //
updateView();
//
// Trigger fetch of outbox contents
//
-
fetchOutboxContents();
}
@@ -216,14 +222,34 @@ void LLFloaterOutbox::fetchOutboxContents()
}
}
-void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
+void LLFloaterOutbox::setupOutbox()
{
- llassert(outboxId.notNull());
- llassert(mOutboxId.isNull());
- llassert(mCategoriesObserver == NULL);
-
- mOutboxId = outboxId;
-
+ if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() != MarketplaceStatusCodes::MARKET_PLACE_MERCHANT)
+ {
+ // If we are *not* a merchant or we have no market place connection established yet, do nothing
+ return;
+ }
+
+ // We are a merchant. Get the outbox, create it if needs be.
+ LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true);
+ if (outbox_id.isNull())
+ {
+ // We should never get there unless the inventory fails badly
+ llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
+ return;
+ }
+
+ // Consolidate Merchant Outbox
+ // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, things get messy and conventions get broken down eventually
+ gInventory.consolidateForType(outbox_id, LLFolderType::FT_OUTBOX);
+
+ if (outbox_id == mOutboxId)
+ {
+ llwarns << "Inventory warning: Merchant outbox already set" << llendl;
+ return;
+ }
+ mOutboxId = outbox_id;
+
// No longer need to observe new category creation
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
@@ -231,45 +257,55 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
delete mCategoryAddedObserver;
mCategoryAddedObserver = NULL;
}
+ llassert(!mCategoryAddedObserver);
- // Create observer for outbox modifications
- mCategoriesObserver = new LLInventoryCategoriesObserver();
- gInventory.addObserver(mCategoriesObserver);
-
- mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+ // Create observer for outbox modifications : clear the old one and create a new one
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ gInventory.removeObserver(mCategoriesObserver);
+ delete mCategoriesObserver;
+ }
+ mCategoriesObserver = new LLInventoryCategoriesObserver();
+ gInventory.addObserver(mCategoriesObserver);
+ mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+ llassert(mCategoriesObserver);
- //
// Set up the outbox inventory view
- //
-
- mOutboxInventoryPanel =
- LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
- mInventoryPlaceholder->getParent(),
- LLInventoryPanel::child_registry_t::instance());
-
- llassert(mOutboxInventoryPanel);
+ LLInventoryPanel* inventory_panel = mOutboxInventoryPanel.get();
+ if (inventory_panel)
+ {
+ delete inventory_panel;
+ }
+ inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
+ mOutboxInventoryPanel = inventory_panel->getInventoryPanelHandle();
+ llassert(mOutboxInventoryPanel.get() != NULL);
// Reshape the inventory to the proper size
LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
- mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
+ inventory_panel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
-
- mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
- mOutboxInventoryPanel->getFilter().markDefault();
-
+ inventory_panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ inventory_panel->getFilter().markDefault();
+
+ // Get the content of the outbox
fetchOutboxContents();
-
+}
+
+void LLFloaterOutbox::initializeMarketPlace()
+{
//
// Initialize the marketplace import API
//
-
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
- importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
- importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
- importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
- importer.initialize();
+ if (!importer.isInitialized())
+ {
+ importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
+ importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
+ importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
+ importer.initialize();
+ }
}
void LLFloaterOutbox::setStatusString(const std::string& statusString)
@@ -281,18 +317,26 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString)
void LLFloaterOutbox::updateFolderCount()
{
- S32 item_count = 0;
-
- if (mOutboxId.notNull())
+ if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
{
- LLInventoryModel::cat_array_t * cats;
- LLInventoryModel::item_array_t * items;
- gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+ S32 item_count = 0;
- item_count = cats->count() + items->count();
- }
+ if (mOutboxId.notNull())
+ {
+ LLInventoryModel::cat_array_t * cats;
+ LLInventoryModel::item_array_t * items;
+ gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+
+ item_count = cats->count() + items->count();
+ }
- mOutboxItemCount = item_count;
+ mOutboxItemCount = item_count;
+ }
+ else
+ {
+ // If there's no outbox, the number of items in it should be set to 0 for consistency
+ mOutboxItemCount = 0;
+ }
if (!mImportBusy)
{
@@ -302,7 +346,7 @@ void LLFloaterOutbox::updateFolderCount()
void LLFloaterOutbox::updateFolderCountStatus()
{
- if (mOutboxInventoryPanel)
+ if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
{
switch (mOutboxItemCount)
{
@@ -327,18 +371,23 @@ void LLFloaterOutbox::updateFolderCountStatus()
void LLFloaterOutbox::updateView()
{
updateFolderCount();
+ LLInventoryPanel* panel = mOutboxInventoryPanel.get();
if (mOutboxItemCount > 0)
{
- mOutboxInventoryPanel->setVisible(TRUE);
+ panel->setVisible(TRUE);
mInventoryPlaceholder->setVisible(FALSE);
+ mOutboxTopLevelDropZone->setVisible(TRUE);
}
else
{
- if (mOutboxInventoryPanel)
+ if (panel)
{
- mOutboxInventoryPanel->setVisible(FALSE);
+ panel->setVisible(FALSE);
}
+
+ // Show the drop zone if there is an outbox folder
+ mOutboxTopLevelDropZone->setVisible(mOutboxId.notNull());
mInventoryPlaceholder->setVisible(TRUE);
@@ -347,19 +396,41 @@ void LLFloaterOutbox::updateView()
std::string outbox_tooltip;
const LLSD& subs = getMarketplaceStringSubstitutions();
+ U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();
if (mOutboxId.notNull())
{
+ // Does the outbox needs recreation?
+ if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId))
+ {
+ setupOutbox();
+ }
+ // "Outbox is empty!" message strings
outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs);
outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
}
- else
+ else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
+ {
+ // "Initializing!" message strings
+ outbox_text = LLTrans::getString("InventoryOutboxInitializing", subs);
+ outbox_title = LLTrans::getString("InventoryOutboxInitializingTitle");
+ outbox_tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip");
+ }
+ else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT)
{
+ // "Not a merchant!" message strings
outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
}
+ else
+ {
+ // "Errors!" message strings
+ outbox_text = LLTrans::getString("InventoryOutboxError", subs);
+ outbox_title = LLTrans::getString("InventoryOutboxErrorTitle");
+ outbox_tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ }
mInventoryText->setValue(outbox_text);
mInventoryTitle->setValue(outbox_title);
@@ -378,9 +449,10 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EAcceptance* accept,
std::string& tooltip_msg)
{
- if ((mOutboxInventoryPanel == NULL) ||
+ if ((mOutboxInventoryPanel.get() == NULL) ||
(mWindowShade && mWindowShade->isShown()) ||
- LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
+ LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() ||
+ mOutboxId.isNull())
{
return FALSE;
}
@@ -391,15 +463,16 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// Determine if the mouse is inside the inventory panel itself or just within the floater
bool pointInInventoryPanel = false;
bool pointInInventoryPanelChild = false;
- LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
- if (mOutboxInventoryPanel->getVisible())
+ LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+ LLFolderView* root_folder = panel->getRootFolder();
+ if (panel->getVisible())
{
S32 inv_x, inv_y;
- localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel);
+ localPointToOtherView(x, y, &inv_x, &inv_y, panel);
- pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y);
+ pointInInventoryPanel = panel->getRect().pointInRect(inv_x, inv_y);
- LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true);
+ LLView * inventory_panel_child_at_point = panel->childFromPoint(inv_x, inv_y, true);
pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder);
}
@@ -439,23 +512,26 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)
void LLFloaterOutbox::onImportButtonClicked()
{
- mOutboxInventoryPanel->clearSelection();
+ if (mOutboxInventoryPanel.get())
+ {
+ mOutboxInventoryPanel.get()->clearSelection();
+ }
mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
}
void LLFloaterOutbox::onOutboxChanged()
{
- llassert(!mOutboxId.isNull());
-
- //if (mOutboxInventoryPanel)
- //{
- // mOutboxInventoryPanel->requestSort();
- //}
-
- fetchOutboxContents();
-
- updateView();
+ LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
+ if (mOutboxId.notNull() && category)
+ {
+ fetchOutboxContents();
+ updateView();
+ }
+ else
+ {
+ cleanOutbox();
+ }
}
void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
@@ -486,6 +562,11 @@ void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
void LLFloaterOutbox::importStatusChanged(bool inProgress)
{
+ if (mOutboxId.isNull() && (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT))
+ {
+ setupOutbox();
+ }
+
if (inProgress)
{
if (mImportBusy)
@@ -503,6 +584,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
}
else
{
+ setStatusString("");
mImportBusy = false;
mImportButton->setEnabled(mOutboxItemCount > 0);
mInventoryImportInProgress->setVisible(false);
@@ -513,7 +595,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
{
- if (status != MarketplaceErrorCodes::IMPORT_DONE)
+ if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
{
char status_string[16];
sprintf(status_string, "%d", status);
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index a91d8c1139..40519c8fd2 100755
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -54,7 +54,7 @@ public:
LLFloaterOutbox(const LLSD& key);
~LLFloaterOutbox();
- void setupOutbox(const LLUUID& outboxId);
+ void initializeMarketPlace();
// virtuals
BOOL postBuild();
@@ -70,6 +70,8 @@ public:
void onMouseLeave(S32 x, S32 y, MASK mask);
protected:
+ void setupOutbox();
+ void cleanOutbox();
void fetchOutboxContents();
void importReportResults(U32 status, const LLSD& content);
@@ -104,7 +106,7 @@ private:
LLTextBox * mInventoryTitle;
LLUUID mOutboxId;
- LLInventoryPanel * mOutboxInventoryPanel;
+ LLHandle<LLInventoryPanel> mOutboxInventoryPanel;
U32 mOutboxItemCount;
LLPanel * mOutboxTopLevelDropZone;
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 80b55c3cbb..0880a5f35a 100755
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -1,7 +1,7 @@
/**
* @file llfloaterperms.cpp
* @brief Asset creation permission preferences.
- * @author Coco
+ * @author Jonathan Yap
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,101 +32,230 @@
#include "llviewerwindow.h"
#include "lluictrlfactory.h"
#include "llpermissions.h"
-
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llnotificationsutil.h"
LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
: LLFloater(seed)
{
- mCommitCallbackRegistrar.add("Perms.Copy", boost::bind(&LLFloaterPerms::onCommitCopy, this));
- mCommitCallbackRegistrar.add("Perms.OK", boost::bind(&LLFloaterPerms::onClickOK, this));
- mCommitCallbackRegistrar.add("Perms.Cancel", boost::bind(&LLFloaterPerms::onClickCancel, this));
-
}
BOOL LLFloaterPerms::postBuild()
{
- mCloseSignal.connect(boost::bind(&LLFloaterPerms::cancel, this));
-
+ return TRUE;
+}
+
+//static
+U32 LLFloaterPerms::getGroupPerms(std::string prefix)
+{
+ return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY | PERM_MOVE | PERM_MODIFY : PERM_NONE;
+}
+
+//static
+U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
+{
+ return gSavedSettings.getBOOL(prefix+"EveryoneCopy") ? PERM_COPY : PERM_NONE;
+}
+
+//static
+U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
+{
+ U32 flags = PERM_MOVE;
+ if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+ {
+ flags |= PERM_COPY;
+ }
+ if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
+ {
+ flags |= PERM_MODIFY;
+ }
+ if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+ {
+ flags |= PERM_TRANSFER;
+ }
+ return flags;
+}
+
+//static
+U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix)
+{
+ // Sets bits for permissions that are off
+ U32 flags = PERM_MOVE;
+ if ( !gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+ {
+ flags |= PERM_COPY;
+ }
+ if ( !gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
+ {
+ flags |= PERM_MODIFY;
+ }
+ if ( !gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+ {
+ flags |= PERM_TRANSFER;
+ }
+ return flags;
+}
+
+static bool mCapSent = false;
+
+LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed)
+ : LLFloater(seed)
+{
+ mCommitCallbackRegistrar.add("PermsDefault.Copy", boost::bind(&LLFloaterPermsDefault::onCommitCopy, this, _2));
+ mCommitCallbackRegistrar.add("PermsDefault.OK", boost::bind(&LLFloaterPermsDefault::onClickOK, this));
+ mCommitCallbackRegistrar.add("PermsDefault.Cancel", boost::bind(&LLFloaterPermsDefault::onClickCancel, this));
+}
+
+
+// String equivalents of enum Categories - initialization order must match enum order!
+const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
+{
+ "Objects",
+ "Uploads",
+ "Scripts",
+ "Notecards",
+ "Gestures",
+ "Wearables"
+};
+
+BOOL LLFloaterPermsDefault::postBuild()
+{
+ if(!gSavedSettings.getBOOL("DefaultUploadPermissionsConverted"))
+ {
+ gSavedSettings.setBOOL("UploadsEveryoneCopy", gSavedSettings.getBOOL("EveryoneCopy"));
+ gSavedSettings.setBOOL("UploadsNextOwnerCopy", gSavedSettings.getBOOL("NextOwnerCopy"));
+ gSavedSettings.setBOOL("UploadsNextOwnerModify", gSavedSettings.getBOOL("NextOwnerModify"));
+ gSavedSettings.setBOOL("UploadsNextOwnerTransfer", gSavedSettings.getBOOL("NextOwnerTransfer"));
+ gSavedSettings.setBOOL("UploadsShareWithGroup", gSavedSettings.getBOOL("ShareWithGroup"));
+ gSavedSettings.setBOOL("DefaultUploadPermissionsConverted", true);
+ }
+
+ mCloseSignal.connect(boost::bind(&LLFloaterPermsDefault::cancel, this));
+
refresh();
- return TRUE;
+ return true;
}
-void LLFloaterPerms::onClickOK()
+void LLFloaterPermsDefault::onClickOK()
{
ok();
closeFloater();
}
-void LLFloaterPerms::onClickCancel()
+void LLFloaterPermsDefault::onClickCancel()
{
cancel();
closeFloater();
}
-void LLFloaterPerms::onCommitCopy()
+void LLFloaterPermsDefault::onCommitCopy(const LLSD& user_data)
{
// Implements fair use
- BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy");
+ std::string prefix = user_data.asString();
+
+ BOOL copyable = gSavedSettings.getBOOL(prefix+"NextOwnerCopy");
if(!copyable)
{
- gSavedSettings.setBOOL("NextOwnerTransfer", TRUE);
+ gSavedSettings.setBOOL(prefix+"NextOwnerTransfer", TRUE);
}
- LLCheckBoxCtrl* xfer = getChild<LLCheckBoxCtrl>("next_owner_transfer");
+ LLCheckBoxCtrl* xfer = getChild<LLCheckBoxCtrl>(prefix+"_transfer");
xfer->setEnabled(copyable);
}
-void LLFloaterPerms::ok()
+class LLFloaterPermsResponder : public LLHTTPClient::Responder
{
- refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official.
-}
+public:
+ LLFloaterPermsResponder(): LLHTTPClient::Responder() {}
+private:
+ static std::string sPreviousReason;
+
+ void error(U32 status, const std::string& reason)
+ {
+ // Do not display the same error more than once in a row
+ if (reason != sPreviousReason)
+ {
+ sPreviousReason = reason;
+ LLSD args;
+ args["REASON"] = reason;
+ LLNotificationsUtil::add("DefaultObjectPermissions", args);
+ }
+ }
+ void result(const LLSD& content)
+ {
+ // Since we have had a successful POST call be sure to display the next error message
+ // even if it is the same as a previous one.
+ sPreviousReason = "";
+ LLFloaterPermsDefault::setCapSent(true);
+ LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL;
+ }
+};
+
+ std::string LLFloaterPermsResponder::sPreviousReason;
-void LLFloaterPerms::cancel()
+void LLFloaterPermsDefault::sendInitialPerms()
{
- gSavedSettings.setBOOL("ShareWithGroup", mShareWithGroup);
- gSavedSettings.setBOOL("EveryoneCopy", mEveryoneCopy);
- gSavedSettings.setBOOL("NextOwnerCopy", mNextOwnerCopy);
- gSavedSettings.setBOOL("NextOwnerModify", mNextOwnerModify);
- gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer);
+ if(!mCapSent)
+ {
+ updateCap();
+ }
}
-void LLFloaterPerms::refresh()
+void LLFloaterPermsDefault::updateCap()
{
- mShareWithGroup = gSavedSettings.getBOOL("ShareWithGroup");
- mEveryoneCopy = gSavedSettings.getBOOL("EveryoneCopy");
- mNextOwnerCopy = gSavedSettings.getBOOL("NextOwnerCopy");
- mNextOwnerModify = gSavedSettings.getBOOL("NextOwnerModify");
- mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer");
+ std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences");
+
+ if(!object_url.empty())
+ {
+ LLSD report = LLSD::emptyMap();
+ report["default_object_perm_masks"]["Group"] =
+ (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]);
+ report["default_object_perm_masks"]["Everyone"] =
+ (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]);
+ report["default_object_perm_masks"]["NextOwner"] =
+ (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
+
+ LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder());
+ }
}
-//static
-U32 LLFloaterPerms::getGroupPerms(std::string prefix)
-{
- return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE;
+void LLFloaterPermsDefault::setCapSent(bool cap_sent)
+{
+ mCapSent = cap_sent;
}
-//static
-U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
+void LLFloaterPermsDefault::ok()
{
- return gSavedSettings.getBOOL(prefix+"EveryoneCopy") ? PERM_COPY : PERM_NONE;
+// Changes were already applied automatically to saved settings.
+// Refreshing internal values makes it official.
+ refresh();
+
+// We know some setting has changed but not which one. Just in case it was a setting for
+// object permissions tell the server what the values are.
+ updateCap();
}
-//static
-U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
+void LLFloaterPermsDefault::cancel()
{
- U32 flags = PERM_MOVE;
- if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+ for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++)
{
- flags |= PERM_COPY;
- }
- if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
- {
- flags |= PERM_MODIFY;
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]);
}
- if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+}
+
+void LLFloaterPermsDefault::refresh()
+{
+ for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++)
{
- flags |= PERM_TRANSFER;
+ mShareWithGroup[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"ShareWithGroup");
+ mEveryoneCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"EveryoneCopy");
+ mNextOwnerCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerCopy");
+ mNextOwnerModify[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerModify");
+ mNextOwnerTransfer[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerTransfer");
}
- return flags;
}
-
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 6b65f4b0cd..2bb0a19dc1 100755
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -1,7 +1,7 @@
/**
* @file llfloaterperms.h
* @brief Asset creation permission preferences.
- * @author Coco
+ * @author Jonathan Yap
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,26 +36,57 @@ class LLFloaterPerms : public LLFloater
public:
/*virtual*/ BOOL postBuild();
- void ok();
- void cancel();
- void onClickOK();
- void onClickCancel();
- void onCommitCopy();
+
// Convenience methods to get current permission preference bitfields from saved settings:
static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy"
static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup"
static U32 getNextOwnerPerms(std::string prefix=""); // bitfield for prefix + "NextOwner" + "Copy", "Modify", and "Transfer"
+ static U32 getNextOwnerPermsInverted(std::string prefix="");
private:
LLFloaterPerms(const LLSD& seed);
+
+};
+
+class LLFloaterPermsDefault : public LLFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ /*virtual*/ BOOL postBuild();
+ void ok();
+ void cancel();
+ void onClickOK();
+ void onClickCancel();
+ void onCommitCopy(const LLSD& user_data);
+ static void sendInitialPerms();
+ static void updateCap();
+ static void setCapSent(bool cap_sent);
+
+// Update instantiation of sCategoryNames in the .cpp file to match if you change this!
+enum Categories
+{
+ CAT_OBJECTS,
+ CAT_UPLOADS,
+ CAT_SCRIPTS,
+ CAT_NOTECARDS,
+ CAT_GESTURES,
+ CAT_WEARABLES,
+ CAT_LAST
+};
+
+private:
+ LLFloaterPermsDefault(const LLSD& seed);
void refresh();
- BOOL // cached values only for implementing cancel.
- mShareWithGroup,
- mEveryoneCopy,
- mNextOwnerCopy,
- mNextOwnerModify,
- mNextOwnerTransfer;
+ static const std::string sCategoryNames[CAT_LAST];
+
+ // cached values only for implementing cancel.
+ bool mShareWithGroup[CAT_LAST];
+ bool mEveryoneCopy[CAT_LAST];
+ bool mNextOwnerCopy[CAT_LAST];
+ bool mNextOwnerModify[CAT_LAST];
+ bool mNextOwnerTransfer[CAT_LAST];
};
#endif
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b50a2e6f85..04b83c0613 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -347,6 +347,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+ mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
sSkin = gSavedSettings.getString("SkinCurrent");
@@ -1188,6 +1189,9 @@ void LLFloaterPreference::refreshEnabledState()
disableUnavailableSettings();
getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
+
+ // Cannot have floater active until caps have been received
+ getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
}
void LLFloaterPreference::disableUnavailableSettings()
@@ -1683,6 +1687,11 @@ void LLFloaterPreference::onClickActionChange()
mClickActionDirty = true;
}
+void LLFloaterPreference::onClickPermsDefault()
+{
+ LLFloaterReg::showInstance("perms_default");
+}
+
void LLFloaterPreference::onDeleteTranscripts()
{
LLSD args;
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index cb180f6f1e..e287631b1a 100755
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -164,6 +164,7 @@ public:
void onClickBlockList();
void onClickProxySettings();
void onClickTranslationSettings();
+ void onClickPermsDefault();
void onClickAutoReplace();
void onClickSpellChecker();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index c28657dbcd..aac3a41b9e 100755
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -232,16 +232,16 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
return continue_filtering;
}
-LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
-{
- return &mInventoryViewModel;
-}
-
-
-const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
-{
- return &mInventoryViewModel;
-}
+//LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+//{
+// return &mInventoryViewModel;
+//}
+//
+//
+//const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+//{
+// return &mInventoryViewModel;
+//}
bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 70ffdc14ff..e8ebd21de4 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1352,7 +1352,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
// IM_SESSION_INVITE means that this is an Ad-hoc incoming chat
// (it can be also Group chat but it is checked above)
// In this case mInitialTargetIDs contains Ad-hoc session ID and it should not be added
- // to Recent People to prevent showing of an item with (???)(???). See EXT-8246.
+ // to Recent People to prevent showing of an item with (?? ?)(?? ?), sans the spaces. See EXT-8246.
// Concrete participants will be added into this list once they sent message in chat.
if (IM_SESSION_INVITE == dialog) return;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 935fe2b4d0..ed7fd3cd34 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -369,15 +369,74 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
mItemLock[cat_id] = false;
}
+void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type)
+{
+ // Make a list of folders that are not "main_id" and are of "type"
+ std::vector<LLUUID> folder_ids;
+ for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit)
+ {
+ LLViewerInventoryCategory* cat = cit->second;
+ if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id))
+ {
+ folder_ids.push_back(cat->getUUID());
+ }
+ }
+
+ // Iterate through those folders
+ for (std::vector<LLUUID>::iterator folder_ids_it = folder_ids.begin(); folder_ids_it != folder_ids.end(); ++folder_ids_it)
+ {
+ LLUUID folder_id = (*folder_ids_it);
+
+ // Get the content of this folder
+ cat_array_t* cats;
+ item_array_t* items;
+ getDirectDescendentsOf(folder_id, cats, items);
+
+ // Move all items to the main folder
+ // Note : we get the list of UUIDs and iterate on them instead of iterating directly on item_array_t
+ // elements. This is because moving elements modify the maps and, consequently, invalidate iterators on them.
+ // This "gather and iterate" method is verbose but resilient.
+ std::vector<LLUUID> list_uuids;
+ for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+ {
+ LLViewerInventoryItem* item = getItem(*it);
+ changeItemParent(item, main_id, TRUE);
+ }
+
+ // Move all folders to the main folder
+ list_uuids.clear();
+ for (cat_array_t::const_iterator it = cats->begin(); it != cats->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+ {
+ LLViewerInventoryCategory* cat = getCategory(*it);
+ changeCategoryParent(cat, main_id, TRUE);
+ }
+
+ // Purge the emptied folder
+ // Note: we'd like to use purgeObject() but it doesn't cleanly eliminate the folder
+ // which leads to issues further down the road when the folder is found again
+ //purgeObject(folder_id);
+ // We remove the folder and empty the trash instead which seems to work
+ removeCategory(folder_id);
+ gInventory.emptyFolderType("", LLFolderType::FT_TRASH);
+ }
+}
+
// findCategoryUUIDForType() returns the uuid of the category that
// specifies 'type' as what it defaults to containing. The category is
// not necessarily only for that type. *NOTE: This will create a new
// inventory category on the fly if one does not exist.
-const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,
+const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,
bool find_in_library*/)
{
LLUUID rv = LLUUID::null;
-
const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();
if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
{
@@ -392,9 +451,9 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
S32 count = cats->count();
for(S32 i = 0; i < count; ++i)
{
- if(cats->get(i)->getPreferredType() == preferred_type)
+ if (cats->get(i)->getPreferredType() == preferred_type)
{
- rv = cats->get(i)->getUUID();
+ rv = cats->get(i)->getUUID();
break;
}
}
@@ -587,7 +646,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
return id;
}
-// Starting with the object specified, add it's descendents to the
+// Starting with the object specified, add its descendents to the
// array provided, but do not add the inventory object specified by
// id. There is no guaranteed order. Neither array will be erased
// before adding objects to it. Do not store a copy of the pointers
@@ -1003,7 +1062,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
new_cat->copyViewerCategory(cat);
addCategory(new_cat);
- // make sure this category is correctly referenced by it's parent.
+ // make sure this category is correctly referenced by its parent.
cat_array_t* cat_array;
cat_array = getUnlockedCatArray(cat->getParentUUID());
if(cat_array)
@@ -1209,12 +1268,6 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
// folders, items, etc in a fairly efficient manner.
void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
{
- EHasChildren children = categoryHasChildren(id);
- if(children == CHILDREN_NO)
- {
- llinfos << "Not purging descendents of " << id << llendl;
- return;
- }
LLPointer<LLViewerInventoryCategory> cat = getCategory(id);
if (cat.notNull())
{
@@ -1225,7 +1278,7 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
<< " iterate and purge non hidden items" << llendl;
cat_array_t* categories;
item_array_t* items;
- // Get the list of direct descendants in tha categoy passed as argument
+ // Get the list of direct descendants in that category passed as argument
getDirectDescendentsOf(id, categories, items);
std::vector<LLUUID> list_uuids;
// Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8aac879a93..544ca5e5dc 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -263,6 +263,11 @@ public:
// Get the inventoryID or item that this item points to, else just return object_id
const LLUUID& getLinkedItemID(const LLUUID& object_id) const;
LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const;
+
+ // Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders
+ // Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories
+ void consolidateForType(const LLUUID& id, LLFolderType::EType type);
+
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 9db175ec2e..16427f2016 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -690,15 +690,24 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
if (!mCategoryMap.size())
return;
+ std::vector<LLUUID> deleted_categories_ids;
+
for (category_map_t::iterator iter = mCategoryMap.begin();
iter != mCategoryMap.end();
++iter)
{
const LLUUID& cat_id = (*iter).first;
-
+ LLCategoryData& cat_data = (*iter).second;
+
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
if (!category)
+ {
+ llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl;
+ cat_data.mCallback();
+ // Keep track of those deleted categories so we can remove them
+ deleted_categories_ids.push_back(cat_id);
continue;
+ }
const S32 version = category->getVersion();
const S32 expected_num_descendents = category->getDescendentCount();
@@ -726,8 +735,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
const S32 current_num_known_descendents = cats->count() + items->count();
- LLCategoryData& cat_data = (*iter).second;
-
bool cat_changed = false;
// If category version or descendents count has changed
@@ -757,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
if (cat_changed)
cat_data.mCallback();
}
+
+ // Remove deleted categories from the list
+ for (std::vector<LLUUID>::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id)
+ {
+ removeCategory(*deleted_id);
+ }
}
bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e5b9e11d48..81ee7ac07e 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -137,7 +137,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
LLPanel(p),
mInventoryObserver(NULL),
mCompletionObserver(NULL),
- mFolderRoot(NULL),
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
mInventory(p.inventory),
@@ -196,6 +195,32 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
return LLUICtrlFactory::create<LLFolderView>(p);
}
+void LLInventoryPanel::clearFolderRoot()
+{
+ gIdleCallbacks.deleteFunction(idle, this);
+ gIdleCallbacks.deleteFunction(onIdle, this);
+
+ if (mInventoryObserver)
+ {
+ mInventory->removeObserver(mInventoryObserver);
+ delete mInventoryObserver;
+ mInventoryObserver = NULL;
+ }
+ if (mCompletionObserver)
+ {
+ mInventory->removeObserver(mCompletionObserver);
+ delete mCompletionObserver;
+ mCompletionObserver = NULL;
+ }
+
+ if (mScroller)
+ {
+ removeChild(mScroller);
+ delete mScroller;
+ mScroller = NULL;
+ }
+}
+
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
// save off copy of params
@@ -203,23 +228,23 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
// Clear up the root view
// Note: This needs to be done *before* we build the new folder view
LLUUID root_id = getRootFolderID();
- if (mFolderRoot)
+ if (mFolderRoot.get())
{
removeItemID(root_id);
- mFolderRoot->destroyView();
- mFolderRoot = NULL;
+ mFolderRoot.get()->destroyView();
}
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
{
// Determine the root folder in case specified, and
// build the views starting with that folder.
- mFolderRoot = createFolderRoot(root_id);
+ LLFolderView* folder_view = createFolderRoot(root_id);
+ mFolderRoot = folder_view->getHandle();
- addItemID(root_id, mFolderRoot);
+ addItemID(root_id, mFolderRoot.get());
}
mCommitCallbackRegistrar.popScope();
- mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
// Scroller
LLRect scroller_view_rect = getRect();
@@ -228,10 +253,10 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
scroller_params.rect(scroller_view_rect);
mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
addChild(mScroller);
- mScroller->addChild(mFolderRoot);
- mFolderRoot->setScrollContainer(mScroller);
- mFolderRoot->setFollowsAll();
- mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
+ mScroller->addChild(mFolderRoot.get());
+ mFolderRoot.get()->setScrollContainer(mScroller);
+ mFolderRoot.get()->setFollowsAll();
+ mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);
// Set up the callbacks from the inventory we're viewing, and then build everything.
mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -259,8 +284,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
}
// hide inbox
- getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
- getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+ if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible"))
+ {
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+ }
// set the filter for the empty folder if the debug setting is on
if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
@@ -277,23 +305,13 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
LLInventoryPanel::~LLInventoryPanel()
{
- gIdleCallbacks.deleteFunction(idle, this);
-
U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
- if (mSortOrderSetting != INHERIT_SORT_ORDER)
- {
- gSavedSettings.setU32(mSortOrderSetting, sort_order);
- }
-
- gIdleCallbacks.deleteFunction(onIdle, this);
-
- // LLView destructor will take care of the sub-views.
- mInventory->removeObserver(mInventoryObserver);
- mInventory->removeObserver(mCompletionObserver);
- delete mInventoryObserver;
- delete mCompletionObserver;
-
- mScroller = NULL;
+ if (mSortOrderSetting != INHERIT_SORT_ORDER)
+ {
+ gSavedSettings.setU32(mSortOrderSetting, sort_order);
+ }
+
+ clearFolderRoot();
}
void LLInventoryPanel::draw()
@@ -360,9 +378,9 @@ void LLInventoryPanel::setSortOrder(U32 order)
if (order != getFolderViewModel()->getSorter().getSortOrder())
{
getFolderViewModel()->setSorter(sorter);
- mFolderRoot->arrangeAll();
+ mFolderRoot.get()->arrangeAll();
// try to keep selection onscreen, even if it wasn't to start with
- mFolderRoot->scrollToShowSelection();
+ mFolderRoot.get()->scrollToShowSelection();
}
}
@@ -505,7 +523,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
// Add the UI element for this item.
buildNewViews(item_id);
// Select any newly created object that has the auto rename at top of folder root set.
- if(mFolderRoot->getRoot()->needsAutoRename())
+ if(mFolderRoot.get()->getRoot()->needsAutoRename())
{
setSelection(item_id, FALSE);
}
@@ -556,17 +574,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
}
}
-LLFolderView* LLInventoryPanel::getRootFolder()
-{
- return mFolderRoot;
-}
-
LLUUID LLInventoryPanel::getRootFolderID()
{
- if (mFolderRoot && mFolderRoot->getViewModelItem())
+ if (mFolderRoot.get() && mFolderRoot.get()->getViewModelItem())
{
- return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
-
+ return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot.get()->getViewModelItem())->getUUID();
}
else
{
@@ -587,6 +599,9 @@ LLUUID LLInventoryPanel::getRootFolderID()
}
else if (preferred_type != LLFolderType::FT_NONE)
{
+ LLStringExplicit label(mParams.start_folder.name());
+ setLabel(label);
+
root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
if (root_id.isNull())
{
@@ -646,24 +661,33 @@ void LLInventoryPanel::idle(void* user_data)
}
- panel->mFolderRoot->update();
- // while dragging, update selection rendering to reflect single/multi drag status
- if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
- {
- EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
- if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
- {
- panel->mFolderRoot->setShowSingleSelection(TRUE);
- }
- else
- {
- panel->mFolderRoot->setShowSingleSelection(FALSE);
- }
-}
- else
- {
- panel->mFolderRoot->setShowSingleSelection(FALSE);
- }
+ // Take into account the fact that the root folder might be invalidated
+ if (panel->mFolderRoot.get())
+ {
+ panel->mFolderRoot.get()->update();
+ // while dragging, update selection rendering to reflect single/multi drag status
+ if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+ {
+ EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+ if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+ {
+ panel->mFolderRoot.get()->setShowSingleSelection(TRUE);
+ }
+ else
+ {
+ panel->mFolderRoot.get()->setShowSingleSelection(FALSE);
+ }
+ }
+ else
+ {
+ panel->mFolderRoot.get()->setShowSingleSelection(FALSE);
+ }
+ }
+ else
+ {
+ llwarns << "Inventory : Deleted folder root detected on panel" << llendl;
+ panel->clearFolderRoot();
+ }
}
@@ -714,7 +738,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
LLFolderViewFolder::Params params(mParams.folder);
params.name = bridge->getDisplayName();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.tool_tip = params.name;
@@ -730,7 +754,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
params.name = bridge->getDisplayName();
params.creation_date = bridge->getCreationDate();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
@@ -771,7 +795,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
LLInventoryType::IT_CATEGORY,
this,
&mInventoryViewModel,
- mFolderRoot,
+ mFolderRoot.get(),
objectp->getUUID());
if (new_listener)
{
@@ -787,7 +811,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
item->getInventoryType(),
this,
&mInventoryViewModel,
- mFolderRoot,
+ mFolderRoot.get(),
item->getUUID(),
item->getFlags());
@@ -844,7 +868,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
void LLInventoryPanel::openStartFolderOrMyInventory()
{
// Find My Inventory folder and open it up by name
- for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
+ for (LLView *child = mFolderRoot.get()->getFirstChild(); child; child = mFolderRoot.get()->findNextSibling(child))
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
@@ -859,12 +883,12 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
void LLInventoryPanel::onItemsCompletion()
{
- if (mFolderRoot) mFolderRoot->updateMenu();
+ if (mFolderRoot.get()) mFolderRoot.get()->updateMenu();
}
void LLInventoryPanel::openSelected()
{
- LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
+ LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem();
if(!folder_item) return;
LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
if(!bridge) return;
@@ -873,7 +897,7 @@ void LLInventoryPanel::openSelected()
void LLInventoryPanel::unSelectAll()
{
- mFolderRoot->setSelection(NULL, FALSE, FALSE);
+ mFolderRoot.get()->setSelection(NULL, FALSE, FALSE);
}
@@ -911,14 +935,14 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// If folder view is empty the (x, y) point won't be in its rect
// so the handler must be called explicitly.
// but only if was not handled before. See EXT-6746.
- if (!handled && !mFolderRoot->hasVisibleChildren())
+ if (!handled && !mFolderRoot.get()->hasVisibleChildren())
{
- handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
if (handled)
{
- mFolderRoot->setDragAndDropThisFrame();
+ mFolderRoot.get()->setDragAndDropThisFrame();
}
}
@@ -928,7 +952,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLInventoryPanel::onFocusLost()
{
// inventory no longer handles cut/copy/paste/delete
- if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot)
+ if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot.get())
{
LLEditMenuHandler::gEditMenuHandler = NULL;
}
@@ -939,7 +963,7 @@ void LLInventoryPanel::onFocusLost()
void LLInventoryPanel::onFocusReceived()
{
// inventory now handles cut/copy/paste/delete
- LLEditMenuHandler::gEditMenuHandler = mFolderRoot;
+ LLEditMenuHandler::gEditMenuHandler = mFolderRoot.get();
LLPanel::onFocusReceived();
}
@@ -950,7 +974,7 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
if (acceptsBadge())
{
- badge_added = badge->addToView(mFolderRoot);
+ badge_added = badge->addToView(mFolderRoot.get());
}
return badge_added;
@@ -958,8 +982,8 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
void LLInventoryPanel::openAllFolders()
{
- mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
- mFolderRoot->arrangeAll();
+ mFolderRoot.get()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
+ mFolderRoot.get()->arrangeAll();
}
void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
@@ -975,9 +999,9 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
{
- if (mFolderRoot)
+ if (mFolderRoot.get())
{
- mFolderRoot->setSelectCallback(cb);
+ mFolderRoot.get()->setSelectCallback(cb);
}
}
@@ -1001,7 +1025,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
}
}
- LLFolderView* fv = getRootFolder();
+ LLFolderView* fv = mFolderRoot.get();
if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
{
fv->setNeedsAutoRename(FALSE);
@@ -1020,7 +1044,7 @@ void LLInventoryPanel::doCreate(const LLSD& userdata)
bool LLInventoryPanel::beginIMSession()
{
- std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();
std::string name;
@@ -1114,7 +1138,7 @@ bool LLInventoryPanel::beginIMSession()
bool LLInventoryPanel::attachObject(const LLSD& userdata)
{
// Copy selected item UUIDs to a vector.
- std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();
uuid_vec_t items;
for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
set_iter != selected_items.end();
@@ -1141,7 +1165,7 @@ BOOL LLInventoryPanel::getSinceLogoff()
void LLInventoryPanel::dumpSelectionInformation(void* user_data)
{
LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
- iv->mFolderRoot->dumpSelectionInformation();
+ iv->mFolderRoot.get()->dumpSelectionInformation();
}
BOOL is_inventorysp_active()
@@ -1343,7 +1367,7 @@ void LLInventoryPanel::updateSelection()
void LLInventoryPanel::doToSelected(const LLSD& userdata)
{
- LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), userdata.asString());
return;
}
@@ -1357,7 +1381,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
// Open selected items if enter key hit on the inventory panel
if (mask == MASK_NONE)
{
- LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "open");
handled = TRUE;
}
break;
@@ -1367,7 +1391,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
// Note: on Mac laptop keyboards, backspace and delete are one and the same
if (isSelectionRemovable() && (mask == MASK_NONE))
{
- LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "delete");
handled = TRUE;
}
break;
@@ -1378,9 +1402,9 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
bool LLInventoryPanel::isSelectionRemovable()
{
bool can_delete = false;
- if (mFolderRoot)
+ if (mFolderRoot.get())
{
- std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selection_set = mFolderRoot.get()->getSelectionList();
if (!selection_set.empty())
{
can_delete = true;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 00a90325ad..c0ce513694 100755
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -181,7 +181,7 @@ public:
LLInventoryFilter::EFolderShow getShowFolderState();
// This method is called when something has changed about the inventory.
void modelChanged(U32 mask);
- LLFolderView* getRootFolder();
+ LLFolderView* getRootFolder() { return mFolderRoot.get(); }
LLUUID getRootFolderID();
LLScrollContainer* getScrollableContainer() { return mScroller; }
@@ -217,8 +217,11 @@ public:
void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
void updateSelection();
- LLFolderViewModelInventory* getFolderViewModel();
- const LLFolderViewModelInventory* getFolderViewModel() const;
+ LLFolderViewModelInventory* getFolderViewModel() { return &mInventoryViewModel; }
+ const LLFolderViewModelInventory* getFolderViewModel() const { return &mInventoryViewModel; }
+
+ // Clean up stuff when the folder root gets deleted
+ void clearFolderRoot();
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
@@ -233,7 +236,7 @@ protected:
bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons
bool mShowEmptyMessage;
- LLFolderView* mFolderRoot;
+ LLHandle<LLFolderView> mFolderRoot;
LLScrollContainer* mScroller;
LLFolderViewModelInventory mInventoryViewModel;
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 4cbdfde868..bd21d04b4a 100755
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -61,6 +61,7 @@
#include "llglheaders.h"
#include "lltrans.h"
#include "llvoavatarself.h"
+#include "llhudrender.h"
const F32 RADIUS_PIXELS = 100.f; // size in screen space
const F32 SQ_RADIUS = RADIUS_PIXELS * RADIUS_PIXELS;
@@ -452,6 +453,9 @@ BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
// Route future Mouse messages here preemptively. (Release on mouse up.)
setMouseCapture( TRUE );
LLSelectMgr::getInstance()->enableSilhouette(FALSE);
+
+ mHelpTextTimer.reset();
+ sNumTimesHelpTextShown++;
return TRUE;
}
@@ -1111,6 +1115,31 @@ void LLManipRotate::renderSnapGuides()
}
}
}
+
+
+ // render help text
+ if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
+ {
+ LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
+
+ LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis();
+
+ F32 line_alpha = gSavedSettings.getF32("GridOpacity");
+
+ LLVector3 help_text_pos = selection_center_start + (mRadiusMeters * 3.f * offset_dir);
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+
+ std::string help_text = LLTrans::getString("manip_hint1");
+ LLColor4 help_text_color = LLColor4::white;
+ help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
+ help_text_pos -= offset_dir * mRadiusMeters * 0.4f;
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ }
+ }
}
// Returns TRUE if center of sphere is visible. Also sets a bunch of member variables that are used later (e.g. mCenterToCam)
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index ae0884ac5d..6dc03d8382 100755
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -59,7 +59,7 @@
#include "v2math.h"
#include "llvoavatar.h"
#include "llmeshrepository.h"
-
+#include "lltrans.h"
const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f;
const F32 SNAP_GUIDE_SCREEN_OFFSET = 0.05f;
@@ -68,7 +68,7 @@ const F32 SELECTED_MANIPULATOR_SCALE = 1.2f;
const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f;
const S32 NUM_MANIPULATORS = 14;
-const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] =
+const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] =
{
LLManip::LL_CORNER_NNN,
LLManip::LL_CORNER_NNP,
@@ -87,7 +87,7 @@ const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] =
};
-F32 get_default_max_prim_scale(bool is_flora)
+F32 get_default_max_prim_scale(bool is_flora)
{
// a bit of a hack, but if it's foilage, we don't want to use the
// new larger scale which would result in giant trees and grass
@@ -97,7 +97,7 @@ F32 get_default_max_prim_scale(bool is_flora)
return DEFAULT_MAX_PRIM_SCALE;
}
else
- {
+ {
return DEFAULT_MAX_PRIM_SCALE_NO_MESH;
}
}
@@ -179,7 +179,7 @@ void LLManipScale::handleSelect()
}
LLManipScale::LLManipScale( LLToolComposite* composite )
- :
+ :
LLManip( std::string("Scale"), composite ),
mBoxHandleSize( 1.f ),
mScaledBoxHandleSize( 1.f ),
@@ -190,10 +190,12 @@ LLManipScale::LLManipScale( LLToolComposite* composite )
mScaleSnapUnit1(1.f),
mScaleSnapUnit2(1.f),
mSnapRegimeOffset(0.f),
+ mTickPixelSpacing1(0.f),
+ mTickPixelSpacing2(0.f),
mSnapGuideLength(0.f),
- mInSnapRegime(FALSE),
- mScaleSnapValue(0.f)
-{
+ mSnapRegime(SNAP_REGIME_NONE),
+ mScaleSnappedValue(0.f)
+{
mManipulatorScales = new F32[NUM_MANIPULATORS];
for (S32 i = 0; i < NUM_MANIPULATORS; i++)
{
@@ -214,7 +216,7 @@ void LLManipScale::render()
LLGLDepthTest gls_depth(GL_TRUE);
LLGLEnable gl_blend(GL_BLEND);
LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
-
+
if( canAffectSelection() )
{
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -226,11 +228,11 @@ void LLManipScale::render()
}
////////////////////////////////////////////////////////////////////////
- // Calculate size of drag handles
+ // Calculate size of drag handles
const F32 BOX_HANDLE_BASE_SIZE = 50.0f; // box size in pixels = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR
const F32 BOX_HANDLE_BASE_FACTOR = 0.2f;
-
+
LLVector3 center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal());
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
@@ -283,7 +285,7 @@ void LLManipScale::render()
rot.getAngleAxis(&angle_radians, &x, &y, &z);
gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
+
{
LLGLEnable poly_offset(GL_POLYGON_OFFSET_FILL);
glPolygonOffset( -2.f, -2.f);
@@ -345,7 +347,7 @@ BOOL LLManipScale::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
LLVector3 box_center_agent = bbox.getCenterAgent();
LLVector3 box_corner_agent = bbox.localToAgent( unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ) );
-
+
updateSnapGuides(bbox);
mDragStartPointGlobal = gAgent.getPosGlobalFromAgent(box_corner_agent);
@@ -372,27 +374,27 @@ BOOL LLManipScale::handleMouseUp(S32 x, S32 y, MASK mask)
if( hasMouseCapture() )
{
- if( (LL_FACE_MIN <= (S32)mManipPart)
+ if( (LL_FACE_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_FACE_MAX) )
{
sendUpdates(TRUE,TRUE,FALSE);
}
else
- if( (LL_CORNER_MIN <= (S32)mManipPart)
+ if( (LL_CORNER_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_CORNER_MAX) )
{
sendUpdates(TRUE,TRUE,TRUE);
}
-
+
//send texture update
LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, getStretchTextures());
-
+
LLSelectMgr::getInstance()->enableSilhouette(TRUE);
mManipPart = LL_NO_PART;
// Might have missed last update due to UPDATE_DELAY timing
LLSelectMgr::getInstance()->sendMultipleUpdate( mLastUpdateFlags );
-
+
//gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject"));
LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
}
@@ -413,15 +415,15 @@ BOOL LLManipScale::handleHover(S32 x, S32 y, MASK mask)
{
drag( x, y );
}
- lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipScale (active)" << llendl;
+ lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipScale (active)" << llendl;
}
else
{
- mInSnapRegime = FALSE;
+ mSnapRegime = SNAP_REGIME_NONE;
// not dragging...
highlightManipulators(x, y);
}
-
+
// Patch up textures, if possible.
LLSelectMgr::getInstance()->adjustTexturesByScale(FALSE, getStretchTextures());
@@ -458,7 +460,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection();
LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview();
transform.initAll(LLVector3(1.f, 1.f, 1.f), bbox.getRotation(), bbox.getPositionAgent());
-
+
transform *= modelView;
transform *= projMatrix;
}
@@ -477,7 +479,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
mManipulatorVertices[numManips++] = LLVector4(max.mV[VX], min.mV[VY], max.mV[VZ], 1.f);
mManipulatorVertices[numManips++] = LLVector4(max.mV[VX], max.mV[VY], min.mV[VZ], 1.f);
mManipulatorVertices[numManips++] = LLVector4(max.mV[VX], max.mV[VY], max.mV[VZ], 1.f);
-
+
// 1-D highlights are applicable iff one object is selected
if( mObjectSelection->getObjectCount() == 1 )
{
@@ -492,13 +494,13 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer());
mProjectedManipulators.clear();
-
+
for (S32 i = 0; i < numManips; i++)
{
LLVector4 projectedVertex = mManipulatorVertices[i] * transform;
projectedVertex = projectedVertex * (1.f / projectedVertex.mV[VW]);
- ManipulatorHandle* projManipulator = new ManipulatorHandle(LLVector3(projectedVertex.mV[VX], projectedVertex.mV[VY],
+ ManipulatorHandle* projManipulator = new ManipulatorHandle(LLVector3(projectedVertex.mV[VX], projectedVertex.mV[VY],
projectedVertex.mV[VZ]), MANIPULATOR_IDS[i], (i < 7) ? SCALE_MANIP_CORNER : SCALE_MANIP_FACE);
mProjectedManipulators.insert(projManipulator);
}
@@ -512,13 +514,13 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
mHighlightedPart = LL_NO_PART;
- for (minpulator_list_t::iterator iter = mProjectedManipulators.begin();
+ for (manipulator_list_t::iterator iter = mProjectedManipulators.begin();
iter != mProjectedManipulators.end(); ++iter)
{
ManipulatorHandle* manipulator = *iter;
{
- manip2d.setVec(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height);
-
+ manip2d.set(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height);
+
delta = manip2d - mousePos;
if (delta.magVecSquared() < MAX_MANIP_SELECT_DISTANCE_SQUARED)
{
@@ -549,36 +551,36 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
void LLManipScale::renderFaces( const LLBBox& bbox )
{
- // Don't bother to render the drag handles for 1-D scaling if
+ // Don't bother to render the drag handles for 1-D scaling if
// more than one object is selected or if it is an attachment
if ( mObjectSelection->getObjectCount() > 1 )
{
return;
}
- // This is a flattened representation of the box as render here
- // .
- // (+++) (++-) /|\t
- // +------------+ | (texture coordinates)
- // | | |
- // | 1 | (*) --->s
- // | +X |
+ // This is a flattened representation of the box as render here
+ // .
+ // (+++) (++-) /|\t
+ // +------------+ | (texture coordinates)
+ // | | |
+ // | 1 | (*) --->s
+ // | +X |
// | |
- // (+++) (+-+)| |(+--) (++-) (+++)
- // +------------+------------+------------+------------+
- // |0 3|3 7|7 4|4 0|
- // | 0 | 4 | 5 | 2 |
- // | +Z | -Y | -Z | +Y |
- // | | | | |
- // |1 2|2 6|6 5|5 1|
- // +------------+------------+------------+------------+
- // (-++) (--+)| |(---) (-+-) (-++)
- // | 3 |
- // | -X |
- // | |
- // | |
- // +------------+
- // (-++) (-+-)
+ // (+++) (+-+)| |(+--) (++-) (+++)
+ // +------------+------------+------------+------------+
+ // |0 3|3 7|7 4|4 0|
+ // | 0 | 4 | 5 | 2 |
+ // | +Z | -Y | -Z | +Y |
+ // | | | | |
+ // |1 2|2 6|6 5|5 1|
+ // +------------+------------+------------+------------+
+ // (-++) (--+)| |(---) (-+-) (-++)
+ // | 3 |
+ // | -X |
+ // | |
+ // | |
+ // +------------+
+ // (-++) (-+-)
LLColor4 highlight_color( 1.f, 1.f, 1.f, 0.5f);
LLColor4 normal_color( 1.f, 1.f, 1.f, 0.3f);
@@ -602,7 +604,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
{
gGL.color4fv( default_normal_color.mV );
LLGLDepthTest gls_depth(GL_FALSE);
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::QUADS);
{
// Face 0
gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]);
@@ -645,9 +647,9 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
// Find nearest vertex
LLVector3 orientWRTHead = bbox.agentToLocalBasis( bbox.getCenterAgent() - gAgentCamera.getCameraPositionAgent() );
- U32 nearest =
- (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
- (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
+ U32 nearest =
+ (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
+ (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
(orientWRTHead.mV[2] < 0.0f ? 4 : 0);
// opposite faces on Linden cubes:
@@ -656,7 +658,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
// 2 & 4
// Table of order to draw faces, based on nearest vertex
- static U32 face_list[8][6] = {
+ static U32 face_list[8][6] = {
{ 2,0,1, 4,5,3 }, // v6 F201 F453
{ 2,0,3, 4,5,1 }, // v7 F203 F451
{ 4,0,1, 2,5,3 }, // v5 F401 F253
@@ -723,7 +725,7 @@ void LLManipScale::renderEdges( const LLBBox& bbox )
{
gGL.translatef( center_to_edge.mV[0], center_to_edge.mV[1], center_to_edge.mV[2] );
conditionalHighlight( part );
- gGL.scalef(
+ gGL.scalef(
direction.mV[0] ? edge_width : extent.mV[VX],
direction.mV[1] ? edge_width : extent.mV[VY],
direction.mV[2] ? edge_width : extent.mV[VZ] );
@@ -757,7 +759,7 @@ void LLManipScale::renderCorners( const LLBBox& bbox )
y_offset = bbox.getMaxLocal().mV[VY];
}
x_offset = bbox.getMaxLocal().mV[VX];
- }
+ }
}
@@ -782,7 +784,7 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
{
// Draws a single "jacks" style handle: a long, retangular box from start to end.
LLVector3 offset_start = end - start;
- offset_start.normVec();
+ offset_start.normalize();
offset_start = start + mBoxHandleSize * offset_start;
LLVector3 delta = end - offset_start;
@@ -791,7 +793,7 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
gGL.pushMatrix();
{
gGL.translatef( pos.mV[VX], pos.mV[VY], pos.mV[VZ] );
- gGL.scalef(
+ gGL.scalef(
mBoxHandleSize + llabs(delta.mV[VX]),
mBoxHandleSize + llabs(delta.mV[VY]),
mBoxHandleSize + llabs(delta.mV[VZ]));
@@ -805,21 +807,20 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
}
}
-
+// General scale call
void LLManipScale::drag( S32 x, S32 y )
{
- if( (LL_FACE_MIN <= (S32)mManipPart)
+ if( (LL_FACE_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_FACE_MAX) )
{
dragFace( x, y );
}
- else
- if( (LL_CORNER_MIN <= (S32)mManipPart)
+ else if( (LL_CORNER_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_CORNER_MAX) )
{
dragCorner( x, y );
}
-
+
// store changes to override updates
for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++)
@@ -834,139 +835,110 @@ void LLManipScale::drag( S32 x, S32 y )
selectNode->mLastScale = cur->getScale();
selectNode->mLastPositionLocal = cur->getPosition();
}
- }
+ }
LLSelectMgr::getInstance()->updateSelectionCenter();
- gAgentCamera.clearFocusObject();
+ gAgentCamera.clearFocusObject();
}
-// Scale around the
+// Scale on three axis simultaneously
void LLManipScale::dragCorner( S32 x, S32 y )
{
- LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
-
// Suppress scale if mouse hasn't moved.
if (x == mLastMouseX && y == mLastMouseY)
{
- // sendUpdates(TRUE,TRUE,TRUE);
return;
}
mLastMouseX = x;
mLastMouseY = y;
- LLVector3d drag_start_point_global = mDragStartPointGlobal;
- LLVector3d drag_start_center_global = mDragStartCenterGlobal;
- LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(drag_start_point_global);
- LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global);
+ LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(mDragStartPointGlobal);
+ LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(mDragStartCenterGlobal);
LLVector3d drag_start_dir_d;
- drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global);
- LLVector3 drag_start_dir_f;
- drag_start_dir_f.setVec(drag_start_dir_d);
+ drag_start_dir_d.set(mDragStartPointGlobal - mDragStartCenterGlobal);
F32 s = 0;
F32 t = 0;
- nearestPointOnLineFromMouse(x, y,
- drag_start_center_agent,
- drag_start_point_agent,
- s, t );
-
- F32 drag_start_dist = dist_vec(drag_start_point_agent, drag_start_center_agent);
+ nearestPointOnLineFromMouse(x, y,
+ drag_start_center_agent,
+ drag_start_point_agent,
+ s, t );
if( s <= 0 ) // we only care about intersections in front of the camera
{
return;
}
+ mDragPointGlobal = lerp(mDragStartCenterGlobal, mDragStartPointGlobal, t);
- LLVector3d drag_point_global = drag_start_center_global + t * drag_start_dir_d;
-
- F32 scale_factor = t;
-
- BOOL uniform = LLManipScale::getUniform();
-
- if( !uniform )
- {
- scale_factor = 0.5f + (scale_factor * 0.5f);
- }
+ LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
+ F32 scale_factor = 1.f;
+ F32 max_scale = partToMaxScale(mManipPart, bbox);
+ F32 min_scale = partToMinScale(mManipPart, bbox);
+ BOOL uniform = LLManipScale::getUniform();
// check for snapping
- LLVector3 drag_center_agent = gAgent.getPosAgentFromGlobal(drag_point_global);
LLVector3 mouse_on_plane1;
- getMousePointOnPlaneAgent(mouse_on_plane1, x, y, drag_center_agent, mScalePlaneNormal1);
- LLVector3 mouse_on_plane2;
- getMousePointOnPlaneAgent(mouse_on_plane2, x, y, drag_center_agent, mScalePlaneNormal2);
- LLVector3 mouse_dir_1 = mouse_on_plane1 - mScaleCenter;
- LLVector3 mouse_dir_2 = mouse_on_plane2 - mScaleCenter;
- LLVector3 mouse_to_scale_line_1 = mouse_dir_1 - projected_vec(mouse_dir_1, mScaleDir);
- LLVector3 mouse_to_scale_line_2 = mouse_dir_2 - projected_vec(mouse_dir_2, mScaleDir);
- LLVector3 mouse_to_scale_line_dir_1 = mouse_to_scale_line_1;
- mouse_to_scale_line_dir_1.normVec();
- if (mouse_to_scale_line_dir_1 * mSnapGuideDir1 < 0.f)
- {
- // need to keep sign of mouse offset wrt to snap guide direction
- mouse_to_scale_line_dir_1 *= -1.f;
- }
- LLVector3 mouse_to_scale_line_dir_2 = mouse_to_scale_line_2;
- mouse_to_scale_line_dir_2.normVec();
- if (mouse_to_scale_line_dir_2 * mSnapGuideDir2 < 0.f)
- {
- // need to keep sign of mouse offset wrt to snap guide direction
- mouse_to_scale_line_dir_2 *= -1.f;
- }
-
- F32 snap_dir_dot_mouse_offset1 = mSnapGuideDir1 * mouse_to_scale_line_dir_1;
- F32 snap_dir_dot_mouse_offset2 = mSnapGuideDir2 * mouse_to_scale_line_dir_2;
+ getMousePointOnPlaneAgent(mouse_on_plane1, x, y, mScaleCenter, mScalePlaneNormal1);
+ mouse_on_plane1 -= mScaleCenter;
- F32 dist_from_scale_line_1 = mouse_to_scale_line_1 * mouse_to_scale_line_dir_1;
- F32 dist_from_scale_line_2 = mouse_to_scale_line_2 * mouse_to_scale_line_dir_2;
+ LLVector3 mouse_on_plane2;
+ getMousePointOnPlaneAgent(mouse_on_plane2, x, y, mScaleCenter, mScalePlaneNormal2);
+ mouse_on_plane2 -= mScaleCenter;
- F32 max_scale = partToMaxScale(mManipPart, bbox);
- F32 min_scale = partToMinScale(mManipPart, bbox);
+ LLVector3 projected_drag_pos1 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane1, mSnapGuideDir1));
+ LLVector3 projected_drag_pos2 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane2, mSnapGuideDir2));
BOOL snap_enabled = gSavedSettings.getBOOL("SnapEnabled");
- if (snap_enabled && dist_from_scale_line_1 > mSnapRegimeOffset * snap_dir_dot_mouse_offset1)
+ if (snap_enabled && (mouse_on_plane1 - projected_drag_pos1) * mSnapGuideDir1 > mSnapRegimeOffset)
{
- mInSnapRegime = TRUE;
- LLVector3 projected_drag_pos = mouse_on_plane1 - (dist_from_scale_line_1 / snap_dir_dot_mouse_offset1) * mSnapGuideDir1;
- F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir;
+ F32 drag_dist = mScaleDir * projected_drag_pos1; // Projecting the drag position allows for negative results, vs using the length which will result in a "reverse scaling" bug.
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + projected_drag_pos1, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions);
F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions);
- mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ mScaleSnappedValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ scale_factor = mScaleSnappedValue / dist_vec(drag_start_point_agent, drag_start_center_agent);
+ mScaleSnappedValue /= mScaleSnapUnit1 * 2.f;
+ mSnapRegime = SNAP_REGIME_UPPER;
- scale_factor = mScaleSnapValue / drag_start_dist;
- if( !uniform )
+ if (!uniform)
{
scale_factor *= 0.5f;
}
}
- else if (snap_enabled && dist_from_scale_line_2 > mSnapRegimeOffset * snap_dir_dot_mouse_offset2)
+ else if (snap_enabled && (mouse_on_plane2 - projected_drag_pos2) * mSnapGuideDir2 > mSnapRegimeOffset )
{
- mInSnapRegime = TRUE;
- LLVector3 projected_drag_pos = mouse_on_plane2 - (dist_from_scale_line_2 / snap_dir_dot_mouse_offset2) * mSnapGuideDir2;
- F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir;
+ F32 drag_dist = mScaleDir * projected_drag_pos2; // Projecting the drag position allows for negative results, vs using the length which will result in a "reverse scaling" bug.
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + projected_drag_pos2, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
F32 snap_dist = mScaleSnapUnit2 / (2.f * cur_subdivisions);
F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit2 / cur_subdivisions);
- mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ mScaleSnappedValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ scale_factor = mScaleSnappedValue / dist_vec(drag_start_point_agent, drag_start_center_agent);
+ mScaleSnappedValue /= mScaleSnapUnit2 * 2.f;
+ mSnapRegime = SNAP_REGIME_LOWER;
- scale_factor = mScaleSnapValue / drag_start_dist;
- if( !uniform )
+ if (!uniform)
{
scale_factor *= 0.5f;
}
}
- else
+ else
{
- mInSnapRegime = FALSE;
+ mSnapRegime = SNAP_REGIME_NONE;
+ scale_factor = t;
+ if (!uniform)
+ {
+ scale_factor = 0.5f + (scale_factor * 0.5f);
+ }
}
+
F32 max_scale_factor = get_default_max_prim_scale() / MIN_PRIM_SCALE;
F32 min_scale_factor = MIN_PRIM_SCALE / get_default_max_prim_scale();
@@ -1008,7 +980,7 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
const LLVector3& scale = selectNode->mSavedScale;
cur->setScale( scale_factor * scale );
-
+
LLVector3 delta_pos;
LLVector3 original_pos = cur->getPositionEdit();
LLVector3d new_pos_global = drag_global + (selectNode->mSavedPositionGlobal - drag_global) * scale_factor;
@@ -1018,7 +990,7 @@ void LLManipScale::dragCorner( S32 x, S32 y )
}
cur->setPositionAbsoluteGlobal( new_pos_global );
rebuild(cur);
-
+
delta_pos = cur->getPositionEdit() - original_pos;
if (selectNode->mIndividualSelection)
@@ -1059,7 +1031,7 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
const LLVector3& scale = selectNode->mSavedScale;
cur->setScale( scale_factor * scale, FALSE );
-
+
if (!selectNode->mIndividualSelection)
{
cur->setPosition(selectNode->mSavedPositionLocal * scale_factor);
@@ -1068,19 +1040,14 @@ void LLManipScale::dragCorner( S32 x, S32 y )
rebuild(cur);
}
}
-
-
-
- mDragPointGlobal = drag_point_global;
}
-
+// Scale on a single axis
void LLManipScale::dragFace( S32 x, S32 y )
{
// Suppress scale if mouse hasn't moved.
if (x == mLastMouseX && y == mLastMouseY)
{
- // sendUpdates(TRUE,TRUE,FALSE);
return;
}
@@ -1093,9 +1060,9 @@ void LLManipScale::dragFace( S32 x, S32 y )
LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global);
LLVector3d drag_start_dir_d;
- drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global);
+ drag_start_dir_d.set(drag_start_point_global - drag_start_center_global);
LLVector3 drag_start_dir_f;
- drag_start_dir_f.setVec(drag_start_dir_d);
+ drag_start_dir_f.set(drag_start_dir_d);
LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
@@ -1139,26 +1106,26 @@ void LLManipScale::dragFace( S32 x, S32 y )
if (snap_enabled && dist_from_scale_line > mSnapRegimeOffset)
{
- mInSnapRegime = TRUE;
+ mSnapRegime = static_cast<ESnapRegimes>(SNAP_REGIME_UPPER | SNAP_REGIME_LOWER); // A face drag doesn't have split regimes.
- if (dist_along_scale_line > max_drag_dist)
+ if (dist_along_scale_line > max_drag_dist)
{
- mScaleSnapValue = max_drag_dist;
+ mScaleSnappedValue = max_drag_dist;
LLVector3 clamp_point = mScaleCenter + max_drag_dist * mScaleDir;
- drag_delta.setVec(clamp_point - drag_start_point_agent);
+ drag_delta.set(clamp_point - drag_start_point_agent);
}
else if (dist_along_scale_line < min_drag_dist)
{
- mScaleSnapValue = min_drag_dist;
+ mScaleSnappedValue = min_drag_dist;
LLVector3 clamp_point = mScaleCenter + min_drag_dist * mScaleDir;
- drag_delta.setVec(clamp_point - drag_start_point_agent);
+ drag_delta.set(clamp_point - drag_start_point_agent);
}
else
{
F32 drag_dist = scale_center_to_mouse * mScaleDir;
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + mScaleDir * drag_dist, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + mScaleDir * drag_dist, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions);
F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions);
relative_snap_dist -= snap_dist;
@@ -1172,7 +1139,7 @@ void LLManipScale::dragFace( S32 x, S32 y )
drag_dist - max_drag_dist,
drag_dist - min_drag_dist);
- mScaleSnapValue = drag_dist - relative_snap_dist;
+ mScaleSnappedValue = (drag_dist - relative_snap_dist) / (mScaleSnapUnit1 * 2.f);
if (llabs(relative_snap_dist) < snap_dist)
{
@@ -1186,9 +1153,9 @@ void LLManipScale::dragFace( S32 x, S32 y )
}
}
}
- else
+ else
{
- mInSnapRegime = FALSE;
+ mSnapRegime = SNAP_REGIME_NONE;
}
LLVector3 dir_agent;
@@ -1204,7 +1171,7 @@ void LLManipScale::dragFace( S32 x, S32 y )
{
dir_agent = bbox.localToAgentBasis( LLVector3::z_axis );
}
- stretchFace(
+ stretchFace(
projected_vec(drag_start_dir_f, dir_agent) + drag_start_center_agent,
projected_vec(drag_delta, dir_agent));
@@ -1223,7 +1190,7 @@ void LLManipScale::sendUpdates( BOOL send_position_update, BOOL send_scale_updat
U32 update_flags = UPD_NONE;
if (send_position_update) update_flags |= UPD_POSITION;
if (send_scale_update) update_flags |= UPD_SCALE;
-
+
// BOOL send_type = SEND_INDIVIDUALS;
if (corner)
{
@@ -1271,7 +1238,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
S32 axis_index = axis.mV[0] ? 0 : (axis.mV[1] ? 1 : 2 );
LLVector3 delta_local = end_local - start_local;
- F32 delta_local_mag = delta_local.magVec();
+ F32 delta_local_mag = delta_local.length();
LLVector3 dir_local;
if (delta_local_mag == 0.f)
{
@@ -1291,13 +1258,13 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
LLVector3 scale = cur->getScale();
scale.mV[axis_index] = desired_scale;
cur->setScale(scale, FALSE);
- rebuild(cur);
+ rebuild(cur);
LLVector3 delta_pos;
if( !getUniform() )
{
LLVector3 delta_pos_local = axis * (0.5f * desired_delta_size);
LLVector3d delta_pos_global;
- delta_pos_global.setVec(cur_bbox.localToAgent( delta_pos_local ) - cur_bbox.getCenterAgent());
+ delta_pos_global.set(cur_bbox.localToAgent( delta_pos_local ) - cur_bbox.getCenterAgent());
LLVector3 cur_pos = cur->getPositionEdit();
if (cur->isRootEdit() && !cur->isAttachment())
@@ -1346,7 +1313,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
void LLManipScale::renderGuidelinesPart( const LLBBox& bbox )
{
LLVector3 guideline_start = bbox.getCenterLocal();
-
+
LLVector3 guideline_end = unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox );
if (!getUniform())
@@ -1355,7 +1322,7 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox )
}
guideline_end -= guideline_start;
- guideline_end.normVec();
+ guideline_end.normalize();
guideline_end *= LLWorld::getInstance()->getRegionWidthInMeters();
guideline_end += guideline_start;
@@ -1376,26 +1343,27 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
LLQuaternion grid_rotation;
LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+ bool uniform = LLManipScale::getUniform();
+
LLVector3 box_corner_agent = bbox.localToAgent(unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ));
- mScaleCenter = getUniform() ? bbox.getCenterAgent() : bbox.localToAgent(unitVectorToLocalBBoxExtent( -1.f * partToUnitVector( mManipPart ), bbox ));
+ mScaleCenter = uniform ? bbox.getCenterAgent() : bbox.localToAgent(unitVectorToLocalBBoxExtent( -1.f * partToUnitVector( mManipPart ), bbox ));
mScaleDir = box_corner_agent - mScaleCenter;
- mScaleDir.normVec();
+ mScaleDir.normalize();
if(mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgentCamera.mHUDCurZoom;
-
}
else
{
- F32 object_distance = dist_vec(mScaleCenter, LLViewerCamera::getInstance()->getOrigin());
+ F32 object_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin());
mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidthRaw() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
}
LLVector3 cam_at_axis;
F32 snap_guide_length;
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
- cam_at_axis.setVec(1.f, 0.f, 0.f);
+ cam_at_axis.set(1.f, 0.f, 0.f);
snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgentCamera.mHUDCurZoom;
}
else
@@ -1404,22 +1372,21 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
F32 manipulator_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin());
snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWorldViewWidthRaw() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
}
-
+
mSnapGuideLength = snap_guide_length / llmax(0.1f, (llmin(mSnapGuideDir1 * cam_at_axis, mSnapGuideDir2 * cam_at_axis)));
LLVector3 off_axis_dir = mScaleDir % cam_at_axis;
- off_axis_dir.normVec();
+ off_axis_dir.normalize();
if( (LL_FACE_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_FACE_MAX) )
{
- LLVector3 object_scale = bbox.getMaxLocal();
- object_scale.scaleVec(off_axis_dir * ~bbox.getRotation());
- object_scale.abs();
- if (object_scale.mV[VX] > object_scale.mV[VY] && object_scale.mV[VX] > object_scale.mV[VZ])
+ LLVector3 bbox_relative_cam_dir = off_axis_dir * ~bbox.getRotation();
+ bbox_relative_cam_dir.abs();
+ if (bbox_relative_cam_dir.mV[VX] > bbox_relative_cam_dir.mV[VY] && bbox_relative_cam_dir.mV[VX] > bbox_relative_cam_dir.mV[VZ])
{
mSnapGuideDir1 = LLVector3::x_axis * bbox.getRotation();
}
- else if (object_scale.mV[VY] > object_scale.mV[VZ])
+ else if (bbox_relative_cam_dir.mV[VY] > bbox_relative_cam_dir.mV[VZ])
{
mSnapGuideDir1 = LLVector3::y_axis * bbox.getRotation();
}
@@ -1429,7 +1396,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
LLVector3 scale_snap = grid_scale;
- mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).magVec();
+ mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).length();
mScaleSnapUnit2 = mScaleSnapUnit1;
mSnapGuideDir1 *= mSnapGuideDir1 * LLViewerCamera::getInstance()->getUpAxis() > 0.f ? 1.f : -1.f;
mSnapGuideDir2 = mSnapGuideDir1 * -1.f;
@@ -1438,7 +1405,6 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
else if( (LL_CORNER_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_CORNER_MAX) )
{
- LLVector3 local_scale_dir = partToUnitVector( mManipPart );
LLVector3 local_camera_dir;
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
@@ -1446,74 +1412,133 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
else
{
- local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent()) * ~bbox.getRotation();
- local_camera_dir.normVec();
- }
- local_scale_dir -= projected_vec(local_scale_dir, local_camera_dir);
- local_scale_dir.normVec();
- LLVector3 x_axis_proj_camera = LLVector3::x_axis - projected_vec(LLVector3::x_axis, local_camera_dir);
- x_axis_proj_camera.normVec();
- LLVector3 y_axis_proj_camera = LLVector3::y_axis - projected_vec(LLVector3::y_axis, local_camera_dir);
- y_axis_proj_camera.normVec();
- LLVector3 z_axis_proj_camera = LLVector3::z_axis - projected_vec(LLVector3::z_axis, local_camera_dir);
- z_axis_proj_camera.normVec();
- F32 x_axis_proj = llabs(local_scale_dir * x_axis_proj_camera);
- F32 y_axis_proj = llabs(local_scale_dir * y_axis_proj_camera);
- F32 z_axis_proj = llabs(local_scale_dir * z_axis_proj_camera);
-
- if (x_axis_proj > y_axis_proj && x_axis_proj > z_axis_proj)
- {
- mSnapGuideDir1 = LLVector3::y_axis;
- mScaleSnapUnit2 = grid_scale.mV[VY];
- mSnapGuideDir2 = LLVector3::z_axis;
- mScaleSnapUnit1 = grid_scale.mV[VZ];
- }
- else if (y_axis_proj > z_axis_proj)
- {
- mSnapGuideDir1 = LLVector3::x_axis;
- mScaleSnapUnit2 = grid_scale.mV[VX];
- mSnapGuideDir2 = LLVector3::z_axis;
- mScaleSnapUnit1 = grid_scale.mV[VZ];
- }
- else
- {
- mSnapGuideDir1 = LLVector3::x_axis;
- mScaleSnapUnit2 = grid_scale.mV[VX];
- mSnapGuideDir2 = LLVector3::y_axis;
- mScaleSnapUnit1 = grid_scale.mV[VY];
+ local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - box_corner_agent) * ~bbox.getRotation();
+ local_camera_dir.normalize();
}
- LLVector3 snap_guide_flip(1.f, 1.f, 1.f);
+ LLVector3 axis_flip;
switch (mManipPart)
{
case LL_CORNER_NNN:
+ axis_flip.set(1.f, 1.f, 1.f);
break;
case LL_CORNER_NNP:
- snap_guide_flip.setVec(1.f, 1.f, -1.f);
+ axis_flip.set(1.f, 1.f, -1.f);
break;
case LL_CORNER_NPN:
- snap_guide_flip.setVec(1.f, -1.f, 1.f);
+ axis_flip.set(1.f, -1.f, 1.f);
break;
case LL_CORNER_NPP:
- snap_guide_flip.setVec(1.f, -1.f, -1.f);
+ axis_flip.set(1.f, -1.f, -1.f);
break;
case LL_CORNER_PNN:
- snap_guide_flip.setVec(-1.f, 1.f, 1.f);
+ axis_flip.set(-1.f, 1.f, 1.f);
break;
case LL_CORNER_PNP:
- snap_guide_flip.setVec(-1.f, 1.f, -1.f);
+ axis_flip.set(-1.f, 1.f, -1.f);
break;
case LL_CORNER_PPN:
- snap_guide_flip.setVec(-1.f, -1.f, 1.f);
+ axis_flip.set(-1.f, -1.f, 1.f);
break;
case LL_CORNER_PPP:
- snap_guide_flip.setVec(-1.f, -1.f, -1.f);
+ axis_flip.set(-1.f, -1.f, -1.f);
+ break;
+ default:
+ break;
+ }
+
+ // account for which side of the object the camera is located and negate appropriate axes
+ local_camera_dir.scaleVec(axis_flip);
+
+ // normalize to object scale
+ LLVector3 bbox_extent = bbox.getExtentLocal();
+ local_camera_dir.scaleVec(LLVector3(1.f / bbox_extent.mV[VX], 1.f / bbox_extent.mV[VY], 1.f / bbox_extent.mV[VZ]));
+
+ S32 scale_face = -1;
+
+ if ((local_camera_dir.mV[VX] > 0.f) == (local_camera_dir.mV[VY] > 0.f))
+ {
+ if ((local_camera_dir.mV[VZ] > 0.f) == (local_camera_dir.mV[VY] > 0.f))
+ {
+ LLVector3 local_camera_dir_abs = local_camera_dir;
+ local_camera_dir_abs.abs();
+ // all neighboring faces of bbox are pointing towards camera or away from camera
+ // use largest magnitude face for snap guides
+ if (local_camera_dir_abs.mV[VX] > local_camera_dir_abs.mV[VY])
+ {
+ if (local_camera_dir_abs.mV[VX] > local_camera_dir_abs.mV[VZ])
+ {
+ scale_face = VX;
+ }
+ else
+ {
+ scale_face = VZ;
+ }
+ }
+ else // y > x
+ {
+ if (local_camera_dir_abs.mV[VY] > local_camera_dir_abs.mV[VZ])
+ {
+ scale_face = VY;
+ }
+ else
+ {
+ scale_face = VZ;
+ }
+ }
+ }
+ else
+ {
+ // z axis facing opposite direction from x and y relative to camera, use x and y for snap guides
+ scale_face = VZ;
+ }
+ }
+ else // x and y axes are facing in opposite directions relative to camera
+ {
+ if ((local_camera_dir.mV[VZ] > 0.f) == (local_camera_dir.mV[VY] > 0.f))
+ {
+ // x axis facing opposite direction from y and z relative to camera, use y and z for snap guides
+ scale_face = VX;
+ }
+ else
+ {
+ // y axis facing opposite direction from x and z relative to camera, use x and z for snap guides
+ scale_face = VY;
+ }
+ }
+
+ switch(scale_face)
+ {
+ case VX:
+ // x axis face being scaled, use y and z for snap guides
+ mSnapGuideDir1 = LLVector3::y_axis.scaledVec(axis_flip);
+ mScaleSnapUnit1 = grid_scale.mV[VZ];
+ mSnapGuideDir2 = LLVector3::z_axis.scaledVec(axis_flip);
+ mScaleSnapUnit2 = grid_scale.mV[VY];
+ break;
+ case VY:
+ // y axis facing being scaled, use x and z for snap guides
+ mSnapGuideDir1 = LLVector3::x_axis.scaledVec(axis_flip);
+ mScaleSnapUnit1 = grid_scale.mV[VZ];
+ mSnapGuideDir2 = LLVector3::z_axis.scaledVec(axis_flip);
+ mScaleSnapUnit2 = grid_scale.mV[VX];
+ break;
+ case VZ:
+ // z axis facing being scaled, use x and y for snap guides
+ mSnapGuideDir1 = LLVector3::x_axis.scaledVec(axis_flip);
+ mScaleSnapUnit1 = grid_scale.mV[VY];
+ mSnapGuideDir2 = LLVector3::y_axis.scaledVec(axis_flip);
+ mScaleSnapUnit2 = grid_scale.mV[VX];
break;
default:
+ mSnapGuideDir1.setZero();
+ mScaleSnapUnit1 = 0.f;
+
+ mSnapGuideDir2.setZero();
+ mScaleSnapUnit2 = 0.f;
break;
}
- mSnapGuideDir1.scaleVec(snap_guide_flip);
- mSnapGuideDir2.scaleVec(snap_guide_flip);
+
mSnapGuideDir1.rotVec(bbox.getRotation());
mSnapGuideDir2.rotVec(bbox.getRotation());
mSnapDir1 = -1.f * mSnapGuideDir2;
@@ -1521,13 +1546,22 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
mScalePlaneNormal1 = mSnapGuideDir1 % mScaleDir;
- mScalePlaneNormal1.normVec();
+ mScalePlaneNormal1.normalize();
mScalePlaneNormal2 = mSnapGuideDir2 % mScaleDir;
- mScalePlaneNormal2.normVec();
+ mScalePlaneNormal2.normalize();
mScaleSnapUnit1 = mScaleSnapUnit1 / (mSnapDir1 * mScaleDir);
mScaleSnapUnit2 = mScaleSnapUnit2 / (mSnapDir2 * mScaleDir);
+
+ mTickPixelSpacing1 = llround((F32)MIN_DIVISION_PIXEL_WIDTH / (mScaleDir % mSnapGuideDir1).length());
+ mTickPixelSpacing2 = llround((F32)MIN_DIVISION_PIXEL_WIDTH / (mScaleDir % mSnapGuideDir2).length());
+
+ if (uniform)
+ {
+ mScaleSnapUnit1 *= 0.5f;
+ mScaleSnapUnit2 *= 0.5f;
+ }
}
void LLManipScale::renderSnapGuides(const LLBBox& bbox)
@@ -1537,7 +1571,6 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
return;
}
- F32 max_subdivisions = sGridMaxSubdivisionLevel;
F32 grid_alpha = gSavedSettings.getF32("GridOpacity");
F32 max_point_on_scale_line = partToMaxScale(mManipPart, bbox);
@@ -1551,10 +1584,10 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
LLColor4 tick_color = setupSnapGuideRenderPass(pass);
gGL.begin(LLRender::LINES);
- LLVector3 line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset);
- LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f)));
- LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f));
-
+ LLVector3 line_mid = mScaleCenter + (mScaleSnappedValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset);
+ LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnappedValue, mSnapGuideLength * 0.5f)));
+ LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnappedValue, mSnapGuideLength * 0.5f));
+
gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f);
gGL.vertex3fv(line_start.mV);
gGL.color4fv(tick_color.mV);
@@ -1563,9 +1596,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f);
gGL.vertex3fv(line_end.mV);
- line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset);
- line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f)));
- line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f));
+ line_mid = mScaleCenter + (mScaleSnappedValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset);
+ line_start = line_mid - (mScaleDir * (llmin(mScaleSnappedValue, mSnapGuideLength * 0.5f)));
+ line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnappedValue, mSnapGuideLength * 0.5f));
gGL.vertex3fv(line_start.mV);
gGL.color4fv(tick_color.mV);
gGL.vertex3fv(line_mid.mV);
@@ -1578,31 +1611,38 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
{
LLGLDepthTest gls_depth(GL_FALSE);
- F32 dist_grid_axis = (drag_point - mScaleCenter) * mScaleDir;
+ F32 dist_grid_axis = llmax(0.f, (drag_point - mScaleCenter) * mScaleDir);
+
+ F32 smallest_subdivision1 = mScaleSnapUnit1 / sGridMaxSubdivisionLevel;
+ F32 smallest_subdivision2 = mScaleSnapUnit2 / sGridMaxSubdivisionLevel;
+
+ F32 dist_scale_units_1 = dist_grid_axis / smallest_subdivision1;
+ F32 dist_scale_units_2 = dist_grid_axis / smallest_subdivision2;
+
// find distance to nearest smallest grid unit
- F32 grid_offset1 = fmodf(dist_grid_axis, mScaleSnapUnit1 / max_subdivisions);
- F32 grid_offset2 = fmodf(dist_grid_axis, mScaleSnapUnit2 / max_subdivisions);
+ F32 grid_multiple1 = llfloor(dist_scale_units_1);
+ F32 grid_multiple2 = llfloor(dist_scale_units_2);
+ F32 grid_offset1 = fmodf(dist_grid_axis, smallest_subdivision1);
+ F32 grid_offset2 = fmodf(dist_grid_axis, smallest_subdivision2);
// how many smallest grid units are we away from largest grid scale?
- S32 sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 / sGridMinSubdivisionLevel) / (mScaleSnapUnit1 / max_subdivisions));
- S32 sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 / sGridMinSubdivisionLevel) / (mScaleSnapUnit2 / max_subdivisions));
+ S32 sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 / sGridMinSubdivisionLevel) / smallest_subdivision1);
+ S32 sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 / sGridMinSubdivisionLevel) / smallest_subdivision2);
- S32 num_ticks_per_side1 = llmax(1, lltrunc(0.5f * mSnapGuideLength / (mScaleSnapUnit1 / max_subdivisions)));
- S32 num_ticks_per_side2 = llmax(1, lltrunc(0.5f * mSnapGuideLength / (mScaleSnapUnit2 / max_subdivisions)));
- F32 dist_scale_units_1 = dist_grid_axis / (mScaleSnapUnit1 / max_subdivisions);
- F32 dist_scale_units_2 = dist_grid_axis / (mScaleSnapUnit2 / max_subdivisions);
+ S32 num_ticks_per_side1 = llmax(1, lltrunc(0.5f * mSnapGuideLength / smallest_subdivision1));
+ S32 num_ticks_per_side2 = llmax(1, lltrunc(0.5f * mSnapGuideLength / smallest_subdivision2));
S32 ticks_from_scale_center_1 = lltrunc(dist_scale_units_1);
S32 ticks_from_scale_center_2 = lltrunc(dist_scale_units_2);
- S32 max_ticks1 = llceil(max_point_on_scale_line / (mScaleSnapUnit1 / max_subdivisions) - dist_scale_units_1);
- S32 max_ticks2 = llceil(max_point_on_scale_line / (mScaleSnapUnit2 / max_subdivisions) - dist_scale_units_2);
+ S32 max_ticks1 = llceil(max_point_on_scale_line / smallest_subdivision1 - dist_scale_units_1);
+ S32 max_ticks2 = llceil(max_point_on_scale_line / smallest_subdivision2 - dist_scale_units_2);
S32 start_tick = 0;
S32 stop_tick = 0;
- if (mInSnapRegime)
+ if (mSnapRegime != SNAP_REGIME_NONE)
{
// draw snap guide line
gGL.begin(LLRender::LINES);
- LLVector3 snap_line_center = mScaleCenter + (mScaleSnapValue * mScaleDir);
+ LLVector3 snap_line_center = bbox.localToAgent(unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ));
LLVector3 snap_line_start = snap_line_center + (mSnapGuideDir1 * mSnapRegimeOffset);
LLVector3 snap_line_end = snap_line_center + (mSnapGuideDir2 * mSnapRegimeOffset);
@@ -1624,22 +1664,22 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
LLVector3 arrow_span = mScaleDir;
arrow_dir = snap_line_start - snap_line_center;
- arrow_dir.normVec();
+ arrow_dir.normalize();
gGL.vertex3fv((snap_line_start + arrow_dir * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_start + arrow_span * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_start - arrow_span * mBoxHandleSize).mV);
arrow_dir = snap_line_end - snap_line_center;
- arrow_dir.normVec();
+ arrow_dir.normalize();
gGL.vertex3fv((snap_line_end + arrow_dir * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_end + arrow_span * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_end - arrow_span * mBoxHandleSize).mV);
}
gGL.end();
}
-
+
LLVector2 screen_translate_axis(llabs(mScaleDir * LLViewerCamera::getInstance()->getLeftAxis()), llabs(mScaleDir * LLViewerCamera::getInstance()->getUpAxis()));
- screen_translate_axis.normVec();
+ screen_translate_axis.normalize();
S32 tick_label_spacing = llround(screen_translate_axis * sTickLabelSpacing);
@@ -1655,17 +1695,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
for (S32 i = start_tick; i <= stop_tick; i++)
{
F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side1)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit1 / max_subdivisions * (F32)i - grid_offset1));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1);
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
- if (fmodf((F32)(i + sub_div_offset_1), (max_subdivisions / cur_subdivisions)) != 0.f)
+ if (fmodf((F32)(i + sub_div_offset_1), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f)
{
continue;
}
F32 tick_scale = 1.f;
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + sub_div_offset_1), division_level) == 0.f)
{
@@ -1688,17 +1728,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
for (S32 i = start_tick; i <= stop_tick; i++)
{
F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side2)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit2 / max_subdivisions * (F32)i - grid_offset2));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2);
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
- if (fmodf((F32)(i + sub_div_offset_2), (max_subdivisions / cur_subdivisions)) != 0.f)
+ if (fmodf((F32)(i + sub_div_offset_2), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f)
{
continue;
}
F32 tick_scale = 1.f;
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + sub_div_offset_2), division_level) == 0.f)
{
@@ -1716,21 +1756,21 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
gGL.end();
}
- // render tick labels
+ // render upper tick labels
start_tick = -(llmin(ticks_from_scale_center_1, num_ticks_per_side1));
stop_tick = llmin(max_ticks1, num_ticks_per_side1);
F32 grid_resolution = mObjectSelection->getSelectType() == SELECT_TYPE_HUD ? 0.25f : llmax(gSavedSettings.getF32("GridResolution"), 0.001f);
- S32 label_sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 * 32.f) / (mScaleSnapUnit1 / max_subdivisions));
- S32 label_sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 * 32.f) / (mScaleSnapUnit2 / max_subdivisions));
+ S32 label_sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 * 32.f) / smallest_subdivision1);
+ S32 label_sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 * 32.f) / smallest_subdivision2);
for (S32 i = start_tick; i <= stop_tick; i++)
{
F32 tick_scale = 1.f;
F32 alpha = grid_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side1)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit1 / max_subdivisions * (F32)i - grid_offset1));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1);
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + label_sub_div_offset_1), division_level) == 0.f)
{
@@ -1739,39 +1779,34 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
tick_scale *= 0.7f;
}
- if (fmodf((F32)(i + label_sub_div_offset_1), (max_subdivisions / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, tick_label_spacing)))) == 0.f)
+ if (fmodf((F32)(i + label_sub_div_offset_1), (sGridMaxSubdivisionLevel / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, tick_label_spacing)))) == 0.f)
{
- LLVector3 text_origin = tick_pos +
- (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale));
+ LLVector3 text_origin = tick_pos + (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale));
EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode();
- F32 tick_val;
+ F32 tick_value;
if (grid_mode == GRID_MODE_WORLD)
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit1 / grid_resolution);
+ tick_value = (grid_multiple1 + i) / (sGridMaxSubdivisionLevel / grid_resolution);
}
else
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit1 * 2.f);
- }
-
- if (getUniform())
- {
- tick_val *= 2.f;
+ tick_value = (grid_multiple1 + i) / (2.f * sGridMaxSubdivisionLevel);
}
F32 text_highlight = 0.8f;
- if (is_approx_equal(tick_val, mScaleSnapValue) && mInSnapRegime)
+ // Highlight this text if the tick value matches the snapped to value, and if either the second set of ticks isn't going to be shown or cursor is in the first snap regime.
+ if (is_approx_equal(tick_value, mScaleSnappedValue) && (mScaleSnapUnit2 == mScaleSnapUnit1 || (mSnapRegime & SNAP_REGIME_UPPER)))
{
text_highlight = 1.f;
}
- renderTickValue(text_origin, tick_val, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
+ renderTickValue(text_origin, tick_value, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
}
}
- // label ticks on opposite side
+ // label ticks on opposite side, only can happen in scaling modes that effect more than one axis and when the object's axis don't have the same scale. A differing scale indicates both conditions.
if (mScaleSnapUnit2 != mScaleSnapUnit1)
{
start_tick = -(llmin(ticks_from_scale_center_2, num_ticks_per_side2));
@@ -1780,9 +1815,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
{
F32 tick_scale = 1.f;
F32 alpha = grid_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side2)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit2 / max_subdivisions * (F32)i - grid_offset2));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2);
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + label_sub_div_offset_2), division_level) == 0.f)
{
@@ -1791,35 +1826,29 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
tick_scale *= 0.7f;
}
- if (fmodf((F32)(i + label_sub_div_offset_2), (max_subdivisions / llmin(max_subdivisions, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, tick_label_spacing)))) == 0.f)
+ if (fmodf((F32)(i + label_sub_div_offset_2), (sGridMaxSubdivisionLevel / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, tick_label_spacing)))) == 0.f)
{
- LLVector3 text_origin = tick_pos +
- (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale));
+ LLVector3 text_origin = tick_pos + (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale));
EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode();
- F32 tick_val;
+ F32 tick_value;
if (grid_mode == GRID_MODE_WORLD)
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit2 / grid_resolution);
+ tick_value = (grid_multiple2 + i) / (sGridMaxSubdivisionLevel / grid_resolution);
}
else
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit2 * 2.f);
- }
-
- if (getUniform())
- {
- tick_val *= 2.f;
+ tick_value = (grid_multiple2 + i) / (2.f * sGridMaxSubdivisionLevel);
}
F32 text_highlight = 0.8f;
- if (is_approx_equal(tick_val, mScaleSnapValue) && mInSnapRegime)
+ if (is_approx_equal(tick_value, mScaleSnappedValue) && (mSnapRegime & SNAP_REGIME_LOWER))
{
text_highlight = 1.f;
}
- renderTickValue(text_origin, tick_val, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
+ renderTickValue(text_origin, tick_value, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
}
}
}
@@ -1845,13 +1874,13 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
LLVector3 help_text_pos = selection_center_start + (mSnapRegimeOffset * 5.f * offset_dir);
const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
- std::string help_text = "Move mouse cursor over ruler";
+ std::string help_text = LLTrans::getString("manip_hint1");
LLColor4 help_text_color = LLColor4::white;
help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, grid_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
- help_text = "to snap to grid";
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapRegimeOffset * 0.4f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
}
}
}
@@ -1860,17 +1889,15 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
// Returns unit vector in direction of part of an origin-centered cube
LLVector3 LLManipScale::partToUnitVector( S32 part ) const
{
- if( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) )
+ if ( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) )
{
return faceToUnitVector( part );
}
- else
- if( (LL_CORNER_MIN <= part) && (part <= LL_CORNER_MAX) )
+ else if ( (LL_CORNER_MIN <= part) && (part <= LL_CORNER_MAX) )
{
return cornerToUnitVector( part );
}
- else
- if( (LL_EDGE_MIN <= part) && (part <= LL_EDGE_MAX ) )
+ else if ( (LL_EDGE_MIN <= part) && (part <= LL_EDGE_MAX ) )
{
return edgeToUnitVector( part );
}
@@ -1882,27 +1909,32 @@ LLVector3 LLManipScale::partToUnitVector( S32 part ) const
LLVector3 LLManipScale::faceToUnitVector( S32 part ) const
{
llassert( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) );
+ LLVector3 vec;
switch( part )
{
case LL_FACE_POSX:
- return LLVector3( 1.f, 0.f, 0.f );
-
+ vec.set( 1.f, 0.f, 0.f );
+ break;
case LL_FACE_NEGX:
- return LLVector3( -1.f, 0.f, 0.f );
-
+ vec.set( -1.f, 0.f, 0.f );
+ break;
case LL_FACE_POSY:
- return LLVector3( 0.f, 1.f, 0.f );
-
+ vec.set( 0.f, 1.f, 0.f );
+ break;
case LL_FACE_NEGY:
- return LLVector3( 0.f, -1.f, 0.f );
-
+ vec.set( 0.f, -1.f, 0.f );
+ break;
case LL_FACE_POSZ:
- return LLVector3( 0.f, 0.f, 1.f );
-
+ vec.set( 0.f, 0.f, 1.f );
+ break;
case LL_FACE_NEGZ:
- return LLVector3( 0.f, 0.f, -1.f );
+ vec.set( 0.f, 0.f, -1.f );
+ break;
+ default:
+ vec.clear();
}
- return LLVector3();
+
+ return vec;
}
@@ -1914,31 +1946,31 @@ LLVector3 LLManipScale::cornerToUnitVector( S32 part ) const
switch(part)
{
case LL_CORNER_NNN:
- vec.setVec(-F_SQRT3, -F_SQRT3, -F_SQRT3);
+ vec.set(-OO_SQRT3, -OO_SQRT3, -OO_SQRT3);
break;
- case LL_CORNER_NNP:
- vec.setVec(-F_SQRT3, -F_SQRT3, F_SQRT3);
+ case LL_CORNER_NNP:
+ vec.set(-OO_SQRT3, -OO_SQRT3, OO_SQRT3);
break;
case LL_CORNER_NPN:
- vec.setVec(-F_SQRT3, F_SQRT3, -F_SQRT3);
+ vec.set(-OO_SQRT3, OO_SQRT3, -OO_SQRT3);
break;
case LL_CORNER_NPP:
- vec.setVec(-F_SQRT3, F_SQRT3, F_SQRT3);
+ vec.set(-OO_SQRT3, OO_SQRT3, OO_SQRT3);
break;
case LL_CORNER_PNN:
- vec.setVec(F_SQRT3, -F_SQRT3, -F_SQRT3);
+ vec.set(OO_SQRT3, -OO_SQRT3, -OO_SQRT3);
break;
case LL_CORNER_PNP:
- vec.setVec(F_SQRT3, -F_SQRT3, F_SQRT3);
+ vec.set(OO_SQRT3, -OO_SQRT3, OO_SQRT3);
break;
case LL_CORNER_PPN:
- vec.setVec(F_SQRT3, F_SQRT3, -F_SQRT3);
+ vec.set(OO_SQRT3, OO_SQRT3, -OO_SQRT3);
break;
case LL_CORNER_PPP:
- vec.setVec(F_SQRT3, F_SQRT3, F_SQRT3);
+ vec.set(OO_SQRT3, OO_SQRT3, OO_SQRT3);
break;
default:
- vec.clearVec();
+ vec.clear();
}
return vec;
@@ -1965,8 +1997,8 @@ LLVector3 LLManipScale::unitVectorToLocalBBoxExtent( const LLVector3& v, const L
LLVector3 ctr = bbox.getCenterLocal();
return LLVector3(
- v.mV[0] ? (v.mV[0]>0 ? max.mV[0] : min.mV[0] ) : ctr.mV[0],
- v.mV[1] ? (v.mV[1]>0 ? max.mV[1] : min.mV[1] ) : ctr.mV[1],
+ v.mV[0] ? (v.mV[0]>0 ? max.mV[0] : min.mV[0] ) : ctr.mV[0],
+ v.mV[1] ? (v.mV[1]>0 ? max.mV[1] : min.mV[1] ) : ctr.mV[1],
v.mV[2] ? (v.mV[2]>0 ? max.mV[2] : min.mV[2] ) : ctr.mV[2] );
}
@@ -1984,7 +2016,7 @@ F32 LLManipScale::partToMaxScale( S32 part, const LLBBox &bbox ) const
max_extent = bbox_extents.mV[i];
}
}
- max_scale_factor = bbox_extents.magVec() * get_default_max_prim_scale() / max_extent;
+ max_scale_factor = bbox_extents.length() * get_default_max_prim_scale() / max_extent;
if (getUniform())
{
@@ -2007,7 +2039,7 @@ F32 LLManipScale::partToMinScale( S32 part, const LLBBox &bbox ) const
min_extent = bbox_extents.mV[i];
}
}
- F32 min_scale_factor = bbox_extents.magVec() * MIN_PRIM_SCALE / min_extent;
+ F32 min_scale_factor = bbox_extents.length() * MIN_PRIM_SCALE / min_extent;
if (getUniform())
{
@@ -2058,7 +2090,7 @@ LLVector3 LLManipScale::nearestAxis( const LLVector3& v ) const
// virtual
BOOL LLManipScale::canAffectSelection()
{
- // An selection is scalable if you are allowed to both edit and move
+ // An selection is scalable if you are allowed to both edit and move
// everything in it, and it does not have any sitting agents
BOOL can_scale = mObjectSelection->getObjectCount() != 0;
if (can_scale)
diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h
index 5cb8898fd0..e1da7a1bb5 100755
--- a/indra/newview/llmanipscale.h
+++ b/indra/newview/llmanipscale.h
@@ -51,6 +51,13 @@ typedef enum e_scale_manipulator_type
SCALE_MANIP_FACE
} EScaleManipulatorType;
+typedef enum e_snap_regimes
+{
+ SNAP_REGIME_NONE = 0, //!< The cursor is not in either of the snap regimes.
+ SNAP_REGIME_UPPER = 0x1, //!< The cursor is, non-exclusively, in the first of the snap regimes. Prefer to treat as bitmask.
+ SNAP_REGIME_LOWER = 0x2 //!< The cursor is, non-exclusively, in the second of the snap regimes. Prefer to treat as bitmask.
+} ESnapRegimes;
+
class LLManipScale : public LLManip
{
@@ -96,7 +103,7 @@ private:
void renderSnapGuides( const LLBBox& local_bbox );
void revert();
-
+
inline void conditionalHighlight( U32 part, const LLColor4* highlight = NULL, const LLColor4* normal = NULL );
void drag( S32 x, S32 y );
@@ -135,33 +142,35 @@ private:
};
- F32 mBoxHandleSize; // The size of the handles at the corners of the bounding box
- F32 mScaledBoxHandleSize; // handle size after scaling for selection feedback
+ F32 mBoxHandleSize; //!< The size of the handles at the corners of the bounding box.
+ F32 mScaledBoxHandleSize; //!< Handle size after scaling for selection feedback.
LLVector3d mDragStartPointGlobal;
- LLVector3d mDragStartCenterGlobal; // The center of the bounding box of all selected objects at time of drag start
+ LLVector3d mDragStartCenterGlobal; //!< The center of the bounding box of all selected objects at time of drag start.
LLVector3d mDragPointGlobal;
LLVector3d mDragFarHitGlobal;
S32 mLastMouseX;
S32 mLastMouseY;
BOOL mSendUpdateOnMouseUp;
U32 mLastUpdateFlags;
- typedef std::set<ManipulatorHandle*, compare_manipulators> minpulator_list_t;
- minpulator_list_t mProjectedManipulators;
+ typedef std::set<ManipulatorHandle*, compare_manipulators> manipulator_list_t;
+ manipulator_list_t mProjectedManipulators;
LLVector4 mManipulatorVertices[14];
- F32 mScaleSnapUnit1; // size of snap multiples for axis 1
- F32 mScaleSnapUnit2; // size of snap multiples for axis 2
- LLVector3 mScalePlaneNormal1; // normal of plane in which scale occurs that most faces camera
- LLVector3 mScalePlaneNormal2; // normal of plane in which scale occurs that most faces camera
- LLVector3 mSnapGuideDir1;
- LLVector3 mSnapGuideDir2;
- LLVector3 mSnapDir1;
- LLVector3 mSnapDir2;
- F32 mSnapRegimeOffset;
+ F32 mScaleSnapUnit1; //!< Size of snap multiples for the upper scale.
+ F32 mScaleSnapUnit2; //!< Size of snap multiples for the lower scale.
+ LLVector3 mScalePlaneNormal1; //!< Normal of plane in which scale occurs that most faces camera.
+ LLVector3 mScalePlaneNormal2; //!< Normal of plane in which scale occurs that most faces camera.
+ LLVector3 mSnapGuideDir1; //!< The direction in which the upper snap guide tick marks face.
+ LLVector3 mSnapGuideDir2; //!< The direction in which the lower snap guide tick marks face.
+ LLVector3 mSnapDir1; //!< The direction in which the upper snap guides face.
+ LLVector3 mSnapDir2; //!< The direction in which the lower snap guides face.
+ F32 mSnapRegimeOffset; //!< How far off the scale axis centerline the mouse can be before it exits/enters the snap regime.
+ F32 mTickPixelSpacing1; //!< The pixel spacing between snap guide tick marks for the upper scale.
+ F32 mTickPixelSpacing2; //!< The pixel spacing between snap guide tick marks for the lower scale.
F32 mSnapGuideLength;
- LLVector3 mScaleCenter;
- LLVector3 mScaleDir;
- F32 mScaleSnapValue;
- BOOL mInSnapRegime;
+ LLVector3 mScaleCenter; //!< The location of the origin of the scaling operation.
+ LLVector3 mScaleDir; //!< The direction of the scaling action. In face-dragging this is aligned with one of the cardinal axis relative to the prim, but in corner-dragging this is along the diagonal.
+ F32 mScaleSnappedValue; //!< The distance of the current position nearest the mouse location, measured along mScaleDir. Is measured either from the center or from the far face/corner depending upon whether uniform scaling is true or false respectively.
+ ESnapRegimes mSnapRegime; //<! Which, if any, snap regime the cursor is currently residing in.
F32* mManipulatorScales;
};
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 06bf294417..d237e5ef44 100755
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -61,6 +61,7 @@
#include "llui.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
+#include "lltrans.h"
const S32 NUM_AXES = 3;
const S32 MOUSE_DRAG_SLOP = 2; // pixels
@@ -111,7 +112,6 @@ LLManipTranslate::LLManipTranslate( LLToolComposite* composite )
: LLManip( std::string("Move"), composite ),
mLastHoverMouseX(-1),
mLastHoverMouseY(-1),
- mSendUpdateOnMouseUp(FALSE),
mMouseOutsideSlop(FALSE),
mCopyMadeThisDrag(FALSE),
mMouseDownX(-1),
@@ -125,7 +125,6 @@ LLManipTranslate::LLManipTranslate( LLToolComposite* composite )
mSnapOffsetMeters(0.f),
mSubdivisions(10.f),
mInSnapRegime(FALSE),
- mSnapped(FALSE),
mArrowScales(1.f, 1.f, 1.f),
mPlaneScales(1.f, 1.f, 1.f),
mPlaneManipPositions(1.f, 1.f, 1.f, 1.f)
@@ -1441,13 +1440,13 @@ void LLManipTranslate::renderSnapGuides()
LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis);
const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
- std::string help_text = "Move mouse cursor over ruler";
+ std::string help_text = LLTrans::getString("manip_hint1");
LLColor4 help_text_color = LLColor4::white;
help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
- help_text = "to snap to grid";
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
}
}
}
diff --git a/indra/newview/llmaniptranslate.h b/indra/newview/llmaniptranslate.h
index 37567c7bd1..3c37bbd698 100755
--- a/indra/newview/llmaniptranslate.h
+++ b/indra/newview/llmaniptranslate.h
@@ -85,7 +85,6 @@ protected:
private:
S32 mLastHoverMouseX;
S32 mLastHoverMouseY;
- BOOL mSendUpdateOnMouseUp;
BOOL mMouseOutsideSlop; // true after mouse goes outside slop region
BOOL mCopyMadeThisDrag;
S32 mMouseDownX;
@@ -107,7 +106,6 @@ private:
LLVector3 mGridScale;
F32 mSubdivisions;
BOOL mInSnapRegime;
- BOOL mSnapped;
LLVector3 mArrowScales;
LLVector3 mPlaneScales;
LLVector4 mPlaneManipPositions;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 0b009b68f7..05c9d76810 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -30,6 +30,7 @@
#include "llagent.h"
#include "llhttpclient.h"
+#include "llsdserialize.h"
#include "lltimer.h"
#include "lltrans.h"
#include "llviewercontrol.h"
@@ -135,19 +136,25 @@ namespace LLMarketplaceImport
llinfos << " SLM POST status: " << status << llendl;
llinfos << " SLM POST reason: " << reason << llendl;
llinfos << " SLM POST content: " << content.asString() << llendl;
-
llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
}
- if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
- (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
- (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ // MAINT-2301 : we determined we can safely ignore that error in that context
+ if (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)
{
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ llinfos << " SLM POST : Ignoring time out status and treating it as success" << llendl;
+ }
+ status = MarketplaceErrorCodes::IMPORT_DONE;
+ }
+
+ if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM POST clearing marketplace cookie due to client or server error" << llendl;
}
-
sMarketplaceCookie.clear();
}
@@ -182,20 +189,25 @@ namespace LLMarketplaceImport
llinfos << " SLM GET status: " << status << llendl;
llinfos << " SLM GET reason: " << reason << llendl;
llinfos << " SLM GET content: " << content.asString() << llendl;
-
llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
}
- if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
- (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
+ // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initally empty
+ if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
+ (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
+ (status != MarketplaceErrorCodes::IMPORT_NOT_FOUND))
{
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ llinfos << " SLM GET clearing marketplace cookie due to client or server error" << llendl;
}
-
sMarketplaceCookie.clear();
}
+ else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
+ {
+ llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl;
+ }
sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
sImportGetPending = false;
@@ -256,7 +268,12 @@ namespace LLMarketplaceImport
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM GET: " << url << llendl;
+ llinfos << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << llendl;
+ LLSD headers = LLViewerMedia::getHeaders();
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(headers, str);
+ llinfos << " SLM GET: headers " << llendl;
+ llinfos << str.str() << llendl;
}
slmGetTimer.start();
@@ -287,7 +304,11 @@ namespace LLMarketplaceImport
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM GET: " << url << llendl;
+ llinfos << " SLM GET: pollStatus, LLHTTPClient::get, url = " << url << llendl;
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(headers, str);
+ llinfos << " SLM GET: headers " << llendl;
+ llinfos << str.str() << llendl;
}
slmGetTimer.start();
@@ -321,11 +342,15 @@ namespace LLMarketplaceImport
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM POST: " << url << llendl;
+ llinfos << " SLM POST: triggerImport, LLHTTPClient::post, url = " << url << llendl;
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(headers, str);
+ llinfos << " SLM POST: headers " << llendl;
+ llinfos << str.str() << llendl;
}
slmPostTimer.start();
- LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
+ LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
return true;
}
@@ -356,6 +381,7 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
: mAutoTriggerImport(false)
, mImportInProgress(false)
, mInitialized(false)
+ , mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
, mErrorInitSignal(NULL)
, mStatusChangedSignal(NULL)
, mStatusReportSignal(NULL)
@@ -394,20 +420,27 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb
void LLMarketplaceInventoryImporter::initialize()
{
- llassert(!mInitialized);
+ if (mInitialized)
+ {
+ return;
+ }
if (!LLMarketplaceImport::hasSessionCookie())
{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING;
LLMarketplaceImport::establishMarketplaceSessionCookie();
}
+ else
+ {
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;
+ }
}
void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
{
mInitialized = false;
-
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED;
initialize();
-
mAutoTriggerImport = true;
}
@@ -459,17 +492,30 @@ void LLMarketplaceInventoryImporter::updateImport()
if (mInitialized)
{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;
// Follow up with auto trigger of import
if (mAutoTriggerImport)
{
mAutoTriggerImport = false;
-
mImportInProgress = triggerImport();
}
}
- else if (mErrorInitSignal)
+ else
{
- (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ U32 status = LLMarketplaceImport::getResultStatus();
+ if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
+ (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR))
+ {
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT;
+ }
+ else
+ {
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+ }
+ if (mErrorInitSignal && (mMarketPlaceStatus == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE))
+ {
+ (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ }
}
}
}
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 4b8f7a1ac7..abe60890a3 100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -47,10 +47,27 @@ namespace MarketplaceErrorCodes
IMPORT_DONE = 200,
IMPORT_PROCESSING = 202,
IMPORT_REDIRECT = 302,
+ IMPORT_BAD_REQUEST = 400,
IMPORT_AUTHENTICATION_ERROR = 401,
+ IMPORT_FORBIDDEN = 403,
+ IMPORT_NOT_FOUND = 404,
IMPORT_DONE_WITH_ERRORS = 409,
IMPORT_JOB_FAILED = 410,
IMPORT_JOB_TIMEOUT = 499,
+ IMPORT_SERVER_SITE_DOWN = 500,
+ IMPORT_SERVER_API_DISABLED = 503,
+ };
+}
+
+namespace MarketplaceStatusCodes
+{
+ enum sCode
+ {
+ MARKET_PLACE_NOT_INITIALIZED = 0,
+ MARKET_PLACE_INITIALIZING = 1,
+ MARKET_PLACE_CONNECTION_FAILURE = 2,
+ MARKET_PLACE_MERCHANT = 3,
+ MARKET_PLACE_NOT_MERCHANT = 4,
};
}
@@ -73,6 +90,8 @@ public:
void initialize();
bool triggerImport();
bool isImportInProgress() const { return mImportInProgress; }
+ bool isInitialized() const { return mInitialized; }
+ U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
protected:
void reinitializeAndTriggerImport();
@@ -82,6 +101,7 @@ private:
bool mAutoTriggerImport;
bool mImportInProgress;
bool mInitialized;
+ U32 mMarketPlaceStatus;
status_report_signal_t * mErrorInitSignal;
status_changed_signal_t * mStatusChangedSignal;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 5afd2cb329..b0c8aa2d3a 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2004,9 +2004,9 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
result["asset_type"] = "mesh";
result["inventory_type"] = "object";
result["description"] = "(No Description)";
- result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms());
- result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms());
- result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms());
+ result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms("Uploads"));
+ result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms("Uploads"));
+ result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms("Uploads"));
res["mesh_list"] = LLSD::emptyArray();
res["texture_list"] = LLSD::emptyArray();
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 7ddd04fed0..3b5a69fd3a 100755
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -64,8 +64,7 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
mNameColumnIndex(p.name_column.column_index),
mNameColumn(p.name_column.column_name),
mAllowCallingCardDrop(p.allow_calling_card_drop),
- mShortNames(p.short_names),
- mAvatarNameCacheConnection()
+ mShortNames(p.short_names)
{}
// public
@@ -328,13 +327,16 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
else
{
// ...schedule a callback
- // This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached.
- // *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list.
- if (mAvatarNameCacheConnection.connected())
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id);
+ if (it != mAvatarNameCacheConnections.end())
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
}
- mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle()));
+ mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle()));
}
break;
}
@@ -391,9 +393,18 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name,
+ std::string suffix,
LLHandle<LLNameListItem> item)
{
- mAvatarNameCacheConnection.disconnect();
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id);
+ if (it != mAvatarNameCacheConnections.end())
+ {
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
+ }
std::string name;
if (mShortNames)
@@ -401,6 +412,12 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
else
name = av_name.getCompleteName();
+ // Append optional suffix.
+ if (!suffix.empty())
+ {
+ name.append(suffix);
+ }
+
LLNameListItem* list_item = item.get();
if (list_item && list_item->getUUID() == agent_id)
{
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 92e82b672d..4ed260d847 100755
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -114,10 +114,14 @@ protected:
LLNameListCtrl(const Params&);
virtual ~LLNameListCtrl()
{
- if (mAvatarNameCacheConnection.connected())
+ for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
}
+ mAvatarNameCacheConnections.clear();
}
friend class LLUICtrlFactory;
public:
@@ -155,14 +159,15 @@ public:
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
private:
void showInspector(const LLUUID& avatar_id, bool is_group);
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle<LLNameListItem> item);
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle<LLNameListItem> item);
private:
S32 mNameColumnIndex;
std::string mNameColumn;
BOOL mAllowCallingCardDrop;
bool mShortNames; // display name only, no SLID
- boost::signals2::connection mAvatarNameCacheConnection;
+ typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+ avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 1a427338e5..89a9e0dc16 100755
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -59,6 +59,7 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llworld.h"
+#include "llfloaterperms.h"
//
// Imported globals
@@ -156,12 +157,14 @@ void LLPanelContents::onClickNewScript(void *userdata)
{
LLPermissions perm;
perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+
+ // Parameters are base, owner, everyone, group, next
perm.initMasks(
PERM_ALL,
PERM_ALL,
- PERM_NONE,
- PERM_NONE,
- PERM_MOVE | PERM_TRANSFER);
+ LLFloaterPerms::getEveryonePerms("Scripts"),
+ LLFloaterPerms::getGroupPerms("Scripts"),
+ PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Scripts"));
std::string desc;
LLViewerAssetType::generateDescriptionFor(LLAssetType::AT_LSL_TEXT, desc);
LLPointer<LLViewerInventoryItem> new_item =
@@ -179,6 +182,8 @@ void LLPanelContents::onClickNewScript(void *userdata)
time_corrected());
object->saveScript(new_item, TRUE, true);
+ std::string name = new_item->getName();
+
// *NOTE: In order to resolve SL-22177, we needed to create
// the script first, and then you have to click it in
// inventory to edit it.
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index c30c932c41..4cb6506b61 100755
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -743,17 +743,20 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
mChanged(FALSE),
mPendingMemberUpdate(FALSE),
mHasMatch(FALSE),
- mNumOwnerAdditions(0),
- mAvatarNameCacheConnection()
+ mNumOwnerAdditions(0)
{
}
LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
{
- if (mAvatarNameCacheConnection.connected())
+ for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
}
+ mAvatarNameCacheConnections.clear();
if (mMembersList)
{
gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName());
@@ -1644,9 +1647,17 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
mHasMatch = TRUE;
}
-void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
+void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id)
{
- mAvatarNameCacheConnection.disconnect();
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(av_id);
+ if (it != mAvatarNameCacheConnections.end())
+ {
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
+ }
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
if (!gdatap
@@ -1719,12 +1730,16 @@ void LLPanelGroupMembersSubTab::updateMembers()
else
{
// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
- // *TODO : Add one callback per fetched avatar name
- if (mAvatarNameCacheConnection.connected())
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(mMemberProgress->first);
+ if (it != mAvatarNameCacheConnections.end())
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
}
- mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
+ mAvatarNameCacheConnections[mMemberProgress->first] = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2, _1));
}
}
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 0cf272f3ee..baa2d40c7e 100755
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -189,7 +189,7 @@ public:
virtual void setGroupID(const LLUUID& id);
void addMemberToList(LLGroupMemberData* data);
- void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
+ void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id);
protected:
typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;
@@ -215,7 +215,8 @@ protected:
U32 mNumOwnerAdditions;
LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
- boost::signals2::connection mAvatarNameCacheConnection;
+ typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+ avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index adfb2dee86..da938712d7 100755
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -69,7 +69,7 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
LLInboxFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.tool_tip = params.name;
params.font_color = item_color;
@@ -86,7 +86,7 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
params.name = bridge->getDisplayName();
params.creation_date = bridge->getCreationDate();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 4c2213c198..5eadd65884 100755
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -91,17 +91,17 @@ LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
void LLPlacesInventoryPanel::saveFolderState()
{
mSavedFolderState->setApply(FALSE);
- mFolderRoot->applyFunctorRecursively(*mSavedFolderState);
+ mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);
}
// re-open folders which state was saved
void LLPlacesInventoryPanel::restoreFolderState()
{
mSavedFolderState->setApply(TRUE);
- mFolderRoot->applyFunctorRecursively(*mSavedFolderState);
+ mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);
LLOpenFoldersWithSelection opener;
- mFolderRoot->applyFunctorRecursively(opener);
- mFolderRoot->scrollToShowSelection();
+ mFolderRoot.get()->applyFunctorRecursively(opener);
+ mFolderRoot.get()->scrollToShowSelection();
}
S32 LLPlacesInventoryPanel::notify(const LLSD& info)
@@ -111,11 +111,11 @@ S32 LLPlacesInventoryPanel::notify(const LLSD& info)
std::string str_action = info["action"];
if(str_action == "select_first")
{
- return mFolderRoot->notify(info);
+ return mFolderRoot.get()->notify(info);
}
else if(str_action == "select_last")
{
- return mFolderRoot->notify(info);
+ return mFolderRoot.get()->notify(info);
}
}
return 0;
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 2e91ceee2e..040cbc22a6 100755
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -119,7 +119,6 @@ private:
LLSidepanelInventory::LLSidepanelInventory()
: LLPanel()
, mItemPanel(NULL)
- , mInventoryPanelInbox(NULL)
, mPanelMainInventory(NULL)
, mInboxEnabled(false)
, mCategoriesObserver(NULL)
@@ -299,7 +298,7 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
// (this can happen multiple times on the initial session that creates the inbox)
//
- if (mInventoryPanelInbox != NULL)
+ if (mInventoryPanelInbox.get() != NULL)
{
return;
}
@@ -333,7 +332,8 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
//
LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
- mInventoryPanelInbox = inbox->setupInventoryPanel();
+ LLInventoryPanel* inventory_panel = inbox->setupInventoryPanel();
+ mInventoryPanelInbox = inventory_panel->getInventoryPanelHandle();
}
void LLSidepanelInventory::enableInbox(bool enabled)
@@ -461,9 +461,9 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
- if (mInventoryPanelInbox)
+ if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
+ current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
}
if (!current_item)
@@ -614,10 +614,10 @@ void LLSidepanelInventory::updateVerbs()
bool LLSidepanelInventory::canShare()
{
- LLInventoryPanel* inbox = mInventoryPanelInbox;
+ LLInventoryPanel* inbox = mInventoryPanelInbox.get();
// Avoid flicker in the Recent tab while inventory is being loaded.
- if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty())
+ if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty())
&& (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
{
return false;
@@ -652,9 +652,9 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
if (!current_item)
{
- if (mInventoryPanelInbox)
+ if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
+ current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
}
if (!current_item)
@@ -671,12 +671,12 @@ U32 LLSidepanelInventory::getSelectedCount()
{
int count = 0;
- std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
count += selection_list.size();
- if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
+ if ((count == 0) && mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+ selection_list = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
count += selection_list.size();
}
@@ -714,9 +714,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
}
}
- if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL))
+ if (clearInbox && mInboxEnabled && mInventoryPanelInbox.get())
{
- mInventoryPanelInbox->clearSelection();
+ mInventoryPanelInbox.get()->clearSelection();
}
updateVerbs();
@@ -726,9 +726,9 @@ std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
{
std::set<LLFolderViewItem*> inventory_selected_uuids;
- if (mInboxEnabled && (mInventoryPanelInbox != NULL))
+ if (mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+ inventory_selected_uuids = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
}
return inventory_selected_uuids;
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index e8b2808d4f..17a3098db9 100755
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -57,7 +57,7 @@ public:
/*virtual*/ void onOpen(const LLSD& key);
LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
- LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox; }
+ LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox.get(); }
LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }
BOOL isMainInventoryPanelActive() const;
@@ -99,7 +99,7 @@ protected:
//
private:
LLPanel* mInventoryPanel; // Main inventory view
- LLInventoryPanel* mInventoryPanelInbox;
+ LLHandle<LLInventoryPanel> mInventoryPanelInbox;
LLSidepanelItemInfo* mItemPanel; // Individual item view
LLSidepanelTaskInfo* mTaskPanel; // Individual in-world object view
LLPanelMainInventory* mPanelMainInventory;
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 9824f2dd38..c983527762 100755
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -46,7 +46,7 @@
const S32 BOTTOM_PAD = VPAD * 3;
const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
S32 BUTTON_WIDTH = 90;
-// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
+// *TODO: magic numbers(?) - copied from llnotify.cpp(250)
const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index a8eeddb798..632a7d8bc3 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -262,6 +262,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);
LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);
LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
+ LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPermsDefault>);
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
@@ -270,7 +271,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
- LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index a179b61cff..991f6b40e6 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -30,6 +30,9 @@
#include "lldictionary.h"
#include "llmemory.h"
#include "llvisualparam.h"
+#include "llcontrol.h"
+
+extern LLControlGroup gSavedSettings;
static const std::string empty_string;
@@ -132,8 +135,9 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
- addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
- addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
+ bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
+ addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
+ addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Merchant Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index fff9821e86..e8ae621e41 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -65,6 +65,7 @@
#include "llavataractions.h"
#include "lllogininstance.h"
#include "llfavoritesbar.h"
+#include "llfloaterperms.h"
// Two do-nothing ops for use in callbacks.
void no_op_inventory_func(const LLUUID&) {}
@@ -989,24 +990,73 @@ void activate_gesture_cb(const LLUUID& inv_item)
LLGestureMgr::instance().activateGesture(inv_item);
}
-void create_gesture_cb(const LLUUID& inv_item)
+void create_script_cb(const LLUUID& inv_item)
{
- if (inv_item.isNull())
- return;
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts"));
- LLGestureMgr::instance().activateGesture(inv_item);
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
+void create_gesture_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLGestureMgr::instance().activateGesture(inv_item);
- LLViewerInventoryItem* item = gInventory.getItem(inv_item);
- if (!item) return;
- gInventory.updateItem(item);
- gInventory.notifyObservers();
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
- LLPreviewGesture* preview = LLPreviewGesture::show(inv_item, LLUUID::null);
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
+ LLPreviewGesture* preview = LLPreviewGesture::show(inv_item, LLUUID::null);
+ // Force to be entirely onscreen.
+ gFloaterView->adjustToFitScreen(preview, FALSE);
+ }
+ }
}
+void create_notecard_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards"));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
LLInventoryCallbackManager gInventoryCallbacks;
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
@@ -1260,22 +1310,45 @@ void create_new_item(const std::string& name,
LLViewerAssetType::generateDescriptionFor(asset_type, desc);
next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER;
-
- if (inv_type == LLInventoryType::IT_GESTURE)
- {
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
- NOT_WEARABLE, next_owner_perm, cb);
- }
- else
+ LLPointer<LLInventoryCallback> cb = NULL;
+
+ switch (inv_type)
{
- LLPointer<LLInventoryCallback> cb = NULL;
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
- NOT_WEARABLE, next_owner_perm, cb);
+ case LLInventoryType::IT_LSL:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_script_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Scripts");
+ break;
+ }
+
+ case LLInventoryType::IT_GESTURE:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Gestures");
+ break;
+ }
+
+ case LLInventoryType::IT_NOTECARD:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_notecard_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Notecards");
+ break;
+ }
+ default:
+ break;
}
-
+
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ parent_id,
+ LLTransactionID::tnull,
+ name,
+ desc,
+ asset_type,
+ inv_type,
+ NOT_WEARABLE,
+ next_owner_perm,
+ cb);
}
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
@@ -1316,7 +1389,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
parent_id,
LLAssetType::AT_LSL_TEXT,
LLInventoryType::IT_LSL,
- PERM_MOVE | PERM_TRANSFER);
+ PERM_MOVE | PERM_TRANSFER); // overridden in create_new_item
}
else if ("notecard" == type_name)
{
@@ -1325,7 +1398,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
parent_id,
LLAssetType::AT_NOTECARD,
LLInventoryType::IT_NOTECARD,
- PERM_ALL);
+ PERM_ALL); // overridden in create_new_item
}
else if ("gesture" == type_name)
{
@@ -1334,7 +1407,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
parent_id,
LLAssetType::AT_GESTURE,
LLInventoryType::IT_GESTURE,
- PERM_ALL);
+ PERM_ALL); // overridden in create_new_item
}
else
{
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index ab19a12014..dc2fdb8c8d 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -249,7 +249,9 @@ void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachme
void activate_gesture_cb(const LLUUID& inv_item);
+void create_script_cb(const LLUUID& inv_item);
void create_gesture_cb(const LLUUID& inv_item);
+void create_notecard_cb(const LLUUID& inv_item);
class AddFavoriteLandmarkCallback : public LLInventoryCallback
{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 21fb8d519b..e21752da53 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -191,7 +191,7 @@ public:
// 500 means "Internal Server error" but we decided it's okay to
// accept this and go past it in the MIME type probe
// 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com
- // 499 is a code specifc to join.secondlife.com (????) apparently safe to ignore
+ // 499 is a code specifc to join.secondlife.com (?) apparently safe to ignore
// if( ((status >= 200) && (status < 300)) ||
// ((status >= 400) && (status < 499)) ||
// (status == 500) ||
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index be78603e2d..16e75a4ad7 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -442,9 +442,9 @@ class LLFileUploadBulk : public view_listener_t
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms(),
- LLFloaterPerms::getGroupPerms(),
- LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
display_name,
callback,
expected_upload_cost,
@@ -1004,9 +1004,9 @@ void upload_done_callback(
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_NONE,
- PERM_NONE,
- PERM_NONE,
- PERM_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
display_name,
callback,
expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index df5c7d5c2e..db3e7049d9 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -644,25 +644,57 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
gAgent.sendMessage();
}
+static LLSD sSavedGroupInvite;
+static LLSD sSavedResponse;
+
bool join_group_response(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+// A bit of variable saving and restoring is used to deal with the case where your group list is full and you
+// receive an invitation to another group. The data from that invitation is stored in the sSaved
+// variables. If you then drop a group and click on the Join button the stored data is restored and used
+// to join the group.
+ LLSD notification_adjusted = notification;
+ LLSD response_adjusted = response;
+
+ std::string action = notification["name"];
+
+// Storing all the information by group id allows for the rare case of being at your maximum
+// group count and receiving more than one invitation.
+ std::string id = notification_adjusted["payload"]["group_id"].asString();
+
+ if ("JoinGroup" == action || "JoinGroupCanAfford" == action)
+ {
+ sSavedGroupInvite[id] = notification;
+ sSavedResponse[id] = response;
+ }
+ else if ("JoinedTooManyGroupsMember" == action)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == opt) // Join button pressed
+ {
+ notification_adjusted = sSavedGroupInvite[id];
+ response_adjusted = sSavedResponse[id];
+ }
+ }
+
+ S32 option = LLNotificationsUtil::getSelectedOption(notification_adjusted, response_adjusted);
bool accept_invite = false;
- LLUUID group_id = notification["payload"]["group_id"].asUUID();
- LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
- std::string name = notification["payload"]["name"].asString();
- std::string message = notification["payload"]["message"].asString();
- S32 fee = notification["payload"]["fee"].asInteger();
+ LLUUID group_id = notification_adjusted["payload"]["group_id"].asUUID();
+ LLUUID transaction_id = notification_adjusted["payload"]["transaction_id"].asUUID();
+ std::string name = notification_adjusted["payload"]["name"].asString();
+ std::string message = notification_adjusted["payload"]["message"].asString();
+ S32 fee = notification_adjusted["payload"]["fee"].asInteger();
if (option == 2 && !group_id.isNull())
{
LLGroupActions::show(group_id);
LLSD args;
args["MESSAGE"] = message;
- LLNotificationsUtil::add("JoinGroup", args, notification["payload"]);
+ LLNotificationsUtil::add("JoinGroup", args, notification_adjusted["payload"]);
return false;
}
+
if(option == 0 && !group_id.isNull())
{
// check for promotion or demotion.
@@ -677,7 +709,8 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
{
LLSD args;
args["NAME"] = name;
- LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
+ LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification_adjusted["payload"]);
+ return false;
}
}
@@ -691,7 +724,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
args["COST"] = llformat("%d", fee);
// Set the fee for next time to 0, so that we don't keep
// asking about a fee.
- LLSD next_payload = notification["payload"];
+ LLSD next_payload = notification_adjusted["payload"];
next_payload["fee"] = 0;
LLNotificationsUtil::add("JoinGroupCanAfford",
args,
@@ -717,6 +750,9 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
transaction_id);
}
+ sSavedGroupInvite[id] = LLSD::emptyMap();
+ sSavedResponse[id] = LLSD::emptyMap();
+
return false;
}
@@ -1876,6 +1912,7 @@ void inventory_offer_handler(LLOfferInfo* info)
return;
}
+ bool bAutoAccept(false);
// Avoid the Accept/Discard dialog if the user so desires. JC
if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
&& (info->mType == LLAssetType::AT_NOTECARD
@@ -1884,8 +1921,7 @@ void inventory_offer_handler(LLOfferInfo* info)
{
// For certain types, just accept the items into the inventory,
// and possibly open them on receipt depending upon "ShowNewInventory".
- info->forceResponse(IOR_ACCEPT);
- return;
+ bAutoAccept = true;
}
// Strip any SLURL from the message display. (DEV-2754)
@@ -1953,7 +1989,7 @@ void inventory_offer_handler(LLOfferInfo* info)
LLNotification::Params p;
// Object -> Agent Inventory Offer
- if (info->mFromObject)
+ if (info->mFromObject && !bAutoAccept)
{
// Inventory Slurls don't currently work for non agent transfers, so only display the object name.
args["ITEM_SLURL"] = msg;
@@ -1999,11 +2035,12 @@ void inventory_offer_handler(LLOfferInfo* info)
send_do_not_disturb_message(gMessageSystem, info->mFromID);
}
- // Inform user that there is a script floater via toast system
+ if( !bAutoAccept ) // if we auto accept, do not pester the user
{
+ // Inform user that there is a script floater via toast system
payload["give_inventory_notification"] = TRUE;
- p.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
+ p.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
}
}
@@ -5981,7 +6018,7 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
}
}
- send_sound_trigger(LLUUID(gSavedSettings.getString("UISndRestart")), 1.0f);
+ make_ui_sound("UISndRestart");
}
LLNotificationsUtil::add(notificationID, llsdBlock);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index e62998db70..21ab1bdca5 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -100,6 +100,7 @@
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
+#include "llfloaterperms.h"
//#define DEBUG_UPDATE_TYPE
@@ -2499,6 +2500,7 @@ void LLViewerObject::saveScript(
* interaction with doUpdateInventory() called below.
*/
lldebugs << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << llendl;
+
LLPointer<LLViewerInventoryItem> task_item =
new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
item->getAssetUUID(), item->getType(),
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index f667c2bf33..63c69b4481 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -76,6 +76,7 @@
#include "object_flags.h"
#include "llappviewer.h"
+#include "llfloaterperms.h"
extern F32 gMinObjectDistance;
extern BOOL gAnimateTextures;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index d848bfb1f9..61c383dd85 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -71,6 +71,7 @@
#include "stringize.h"
#include "llviewercontrol.h"
#include "llsdserialize.h"
+#include "llfloaterperms.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -1584,6 +1585,7 @@ void LLViewerRegion::unpackRegionHandshake()
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
+ capabilityNames.append("AgentPreferences");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
@@ -1854,6 +1856,8 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
{
mCapabilitiesReceivedSignal(getRegionID());
+ LLFloaterPermsDefault::sendInitialPerms();
+
// This is a single-shot signal. Forget callbacks to save resources.
mCapabilitiesReceivedSignal.disconnect_all_slots();
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 5da8a78b1b..805dc99654 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1362,49 +1362,10 @@ void LLPipeline::createLUTBuffers()
{
if (!mLightFunc)
{
- /*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
- U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
- U8* ls = new U8[lightResX*lightResY];
- F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
- // Calculate the (normalized) Blinn-Phong specular lookup texture.
- for (U32 y = 0; y < lightResY; ++y)
- {
- for (U32 x = 0; x < lightResX; ++x)
- {
- ls[y*lightResX+x] = 0;
- F32 sa = (F32) x/(lightResX-1);
- F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * specExp;
-
- // Nothing special here. Just your typical blinn-phong term.
- spec = powf(sa, n);
-
- // Apply our normalization function.
- // Note: This is the full equation that applies the full normalization curve, not an approximation.
- // This is fine, given we only need to create our LUT once per buffer initialization.
- // The only trade off is we have a really low dynamic range.
- // This means we have to account for things not being able to exceed 0 to 1 in our shaders.
- spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
-
- // Always sample at a 1.0/2.2 curve.
- // This "Gamma corrects" our specular term, boosting our lower exponent reflections.
- spec = powf(spec, 1.f/2.2f);
-
- // Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders.
- // This allows for our specular term to exceed a value of 1 in our shaders.
- // This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1.
- // Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times.
- // This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents.
- // Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
- ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
- }
- }*/
-
-
U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
F32* ls = new F32[lightResX*lightResY];
- //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
// Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
for (U32 y = 0; y < lightResY; ++y)
{
@@ -1413,7 +1374,7 @@ void LLPipeline::createLUTBuffers()
ls[y*lightResX+x] = 0;
F32 sa = (F32) x/(lightResX-1);
F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * 368;
+ F32 n = spec * spec * specExp;
// Nothing special here. Just your typical blinn-phong term.
spec = powf(sa, n);
@@ -1426,23 +1387,6 @@ void LLPipeline::createLUTBuffers()
// Since we use R16F, we no longer have a dynamic range issue we need to work around here.
// Though some older drivers may not like this, newer drivers shouldn't have this problem.
ls[y*lightResX+x] = spec;
-
-
- //beckmann distribution
- /*F32 alpha = acosf((F32) x/(lightResX-1));
- F32 m = 1.f - (F32) y/(lightResY-1);
-
- F32 cos4_alpha = cosf(alpha);
- cos4_alpha *= cos4_alpha;
- cos4_alpha *= cos4_alpha;
-
- F32 tan_alpha = tanf(alpha);
- F32 tan2_alpha = tan_alpha*tan_alpha;
-
- F32 k = expf(-(tan2_alpha)/(m*m)) /
- (3.14159f*m*m*cos4_alpha);
-
- ls[y*lightResX+x] = k;*/
}
}
@@ -1455,7 +1399,6 @@ void LLPipeline::createLUTBuffers()
LLImageGL::generateTextures(1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
- //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
index 5fdd4aa49d..49be4290c7 100755
--- a/indra/newview/skins/default/xui/en/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
@@ -47,7 +47,7 @@
width="16" />
<scroll_list.columns
name="text"
- width="234" />
+ relative_width="1" />
</scroll_list>
<text
type="string"
@@ -77,7 +77,7 @@
width="16" />
<scroll_list.columns
name="text"
- width="234" />
+ relative_width="1" />
</scroll_list>
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
deleted file mode 100755
index ff454e3ebf..0000000000
--- a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="180"
- layout="topleft"
- name="perm prefs"
- help_topic="perm_prefs"
- save_rect="true"
- title="DEFAULT UPLOAD PERMISSIONS"
- width="315">
- <panel
- follows="left|top|right|bottom"
- height="120"
- label="Permissions"
- layout="topleft"
- left="10"
- name="permissions"
- top="20"
- width="315">
- <check_box
- control_name="ShareWithGroup"
- height="16"
- label="Share with group"
- layout="topleft"
- left="10"
- name="share_with_group"
- top="5"
- width="150" />
- <check_box
- control_name="EveryoneCopy"
- height="16"
- label="Allow anyone to copy"
- layout="topleft"
- left_delta="0"
- name="everyone_copy"
- top_pad="5"
- width="150" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- name="NextOwnerLabel"
- top_pad="5"
- width="200">
- Next owner can:
- </text>
- <check_box
- control_name="NextOwnerModify"
- height="16"
- label="Modify"
- layout="topleft"
- left_delta="0"
- name="next_owner_modify"
- top_pad="5"
- width="150" />
- <check_box
- control_name="NextOwnerCopy"
- height="16"
- label="Copy"
- layout="topleft"
- left_delta="0"
- name="next_owner_copy"
- top_pad="5"
- width="150" >
- <check_box.commit_callback
- function="Perms.Copy" />
- </check_box>
- <check_box
- enabled_control="NextOwnerCopy"
- control_name="NextOwnerTransfer"
- enabled="false"
- height="16"
- initial_value="true"
- label="Resell/Give away"
- layout="topleft"
- left_delta="0"
- name="next_owner_transfer"
- top_pad="5"
- width="150" />
- </panel>
- <button
- height="20"
- label="OK"
- label_selected="OK"
- layout="topleft"
- left="90"
- name="ok"
- top="150"
- width="100">
- <button.commit_callback
- function="Perms.OK" />
- </button>
- <button
- height="20"
- label="Cancel"
- label_selected="Cancel"
- layout="topleft"
- left_pad="5"
- name="cancel"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="Perms.Cancel" />
- </button>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_perms_default.xml b/indra/newview/skins/default/xui/en/floater_perms_default.xml
new file mode 100644
index 0000000000..ceb260fffb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_perms_default.xml
@@ -0,0 +1,503 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ height="250"
+ layout="topleft"
+ name="perms default"
+ help_topic="perms_default"
+ save_rect="true"
+ title="DEFAULT CREATION PERMISSIONS"
+ width="700">
+ <panel
+ follows="left|top|right|bottom"
+ height="200"
+ label="Default Permissions"
+ layout="topleft"
+ left="10"
+ name="default permissions"
+ top="20"
+ width="690">
+ <view_border
+ bevel_style="none"
+ height="18"
+ top="8"
+ left="0"
+ width="430" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="right"
+ layout="topleft"
+ left="0"
+ top="10"
+ width="115">
+ Next owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ width="100">
+ Copy
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ width="100">
+ Modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ width="100">
+ Transfer
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="32"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ word_wrap="true"
+ width="100">
+ Share with group
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="32"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ word_wrap="true"
+ width="120">
+ Allow anyone to copy
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ tool_tip="Set default permissions for when Objects are created"
+ width="100">
+ Objects
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Object"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="ObjectsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="objects_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Objects" />
+ </check_box>
+ <check_box
+ control_name="ObjectsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="objects_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="ObjectsNextOwnerCopy"
+ control_name="ObjectsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="objects_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="ObjectsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="objects_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="ObjectsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="objects_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for uploaded items"
+ width="100">
+ Uploads
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Texture"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="UploadsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="uploads_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Uploads" />
+ </check_box>
+ <check_box
+ control_name="UploadsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="uploads_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="UploadsNextOwnerCopy"
+ control_name="UploadsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="uploads_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="UploadsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="uploads_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="UploadsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="uploads_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Scripts are created"
+ width="100">
+ Scripts
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Script"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="ScriptsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="scripts_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Scripts" />
+ </check_box>
+ <check_box
+ control_name="ScriptsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="scripts_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="ScriptsNextOwnerCopy"
+ control_name="ScriptsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="scripts_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="ScriptsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="scripts_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="ScriptsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="scripts_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Notecards are created"
+ width="100">
+ Notecards
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Notecard"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="NotecardsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="notecards_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Notecards" />
+ </check_box>
+ <check_box
+ control_name="NotecardsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="notecards_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="NotecardsNextOwnerCopy"
+ control_name="NotecardsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="notecards_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="NotecardsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="notecards_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="NotecardsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="notecards_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Gestures are created"
+ width="100">
+ Gestures
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Gesture"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="GesturesNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="gestures_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Gestures" />
+ </check_box>
+ <check_box
+ control_name="GesturesNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="gestures_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="GesturesNextOwnerCopy"
+ control_name="GesturesNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="gestures_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="GesturesShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="gestures_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="GesturesEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="gestures_a"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Clothing or Body Parts are created"
+ width="100">
+ Wearables
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_BodyShape"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="WearablesNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="wearables_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Wearables" />
+ </check_box>
+ <check_box
+ control_name="WearablesNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="wearables_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="WearablesNextOwnerCopy"
+ control_name="WearablesNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="wearables_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="WearablesShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="wearables_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="WearablesEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="wearables_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ </panel>
+ <button
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ name="ok"
+ left="475"
+ width="100">
+ <button.commit_callback
+ function="PermsDefault.OK" />
+ </button>
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="PermsDefault.Cancel" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 29720a680b..afeb1bf226 100755
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -63,13 +63,6 @@
function="File.UploadBulk"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Set Default Upload Permissions"
- name="perm prefs">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="perm_prefs" />
- </menu_item_call>
</menu>
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 7e8d2aaf9a..b30553281f 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1187,8 +1187,9 @@
<menu_item_call.on_enable
function="SomethingSelected" />
</menu_item_call>
+ <menu_item_separator/>
<menu_item_call
- label="Grid Options"
+ label="Grid Options..."
name="Grid Options"
shortcut="control|shift|B">
<menu_item_call.on_click
@@ -1197,6 +1198,13 @@
<menu_item_call.on_enable
function="Tools.EnableToolNotPie" />
</menu_item_call>
+ <menu_item_call
+ label="Set Default Permissions..."
+ name="Set default permissions">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="perms_default" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -1264,13 +1272,6 @@
function="File.UploadBulk"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Set Default Upload Permissions"
- name="perm prefs">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="perm_prefs" />
- </menu_item_call>
</menu>
<menu_item_separator/>
<menu_item_call
@@ -2559,6 +2560,16 @@
parameter="lights" />
</menu_item_check>
<menu_item_check
+ label="Particles"
+ name="Particles">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="particles" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="particles" />
+ </menu_item_check>
+ <menu_item_check
label="Collision Skeleton"
name="Collision Skeleton">
<menu_item_check.on_check
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c97af4e9ef..9af80a23a7 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -271,7 +271,7 @@ See the [[MARKETPLACE_IMPORTS_URL] error log] for more information.
icon="OutboxStatus_Error"
name="OutboxImportFailed"
type="outbox">
-Transfer failed
+Transfer failed with error &apos;[ERROR_CODE]&apos;
No folders were sent to the Marketplace because of a system or network error. Try again later.
@@ -284,7 +284,7 @@ No folders were sent to the Marketplace because of a system or network error. T
icon="OutboxStatus_Error"
name="OutboxInitFailed"
type="outbox">
-Marketplace initialization failed
+Marketplace initialization failed with error &apos;[ERROR_CODE]&apos;
Initialization with the Marketplace failed because of a system or network error. Try again later.
@@ -10223,5 +10223,16 @@ Cannot create large prims that intersect other players. Please re-try when othe
name="okignore"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DefaultObjectPermissions"
+ type="alert">
+ There was a problem saving the default permissions due to the following reason: [REASON]. Please try setting the default permissions later.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 50fd57494f..2e778014c5 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -222,4 +222,15 @@
name="show_develop_menu_check"
top_pad="5"
width="237"/>
+ <button
+ height="20"
+ label="Default Creation Permissions"
+ layout="topleft"
+ name="default_creation_permissions"
+ left="30"
+ top_pad = "20"
+ width="250">
+ <button.commit_callback
+ function="Pref.PermsDefault" />
+ </button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 67f75fe1d2..e44a013dc7 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -419,6 +419,8 @@ Please try logging in again in a minute.</string>
<string name="multiple_textures">Multiple</string>
<string name="use_texture">Use texture</string>
+ <string name="manip_hint1">Move mouse cursor over ruler</string>
+ <string name="manip_hint2">to snap to grid</string>
<!-- world map -->
<string name="texture_loading">Loading...</string>
@@ -2245,6 +2247,16 @@ If you'd like to become a merchant, you'll need to [[MARKETPLACE_CREATE_STORE_UR
<string name="InventoryOutboxNoItems">
Drag folders to this area and click "Send to Marketplace" to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].
</string>
+ <string name="InventoryOutboxInitializingTitle">Initializing Marketplace.</string>
+ <string name="InventoryOutboxInitializingTooltip"></string>
+ <string name="InventoryOutboxInitializing">
+We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace store].
+ </string>
+ <string name="InventoryOutboxErrorTitle">Marketplace Errors.</string>
+ <string name="InventoryOutboxErrorTooltip"></string>
+ <string name="InventoryOutboxError">
+The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
+ </string>
<string name="Marketplace Error None">No errors</string>
<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string>