summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt12
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/commands.xml30
-rw-r--r--indra/newview/app_settings/settings.xml43
-rw-r--r--indra/newview/llagentcamera.cpp8
-rw-r--r--indra/newview/llagentcamera.h1
-rw-r--r--indra/newview/llagentwearables.cpp4
-rw-r--r--indra/newview/llappearancemgr.cpp20
-rw-r--r--indra/newview/llappviewer.cpp24
-rw-r--r--indra/newview/llappviewer.h4
-rw-r--r--indra/newview/llcontrolavatar.cpp10
-rw-r--r--indra/newview/llconversationlog.cpp4
-rw-r--r--indra/newview/llface.cpp2
-rw-r--r--indra/newview/llfavoritesbar.cpp70
-rw-r--r--indra/newview/llfavoritesbar.h9
-rw-r--r--indra/newview/llflickrconnect.cpp538
-rw-r--r--indra/newview/llflickrconnect.h108
-rw-r--r--indra/newview/llfloaterbigpreview.h2
-rw-r--r--indra/newview/llfloaterconversationpreview.cpp7
-rw-r--r--indra/newview/llfloaterconversationpreview.h1
-rw-r--r--indra/newview/llfloaterexperiences.cpp8
-rw-r--r--indra/newview/llfloaterflickr.cpp787
-rw-r--r--indra/newview/llfloaterflickr.h134
-rw-r--r--indra/newview/llfloaterforgetuser.cpp348
-rw-r--r--indra/newview/llfloaterforgetuser.h56
-rw-r--r--indra/newview/llfloatergesture.cpp53
-rw-r--r--indra/newview/llfloatergesture.h3
-rw-r--r--indra/newview/llfloatergridstatus.cpp2
-rw-r--r--indra/newview/llfloatergroupinvite.cpp11
-rw-r--r--indra/newview/llfloatergroupinvite.h2
-rw-r--r--indra/newview/llfloaterland.cpp2
-rw-r--r--indra/newview/llfloaterlinkreplace.cpp85
-rw-r--r--indra/newview/llfloaterlinkreplace.h1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp9
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp84
-rw-r--r--indra/newview/llfloaterpreference.h3
-rw-r--r--indra/newview/llfloaterproperties.cpp2
-rw-r--r--indra/newview/llfloatersnapshot.cpp7
-rw-r--r--indra/newview/llfloatertwitter.cpp810
-rw-r--r--indra/newview/llfloatertwitter.h138
-rw-r--r--indra/newview/llfloaterwebcontent.cpp22
-rw-r--r--indra/newview/llhudeffectbeam.cpp12
-rw-r--r--indra/newview/llhudeffectlookat.cpp20
-rw-r--r--indra/newview/llhudeffectpointat.cpp20
-rw-r--r--indra/newview/llhudeffecttrail.cpp12
-rw-r--r--indra/newview/llimagefiltersmanager.cpp2
-rw-r--r--indra/newview/llimagefiltersmanager.h2
-rw-r--r--indra/newview/llimprocessing.cpp22
-rw-r--r--indra/newview/llimview.cpp11
-rw-r--r--indra/newview/llimview.h1
-rw-r--r--indra/newview/llinventorybridge.cpp2
-rw-r--r--indra/newview/llinventoryfilter.cpp74
-rw-r--r--indra/newview/llinventoryfilter.h3
-rw-r--r--indra/newview/llinventorypanel.cpp1
-rw-r--r--indra/newview/lllogchat.cpp47
-rw-r--r--indra/newview/lllogchat.h3
-rw-r--r--indra/newview/llloginhandler.cpp7
-rw-r--r--indra/newview/llmediactrl.cpp19
-rw-r--r--indra/newview/llmediactrl.h1
-rw-r--r--indra/newview/llmoveview.cpp2
-rw-r--r--indra/newview/llnotificationlistitem.cpp1
-rw-r--r--indra/newview/llpanelclassified.cpp1
-rw-r--r--indra/newview/llpanelgrouproles.cpp2
-rw-r--r--indra/newview/llpanellogin.cpp498
-rw-r--r--indra/newview/llpanellogin.h17
-rw-r--r--indra/newview/llpanelnearbymedia.cpp23
-rw-r--r--indra/newview/llpanelobjectinventory.cpp9
-rw-r--r--indra/newview/llpanelplaces.cpp6
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp16
-rw-r--r--indra/newview/llpanelsnapshotoptions.cpp30
-rw-r--r--indra/newview/llpanelvolumepulldown.cpp2
-rw-r--r--indra/newview/llsecapi.h50
-rw-r--r--indra/newview/llsechandler_basic.cpp189
-rw-r--r--indra/newview/llsechandler_basic.h65
-rw-r--r--indra/newview/llselectmgr.cpp109
-rw-r--r--indra/newview/llselectmgr.h19
-rw-r--r--indra/newview/llsidepanelappearance.cpp2
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp142
-rw-r--r--indra/newview/llsidepaneliteminfo.h15
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp63
-rw-r--r--indra/newview/llsidepaneltaskinfo.h1
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp2
-rw-r--r--indra/newview/llstartup.cpp80
-rw-r--r--indra/newview/llstartup.h1
-rw-r--r--indra/newview/llstatusbar.cpp35
-rw-r--r--indra/newview/llstatusbar.h3
-rw-r--r--indra/newview/lltexturecache.cpp126
-rw-r--r--indra/newview/lltexturecache.h10
-rw-r--r--indra/newview/lltoastalertpanel.cpp72
-rw-r--r--indra/newview/lltoastalertpanel.h5
-rw-r--r--indra/newview/lltoastnotifypanel.cpp23
-rw-r--r--indra/newview/lltoastnotifypanel.h2
-rw-r--r--indra/newview/lltoastpanel.cpp108
-rw-r--r--indra/newview/lltoastpanel.h19
-rw-r--r--indra/newview/lltool.cpp6
-rw-r--r--indra/newview/lltool.h1
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/lltoolgrab.cpp11
-rw-r--r--indra/newview/lltoolmgr.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp37
-rw-r--r--indra/newview/lltoolpie.h1
-rw-r--r--indra/newview/lltwitterconnect.cpp576
-rw-r--r--indra/newview/lltwitterconnect.h107
-rw-r--r--indra/newview/llviewerdisplay.cpp2
-rw-r--r--indra/newview/llviewerfloaterreg.cpp9
-rw-r--r--indra/newview/llviewerinventory.cpp2
-rw-r--r--indra/newview/llviewerjointattachment.cpp16
-rw-r--r--indra/newview/llviewerjointattachment.h2
-rw-r--r--indra/newview/llviewermedia.cpp15
-rw-r--r--indra/newview/llviewermedia.h5
-rw-r--r--indra/newview/llviewermediafocus.cpp7
-rw-r--r--indra/newview/llviewermenu.cpp45
-rw-r--r--indra/newview/llviewermessage.cpp237
-rw-r--r--indra/newview/llviewermessage.h3
-rw-r--r--indra/newview/llviewerobject.cpp262
-rw-r--r--indra/newview/llviewerobject.h14
-rw-r--r--indra/newview/llviewerobjectlist.cpp2
-rw-r--r--indra/newview/llviewerparcelaskplay.cpp301
-rw-r--r--indra/newview/llviewerparcelaskplay.h89
-rw-r--r--indra/newview/llviewerparcelmediaautoplay.cpp53
-rw-r--r--indra/newview/llviewerparcelmediaautoplay.h3
-rw-r--r--indra/newview/llviewerparcelmgr.cpp57
-rw-r--r--indra/newview/llviewerparcelmgr.h3
-rw-r--r--indra/newview/llviewerregion.cpp2
-rw-r--r--indra/newview/llviewerstats.cpp21
-rw-r--r--indra/newview/llviewerwindow.cpp93
-rw-r--r--indra/newview/llviewerwindow.h7
-rw-r--r--indra/newview/llvoavatar.cpp92
-rw-r--r--indra/newview/llvoiceclient.cpp23
-rw-r--r--indra/newview/llvoiceclient.h6
-rw-r--r--indra/newview/pipeline.cpp24
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/de/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/de/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_avatar_textures.xml137
-rw-r--r--indra/newview/skins/default/xui/en/floater_flickr.xml90
-rw-r--r--indra/newview/skins/default/xui/en/floater_forget_user.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_merchant_outbox.xml156
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_trash.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_twitter.xml75
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml10
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml30
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml148
-rw-r--r--indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_account.xml79
-rw-r--r--indra/newview/skins/default/xui/en/panel_flickr_photo.xml259
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml60
-rw-r--r--indra/newview/skins/default/xui/en/panel_outbox_inventory.xml31
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml49
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_sound.xml53
-rw-r--r--indra/newview/skins/default/xui/en/panel_snapshot_options.xml34
-rw-r--r--indra/newview/skins/default/xui/en/panel_twitter_account.xml81
-rw-r--r--indra/newview/skins/default/xui/en/panel_twitter_photo.xml196
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml32
-rw-r--r--indra/newview/skins/default/xui/en/teleport_strings.xml3
-rw-r--r--indra/newview/skins/default/xui/es/floater_about_land.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/es/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about_land.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_about_land.xml8
-rw-r--r--indra/newview/skins/default/xui/it/floater_buy_currency.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/it/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml29
-rw-r--r--indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about_land.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about_land.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_chat.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about_land.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml32
-rw-r--r--indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/tests/llsecapi_test.cpp10
-rwxr-xr-xindra/newview/viewer_manifest.py1
199 files changed, 3951 insertions, 5656 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 694e89ab99..cf8f99ed25 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -208,7 +208,6 @@ set(viewer_SOURCE_FILES
llfilteredwearablelist.cpp
llfirstuse.cpp
llflexibleobject.cpp
- llflickrconnect.cpp
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloaterauction.cpp
@@ -244,8 +243,8 @@ set(viewer_SOURCE_FILES
llfloaterexperiencepicker.cpp
llfloaterexperienceprofile.cpp
llfloaterexperiences.cpp
- llfloaterflickr.cpp
llfloaterfonttest.cpp
+ llfloaterforgetuser.cpp
llfloatergesture.cpp
llfloatergodtools.cpp
llfloatergotoline.cpp
@@ -317,7 +316,6 @@ set(viewer_SOURCE_FILES
llfloatertos.cpp
llfloatertoybox.cpp
llfloatertranslationsettings.cpp
- llfloatertwitter.cpp
llfloateruipreview.cpp
llfloaterurlentry.cpp
llfloatervoiceeffect.cpp
@@ -615,7 +613,6 @@ set(viewer_SOURCE_FILES
lltransientdockablefloater.cpp
lltransientfloatermgr.cpp
lltranslate.cpp
- lltwitterconnect.cpp
lluiavatar.cpp
lluilistener.cpp
lluploaddialog.cpp
@@ -663,6 +660,7 @@ set(viewer_SOURCE_FILES
llviewerobject.cpp
llviewerobjectlist.cpp
llvieweroctree.cpp
+ llviewerparcelaskplay.cpp
llviewerparcelmedia.cpp
llviewerparcelmediaautoplay.cpp
llviewerparcelmgr.cpp
@@ -833,7 +831,6 @@ set(viewer_HEADER_FILES
llfilteredwearablelist.h
llfirstuse.h
llflexibleobject.h
- llflickrconnect.h
llfloaterabout.h
llfloaterbvhpreview.h
llfloaterauction.h
@@ -869,8 +866,8 @@ set(viewer_HEADER_FILES
llfloaterexperiencepicker.h
llfloaterexperienceprofile.h
llfloaterexperiences.h
- llfloaterflickr.h
llfloaterfonttest.h
+ llfloaterforgetuser.h
llfloatergesture.h
llfloatergodtools.h
llfloatergotoline.h
@@ -945,7 +942,6 @@ set(viewer_HEADER_FILES
llfloatertos.h
llfloatertoybox.h
llfloatertranslationsettings.h
- llfloatertwitter.h
llfloateruipreview.h
llfloaterurlentry.h
llfloatervoiceeffect.h
@@ -1233,7 +1229,6 @@ set(viewer_HEADER_FILES
lltransientdockablefloater.h
lltransientfloatermgr.h
lltranslate.h
- lltwitterconnect.h
lluiconstants.h
lluiavatar.h
lluilistener.h
@@ -1282,6 +1277,7 @@ set(viewer_HEADER_FILES
llviewerobject.h
llviewerobjectlist.h
llvieweroctree.h
+ llviewerparcelaskplay.h
llviewerparcelmedia.h
llviewerparcelmediaautoplay.h
llviewerparcelmgr.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index b98d1d3fa7..c44315e3f0 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.3.5
+6.3.7
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index cab0c523b2..98143bbce6 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -150,16 +150,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="moveview"
/>
- <command name="outbox"
- available_in_toybox="false"
- icon="Command_Outbox_Icon"
- label_ref="Command_Outbox_Label"
- tooltip_ref="Command_Outbox_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="outbox"
- is_running_function="Floater.IsOpen"
- is_running_parameters="outbox"
- />
<command name="people"
available_in_toybox="true"
icon="Command_People_Icon"
@@ -228,26 +218,6 @@
is_running_function="Floater.IsOpen"
is_running_parameters="snapshot"
/>
- <command name="flickr"
- available_in_toybox="true"
- icon="Command_Flickr_Icon"
- label_ref="Command_Flickr_Label"
- tooltip_ref="Command_Flickr_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="flickr"
- is_running_function="Floater.IsOpen"
- is_running_parameters="flickr"
- />
- <command name="twitter"
- available_in_toybox="true"
- icon="Command_Twitter_Icon"
- label_ref="Command_Twitter_Label"
- tooltip_ref="Command_Twitter_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="twitter"
- is_running_function="Floater.IsOpen"
- is_running_parameters="twitter"
- />
<command name="speak"
available_in_toybox="true"
icon="Command_Speak_Icon"
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 49601ae98f..da1e87fda4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4913,7 +4913,7 @@
<key>InventoryOutboxDisplayBoth</key>
<map>
<key>Comment</key>
- <string>Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
+ <string>(Deprecated) Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -5304,7 +5304,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>https://secondlife-status.statuspage.io/history.atom</string>
+ <string>https://status.secondlifegrid.net/history.atom</string>
</map>
<key>GridStatusUpdateDelay</key>
<map>
@@ -7494,11 +7494,11 @@
<key>ParcelMediaAutoPlayEnable</key>
<map>
<key>Comment</key>
- <string>Auto play parcel media when available</string>
+ <string>Auto play parcel media when available. 0 - Do not autoplay; 1- Autoplay; 2 - Ask</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
<integer>1</integer>
</map>
@@ -8434,6 +8434,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RememberUser</key>
+ <map>
+ <key>Comment</key>
+ <string>Keep user name for next login</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RememberPassword</key>
<map>
<key>Comment</key>
@@ -9276,7 +9287,7 @@
<key>RenderShadowResolutionScale</key>
<map>
<key>Comment</key>
- <string>Scale of shadow map resolution vs. screen resolution</string>
+ <string>Scale of shadow map resolution vs. screen resolution (only positivie values are allowed)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -11219,6 +11230,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>BasicUITooltips</key>
+ <map>
+ <key>Comment</key>
+ <string>Show tooltips for various 2D UI elements like buttons or checkboxes, won't supress tooltips like drag'n'drop, inworld, links or media</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>ShowHoverTips</key>
<map>
<key>Comment</key>
@@ -13133,6 +13155,17 @@
<key>Value</key>
<real>3</real>
</map>
+ <key>HUDScaleFactor</key>
+ <map>
+ <key>Comment</key>
+ <string>Scale of HUD attachments</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
<key>UIScaleFactor</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 0b4b848014..8edb1a5f0b 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -807,6 +807,12 @@ void LLAgentCamera::setCameraZoomFraction(F32 fraction)
startCameraAnimation();
}
+F32 LLAgentCamera::getAgentHUDTargetZoom()
+{
+ static LLCachedControl<F32> hud_scale_factor(gSavedSettings, "HUDScaleFactor");
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ return (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) ? hud_scale_factor*gAgentCamera.mHUDTargetZoom : hud_scale_factor;
+}
//-----------------------------------------------------------------------------
// cameraOrbitAround()
@@ -1449,7 +1455,7 @@ void LLAgentCamera::updateCamera()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
{
// clear any existing "early" movements of attachment
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index d087de1e2f..a4bc8434b0 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -266,6 +266,7 @@ public:
F32 getCameraZoomFraction(); // Get camera zoom as fraction of minimum and maximum zoom
void setCameraZoomFraction(F32 fraction); // Set camera zoom as fraction of minimum and maximum zoom
F32 calcCameraFOVZoomFactor();
+ F32 getAgentHUDTargetZoom();
//--------------------------------------------------------------------
// Pan
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 15e4de8f69..013c40f557 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1323,7 +1323,7 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *objectp = (*attachment_iter);
+ LLViewerObject *objectp = attachment_iter->get();
if (objectp)
{
LLUUID object_item_id = objectp->getAttachmentItemID();
@@ -1387,7 +1387,7 @@ std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *objectp = (*attachment_iter);
+ LLViewerObject *objectp = attachment_iter->get();
if (objectp && objectp->isTempAttachment())
{
temp_attachs.push_back(objectp);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 7325ec598a..3c3dda1765 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1713,6 +1713,24 @@ void LLAppearanceMgr::slamCategoryLinks(const LLUUID& src_id, const LLUUID& dst_
LLInventoryModel::item_array_t* items;
LLSD contents = LLSD::emptyArray();
gInventory.getDirectDescendentsOf(src_id, cats, items);
+ if (!cats || !items)
+ {
+ // NULL means the call failed -- cats/items map doesn't exist (note: this does NOT mean
+ // that the cat just doesn't have any items or subfolders).
+ LLViewerInventoryCategory* category = gInventory.getCategory(src_id);
+ if (category)
+ {
+ LL_WARNS() << "Category '" << category->getName() << "' descendents corrupted, linking content failed." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "Category could not be retrieved, linking content failed." << LL_ENDL;
+ }
+ llassert(cats != NULL && items != NULL);
+
+ return;
+ }
+
LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
iter != items->end();
@@ -2911,7 +2929,7 @@ void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
if (attached_object)
{
objects_to_remove.push_back(attached_object);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ff897ef962..b232a8c3bb 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -68,6 +68,7 @@
#include "llviewerwindow.h"
#include "llviewerdisplay.h"
#include "llviewermedia.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewermediafocus.h"
#include "llviewermessage.h"
@@ -670,7 +671,8 @@ LLAppViewer::LLAppViewer()
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
- mPurgeOnExit(false),
+ mPurgeCacheOnExit(false),
+ mPurgeUserDataOnExit(false),
mSecondInstance(false),
mSavedFinalSnapshot(false),
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
@@ -1923,6 +1925,11 @@ bool LLAppViewer::cleanup()
{
gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
LL_INFOS() << "Saved settings" << LL_ENDL;
+
+ if (LLViewerParcelAskPlay::instanceExists())
+ {
+ LLViewerParcelAskPlay::getInstance()->saveSettings();
+ }
}
std::string warnings_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Warnings"));
@@ -1943,7 +1950,7 @@ bool LLAppViewer::cleanup()
LLConversationLog::instance().cache();
}
- if (mPurgeOnExit)
+ if (mPurgeCacheOnExit)
{
LL_INFOS() << "Purging all cache files on exit" << LL_ENDL;
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
@@ -1984,6 +1991,14 @@ bool LLAppViewer::cleanup()
}
}
+ if (mPurgeUserDataOnExit)
+ {
+ // Ideally we should not save anything from this session since it is going to be purged now,
+ // but this is a very 'rare' case (user deleting himself), not worth overcomplicating 'save&cleanup' code
+ std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + LLStartUp::getUserId();
+ gDirUtilp->deleteDirAndContents(user_path);
+ }
+
// Delete workers first
// shotdown all worker threads before deleting them in case of co-dependencies
mAppCoreHttp.requestStop();
@@ -2125,6 +2140,9 @@ void watchdog_llerrs_callback(const std::string &error_string)
{
gLLErrorActivated = true;
+ gDebugInfo["FatalMessage"] = error_string;
+ LLAppViewer::instance()->writeDebugInfo();
+
#ifdef LL_WINDOWS
RaiseException(0,0,0,0);
#else
@@ -4452,7 +4470,7 @@ void LLAppViewer::badNetworkHandler()
// Flush all of our caches on exit in the case of disconnect due to
// invalid packets.
- mPurgeOnExit = TRUE;
+ mPurgeCacheOnExit = TRUE;
std::ostringstream message;
message <<
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 788fe6a19b..1298ba51e2 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -190,6 +190,7 @@ public:
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
+ void purgeUserDataOnExit() { mPurgeUserDataOnExit = true; }
void purgeCache(); // Clear the local cache.
void purgeCacheImmediate(); //clear local cache immediately.
S32 updateTextureThreads(F32 max_time);
@@ -281,7 +282,8 @@ private:
std::string mSerialNumber;
bool mPurgeCache;
- bool mPurgeOnExit;
+ bool mPurgeCacheOnExit;
+ bool mPurgeUserDataOnExit;
LLViewerJoystick* joystick;
bool mSavedFinalSnapshot;
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 92eeebd705..f0682dc1ba 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -171,7 +171,10 @@ void LLControlAvatar::matchVolumeTransform()
if (attached_av)
{
LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp);
- setPositionAgent(mRootVolp->getRenderPosition());
+ if (getRegion() && !isDead())
+ {
+ setPositionAgent(mRootVolp->getRenderPosition());
+ }
attach->updateWorldPRSParent();
LLVector3 joint_pos = attach->getWorldPosition();
LLQuaternion joint_rot = attach->getWorldRotation();
@@ -227,7 +230,10 @@ void LLControlAvatar::matchVolumeTransform()
#endif
setRotation(bind_rot*obj_rot);
mRoot->setWorldRotation(bind_rot*obj_rot);
- setPositionAgent(vol_pos);
+ if (getRegion() && !isDead())
+ {
+ setPositionAgent(vol_pos);
+ }
mRoot->setPosition(vol_pos + mPositionConstraintFixup);
F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale");
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index f7c61efce0..5539fa75dd 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -490,7 +490,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
(S32)conv_it->getConversationType(),
(S32)0,
(S32)conv_it->hasOfflineMessages(),
- conv_it->getConversationName().c_str(),
+ LLURI::escape(conv_it->getConversationName()).c_str(),
participant_id.c_str(),
conversation_id.c_str(),
LLURI::escape(conv_it->getHistoryFileName()).c_str());
@@ -545,7 +545,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
params.time(LLUnits::Seconds::fromValue(time))
.conversation_type((SessionType)stype)
.has_offline_ims(has_offline_ims)
- .conversation_name(conv_name_buffer)
+ .conversation_name(LLURI::unescape(conv_name_buffer))
.participant_id(LLUUID(part_id_buffer))
.session_id(LLUUID(conv_id_buffer))
.history_filename(LLURI::unescape(history_file_name));
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 1587903a15..85ee33edb1 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -456,7 +456,7 @@ void LLFace::setTextureIndex(U8 index)
}
else
{
- if (mDrawInfo && !mDrawInfo->mTextureList.empty())
+ if (mDrawInfo && mDrawInfo->mTextureList.size() <= 1)
{
LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL;
}
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 5b4b7789b4..17952349dc 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1493,19 +1493,25 @@ void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
}
// static
-std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
+std::string LLFavoritesOrderStorage::getStoredFavoritesFilename(const std::string &grid)
{
- std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+ std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
return (user_dir.empty() ? ""
: gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"stored_favorites_"
- + LLGridManager::getInstance()->getGrid()
+ + grid
+ ".xml")
);
}
// static
+std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
+{
+ return getStoredFavoritesFilename(LLGridManager::getInstance()->getGrid());
+}
+
+// static
void LLFavoritesOrderStorage::destroyClass()
{
LLFavoritesOrderStorage::instance().cleanup();
@@ -1602,6 +1608,64 @@ void LLFavoritesOrderStorage::load()
}
}
+// static
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser(const std::string &user, const std::string &grid)
+{
+ std::string filename = getStoredFavoritesFilename(grid);
+ if (!filename.empty())
+ {
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, file);
+ file.close();
+
+ // Note : use the "John Doe" and not the "john.doe" version of the name.
+ // See saveFavoritesSLURLs() here above for the reason why.
+ if (fav_llsd.has(user))
+ {
+ LLSD user_llsd = fav_llsd[user];
+
+ if ((user_llsd.beginArray() != user_llsd.endArray()) && user_llsd.beginArray()->has("id"))
+ {
+ for (LLSD::array_iterator iter = user_llsd.beginArray(); iter != user_llsd.endArray(); ++iter)
+ {
+ LLSD value;
+ value["id"] = iter->get("id").asUUID();
+ iter->assign(value);
+ }
+ fav_llsd[user] = user_llsd;
+ llofstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(fav_llsd, file);
+ file.close();
+ }
+ }
+ else
+ {
+ LL_INFOS("FavoritesBar") << "Removed favorites for " << user << LL_ENDL;
+ fav_llsd.erase(user);
+ }
+ }
+
+ llofstream out_file;
+ out_file.open(filename.c_str());
+ if (out_file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+ LL_INFOS("FavoritesBar") << "saved favorites to '" << filename << "' "
+ << LL_ENDL;
+ out_file.close();
+ }
+ }
+ }
+}
+
+// static
void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
{
std::string filename = getStoredFavoritesFilename();
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index cac32c7f2a..d93161fd7a 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -208,9 +208,15 @@ public:
* @see cleanup()
*/
static void destroyClass();
+ static std::string getStoredFavoritesFilename(const std::string &grid);
static std::string getStoredFavoritesFilename();
static std::string getSavedOrderFileName();
+ // Remove record of specified user's favorites from file on disk.
+ static void removeFavoritesRecordOfUser(const std::string &user, const std::string &grid);
+ // Remove record of current user's favorites from file on disk.
+ static void removeFavoritesRecordOfUser();
+
BOOL saveFavoritesRecord(bool pref_changed = false);
void showFavoritesOnLoginChanged(BOOL show);
@@ -232,9 +238,6 @@ private:
void load();
- // Remove record of current user's favorites from file on disk.
- void removeFavoritesRecordOfUser();
-
void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
diff --git a/indra/newview/llflickrconnect.cpp b/indra/newview/llflickrconnect.cpp
deleted file mode 100644
index d7d161f239..0000000000
--- a/indra/newview/llflickrconnect.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/**
- * @file llflickrconnect.h
- * @author Merov, Cho
- * @brief Connection to Flickr Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llflickrconnect.h"
-
-#include "llagent.h"
-#include "llcallingcard.h" // for LLAvatarTracker
-#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llurlaction.h"
-#include "llimagepng.h"
-#include "llimagejpeg.h"
-#include "lltrans.h"
-#include "llevents.h"
-#include "llviewerregion.h"
-
-#include "llfloaterwebcontent.h"
-#include "llfloaterreg.h"
-#include "llcorehttputil.h"
-
-boost::scoped_ptr<LLEventPump> LLFlickrConnect::sStateWatcher(new LLEventStream("FlickrConnectState"));
-boost::scoped_ptr<LLEventPump> LLFlickrConnect::sInfoWatcher(new LLEventStream("FlickrConnectInfo"));
-boost::scoped_ptr<LLEventPump> LLFlickrConnect::sContentWatcher(new LLEventStream("FlickrConnectContent"));
-
-// Local functions
-void log_flickr_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
-{
- // Note: 302 (redirect) is *not* an error that warrants logging
- if (status != 302)
- {
- LL_WARNS("FlickrConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
- }
-}
-
-void toast_user_for_flickr_success()
-{
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("flickr_post_success");
- LLNotificationsUtil::add("FlickrConnect", args);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrConnectCoro(std::string requestToken, std::string oauthVerifier)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD body;
- if (!requestToken.empty())
- body["request_token"] = requestToken;
- if (!oauthVerifier.empty())
- body["oauth_verifier"] = oauthVerifier;
-
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, getFlickrConnectURL("/connection"), body, httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if ( status == LLCore::HttpStatus(HTTP_FOUND) )
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFlickrWeb(location);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << "Connection failed " << status.toString() << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- log_flickr_connect_error("Connect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-bool LLFlickrConnect::testShareStatus(LLSD &result)
-{
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status)
- return true;
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFlickrWeb(location);
- }
- }
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
- connectToFlickr();
- }
- else
- {
- LL_WARNS("FlickrConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_POST_FAILED);
- log_flickr_connect_error("Share", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- return false;
-}
-
-void LLFlickrConnect::flickrShareCoro(LLSD share)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getFlickrConnectURL("/share/photo", true), share, httpOpts);
-
- if (testShareStatus(result))
- {
- toast_user_for_flickr_success();
- LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_POSTED);
- }
-
-}
-
-void LLFlickrConnect::flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- std::string contentType = "multipart/form-data; boundary=" + boundary;
- httpHeaders->append("Content-Type", contentType.c_str());
-
- LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
- LLCore::BufferArrayStream body(raw.get());
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"title\"\r\n\r\n"
- << title << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"description\"\r\n\r\n"
- << description << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"tags\"\r\n\r\n"
- << tags << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"safety_level\"\r\n\r\n"
- << safetyLevel << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getFlickrConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
-
- if (testShareStatus(result))
- {
- toast_user_for_flickr_success();
- LL_DEBUGS("FlickrConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_POSTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrDisconnectCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- setConnectionState(LLFlickrConnect::FLICKR_DISCONNECTING);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getFlickrConnectURL("/connection"), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
- {
- LL_WARNS("FlickrConnect") << "Disconnect failed!" << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_DISCONNECT_FAILED);
-
- log_flickr_connect_error("Disconnect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_DEBUGS("FlickrConnect") << "Disconnect successful. " << LL_ENDL;
- clearInfo();
- setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrConnectedCoro(bool autoConnect)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFlickrConnectURL("/connection", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("FlickrConnect") << "Not connected. " << LL_ENDL;
- if (autoConnect)
- {
- connectToFlickr();
- }
- else
- {
- setConnectionState(LLFlickrConnect::FLICKR_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("FlickrConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
-
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- log_flickr_connect_error("Connected", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("FlickrConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLFlickrConnect::FLICKR_CONNECTED);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLFlickrConnect::flickrInfoCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getFlickrConnectURL("/info", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openFlickrWeb(location);
- }
- }
- else if (!status)
- {
- LL_WARNS("FlickrConnect") << "Flickr Info failed: " << status.toString() << LL_ENDL;
- log_flickr_connect_error("Info", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_INFOS("FlickrConnect") << "Flickr: Info received" << LL_ENDL;
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- storeInfo(result);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-LLFlickrConnect::LLFlickrConnect()
-: mConnectionState(FLICKR_NOT_CONNECTED),
- mConnected(false),
- mInfo(),
- mRefreshInfo(false),
- mReadFromMaster(false)
-{
-}
-
-void LLFlickrConnect::openFlickrWeb(std::string url)
-{
- LLFloaterWebContent::Params p;
- p.url(url);
- p.show_chrome(true);
- p.allow_back_forward_navigation(false);
- p.clean_browser(true);
- LLFloater *floater = LLFloaterReg::showInstance("flickr_web", p);
- //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
- //So when showing the internal web browser, set focus to it's containing floater "flickr_web". When a mouse event
- //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
- //flickr_web floater contains the "webbrowser" panel. JIRA: ACME-744
- gFocusMgr.setKeyboardFocus( floater );
-
- //LLUrlAction::openURLExternal(url);
-}
-
-std::string LLFlickrConnect::getFlickrConnectURL(const std::string& route, bool include_read_from_master)
-{
- std::string url("");
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- //url = "http://pdp15.lindenlab.com/flickr/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
- url = regionp->getCapability("FlickrConnect");
- url += route;
-
- if (include_read_from_master && mReadFromMaster)
- {
- url += "?read_from_master=true";
- }
- }
- return url;
-}
-
-void LLFlickrConnect::connectToFlickr(const std::string& request_token, const std::string& oauth_verifier)
-{
- LLCoros::instance().launch("LLFlickrConnect::flickrConnectCoro",
- boost::bind(&LLFlickrConnect::flickrConnectCoro, this, request_token, oauth_verifier));
-}
-
-void LLFlickrConnect::disconnectFromFlickr()
-{
- LLCoros::instance().launch("LLFlickrConnect::flickrDisconnectCoro",
- boost::bind(&LLFlickrConnect::flickrDisconnectCoro, this));
-}
-
-void LLFlickrConnect::checkConnectionToFlickr(bool auto_connect)
-{
- LLCoros::instance().launch("LLFlickrConnect::flickrConnectedCoro",
- boost::bind(&LLFlickrConnect::flickrConnectedCoro, this, auto_connect));
-}
-
-void LLFlickrConnect::loadFlickrInfo()
-{
- if(mRefreshInfo)
- {
- LLCoros::instance().launch("LLFlickrConnect::flickrInfoCoro",
- boost::bind(&LLFlickrConnect::flickrInfoCoro, this));
- }
-}
-
-void LLFlickrConnect::uploadPhoto(const std::string& image_url, const std::string& title, const std::string& description, const std::string& tags, int safety_level)
-{
- LLSD body;
- body["image"] = image_url;
- body["title"] = title;
- body["description"] = description;
- body["tags"] = tags;
- body["safety_level"] = safety_level;
-
- setConnectionState(LLFlickrConnect::FLICKR_POSTING);
-
- LLCoros::instance().launch("LLFlickrConnect::flickrShareCoro",
- boost::bind(&LLFlickrConnect::flickrShareCoro, this, body));
-}
-
-void LLFlickrConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& title, const std::string& description, const std::string& tags, int safety_level)
-{
- setConnectionState(LLFlickrConnect::FLICKR_POSTING);
-
- LLCoros::instance().launch("LLFlickrConnect::flickrShareImageCoro",
- boost::bind(&LLFlickrConnect::flickrShareImageCoro, this, image,
- title, description, tags, safety_level));
-}
-
-void LLFlickrConnect::storeInfo(const LLSD& info)
-{
- mInfo = info;
- mRefreshInfo = false;
-
- sInfoWatcher->post(info);
-}
-
-const LLSD& LLFlickrConnect::getInfo() const
-{
- return mInfo;
-}
-
-void LLFlickrConnect::clearInfo()
-{
- mInfo = LLSD();
-}
-
-void LLFlickrConnect::setDataDirty()
-{
- mRefreshInfo = true;
-}
-
-void LLFlickrConnect::setConnectionState(LLFlickrConnect::EConnectionState connection_state)
-{
- if(connection_state == FLICKR_CONNECTED)
- {
- mReadFromMaster = true;
- setConnected(true);
- setDataDirty();
- }
- else if(connection_state == FLICKR_NOT_CONNECTED)
- {
- setConnected(false);
- }
- else if(connection_state == FLICKR_POSTED)
- {
- mReadFromMaster = false;
- }
-
- if (mConnectionState != connection_state)
- {
- // set the connection state before notifying watchers
- mConnectionState = connection_state;
-
- LLSD state_info;
- state_info["enum"] = connection_state;
- sStateWatcher->post(state_info);
- }
-}
-
-void LLFlickrConnect::setConnected(bool connected)
-{
- mConnected = connected;
-}
diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h
deleted file mode 100644
index 43cadca708..0000000000
--- a/indra/newview/llflickrconnect.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file llflickrconnect.h
- * @author Merov, Cho
- * @brief Connection to Flickr Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLICKRCONNECT_H
-#define LL_LLFLICKRCONNECT_H
-
-#include "llsingleton.h"
-#include "llimage.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-
-class LLEventPump;
-
-/**
- * @class LLFlickrConnect
- *
- * Manages authentication to, and interaction with, a web service allowing the
- * the viewer to upload photos to Flickr.
- */
-class LLFlickrConnect : public LLSingleton<LLFlickrConnect>
-{
- LLSINGLETON(LLFlickrConnect);
- ~LLFlickrConnect() {};
- LOG_CLASS(LLFlickrConnect);
-public:
- enum EConnectionState
- {
- FLICKR_NOT_CONNECTED = 0,
- FLICKR_CONNECTION_IN_PROGRESS = 1,
- FLICKR_CONNECTED = 2,
- FLICKR_CONNECTION_FAILED = 3,
- FLICKR_POSTING = 4,
- FLICKR_POSTED = 5,
- FLICKR_POST_FAILED = 6,
- FLICKR_DISCONNECTING = 7,
- FLICKR_DISCONNECT_FAILED = 8
- };
-
- void connectToFlickr(const std::string& request_token = "", const std::string& oauth_verifier = ""); // Initiate the complete Flickr connection. Please use checkConnectionToFlickr() in normal use.
- void disconnectFromFlickr(); // Disconnect from the Flickr service.
- void checkConnectionToFlickr(bool auto_connect = false); // Check if an access token is available on the Flickr service. If not, call connectToFlickr().
-
- void loadFlickrInfo();
- void uploadPhoto(const std::string& image_url, const std::string& title, const std::string& description, const std::string& tags, int safety_level);
- void uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& title, const std::string& description, const std::string& tags, int safety_level);
-
- void storeInfo(const LLSD& info);
- const LLSD& getInfo() const;
- void clearInfo();
- void setDataDirty();
-
- void setConnectionState(EConnectionState connection_state);
- void setConnected(bool connected);
- bool isConnected() { return mConnected; }
- bool isTransactionOngoing() { return ((mConnectionState == FLICKR_CONNECTION_IN_PROGRESS) || (mConnectionState == FLICKR_POSTING) || (mConnectionState == FLICKR_DISCONNECTING)); }
- EConnectionState getConnectionState() { return mConnectionState; }
-
- void openFlickrWeb(std::string url);
-
-private:
-
- std::string getFlickrConnectURL(const std::string& route = "", bool include_read_from_master = false);
-
- EConnectionState mConnectionState;
- BOOL mConnected;
- LLSD mInfo;
- bool mRefreshInfo;
- bool mReadFromMaster;
-
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLEventPump> sInfoWatcher;
- static boost::scoped_ptr<LLEventPump> sContentWatcher;
-
- bool testShareStatus(LLSD &result);
- void flickrConnectCoro(std::string requestToken, std::string oauthVerifier);
- void flickrShareCoro(LLSD share);
- void flickrShareImageCoro(LLPointer<LLImageFormatted> image, std::string title, std::string description, std::string tags, int safetyLevel);
- void flickrDisconnectCoro();
- void flickrConnectedCoro(bool autoConnect);
- void flickrInfoCoro();
-
-};
-
-#endif // LL_LLFLICKRCONNECT_H
diff --git a/indra/newview/llfloaterbigpreview.h b/indra/newview/llfloaterbigpreview.h
index 63c6784d36..513ed8da6e 100644
--- a/indra/newview/llfloaterbigpreview.h
+++ b/indra/newview/llfloaterbigpreview.h
@@ -1,6 +1,6 @@
/**
* @file llfloaterbigpreview.h
-* @brief Display of extended (big) preview for snapshots and SL Share
+* @brief Display of extended (big) preview for snapshots
* @author merov@lindenlab.com
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 55561fa128..44725cab70 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -50,6 +50,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
mShowHistory(false),
mMessages(NULL),
mHistoryThreadsBusy(false),
+ mIsGroup(false),
mOpened(false)
{
}
@@ -75,6 +76,7 @@ BOOL LLFloaterConversationPreview::postBuild()
{
name = conv->getConversationName();
file = conv->getHistoryFileName();
+ mIsGroup = (LLIMModel::LLIMSession::GROUP_SESSION == conv->getConversationType());
}
else
{
@@ -82,6 +84,10 @@ BOOL LLFloaterConversationPreview::postBuild()
file = "chat";
}
mChatHistoryFileName = file;
+ if (mIsGroup)
+ {
+ mChatHistoryFileName += GROUP_CHAT_SUFFIX;
+ }
LLStringUtil::format_map_t args;
args["[NAME]"] = name;
std::string title = getString("Title", args);
@@ -145,6 +151,7 @@ void LLFloaterConversationPreview::onOpen(const LLSD& key)
LLSD load_params;
load_params["load_all_history"] = true;
load_params["cut_off_todays_date"] = false;
+ load_params["is_group"] = mIsGroup;
// The temporary message list with "Loading..." text
// Will be deleted upon loading completion in setPages() method
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index a8dbbc9ffe..7ca4ee6945 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -66,6 +66,7 @@ private:
bool mShowHistory;
bool mHistoryThreadsBusy;
bool mOpened;
+ bool mIsGroup;
};
#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llfloaterexperiences.cpp b/indra/newview/llfloaterexperiences.cpp
index fdc1b47334..184e39402a 100644
--- a/indra/newview/llfloaterexperiences.cpp
+++ b/indra/newview/llfloaterexperiences.cpp
@@ -74,10 +74,6 @@ BOOL LLFloaterExperiences::postBuild()
getChild<LLTabContainer>("xp_tabs")->addTabPanel(new LLPanelExperienceLog());
resizeToTabs();
-
- LLEventPumps::instance().obtain("experience_permission").listen("LLFloaterExperiences",
- boost::bind(&LLFloaterExperiences::updatePermissions, this, _1));
-
return TRUE;
}
@@ -163,6 +159,10 @@ void LLFloaterExperiences::refreshContents()
void LLFloaterExperiences::onOpen( const LLSD& key )
{
+ LLEventPumps::instance().obtain("experience_permission").stopListening("LLFloaterExperiences");
+ LLEventPumps::instance().obtain("experience_permission").listen("LLFloaterExperiences",
+ boost::bind(&LLFloaterExperiences::updatePermissions, this, _1));
+
LLViewerRegion* region = gAgent.getRegion();
if(region)
{
diff --git a/indra/newview/llfloaterflickr.cpp b/indra/newview/llfloaterflickr.cpp
deleted file mode 100644
index 69a92b2b54..0000000000
--- a/indra/newview/llfloaterflickr.cpp
+++ /dev/null
@@ -1,787 +0,0 @@
-/**
-* @file llfloaterflickr.cpp
-* @brief Implementation of llfloaterflickr
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterflickr.h"
-
-#include "llagent.h"
-#include "llagentui.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "llflickrconnect.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "llimagefiltersmanager.h"
-#include "llresmgr.h" // LLLocale
-#include "llsdserialize.h"
-#include "llloadingindicator.h"
-#include "llslurl.h"
-#include "lltrans.h"
-#include "llsnapshotlivepreview.h"
-#include "llfloaterbigpreview.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermedia.h"
-#include "lltabcontainer.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include <boost/regex.hpp>
-static LLPanelInjector<LLFlickrPhotoPanel> t_panel_photo("llflickrphotopanel");
-static LLPanelInjector<LLFlickrAccountPanel> t_panel_account("llflickraccountpanel");
-
-const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=flickr&utm_medium=photo&utm_campaign=slshare";
-const std::string DEFAULT_TAG_TEXT = "secondlife ";
-const std::string FLICKR_MACHINE_TAGS_NAMESPACE = "secondlife";
-
-///////////////////////////
-//LLFlickrPhotoPanel///////
-///////////////////////////
-
-LLFlickrPhotoPanel::LLFlickrPhotoPanel() :
-mResolutionComboBox(NULL),
-mRefreshBtn(NULL),
-mBtnPreview(NULL),
-mWorkingLabel(NULL),
-mThumbnailPlaceholder(NULL),
-mTitleTextBox(NULL),
-mDescriptionTextBox(NULL),
-mLocationCheckbox(NULL),
-mTagsTextBox(NULL),
-mRatingComboBox(NULL),
-mBigPreviewFloater(NULL),
-mPostButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFlickrPhotoPanel::onSend, this));
- mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFlickrPhotoPanel::onClickNewSnapshot, this));
- mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFlickrPhotoPanel::onClickBigPreview, this));
-}
-
-LLFlickrPhotoPanel::~LLFlickrPhotoPanel()
-{
- if(mPreviewHandle.get())
- {
- mPreviewHandle.get()->die();
- }
-}
-
-BOOL LLFlickrPhotoPanel::postBuild()
-{
- setVisibleCallback(boost::bind(&LLFlickrPhotoPanel::onVisibilityChange, this, _2));
-
- mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
- mResolutionComboBox->setCommitCallback(boost::bind(&LLFlickrPhotoPanel::updateResolution, this, TRUE));
- mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
- mFilterComboBox->setCommitCallback(boost::bind(&LLFlickrPhotoPanel::updateResolution, this, TRUE));
- mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
- mBtnPreview = getChild<LLButton>("big_preview_btn");
- mWorkingLabel = getChild<LLUICtrl>("working_lbl");
- mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
- mTitleTextBox = getChild<LLUICtrl>("photo_title");
- mDescriptionTextBox = getChild<LLUICtrl>("photo_description");
- mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
- mTagsTextBox = getChild<LLUICtrl>("photo_tags");
- mTagsTextBox->setValue(DEFAULT_TAG_TEXT);
- mRatingComboBox = getChild<LLUICtrl>("rating_combobox");
- mPostButton = getChild<LLUICtrl>("post_photo_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
- mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-
- // Update filter list
- std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
- for (U32 i = 0; i < filter_list.size(); i++)
- {
- filterbox->add(filter_list[i]);
- }
-
- return LLPanel::postBuild();
-}
-
-// virtual
-S32 LLFlickrPhotoPanel::notify(const LLSD& info)
-{
- if (info.has("snapshot-updating"))
- {
- // Disable the Post button and whatever else while the snapshot is not updated
- // updateControls();
- return 1;
- }
-
- if (info.has("snapshot-updated"))
- {
- // Enable the send/post/save buttons.
- updateControls();
-
- // The refresh button is initially hidden. We show it after the first update,
- // i.e. after snapshot is taken
- LLUICtrl * refresh_button = getRefreshBtn();
- if (!refresh_button->getVisible())
- {
- refresh_button->setVisible(true);
- }
- return 1;
- }
-
- return 0;
-}
-
-void LLFlickrPhotoPanel::draw()
-{
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
- // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
- bool no_ongoing_connection = !(LLFlickrConnect::instance().isTransactionOngoing());
- mCancelButton->setEnabled(no_ongoing_connection);
- mTitleTextBox->setEnabled(no_ongoing_connection);
- mDescriptionTextBox->setEnabled(no_ongoing_connection);
- mTagsTextBox->setEnabled(no_ongoing_connection);
- mRatingComboBox->setEnabled(no_ongoing_connection);
- mResolutionComboBox->setEnabled(no_ongoing_connection);
- mFilterComboBox->setEnabled(no_ongoing_connection);
- mRefreshBtn->setEnabled(no_ongoing_connection);
- mBtnPreview->setEnabled(no_ongoing_connection);
- mLocationCheckbox->setEnabled(no_ongoing_connection);
-
- // Reassign the preview floater if we have the focus and the preview exists
- if (hasFocus() && isPreviewVisible())
- {
- attachPreview();
- }
-
- // Toggle the button state as appropriate
- bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
- mBtnPreview->setToggleState(preview_active);
-
- // Display the preview if one is available
- if (previewp && previewp->getThumbnailImage())
- {
- const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
- const S32 thumbnail_w = previewp->getThumbnailWidth();
- const S32 thumbnail_h = previewp->getThumbnailHeight();
-
- // calc preview offset within the preview rect
- const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
- const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
- S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
- S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Apply floater transparency to the texture unless the floater is focused.
- F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
- LLColor4 color = LLColor4::white;
- gl_draw_scaled_image(offset_x, offset_y,
- thumbnail_w, thumbnail_h,
- previewp->getThumbnailImage(), color % alpha);
- }
-
- // Update the visibility of the working (computing preview) label
- mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-
- // Enable Post if we have a preview to send and no on going connection being processed
- mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()));
-
- // Draw the rest of the panel on top of it
- LLPanel::draw();
-}
-
-LLSnapshotLivePreview* LLFlickrPhotoPanel::getPreviewView()
-{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
- return previewp;
-}
-
-void LLFlickrPhotoPanel::onVisibilityChange(BOOL visible)
-{
- if (visible)
- {
- if (mPreviewHandle.get())
- {
- LLSnapshotLivePreview* preview = getPreviewView();
- if(preview)
- {
- LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
- preview->updateSnapshot(TRUE);
- }
- }
- else
- {
- LLRect full_screen_rect = getRootView()->getRect();
- LLSnapshotLivePreview::Params p;
- p.rect(full_screen_rect);
- LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
- mPreviewHandle = previewp->getHandle();
-
- previewp->setContainer(this);
- previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
- previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
- previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
- previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
- previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode
- previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
-
- updateControls();
- }
- }
-}
-
-void LLFlickrPhotoPanel::onClickNewSnapshot()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- if (previewp)
- {
- previewp->updateSnapshot(TRUE);
- }
-}
-
-void LLFlickrPhotoPanel::onClickBigPreview()
-{
- // Toggle the preview
- if (isPreviewVisible())
- {
- LLFloaterReg::hideInstance("big_preview");
- }
- else
- {
- attachPreview();
- LLFloaterReg::showInstance("big_preview");
- }
-}
-
-bool LLFlickrPhotoPanel::isPreviewVisible()
-{
- return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
-}
-
-void LLFlickrPhotoPanel::attachPreview()
-{
- if (mBigPreviewFloater)
- {
- LLSnapshotLivePreview* previewp = getPreviewView();
- mBigPreviewFloater->setPreview(previewp);
- mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
- }
-}
-
-void LLFlickrPhotoPanel::onSend()
-{
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrPhotoPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("FlickrConnectState").listen("LLFlickrPhotoPanel", boost::bind(&LLFlickrPhotoPanel::onFlickrConnectStateChange, this, _1));
-
- // Connect to Flickr if necessary and then post
- if (LLFlickrConnect::instance().isConnected())
- {
- sendPhoto();
- }
- else
- {
- LLFlickrConnect::instance().checkConnectionToFlickr(true);
- }
-}
-
-bool LLFlickrPhotoPanel::onFlickrConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLFlickrConnect::FLICKR_CONNECTED:
- sendPhoto();
- break;
-
- case LLFlickrConnect::FLICKR_POSTED:
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrPhotoPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-void LLFlickrPhotoPanel::sendPhoto()
-{
- // Get the title, description, and tags
- std::string title = mTitleTextBox->getValue().asString();
- std::string description = mDescriptionTextBox->getValue().asString();
- std::string tags = mTagsTextBox->getValue().asString();
-
- // Add the location if required
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- if (add_location)
- {
- // Get the SLURL for the location
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- std::string slurl_string = slurl.getSLURLString();
-
- // Add query parameters so Google Analytics can track incoming clicks!
- slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
-
- std::string photo_link_text = "Visit this location";// at [] in Second Life";
- std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
- if (!parcel_name.empty())
- {
- boost::regex pattern = boost::regex("\\S\\.[a-zA-Z]{2,}");
- boost::match_results<std::string::const_iterator> matches;
- if(!boost::regex_search(parcel_name, matches, pattern))
- {
- photo_link_text += " at " + parcel_name;
- }
- }
- photo_link_text += " in Second Life";
-
- slurl_string = "<a href=\"" + slurl_string + "\">" + photo_link_text + "</a>";
-
- // Add it to the description (pretty crude, but we don't have a better option with photos)
- if (description.empty())
- description = slurl_string;
- else
- description = description + "\n\n" + slurl_string;
-
- // Also add special "machine tags" with location metadata
- const LLVector3& agent_pos_region = gAgent.getPositionAgent();
- LLViewerRegion* region = gAgent.getRegion();
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (region && parcel)
- {
- S32 pos_x = S32(agent_pos_region.mV[VX]);
- S32 pos_y = S32(agent_pos_region.mV[VY]);
- S32 pos_z = S32(agent_pos_region.mV[VZ]);
-
- std::string parcel_name = LLViewerParcelMgr::getInstance()->getAgentParcelName();
- std::string region_name = region->getName();
-
- if (!region_name.empty())
- {
- tags += llformat(" \"%s:region=%s\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), region_name.c_str());
- }
- if (!parcel_name.empty())
- {
- tags += llformat(" \"%s:parcel=%s\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), parcel_name.c_str());
- }
- tags += llformat(" \"%s:x=%d\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), pos_x);
- tags += llformat(" \"%s:y=%d\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), pos_y);
- tags += llformat(" \"%s:z=%d\"", FLICKR_MACHINE_TAGS_NAMESPACE.c_str(), pos_z);
- }
- }
-
- // Get the content rating
- int content_rating = mRatingComboBox->getValue().asInteger();
-
- // Get the image
- LLSnapshotLivePreview* previewp = getPreviewView();
-
- // Post to Flickr
- LLFlickrConnect::instance().uploadPhoto(previewp->getFormattedImage(), title, description, tags, content_rating);
-
- updateControls();
-}
-
-void LLFlickrPhotoPanel::clearAndClose()
-{
- mTitleTextBox->setValue("");
- mDescriptionTextBox->setValue("");
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- if (mBigPreviewFloater)
- {
- mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
- }
- }
-}
-
-void LLFlickrPhotoPanel::updateControls()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
- // *TODO: Separate maximum size for Web images from postcards
- LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
- updateResolution(FALSE);
-}
-
-void LLFlickrPhotoPanel::updateResolution(BOOL do_update)
-{
- LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-
- std::string sdstring = combobox->getSelectedValue();
- LLSD sdres;
- std::stringstream sstream(sdstring);
- LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
-
- S32 width = sdres[0];
- S32 height = sdres[1];
-
- // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
- std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
- if (previewp && combobox->getCurrentIndex() >= 0)
- {
- S32 original_width = 0 , original_height = 0 ;
- previewp->getSize(original_width, original_height) ;
-
- if (width == 0 || height == 0)
- {
- // take resolution from current window size
- LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
- previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
- }
- else
- {
- // use the resolution from the selected pre-canned drop-down choice
- LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
- previewp->setSize(width, height);
- }
-
- checkAspectRatio(width);
-
- previewp->getSize(width, height);
- if ((original_width != width) || (original_height != height))
- {
- previewp->setSize(width, height);
- if (do_update)
- {
- previewp->updateSnapshot(TRUE);
- updateControls();
- }
- }
- // Get the old filter, compare to the current one "filter_name" and set if changed
- std::string original_filter = previewp->getFilter();
- if (original_filter != filter_name)
- {
- previewp->setFilter(filter_name);
- if (do_update)
- {
- previewp->updateSnapshot(FALSE, TRUE);
- updateControls();
- }
- }
- }
-}
-
-void LLFlickrPhotoPanel::checkAspectRatio(S32 index)
-{
- LLSnapshotLivePreview *previewp = getPreviewView() ;
-
- BOOL keep_aspect = FALSE;
-
- if (0 == index) // current window size
- {
- keep_aspect = TRUE;
- }
- else // predefined resolution
- {
- keep_aspect = FALSE;
- }
-
- if (previewp)
- {
- previewp->mKeepAspectRatio = keep_aspect;
- }
-}
-
-LLUICtrl* LLFlickrPhotoPanel::getRefreshBtn()
-{
- return mRefreshBtn;
-}
-
-///////////////////////////
-//LLFlickrAccountPanel//////
-///////////////////////////
-
-LLFlickrAccountPanel::LLFlickrAccountPanel() :
-mAccountCaptionLabel(NULL),
-mAccountNameLabel(NULL),
-mPanelButtons(NULL),
-mConnectButton(NULL),
-mDisconnectButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFlickrAccountPanel::onConnect, this));
- mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFlickrAccountPanel::onDisconnect, this));
-
- setVisibleCallback(boost::bind(&LLFlickrAccountPanel::onVisibilityChange, this, _2));
-}
-
-BOOL LLFlickrAccountPanel::postBuild()
-{
- mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
- mAccountNameLabel = getChild<LLTextBox>("account_name_label");
- mPanelButtons = getChild<LLUICtrl>("panel_buttons");
- mConnectButton = getChild<LLUICtrl>("connect_btn");
- mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
-
- return LLPanel::postBuild();
-}
-
-void LLFlickrAccountPanel::draw()
-{
- LLFlickrConnect::EConnectionState connection_state = LLFlickrConnect::instance().getConnectionState();
-
- //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
- bool disconnecting = connection_state == LLFlickrConnect::FLICKR_DISCONNECTING;
- mDisconnectButton->setEnabled(!disconnecting);
-
- //Disable the 'connect' button when a connection is in progress
- bool connecting = connection_state == LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS;
- mConnectButton->setEnabled(!connecting);
-
- LLPanel::draw();
-}
-
-void LLFlickrAccountPanel::onVisibilityChange(BOOL visible)
-{
- if(visible)
- {
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrAccountPanel");
- LLEventPumps::instance().obtain("FlickrConnectState").listen("LLFlickrAccountPanel", boost::bind(&LLFlickrAccountPanel::onFlickrConnectStateChange, this, _1));
-
- LLEventPumps::instance().obtain("FlickrConnectInfo").stopListening("LLFlickrAccountPanel");
- LLEventPumps::instance().obtain("FlickrConnectInfo").listen("LLFlickrAccountPanel", boost::bind(&LLFlickrAccountPanel::onFlickrConnectInfoChange, this));
-
- //Connected
- if(LLFlickrConnect::instance().isConnected())
- {
- showConnectedLayout();
- }
- //Check if connected (show disconnected layout in meantime)
- else
- {
- showDisconnectedLayout();
- }
- if ((LLFlickrConnect::instance().getConnectionState() == LLFlickrConnect::FLICKR_NOT_CONNECTED) ||
- (LLFlickrConnect::instance().getConnectionState() == LLFlickrConnect::FLICKR_CONNECTION_FAILED))
- {
- LLFlickrConnect::instance().checkConnectionToFlickr();
- }
- }
- else
- {
- LLEventPumps::instance().obtain("FlickrConnectState").stopListening("LLFlickrAccountPanel");
- LLEventPumps::instance().obtain("FlickrConnectInfo").stopListening("LLFlickrAccountPanel");
- }
-}
-
-bool LLFlickrAccountPanel::onFlickrConnectStateChange(const LLSD& data)
-{
- if(LLFlickrConnect::instance().isConnected())
- {
- //In process of disconnecting so leave the layout as is
- if(data.get("enum").asInteger() != LLFlickrConnect::FLICKR_DISCONNECTING)
- {
- showConnectedLayout();
- }
- }
- else
- {
- showDisconnectedLayout();
- }
-
- return false;
-}
-
-bool LLFlickrAccountPanel::onFlickrConnectInfoChange()
-{
- LLSD info = LLFlickrConnect::instance().getInfo();
- std::string clickable_name;
-
- //Strings of format [http://www.somewebsite.com Click Me] become clickable text
- if(info.has("link") && info.has("name"))
- {
- clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
- }
-
- mAccountNameLabel->setText(clickable_name);
-
- return false;
-}
-
-void LLFlickrAccountPanel::showConnectButton()
-{
- if(!mConnectButton->getVisible())
- {
- mConnectButton->setVisible(TRUE);
- mDisconnectButton->setVisible(FALSE);
- }
-}
-
-void LLFlickrAccountPanel::hideConnectButton()
-{
- if(mConnectButton->getVisible())
- {
- mConnectButton->setVisible(FALSE);
- mDisconnectButton->setVisible(TRUE);
- }
-}
-
-void LLFlickrAccountPanel::showDisconnectedLayout()
-{
- mAccountCaptionLabel->setText(getString("flickr_disconnected"));
- mAccountNameLabel->setText(std::string(""));
- showConnectButton();
-}
-
-void LLFlickrAccountPanel::showConnectedLayout()
-{
- LLFlickrConnect::instance().loadFlickrInfo();
-
- mAccountCaptionLabel->setText(getString("flickr_connected"));
- hideConnectButton();
-}
-
-void LLFlickrAccountPanel::onConnect()
-{
- LLFlickrConnect::instance().checkConnectionToFlickr(true);
-}
-
-void LLFlickrAccountPanel::onDisconnect()
-{
- LLFlickrConnect::instance().disconnectFromFlickr();
-}
-
-////////////////////////
-//LLFloaterFlickr///////
-////////////////////////
-
-LLFloaterFlickr::LLFloaterFlickr(const LLSD& key) : LLFloater(key),
- mFlickrPhotoPanel(NULL),
- mStatusErrorText(NULL),
- mStatusLoadingText(NULL),
- mStatusLoadingIndicator(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFlickr::onCancel, this));
-}
-
-void LLFloaterFlickr::onClose(bool app_quitting)
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- LLFloater::onClose(app_quitting);
-}
-
-void LLFloaterFlickr::onCancel()
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- closeFloater();
-}
-
-BOOL LLFloaterFlickr::postBuild()
-{
- // Keep tab of the Photo Panel
- mFlickrPhotoPanel = static_cast<LLFlickrPhotoPanel*>(getChild<LLUICtrl>("panel_flickr_photo"));
- // Connection status widgets
- mStatusErrorText = getChild<LLTextBox>("connection_error_text");
- mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
- mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
- return LLFloater::postBuild();
-}
-
-void LLFloaterFlickr::showPhotoPanel()
-{
- LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFlickrPhotoPanel->getParent());
- if (!parent)
- {
- LL_WARNS() << "Cannot find panel container" << LL_ENDL;
- return;
- }
-
- parent->selectTabPanel(mFlickrPhotoPanel);
-}
-
-void LLFloaterFlickr::draw()
-{
- if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
- {
- mStatusErrorText->setVisible(false);
- mStatusLoadingText->setVisible(false);
- mStatusLoadingIndicator->setVisible(false);
- LLFlickrConnect::EConnectionState connection_state = LLFlickrConnect::instance().getConnectionState();
- std::string status_text;
-
- switch (connection_state)
- {
- case LLFlickrConnect::FLICKR_NOT_CONNECTED:
- // No status displayed when first opening the panel and no connection done
- case LLFlickrConnect::FLICKR_CONNECTED:
- // When successfully connected, no message is displayed
- case LLFlickrConnect::FLICKR_POSTED:
- // No success message to show since we actually close the floater after successful posting completion
- break;
- case LLFlickrConnect::FLICKR_CONNECTION_IN_PROGRESS:
- // Connection loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrConnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFlickrConnect::FLICKR_POSTING:
- // Posting indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrPosting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFlickrConnect::FLICKR_CONNECTION_FAILED:
- // Error connecting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrErrorConnecting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLFlickrConnect::FLICKR_POST_FAILED:
- // Error posting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrErrorPosting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLFlickrConnect::FLICKR_DISCONNECTING:
- // Disconnecting loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrDisconnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLFlickrConnect::FLICKR_DISCONNECT_FAILED:
- // Error disconnecting from the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialFlickrErrorDisconnecting");
- mStatusErrorText->setValue(status_text);
- break;
- }
- }
- LLFloater::draw();
-}
-
diff --git a/indra/newview/llfloaterflickr.h b/indra/newview/llfloaterflickr.h
deleted file mode 100644
index 74da3bcea9..0000000000
--- a/indra/newview/llfloaterflickr.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
-* @file llfloaterflickr.h
-* @brief Header file for llfloaterflickr
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#ifndef LL_LLFLOATERFLICKR_H
-#define LL_LLFLOATERFLICKR_H
-
-#include "llfloater.h"
-#include "lltextbox.h"
-#include "llviewertexture.h"
-
-class LLIconCtrl;
-class LLCheckBoxCtrl;
-class LLSnapshotLivePreview;
-class LLFloaterBigPreview;
-
-class LLFlickrPhotoPanel : public LLPanel
-{
-public:
- LLFlickrPhotoPanel();
- ~LLFlickrPhotoPanel();
-
- BOOL postBuild();
- S32 notify(const LLSD& info);
- void draw();
-
- LLSnapshotLivePreview* getPreviewView();
- void onVisibilityChange(BOOL new_visibility);
- void onClickNewSnapshot();
- void onClickBigPreview();
- void onSend();
- bool onFlickrConnectStateChange(const LLSD& data);
-
- void sendPhoto();
- void clearAndClose();
-
- void updateControls();
- void updateResolution(BOOL do_update);
- void checkAspectRatio(S32 index);
- LLUICtrl* getRefreshBtn();
-
-private:
- bool isPreviewVisible();
- void attachPreview();
-
- LLHandle<LLView> mPreviewHandle;
-
- LLUICtrl * mResolutionComboBox;
- LLUICtrl * mFilterComboBox;
- LLUICtrl * mRefreshBtn;
- LLUICtrl * mWorkingLabel;
- LLUICtrl * mThumbnailPlaceholder;
- LLUICtrl * mTitleTextBox;
- LLUICtrl * mDescriptionTextBox;
- LLUICtrl * mLocationCheckbox;
- LLUICtrl * mTagsTextBox;
- LLUICtrl * mRatingComboBox;
- LLUICtrl * mPostButton;
- LLUICtrl * mCancelButton;
- LLButton * mBtnPreview;
-
- LLFloaterBigPreview * mBigPreviewFloater;
-};
-
-class LLFlickrAccountPanel : public LLPanel
-{
-public:
- LLFlickrAccountPanel();
- BOOL postBuild();
- void draw();
-
-private:
- void onVisibilityChange(BOOL new_visibility);
- bool onFlickrConnectStateChange(const LLSD& data);
- bool onFlickrConnectInfoChange();
- void onConnect();
- void onUseAnotherAccount();
- void onDisconnect();
-
- void showConnectButton();
- void hideConnectButton();
- void showDisconnectedLayout();
- void showConnectedLayout();
-
- LLTextBox * mAccountCaptionLabel;
- LLTextBox * mAccountNameLabel;
- LLUICtrl * mPanelButtons;
- LLUICtrl * mConnectButton;
- LLUICtrl * mDisconnectButton;
-};
-
-
-class LLFloaterFlickr : public LLFloater
-{
-public:
- LLFloaterFlickr(const LLSD& key);
- BOOL postBuild();
- void draw();
- void onClose(bool app_quitting);
- void onCancel();
-
- void showPhotoPanel();
-
-private:
- LLFlickrPhotoPanel* mFlickrPhotoPanel;
- LLTextBox* mStatusErrorText;
- LLTextBox* mStatusLoadingText;
- LLUICtrl* mStatusLoadingIndicator;
-};
-
-#endif // LL_LLFLOATERFLICKR_H
-
diff --git a/indra/newview/llfloaterforgetuser.cpp b/indra/newview/llfloaterforgetuser.cpp
new file mode 100644
index 0000000000..97b022699f
--- /dev/null
+++ b/indra/newview/llfloaterforgetuser.cpp
@@ -0,0 +1,348 @@
+/**
+ * @file llfloaterforgetuser.cpp
+ * @brief LLFloaterForgetUser class definition.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterforgetuser.h"
+
+#include "llappviewer.h"
+#include "llcheckboxctrl.h"
+#include "llfavoritesbar.h"
+#include "llnotificationsutil.h"
+#include "llpanellogin.h" // for helper function getUserName() and to repopulate list if nessesary
+#include "llscrolllistctrl.h"
+#include "llsecapi.h"
+#include "llstartup.h"
+#include "llviewercontrol.h"
+#include "llviewernetwork.h"
+
+
+LLFloaterForgetUser::LLFloaterForgetUser(const LLSD &key)
+ : LLFloater("floater_forget_user"),
+ mLoginPanelDirty(false)
+{
+
+}
+
+LLFloaterForgetUser::~LLFloaterForgetUser()
+{
+ if (mLoginPanelDirty)
+ {
+ LLPanelLogin::resetFields();
+ }
+}
+
+BOOL LLFloaterForgetUser::postBuild()
+{
+ mScrollList = getChild<LLScrollListCtrl>("user_list");
+
+
+ bool show_grid_marks = gSavedSettings.getBOOL("ForceShowGrid");
+ show_grid_marks |= !LLGridManager::getInstance()->isInProductionGrid();
+
+ std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
+
+ if (!show_grid_marks)
+ {
+ // Figure out if there are records for more than one grid in storage
+ for (std::map<std::string, std::string>::iterator grid_iter = known_grids.begin();
+ grid_iter != known_grids.end();
+ grid_iter++)
+ {
+ if (!grid_iter->first.empty()
+ && grid_iter->first != MAINGRID) // a workaround since 'mIsInProductionGrid' might not be set
+ {
+ if (!gSecAPIHandler->emptyCredentialMap("login_list", grid_iter->first))
+ {
+ show_grid_marks = true;
+ break;
+ }
+
+ // "Legacy" viewer support
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid_iter->first);
+ if (cred.notNull())
+ {
+ const LLSD &ident = cred->getIdentifier();
+ if (ident.isMap() && ident.has("type"))
+ {
+ show_grid_marks = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ mUserGridsCount.clear();
+ if (!show_grid_marks)
+ {
+ // just load maingrid
+ loadGridToList(MAINGRID, false);
+ }
+ else
+ {
+ for (std::map<std::string, std::string>::iterator grid_iter = known_grids.begin();
+ grid_iter != known_grids.end();
+ grid_iter++)
+ {
+ if (!grid_iter->first.empty())
+ {
+ loadGridToList(grid_iter->first, true);
+ }
+ }
+ }
+
+ mScrollList->selectFirstItem();
+ bool enable_button = mScrollList->getFirstSelectedIndex() != -1;
+ LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
+ chk_box->setEnabled(enable_button);
+ chk_box->set(FALSE);
+ LLButton *button = getChild<LLButton>("forget");
+ button->setEnabled(enable_button);
+ button->setCommitCallback(boost::bind(&LLFloaterForgetUser::onForgetClicked, this));
+
+ return TRUE;
+}
+
+void LLFloaterForgetUser::onForgetClicked()
+{
+ LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
+ LLSD user_data = scroll_list->getSelectedValue();
+ const std::string user_id = user_data["user_id"];
+
+ LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
+ BOOL delete_data = chk_box->getValue();
+
+ if (delete_data && mUserGridsCount[user_id] > 1)
+ {
+ // more than 1 grid uses this id
+ LLNotificationsUtil::add("LoginRemoveMultiGridUserData", LLSD(), LLSD(), boost::bind(&LLFloaterForgetUser::onConfirmForget, this, _1, _2));
+ return;
+ }
+
+ processForgetUser();
+}
+
+bool LLFloaterForgetUser::onConfirmForget(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ processForgetUser();
+ }
+ return false;
+}
+
+// static
+bool LLFloaterForgetUser::onConfirmLogout(const LLSD& notification, const LLSD& response, const std::string &fav_id, const std::string &grid)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ // Remove creds
+ gSecAPIHandler->removeFromCredentialMap("login_list", grid, LLStartUp::getUserId());
+
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
+ if (cred.notNull() && cred->userID() == LLStartUp::getUserId())
+ {
+ gSecAPIHandler->deleteCredential(cred);
+ }
+
+ // Clean favorites
+ LLFavoritesOrderStorage::removeFavoritesRecordOfUser(fav_id, grid);
+
+ // mark data for removal
+ LLAppViewer::instance()->purgeUserDataOnExit();
+ LLAppViewer::instance()->requestQuit();
+ }
+ return false;
+}
+
+void LLFloaterForgetUser::processForgetUser()
+{
+ LLScrollListCtrl *scroll_list = getChild<LLScrollListCtrl>("user_list");
+ LLCheckBoxCtrl *chk_box = getChild<LLCheckBoxCtrl>("delete_data");
+ BOOL delete_data = chk_box->getValue();
+ LLSD user_data = scroll_list->getSelectedValue();
+ const std::string user_id = user_data["user_id"];
+ const std::string grid = user_data["grid"];
+ const std::string user_name = user_data["label"]; // for favorites
+
+ if (delete_data && user_id == LLStartUp::getUserId() && LLStartUp::getStartupState() > STATE_LOGIN_WAIT)
+ {
+ // we can't delete data for user that is currently logged in
+ // we need to pass grid because we are deleting data universal to grids, but specific grid's user
+ LLNotificationsUtil::add("LoginCantRemoveCurUsername", LLSD(), LLSD(), boost::bind(onConfirmLogout, _1, _2, user_name, grid));
+ return;
+ }
+
+ // key is used for name of user's folder and in credencials
+ // user_name is edentical to favorite's username
+ forgetUser(user_id, user_name, grid, delete_data);
+ mLoginPanelDirty = true;
+ if (delete_data)
+ {
+ mUserGridsCount[user_id] = 0; //no data left to care about
+ }
+ else
+ {
+ mUserGridsCount[user_id]--;
+ }
+
+ // Update UI
+ scroll_list->deleteSelectedItems();
+ scroll_list->selectFirstItem();
+ if (scroll_list->getFirstSelectedIndex() == -1)
+ {
+ LLButton *button = getChild<LLButton>("forget");
+ button->setEnabled(false);
+ chk_box->setEnabled(false);
+ }
+}
+
+//static
+void LLFloaterForgetUser::forgetUser(const std::string &userid, const std::string &fav_id, const std::string &grid, bool delete_data)
+{
+ // Remove creds
+ gSecAPIHandler->removeFromCredentialMap("login_list", grid, userid);
+
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
+ if (cred.notNull() && cred->userID() == userid)
+ {
+ gSecAPIHandler->deleteCredential(cred);
+ }
+
+ // Clean data
+ if (delete_data)
+ {
+ std::string user_path = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter() + userid;
+ gDirUtilp->deleteDirAndContents(user_path);
+
+ // Clean favorites
+ LLFavoritesOrderStorage::removeFavoritesRecordOfUser(fav_id, grid);
+
+ // Note: we do not clean user-related files from cache because there are id dependent (inventory)
+ // files and cache has separate cleaning mechanism either way.
+ // Also this only cleans user from current grid, not all of them.
+ }
+}
+
+void LLFloaterForgetUser::loadGridToList(const std::string &grid, bool show_grid_name)
+{
+ std::string grid_label;
+ if (show_grid_name)
+ {
+ grid_label = LLGridManager::getInstance()->getGridId(grid); //login id (shortened label)
+ }
+ if (gSecAPIHandler->hasCredentialMap("login_list", grid))
+ {
+ LLSecAPIHandler::credential_map_t credencials;
+ gSecAPIHandler->loadCredentialMap("login_list", grid, credencials);
+
+ LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
+ LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
+ while (cr_iter != cr_end)
+ {
+ if (cr_iter->second.notNull()) // basic safety
+ {
+ std::string user_label = LLPanelLogin::getUserName(cr_iter->second);
+ LLSD user_data;
+ user_data["user_id"] = cr_iter->first;
+ user_data["label"] = user_label;
+ user_data["grid"] = grid;
+
+ if (show_grid_name)
+ {
+ user_label += " (" + grid_label + ")";
+ }
+
+ LLScrollListItem::Params item_params;
+ item_params.value(user_data);
+ item_params.columns.add()
+ .value(user_label)
+ .column("user")
+ .font(LLFontGL::getFontSansSerifSmall());
+ mScrollList->addRow(item_params, ADD_BOTTOM);
+
+ // Add one to grid count
+ std::map<std::string, S32>::iterator found = mUserGridsCount.find(cr_iter->first);
+ if (found != mUserGridsCount.end())
+ {
+ found->second++;
+ }
+ else
+ {
+ mUserGridsCount[cr_iter->first] = 1;
+ }
+ }
+ cr_iter++;
+ }
+ }
+ else
+ {
+ // "Legacy" viewer support
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(grid);
+ if (cred.notNull())
+ {
+ const LLSD &ident = cred->getIdentifier();
+ if (ident.isMap() && ident.has("type"))
+ {
+ std::string user_label = LLPanelLogin::getUserName(cred);
+ LLSD user_data;
+ user_data["user_id"] = cred->userID();
+ user_data["label"] = user_label;
+ user_data["grid"] = grid;
+
+ if (show_grid_name)
+ {
+ user_label += " (" + grid_label + ")";
+ }
+
+ LLScrollListItem::Params item_params;
+ item_params.value(user_data);
+ item_params.columns.add()
+ .value(user_label)
+ .column("user")
+ .font(LLFontGL::getFontSansSerifSmall());
+ mScrollList->addRow(item_params, ADD_BOTTOM);
+
+ // Add one to grid count
+ std::map<std::string, S32>::iterator found = mUserGridsCount.find(cred->userID());
+ if (found != mUserGridsCount.end())
+ {
+ found->second++;
+ }
+ else
+ {
+ mUserGridsCount[cred->userID()] = 1;
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/indra/newview/llfloaterforgetuser.h b/indra/newview/llfloaterforgetuser.h
new file mode 100644
index 0000000000..801fcbb412
--- /dev/null
+++ b/indra/newview/llfloaterforgetuser.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterforgetuser.h
+ * @brief LLFloaterForgetUser class declaration.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERFORGETUSER_H
+#define LL_LLFLOATERFORGETUSER_H
+
+#include "llfloater.h"
+
+class LLScrollListCtrl;
+
+class LLFloaterForgetUser : public LLFloater
+{
+public:
+ LLFloaterForgetUser(const LLSD &key);
+ ~LLFloaterForgetUser();
+
+ BOOL postBuild();
+ void onForgetClicked();
+
+private:
+ bool onConfirmForget(const LLSD& notification, const LLSD& response);
+ static bool onConfirmLogout(const LLSD& notification, const LLSD& response, const std::string &favorites_id, const std::string &grid);
+ void processForgetUser();
+ static void forgetUser(const std::string &userid, const std::string &fav_id, const std::string &grid, bool delete_data);
+ void loadGridToList(const std::string &grid, bool show_grid_name);
+
+ LLScrollListCtrl *mScrollList;
+
+ bool mLoginPanelDirty;
+ std::map<std::string, S32> mUserGridsCount;
+};
+
+#endif
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index b840d37c4d..e778e8eb9e 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -41,6 +41,7 @@
#include "llkeyboard.h"
#include "llmenugl.h"
#include "llmultigesture.h"
+#include "llnotificationsutil.h"
#include "llpreviewgesture.h"
#include "llscrolllistctrl.h"
#include "lltrans.h"
@@ -125,6 +126,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mCommitCallbackRegistrar.add("Gesture.Action.ShowPreview", boost::bind(&LLFloaterGesture::onClickEdit, this));
mCommitCallbackRegistrar.add("Gesture.Action.CopyPaste", boost::bind(&LLFloaterGesture::onCopyPasteAction, this, _2));
mCommitCallbackRegistrar.add("Gesture.Action.SaveToCOF", boost::bind(&LLFloaterGesture::addToCurrentOutFit, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.Rename", boost::bind(&LLFloaterGesture::onRenameSelected, this));
mEnableCallbackRegistrar.add("Gesture.EnableAction", boost::bind(&LLFloaterGesture::isActionEnabled, this, _2));
}
@@ -430,6 +432,19 @@ bool LLFloaterGesture::isActionEnabled(const LLSD& command)
{
return mGestureList->getAllSelected().size() == 1;
}
+ else if ("rename_gesture" == command_name)
+ {
+ if (mGestureList->getAllSelected().size() == 1)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(mGestureList->getCurrentID());
+
+ if (item && item->getPermissions().allowModifyBy(gAgentID))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
return true;
}
@@ -514,6 +529,44 @@ void LLFloaterGesture::onActivateBtnClick()
}
}
+void LLFloaterGesture::onRenameSelected()
+{
+ LLViewerInventoryItem* gesture = gInventory.getItem(mGestureList->getCurrentID());
+ if (!gesture)
+ {
+ return;
+ }
+
+ LLSD args;
+ args["NAME"] = gesture->getName();
+
+ LLSD payload;
+ payload["gesture_id"] = mGestureList->getCurrentID();
+
+ LLNotificationsUtil::add("RenameGesture", args, payload, boost::bind(onGestureRename, _1, _2));
+
+}
+
+void LLFloaterGesture::onGestureRename(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) return; // canceled
+
+ std::string new_name = response["new_name"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (!new_name.empty())
+ {
+ LLUUID item_id = notification["payload"]["gesture_id"].asUUID();
+ LLViewerInventoryItem* gesture = gInventory.getItem(item_id);
+ if (gesture && (gesture->getName() != new_name))
+ {
+ LLSD updates;
+ updates["name"] = new_name;
+ update_inventory_item(item_id, updates, NULL);
+ }
+ }
+}
+
void LLFloaterGesture::onCopyPasteAction(const LLSD& command)
{
std::string command_name = command.asString();
diff --git a/indra/newview/llfloatergesture.h b/indra/newview/llfloatergesture.h
index 8efb3e6461..1d702c6704 100644
--- a/indra/newview/llfloatergesture.h
+++ b/indra/newview/llfloatergesture.h
@@ -95,6 +95,9 @@ private:
void onCommitList();
void onCopyPasteAction(const LLSD& command);
void onDeleteSelected();
+ void onRenameSelected();
+
+ static void onGestureRename(const LLSD& notification, const LLSD& response);
LLUUID mSelectedID;
LLUUID mGestureFolderID;
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
index c47ff1c1d9..faa7e9f3db 100644
--- a/indra/newview/llfloatergridstatus.cpp
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -39,7 +39,7 @@
#include "llxmltree.h"
std::map<std::string, std::string> LLFloaterGridStatus::sItemsMap;
-const std::string DEFAULT_GRID_STATUS_URL = "http://secondlife-status.statuspage.io/";
+const std::string DEFAULT_GRID_STATUS_URL = "http://status.secondlifegrid.net/";
LLFloaterGridStatus::LLFloaterGridStatus(const Params& key) :
LLFloaterWebContent(key),
diff --git a/indra/newview/llfloatergroupinvite.cpp b/indra/newview/llfloatergroupinvite.cpp
index 7fdba8734a..30c90ac184 100644
--- a/indra/newview/llfloatergroupinvite.cpp
+++ b/indra/newview/llfloatergroupinvite.cpp
@@ -108,7 +108,7 @@ LLFloaterGroupInvite::~LLFloaterGroupInvite()
}
// static
-void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agent_ids)
+void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agent_ids, bool request_update)
{
const LLFloater::Params& floater_params = LLFloater::getDefaultParams();
S32 floater_header_size = floater_params.header_height;
@@ -126,9 +126,12 @@ void LLFloaterGroupInvite::showForGroup(const LLUUID& group_id, uuid_vec_t *agen
group_id,
(LLFloaterGroupInvite*)NULL);
- // refresh group information
- gAgent.sendAgentDataUpdateRequest();
- LLGroupMgr::getInstance()->clearGroupData(group_id);
+ if (request_update)
+ {
+ // refresh group information
+ gAgent.sendAgentDataUpdateRequest();
+ LLGroupMgr::getInstance()->clearGroupData(group_id);
+ }
if (!fgi)
diff --git a/indra/newview/llfloatergroupinvite.h b/indra/newview/llfloatergroupinvite.h
index f6a3ca5550..657e5711f0 100644
--- a/indra/newview/llfloatergroupinvite.h
+++ b/indra/newview/llfloatergroupinvite.h
@@ -37,7 +37,7 @@ class LLFloaterGroupInvite
public:
virtual ~LLFloaterGroupInvite();
- static void showForGroup(const LLUUID &group_id, uuid_vec_t *agent_ids = NULL);
+ static void showForGroup(const LLUUID &group_id, uuid_vec_t *agent_ids = NULL, bool request_update = true);
protected:
LLFloaterGroupInvite(const LLUUID& group_id = LLUUID::null);
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 3098c6d118..d8f4360142 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2209,7 +2209,7 @@ void LLPanelLandOptions::refreshSearch()
// effort to reduce search spam from small parcels. See also
// the search crawler "grid-crawl.py" in secondlife.com/doc/app/search/ JC
const S32 MIN_PARCEL_AREA_FOR_SEARCH = 128;
- bool large_enough = parcel->getArea() > MIN_PARCEL_AREA_FOR_SEARCH;
+ bool large_enough = parcel->getArea() >= MIN_PARCEL_AREA_FOR_SEARCH;
if (large_enough)
{
if (can_change)
diff --git a/indra/newview/llfloaterlinkreplace.cpp b/indra/newview/llfloaterlinkreplace.cpp
index 10cce3bd22..595d584799 100644
--- a/indra/newview/llfloaterlinkreplace.cpp
+++ b/indra/newview/llfloaterlinkreplace.cpp
@@ -32,6 +32,8 @@
#include "llagent.h"
#include "llappearancemgr.h"
#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llnotifications.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
@@ -142,37 +144,72 @@ void LLFloaterLinkReplace::onStartClicked()
LL_WARNS() << "Cannot replace. Source and target are identical." << LL_ENDL;
return;
}
+
+ const LLUUID& source_item_id = gInventory.getLinkedItemID(mSourceUUID);
+ LLViewerInventoryItem *source_item = gInventory.getItem(source_item_id);
+ const LLUUID& target_item_id = gInventory.getLinkedItemID(mTargetUUID);
+ LLViewerInventoryItem *target_item = gInventory.getItem(target_item_id);
- LLInventoryModel::cat_array_t cat_array;
- LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
- gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
- cat_array,
- mRemainingInventoryItems,
- LLInventoryModel::INCLUDE_TRASH,
- is_linked_item_match);
- LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
- if (mRemainingInventoryItems.size() > 0)
+ LLNotification::Params params("ConfirmReplaceLink");
+ params.functor.function(boost::bind(&LLFloaterLinkReplace::onStartClickedResponse, this, _1, _2));
+ if (source_item && source_item->isWearableType() && source_item->getWearableType() <= LLWearableType::WT_EYES)
{
- LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
- if (target_item)
+ if(target_item && target_item->isWearableType() && source_item->getWearableType() == target_item->getWearableType())
{
- mRemainingItems = (U32)mRemainingInventoryItems.size();
-
- LLStringUtil::format_map_t args;
- args["NUM"] = llformat("%d", mRemainingItems);
- mStatusText->setText(getString("ItemsRemaining", args));
-
- mStartBtn->setEnabled(FALSE);
- mRefreshBtn->setEnabled(FALSE);
-
- mEventTimer.start();
- tick();
+ LLNotifications::instance().forceResponse(params, 0);
}
else
{
- mStatusText->setText(getString("TargetNotFound"));
- LL_WARNS() << "Link replace target not found." << LL_ENDL;
+ LLSD args;
+ args["TYPE"] = LLWearableType::getTypeName(source_item->getWearableType());
+ params.substitutions(args);
+ LLNotifications::instance().add(params);
+ }
+ }
+ else
+ {
+ LLNotifications::instance().forceResponse(params, 0);
+ }
+}
+
+void LLFloaterLinkReplace::onStartClickedResponse(const LLSD& notification, const LLSD& response)
+{
+
+ if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
+ {
+
+ LLInventoryModel::cat_array_t cat_array;
+ LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
+ gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+ cat_array,
+ mRemainingInventoryItems,
+ LLInventoryModel::INCLUDE_TRASH,
+ is_linked_item_match);
+ LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
+
+ if (mRemainingInventoryItems.size() > 0)
+ {
+ LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
+ if (target_item)
+ {
+ mRemainingItems = (U32)mRemainingInventoryItems.size();
+
+ LLStringUtil::format_map_t args;
+ args["NUM"] = llformat("%d", mRemainingItems);
+ mStatusText->setText(getString("ItemsRemaining", args));
+
+ mStartBtn->setEnabled(FALSE);
+ mRefreshBtn->setEnabled(FALSE);
+
+ mEventTimer.start();
+ tick();
+ }
+ else
+ {
+ mStatusText->setText(getString("TargetNotFound"));
+ LL_WARNS() << "Link replace target not found." << LL_ENDL;
+ }
}
}
}
diff --git a/indra/newview/llfloaterlinkreplace.h b/indra/newview/llfloaterlinkreplace.h
index dd5c301206..060773f93e 100644
--- a/indra/newview/llfloaterlinkreplace.h
+++ b/indra/newview/llfloaterlinkreplace.h
@@ -94,6 +94,7 @@ public:
private:
void checkEnableStart();
void onStartClicked();
+ void onStartClickedResponse(const LLSD& notification, const LLSD& response);
void decreaseOpenItemCount();
void updateFoundLinks();
void processBatch(LLInventoryModel::item_array_t items);
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b6efc1590e..c4186132fe 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -3014,6 +3014,15 @@ void LLModelPreview::updateStatusMessages()
{
mFMP->childDisable("ok_btn");
}
+
+ if (mModelNoErrors && mLodsWithParsingError.empty())
+ {
+ mFMP->childEnable("calculate_btn");
+ }
+ else
+ {
+ mFMP->childDisable("calculate_btn");
+ }
//add up physics triangles etc
S32 phys_tris = 0;
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index bfcd1b8b47..dccef88e41 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -31,8 +31,6 @@
#include "llagent.h"
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index fe347a91a3..bcb0dfe856 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -124,7 +124,9 @@ char const* const VISIBILITY_DEFAULT = "default";
char const* const VISIBILITY_HIDDEN = "hidden";
//control value for middle mouse as talk2push button
-const static std::string MIDDLE_MOUSE_CV = "MiddleMouse";
+const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; // for voice client and redability
+const static std::string MOUSE_BUTTON_4_CV = "MouseButton4";
+const static std::string MOUSE_BUTTON_5_CV = "MouseButton5";
/// This must equal the maximum value set for the IndirectMaxComplexity slider in panel_preferences_graphics1.xml
static const U32 INDIRECT_MAX_ARC_OFF = 101; // all the way to the right == disabled
@@ -168,6 +170,7 @@ public:
void setParent(LLFloaterPreference* parent) { mParent = parent; }
BOOL handleKeyHere(KEY key, MASK mask);
+ BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
static void onCancel(void* user_data);
private:
@@ -211,6 +214,25 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
return result;
}
+BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
+{
+ BOOL result = FALSE;
+ if (down
+ && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5)
+ && mask == 0)
+ {
+ mParent->setMouse(clicktype);
+ result = TRUE;
+ closeFloater();
+ }
+ else
+ {
+ result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
+ }
+
+ return result;
+}
+
//static
void LLVoiceSetKeyDialog::onCancel(void* user_data)
{
@@ -397,6 +419,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
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.RememberedUsernames", boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
mCommitCallbackRegistrar.add("Pref.Advanced", boost::bind(&LLFloaterPreference::onClickAdvanced, this));
@@ -1219,7 +1242,7 @@ void LLFloaterPreference::buildPopupLists()
LLNotificationFormPtr formp = templatep->mForm;
LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType();
- if (ignore == LLNotificationForm::IGNORE_NO)
+ if (ignore <= LLNotificationForm::IGNORE_NO)
continue;
LLSD row;
@@ -1694,6 +1717,41 @@ void LLFloaterPreference::setKey(KEY key)
getChild<LLUICtrl>("modifier_combo")->onCommit();
}
+void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click)
+{
+ std::string bt_name;
+ std::string ctrl_value;
+ switch (click)
+ {
+ case LLMouseHandler::CLICK_MIDDLE:
+ bt_name = "middle_mouse";
+ ctrl_value = MIDDLE_MOUSE_CV;
+ break;
+ case LLMouseHandler::CLICK_BUTTON4:
+ bt_name = "button4_mouse";
+ ctrl_value = MOUSE_BUTTON_4_CV;
+ break;
+ case LLMouseHandler::CLICK_BUTTON5:
+ bt_name = "button5_mouse";
+ ctrl_value = MOUSE_BUTTON_5_CV;
+ break;
+ default:
+ break;
+ }
+
+ if (!ctrl_value.empty())
+ {
+ LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
+ // We are using text control names for readability and compatibility with voice
+ p2t_line_editor->setControlValue(ctrl_value);
+ LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
+ if (advanced_preferences)
+ {
+ p2t_line_editor->setValue(advanced_preferences->getString(bt_name));
+ }
+ }
+}
+
void LLFloaterPreference::onClickSetMiddleMouse()
{
LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
@@ -1766,7 +1824,7 @@ void LLFloaterPreference::resetAllIgnored()
iter != LLNotifications::instance().templatesEnd();
++iter)
{
- if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
iter->second->mForm->setIgnored(false);
}
@@ -1779,7 +1837,7 @@ void LLFloaterPreference::setAllIgnored()
iter != LLNotifications::instance().templatesEnd();
++iter)
{
- if (iter->second->mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+ if (iter->second->mForm->getIgnoreType() > LLNotificationForm::IGNORE_NO)
{
iter->second->mForm->setIgnored(true);
}
@@ -2199,6 +2257,11 @@ void LLFloaterPreference::onClickPermsDefault()
LLFloaterReg::showInstance("perms_default");
}
+void LLFloaterPreference::onClickRememberedUsernames()
+{
+ LLFloaterReg::showInstance("forget_username");
+}
+
void LLFloaterPreference::onDeleteTranscripts()
{
LLSD args;
@@ -2431,10 +2494,19 @@ BOOL LLPanelPreference::postBuild()
if (hasChild("modifier_combo", TRUE))
{
//localizing if push2talk button is set to middle mouse
- if (MIDDLE_MOUSE_CV == getChild<LLUICtrl>("modifier_combo")->getValue().asString())
+ std::string modifier_value = getChild<LLUICtrl>("modifier_combo")->getValue().asString();
+ if (MIDDLE_MOUSE_CV == modifier_value)
{
getChild<LLUICtrl>("modifier_combo")->setValue(getString("middle_mouse"));
}
+ else if (MOUSE_BUTTON_4_CV == modifier_value)
+ {
+ getChild<LLUICtrl>("modifier_combo")->setValue(getString("button4_mouse"));
+ }
+ else if (MOUSE_BUTTON_5_CV == modifier_value)
+ {
+ getChild<LLUICtrl>("modifier_combo")->setValue(getString("button5_mouse"));
+ }
}
//////////////////////PanelSetup ///////////////////
@@ -2602,7 +2674,7 @@ void LLPanelPreference::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
- getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
+ getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
}
}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 1b8229ada6..4412c95473 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -148,6 +148,7 @@ public:
void onSelectSkin();
void onClickSetKey();
void setKey(KEY key);
+ void setMouse(LLMouseHandler::EClickType click);
void onClickSetMiddleMouse();
void onClickSetSounds();
void onClickEnablePopup();
@@ -167,7 +168,6 @@ public:
void refreshUI();
- void onCommitParcelMediaAutoPlayEnable();
void onCommitMediaEnabled();
void onCommitMusicEnabled();
void applyResolution();
@@ -180,6 +180,7 @@ public:
void onClickProxySettings();
void onClickTranslationSettings();
void onClickPermsDefault();
+ void onClickRememberedUsernames();
void onClickAutoReplace();
void onClickSpellChecker();
void onClickRenderExceptions();
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index fbb7432f71..64ad40f419 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -85,7 +85,7 @@ public:
}
virtual void changed(U32 mask);
private:
- LLFloaterProperties* mFloater;
+ LLFloaterProperties* mFloater; // Not a handle because LLFloaterProperties is managing LLPropertiesObserver
};
void LLPropertiesObserver::changed(U32 mask)
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 2798e375c7..ef7a9fd536 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -29,8 +29,6 @@
#include "llfloatersnapshot.h"
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
#include "llimagefiltersmanager.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
@@ -1240,10 +1238,7 @@ BOOL LLFloaterSnapshot::isWaitingState()
BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
{
- LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
- LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter");
-
- if (!initialized && !floater_flickr && !floater_twitter)
+ if (!initialized)
return FALSE;
BOOL changed = FALSE;
diff --git a/indra/newview/llfloatertwitter.cpp b/indra/newview/llfloatertwitter.cpp
deleted file mode 100644
index 2b33bc6935..0000000000
--- a/indra/newview/llfloatertwitter.cpp
+++ /dev/null
@@ -1,810 +0,0 @@
-/**
-* @file llfloatertwitter.cpp
-* @brief Implementation of llfloatertwitter
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatertwitter.h"
-
-#include "llagent.h"
-#include "llagentui.h"
-#include "llcheckboxctrl.h"
-#include "llcombobox.h"
-#include "lltwitterconnect.h"
-#include "llfloaterbigpreview.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "llimagefiltersmanager.h"
-#include "llresmgr.h" // LLLocale
-#include "llsdserialize.h"
-#include "llloadingindicator.h"
-#include "llslurl.h"
-#include "lltrans.h"
-#include "llsnapshotlivepreview.h"
-#include "llviewerregion.h"
-#include "llviewercontrol.h"
-#include "llviewermedia.h"
-#include "lltabcontainer.h"
-#include "lltexteditor.h"
-
-static LLPanelInjector<LLTwitterPhotoPanel> t_panel_photo("lltwitterphotopanel");
-static LLPanelInjector<LLTwitterAccountPanel> t_panel_account("lltwitteraccountpanel");
-
-const std::string DEFAULT_PHOTO_LOCATION_URL = "http://maps.secondlife.com/";
-const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=twitter&utm_medium=photo&utm_campaign=slshare";
-const std::string DEFAULT_STATUS_TEXT = " #SecondLife";
-
-///////////////////////////
-//LLTwitterPhotoPanel///////
-///////////////////////////
-
-LLTwitterPhotoPanel::LLTwitterPhotoPanel() :
-mResolutionComboBox(NULL),
-mRefreshBtn(NULL),
-mBtnPreview(NULL),
-mWorkingLabel(NULL),
-mThumbnailPlaceholder(NULL),
-mStatusCounterLabel(NULL),
-mStatusTextBox(NULL),
-mLocationCheckbox(NULL),
-mPhotoCheckbox(NULL),
-mBigPreviewFloater(NULL),
-mPostButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLTwitterPhotoPanel::onSend, this));
- mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLTwitterPhotoPanel::onClickNewSnapshot, this));
- mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLTwitterPhotoPanel::onClickBigPreview, this));
-}
-
-LLTwitterPhotoPanel::~LLTwitterPhotoPanel()
-{
- if(mPreviewHandle.get())
- {
- mPreviewHandle.get()->die();
- }
-}
-
-BOOL LLTwitterPhotoPanel::postBuild()
-{
- setVisibleCallback(boost::bind(&LLTwitterPhotoPanel::onVisibilityChange, this, _2));
-
- mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
- mResolutionComboBox->setValue("[i800,i600]"); // hardcoded defaults ftw!
- mResolutionComboBox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::updateResolution, this, TRUE));
- mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
- mFilterComboBox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::updateResolution, this, TRUE));
- mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
- mBtnPreview = getChild<LLButton>("big_preview_btn");
- mWorkingLabel = getChild<LLUICtrl>("working_lbl");
- mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
- mStatusCounterLabel = getChild<LLUICtrl>("status_counter_label");
- mStatusTextBox = getChild<LLUICtrl>("photo_status");
- mStatusTextBox->setValue(DEFAULT_STATUS_TEXT);
- mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
- mLocationCheckbox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::onAddLocationToggled, this));
- mPhotoCheckbox = getChild<LLUICtrl>("add_photo_cb");
- mPhotoCheckbox->setCommitCallback(boost::bind(&LLTwitterPhotoPanel::onAddPhotoToggled, this));
- mPostButton = getChild<LLUICtrl>("post_photo_btn");
- mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
- mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
-
- // Update filter list
- std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
- for (U32 i = 0; i < filter_list.size(); i++)
- {
- filterbox->add(filter_list[i]);
- }
-
- return LLPanel::postBuild();
-}
-
-// virtual
-S32 LLTwitterPhotoPanel::notify(const LLSD& info)
-{
- if (info.has("snapshot-updating"))
- {
- // Disable the Post button and whatever else while the snapshot is not updated
- // updateControls();
- return 1;
- }
-
- if (info.has("snapshot-updated"))
- {
- // Enable the send/post/save buttons.
- updateControls();
-
- // The refresh button is initially hidden. We show it after the first update,
- // i.e. after snapshot is taken
- LLUICtrl * refresh_button = getRefreshBtn();
- if (!refresh_button->getVisible())
- {
- refresh_button->setVisible(true);
- }
- return 1;
- }
-
- return 0;
-}
-
-void LLTwitterPhotoPanel::draw()
-{
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
-
- // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
- bool no_ongoing_connection = !(LLTwitterConnect::instance().isTransactionOngoing());
- bool photo_checked = mPhotoCheckbox->getValue().asBoolean();
- mCancelButton->setEnabled(no_ongoing_connection);
- mStatusTextBox->setEnabled(no_ongoing_connection);
- mResolutionComboBox->setEnabled(no_ongoing_connection && photo_checked);
- mFilterComboBox->setEnabled(no_ongoing_connection && photo_checked);
- mRefreshBtn->setEnabled(no_ongoing_connection && photo_checked);
- mBtnPreview->setEnabled(no_ongoing_connection);
- mLocationCheckbox->setEnabled(no_ongoing_connection);
- mPhotoCheckbox->setEnabled(no_ongoing_connection);
-
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- bool add_photo = mPhotoCheckbox->getValue().asBoolean();
- updateStatusTextLength(false);
-
- // Reassign the preview floater if we have the focus and the preview exists
- if (hasFocus() && isPreviewVisible())
- {
- attachPreview();
- }
-
- // Toggle the button state as appropriate
- bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
- mBtnPreview->setToggleState(preview_active);
-
- // Display the preview if one is available
- if (previewp && previewp->getThumbnailImage())
- {
- const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
- const S32 thumbnail_w = previewp->getThumbnailWidth();
- const S32 thumbnail_h = previewp->getThumbnailHeight();
-
- // calc preview offset within the preview rect
- const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2 ;
- const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2 ;
- S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
- S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- // Apply floater transparency to the texture unless the floater is focused.
- F32 alpha = (add_photo ? (getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency()) : 0.5f);
- LLColor4 color = LLColor4::white;
- gl_draw_scaled_image(offset_x, offset_y,
- thumbnail_w, thumbnail_h,
- previewp->getThumbnailImage(), color % alpha);
- }
-
- // Update the visibility of the working (computing preview) label
- mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
-
- // Enable Post if we have a preview to send and no on going connection being processed
- mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate()) && (add_photo || add_location || !mStatusTextBox->getValue().asString().empty()));
-
- // Draw the rest of the panel on top of it
- LLPanel::draw();
-}
-
-LLSnapshotLivePreview* LLTwitterPhotoPanel::getPreviewView()
-{
- LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
- return previewp;
-}
-
-void LLTwitterPhotoPanel::onVisibilityChange(BOOL visible)
-{
- if (visible)
- {
- if (mPreviewHandle.get())
- {
- LLSnapshotLivePreview* preview = getPreviewView();
- if(preview)
- {
- LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
- preview->updateSnapshot(TRUE);
- }
- }
- else
- {
- LLRect full_screen_rect = getRootView()->getRect();
- LLSnapshotLivePreview::Params p;
- p.rect(full_screen_rect);
- LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p);
- mPreviewHandle = previewp->getHandle();
-
- previewp->setContainer(this);
- previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
- previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG);
- previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image
- previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots
- previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode
- previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
-
- updateControls();
- }
- }
-}
-
-void LLTwitterPhotoPanel::onAddLocationToggled()
-{
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- updateStatusTextLength(!add_location);
-}
-
-void LLTwitterPhotoPanel::onAddPhotoToggled()
-{
- bool add_photo = mPhotoCheckbox->getValue().asBoolean();
- updateStatusTextLength(!add_photo);
-}
-
-void LLTwitterPhotoPanel::onClickNewSnapshot()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- if (previewp)
- {
- previewp->updateSnapshot(TRUE);
- }
-}
-
-void LLTwitterPhotoPanel::onClickBigPreview()
-{
- // Toggle the preview
- if (isPreviewVisible())
- {
- LLFloaterReg::hideInstance("big_preview");
- }
- else
- {
- attachPreview();
- LLFloaterReg::showInstance("big_preview");
- }
-}
-
-bool LLTwitterPhotoPanel::isPreviewVisible()
-{
- return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
-}
-
-void LLTwitterPhotoPanel::attachPreview()
-{
- if (mBigPreviewFloater)
- {
- LLSnapshotLivePreview* previewp = getPreviewView();
- mBigPreviewFloater->setPreview(previewp);
- mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
- }
-}
-
-void LLTwitterPhotoPanel::onSend()
-{
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterPhotoPanel"); // just in case it is already listening
- LLEventPumps::instance().obtain("TwitterConnectState").listen("LLTwitterPhotoPanel", boost::bind(&LLTwitterPhotoPanel::onTwitterConnectStateChange, this, _1));
-
- // Connect to Twitter if necessary and then post
- if (LLTwitterConnect::instance().isConnected())
- {
- sendPhoto();
- }
- else
- {
- LLTwitterConnect::instance().checkConnectionToTwitter(true);
- }
-}
-
-bool LLTwitterPhotoPanel::onTwitterConnectStateChange(const LLSD& data)
-{
- switch (data.get("enum").asInteger())
- {
- case LLTwitterConnect::TWITTER_CONNECTED:
- sendPhoto();
- break;
-
- case LLTwitterConnect::TWITTER_POSTED:
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterPhotoPanel");
- clearAndClose();
- break;
- }
-
- return false;
-}
-
-void LLTwitterPhotoPanel::sendPhoto()
-{
- // Get the status text
- std::string status = mStatusTextBox->getValue().asString();
-
- // Add the location if required
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- if (add_location)
- {
- // Get the SLURL for the location
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- std::string slurl_string = slurl.getSLURLString();
-
- // Use a valid http:// URL if the scheme is secondlife://
- LLURI slurl_uri(slurl_string);
- if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
- {
- slurl_string = DEFAULT_PHOTO_LOCATION_URL;
- }
-
- // Add query parameters so Google Analytics can track incoming clicks!
- slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
-
- // Add it to the status (pretty crude, but we don't have a better option with photos)
- if (status.empty())
- status = slurl_string;
- else
- status = status + " " + slurl_string;
- }
-
- // Add the photo if required
- bool add_photo = mPhotoCheckbox->getValue().asBoolean();
- if (add_photo)
- {
- // Get the image
- LLSnapshotLivePreview* previewp = getPreviewView();
-
- // Post to Twitter
- LLTwitterConnect::instance().uploadPhoto(previewp->getFormattedImage(), status);
- }
- else
- {
- // Just post the status to Twitter
- LLTwitterConnect::instance().updateStatus(status);
- }
-
- updateControls();
-}
-
-void LLTwitterPhotoPanel::clearAndClose()
-{
- mStatusTextBox->setValue(DEFAULT_STATUS_TEXT);
-
- LLFloater* floater = getParentByType<LLFloater>();
- if (floater)
- {
- floater->closeFloater();
- if (mBigPreviewFloater)
- {
- mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
- }
- }
-}
-
-void LLTwitterPhotoPanel::updateStatusTextLength(BOOL restore_old_status_text)
-{
- bool add_location = mLocationCheckbox->getValue().asBoolean();
-
- // Restrict the status text length to Twitter's character limit
- LLTextEditor* status_text_box = dynamic_cast<LLTextEditor*>(mStatusTextBox);
- if (status_text_box)
- {
- int max_status_length = 280 - (add_location ? 40 : 0);
- status_text_box->setMaxTextLength(max_status_length);
- if (restore_old_status_text)
- {
- if (mOldStatusText.length() > status_text_box->getText().length() && status_text_box->getText() == mOldStatusText.substr(0, status_text_box->getText().length()))
- {
- status_text_box->setText(mOldStatusText);
- }
- if (mOldStatusText.length() <= max_status_length)
- {
- mOldStatusText = "";
- }
- }
- if (status_text_box->getText().length() > max_status_length)
- {
- if (mOldStatusText.length() < status_text_box->getText().length() || status_text_box->getText() != mOldStatusText.substr(0, status_text_box->getText().length()))
- {
- mOldStatusText = status_text_box->getText();
- }
- status_text_box->setText(mOldStatusText.substr(0, max_status_length));
- }
-
- // Update the status character counter
- int characters_remaining = max_status_length - status_text_box->getText().length();
- mStatusCounterLabel->setValue(characters_remaining);
- }
-
-}
-
-void LLTwitterPhotoPanel::updateControls()
-{
- LLSnapshotLivePreview* previewp = getPreviewView();
- BOOL got_snap = previewp && previewp->getSnapshotUpToDate();
-
- // *TODO: Separate maximum size for Web images from postcards
- LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL;
-
- updateResolution(FALSE);
-}
-
-void LLTwitterPhotoPanel::updateResolution(BOOL do_update)
-{
- LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox);
- LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox);
-
- std::string sdstring = combobox->getSelectedValue();
- LLSD sdres;
- std::stringstream sstream(sdstring);
- LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
-
- S32 width = sdres[0];
- S32 height = sdres[1];
-
- // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
- std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
-
- LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get());
- if (previewp && combobox->getCurrentIndex() >= 0)
- {
- S32 original_width = 0 , original_height = 0 ;
- previewp->getSize(original_width, original_height) ;
-
- if (width == 0 || height == 0)
- {
- // take resolution from current window size
- LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL;
- previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
- }
- else
- {
- // use the resolution from the selected pre-canned drop-down choice
- LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
- previewp->setSize(width, height);
- }
-
- checkAspectRatio(width);
-
- previewp->getSize(width, height);
-
- if (original_width != width || original_height != height)
- {
- previewp->setSize(width, height);
- if (do_update)
- {
- previewp->updateSnapshot(TRUE);
- updateControls();
- }
- }
- // Get the old filter, compare to the current one "filter_name" and set if changed
- std::string original_filter = previewp->getFilter();
- if (original_filter != filter_name)
- {
- previewp->setFilter(filter_name);
- if (do_update)
- {
- previewp->updateSnapshot(FALSE, TRUE);
- updateControls();
- }
- }
- }
-}
-
-void LLTwitterPhotoPanel::checkAspectRatio(S32 index)
-{
- LLSnapshotLivePreview *previewp = getPreviewView() ;
-
- BOOL keep_aspect = FALSE;
-
- if (0 == index) // current window size
- {
- keep_aspect = TRUE;
- }
- else // predefined resolution
- {
- keep_aspect = FALSE;
- }
-
- if (previewp)
- {
- previewp->mKeepAspectRatio = keep_aspect;
- }
-}
-
-LLUICtrl* LLTwitterPhotoPanel::getRefreshBtn()
-{
- return mRefreshBtn;
-}
-
-///////////////////////////
-//LLTwitterAccountPanel//////
-///////////////////////////
-
-LLTwitterAccountPanel::LLTwitterAccountPanel() :
-mAccountCaptionLabel(NULL),
-mAccountNameLabel(NULL),
-mPanelButtons(NULL),
-mConnectButton(NULL),
-mDisconnectButton(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLTwitterAccountPanel::onConnect, this));
- mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLTwitterAccountPanel::onDisconnect, this));
-
- setVisibleCallback(boost::bind(&LLTwitterAccountPanel::onVisibilityChange, this, _2));
-}
-
-BOOL LLTwitterAccountPanel::postBuild()
-{
- mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
- mAccountNameLabel = getChild<LLTextBox>("account_name_label");
- mPanelButtons = getChild<LLUICtrl>("panel_buttons");
- mConnectButton = getChild<LLUICtrl>("connect_btn");
- mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
-
- return LLPanel::postBuild();
-}
-
-void LLTwitterAccountPanel::draw()
-{
- LLTwitterConnect::EConnectionState connection_state = LLTwitterConnect::instance().getConnectionState();
-
- //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress
- bool disconnecting = connection_state == LLTwitterConnect::TWITTER_DISCONNECTING;
- mDisconnectButton->setEnabled(!disconnecting);
-
- //Disable the 'connect' button when a connection is in progress
- bool connecting = connection_state == LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS;
- mConnectButton->setEnabled(!connecting);
-
- LLPanel::draw();
-}
-
-void LLTwitterAccountPanel::onVisibilityChange(BOOL visible)
-{
- if(visible)
- {
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterAccountPanel");
- LLEventPumps::instance().obtain("TwitterConnectState").listen("LLTwitterAccountPanel", boost::bind(&LLTwitterAccountPanel::onTwitterConnectStateChange, this, _1));
-
- LLEventPumps::instance().obtain("TwitterConnectInfo").stopListening("LLTwitterAccountPanel");
- LLEventPumps::instance().obtain("TwitterConnectInfo").listen("LLTwitterAccountPanel", boost::bind(&LLTwitterAccountPanel::onTwitterConnectInfoChange, this));
-
- //Connected
- if(LLTwitterConnect::instance().isConnected())
- {
- showConnectedLayout();
- }
- //Check if connected (show disconnected layout in meantime)
- else
- {
- showDisconnectedLayout();
- }
- if ((LLTwitterConnect::instance().getConnectionState() == LLTwitterConnect::TWITTER_NOT_CONNECTED) ||
- (LLTwitterConnect::instance().getConnectionState() == LLTwitterConnect::TWITTER_CONNECTION_FAILED))
- {
- LLTwitterConnect::instance().checkConnectionToTwitter();
- }
- }
- else
- {
- LLEventPumps::instance().obtain("TwitterConnectState").stopListening("LLTwitterAccountPanel");
- LLEventPumps::instance().obtain("TwitterConnectInfo").stopListening("LLTwitterAccountPanel");
- }
-}
-
-bool LLTwitterAccountPanel::onTwitterConnectStateChange(const LLSD& data)
-{
- if(LLTwitterConnect::instance().isConnected())
- {
- //In process of disconnecting so leave the layout as is
- if(data.get("enum").asInteger() != LLTwitterConnect::TWITTER_DISCONNECTING)
- {
- showConnectedLayout();
- }
- }
- else
- {
- showDisconnectedLayout();
- }
-
- return false;
-}
-
-bool LLTwitterAccountPanel::onTwitterConnectInfoChange()
-{
- LLSD info = LLTwitterConnect::instance().getInfo();
- std::string clickable_name;
-
- //Strings of format [http://www.somewebsite.com Click Me] become clickable text
- if(info.has("link") && info.has("name"))
- {
- clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]";
- }
-
- mAccountNameLabel->setText(clickable_name);
-
- return false;
-}
-
-void LLTwitterAccountPanel::showConnectButton()
-{
- if(!mConnectButton->getVisible())
- {
- mConnectButton->setVisible(TRUE);
- mDisconnectButton->setVisible(FALSE);
- }
-}
-
-void LLTwitterAccountPanel::hideConnectButton()
-{
- if(mConnectButton->getVisible())
- {
- mConnectButton->setVisible(FALSE);
- mDisconnectButton->setVisible(TRUE);
- }
-}
-
-void LLTwitterAccountPanel::showDisconnectedLayout()
-{
- mAccountCaptionLabel->setText(getString("twitter_disconnected"));
- mAccountNameLabel->setText(std::string(""));
- showConnectButton();
-}
-
-void LLTwitterAccountPanel::showConnectedLayout()
-{
- LLTwitterConnect::instance().loadTwitterInfo();
-
- mAccountCaptionLabel->setText(getString("twitter_connected"));
- hideConnectButton();
-}
-
-void LLTwitterAccountPanel::onConnect()
-{
- LLTwitterConnect::instance().checkConnectionToTwitter(true);
-}
-
-void LLTwitterAccountPanel::onDisconnect()
-{
- LLTwitterConnect::instance().disconnectFromTwitter();
-}
-
-////////////////////////
-//LLFloaterTwitter///////
-////////////////////////
-
-LLFloaterTwitter::LLFloaterTwitter(const LLSD& key) : LLFloater(key),
- mTwitterPhotoPanel(NULL),
- mStatusErrorText(NULL),
- mStatusLoadingText(NULL),
- mStatusLoadingIndicator(NULL)
-{
- mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterTwitter::onCancel, this));
-}
-
-void LLFloaterTwitter::onClose(bool app_quitting)
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- LLFloater::onClose(app_quitting);
-}
-
-void LLFloaterTwitter::onCancel()
-{
- LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
- if (big_preview_floater)
- {
- big_preview_floater->closeOnFloaterOwnerClosing(this);
- }
- closeFloater();
-}
-
-BOOL LLFloaterTwitter::postBuild()
-{
- // Keep tab of the Photo Panel
- mTwitterPhotoPanel = static_cast<LLTwitterPhotoPanel*>(getChild<LLUICtrl>("panel_twitter_photo"));
- // Connection status widgets
- mStatusErrorText = getChild<LLTextBox>("connection_error_text");
- mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
- mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
- return LLFloater::postBuild();
-}
-
-void LLFloaterTwitter::showPhotoPanel()
-{
- LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mTwitterPhotoPanel->getParent());
- if (!parent)
- {
- LL_WARNS() << "Cannot find panel container" << LL_ENDL;
- return;
- }
-
- parent->selectTabPanel(mTwitterPhotoPanel);
-}
-
-void LLFloaterTwitter::draw()
-{
- if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
- {
- mStatusErrorText->setVisible(false);
- mStatusLoadingText->setVisible(false);
- mStatusLoadingIndicator->setVisible(false);
- LLTwitterConnect::EConnectionState connection_state = LLTwitterConnect::instance().getConnectionState();
- std::string status_text;
-
- switch (connection_state)
- {
- case LLTwitterConnect::TWITTER_NOT_CONNECTED:
- // No status displayed when first opening the panel and no connection done
- case LLTwitterConnect::TWITTER_CONNECTED:
- // When successfully connected, no message is displayed
- case LLTwitterConnect::TWITTER_POSTED:
- // No success message to show since we actually close the floater after successful posting completion
- break;
- case LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS:
- // Connection loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterConnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLTwitterConnect::TWITTER_POSTING:
- // Posting indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterPosting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLTwitterConnect::TWITTER_CONNECTION_FAILED:
- // Error connecting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterErrorConnecting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLTwitterConnect::TWITTER_POST_FAILED:
- // Error posting to the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterErrorPosting");
- mStatusErrorText->setValue(status_text);
- break;
- case LLTwitterConnect::TWITTER_DISCONNECTING:
- // Disconnecting loading indicator
- mStatusLoadingText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterDisconnecting");
- mStatusLoadingText->setValue(status_text);
- mStatusLoadingIndicator->setVisible(true);
- break;
- case LLTwitterConnect::TWITTER_DISCONNECT_FAILED:
- // Error disconnecting from the service
- mStatusErrorText->setVisible(true);
- status_text = LLTrans::getString("SocialTwitterErrorDisconnecting");
- mStatusErrorText->setValue(status_text);
- break;
- }
- }
- LLFloater::draw();
-}
-
diff --git a/indra/newview/llfloatertwitter.h b/indra/newview/llfloatertwitter.h
deleted file mode 100644
index d586799d18..0000000000
--- a/indra/newview/llfloatertwitter.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
-* @file llfloatertwitter.h
-* @brief Header file for llfloatertwitter
-* @author cho@lindenlab.com
-*
-* $LicenseInfo:firstyear=2013&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2013, Linden Research, Inc.
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-*
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
-* $/LicenseInfo$
-*/
-#ifndef LL_LLFLOATERTWITTER_H
-#define LL_LLFLOATERTWITTER_H
-
-#include "llfloater.h"
-#include "lltextbox.h"
-#include "llviewertexture.h"
-
-class LLIconCtrl;
-class LLCheckBoxCtrl;
-class LLSnapshotLivePreview;
-class LLFloaterBigPreview;
-
-class LLTwitterPhotoPanel : public LLPanel
-{
-public:
- LLTwitterPhotoPanel();
- ~LLTwitterPhotoPanel();
-
- BOOL postBuild();
- void draw();
-
- LLSnapshotLivePreview* getPreviewView();
- void onVisibilityChange(BOOL new_visibility);
- void onAddLocationToggled();
- void onAddPhotoToggled();
- void onClickBigPreview();
- void onClickNewSnapshot();
- void onSend();
- S32 notify(const LLSD& info);
- bool onTwitterConnectStateChange(const LLSD& data);
-
- void sendPhoto();
- void clearAndClose();
-
- void updateStatusTextLength(BOOL restore_old_status_text);
- void updateControls();
- void updateResolution(BOOL do_update);
- void checkAspectRatio(S32 index);
- LLUICtrl* getRefreshBtn();
-
-private:
- bool isPreviewVisible();
- void attachPreview();
-
- LLHandle<LLView> mPreviewHandle;
-
- LLUICtrl * mResolutionComboBox;
- LLUICtrl * mFilterComboBox;
- LLUICtrl * mRefreshBtn;
- LLUICtrl * mWorkingLabel;
- LLUICtrl * mThumbnailPlaceholder;
- LLUICtrl * mStatusCounterLabel;
- LLUICtrl * mStatusTextBox;
- LLUICtrl * mLocationCheckbox;
- LLUICtrl * mPhotoCheckbox;
- LLUICtrl * mPostButton;
- LLUICtrl * mCancelButton;
- LLButton * mBtnPreview;
-
- LLFloaterBigPreview * mBigPreviewFloater;
-
- std::string mOldStatusText;
-};
-
-class LLTwitterAccountPanel : public LLPanel
-{
-public:
- LLTwitterAccountPanel();
- BOOL postBuild();
- void draw();
-
-private:
- void onVisibilityChange(BOOL new_visibility);
- bool onTwitterConnectStateChange(const LLSD& data);
- bool onTwitterConnectInfoChange();
- void onConnect();
- void onUseAnotherAccount();
- void onDisconnect();
-
- void showConnectButton();
- void hideConnectButton();
- void showDisconnectedLayout();
- void showConnectedLayout();
-
- LLTextBox * mAccountCaptionLabel;
- LLTextBox * mAccountNameLabel;
- LLUICtrl * mPanelButtons;
- LLUICtrl * mConnectButton;
- LLUICtrl * mDisconnectButton;
-};
-
-
-class LLFloaterTwitter : public LLFloater
-{
-public:
- LLFloaterTwitter(const LLSD& key);
- BOOL postBuild();
- void draw();
- void onClose(bool app_quitting);
- void onCancel();
-
- void showPhotoPanel();
-
-private:
- LLTwitterPhotoPanel* mTwitterPhotoPanel;
- LLTextBox* mStatusErrorText;
- LLTextBox* mStatusLoadingText;
- LLUICtrl* mStatusLoadingIndicator;
-};
-
-#endif // LL_LLFLOATERTWITTER_H
-
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index c591dfacaf..23fd6d9c8e 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -30,8 +30,6 @@
#include "lliconctrl.h"
#include "llfloaterreg.h"
#include "llhttpconstants.h"
-#include "llflickrconnect.h"
-#include "lltwitterconnect.h"
#include "lllayoutstack.h"
#include "llpluginclassmedia.h"
#include "llprogressbar.h"
@@ -288,26 +286,6 @@ void LLFloaterWebContent::onOpen(const LLSD& key)
//virtual
void LLFloaterWebContent::onClose(bool app_quitting)
{
- // If we close the web browsing window showing the Flickr login, we need to signal to this object that the connection will not happen
- // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
- LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web");
- if (flickr_web == this)
- {
- if (!LLFlickrConnect::instance().isConnected())
- {
- LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED);
- }
- }
- // Same with Twitter
- // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad.
- LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web");
- if (twitter_web == this)
- {
- if (!LLTwitterConnect::instance().isConnected())
- {
- LLTwitterConnect::instance().setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- }
- }
LLViewerMedia::getInstance()->proxyWindowClosed(mUUID);
destroy();
}
diff --git a/indra/newview/llhudeffectbeam.cpp b/indra/newview/llhudeffectbeam.cpp
index 54e683e048..d1d83e6e03 100644
--- a/indra/newview/llhudeffectbeam.cpp
+++ b/indra/newview/llhudeffectbeam.cpp
@@ -90,7 +90,7 @@ void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
memset(packed_data, 0, 41);
if (mSourceObject)
{
- htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
}
if (mTargetObject)
@@ -104,11 +104,11 @@ void LLHUDEffectBeam::packData(LLMessageSystem *mesgsys)
if (mTargetObject)
{
- htonmemcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[17]), mTargetObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
+ htolememcpy(&(packed_data[17]), mTargetPos.mdV, MVT_LLVector3d, 24);
}
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
}
@@ -131,7 +131,7 @@ void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 41, blocknum);
- htonmemcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
+ htolememcpy(source_id.mData, packed_data, MVT_LLUUID, 16);
LLViewerObject *objp = gObjectList.findObject(source_id);
if (objp)
@@ -143,7 +143,7 @@ void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
if (use_target_object)
{
- htonmemcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
+ htolememcpy(target_id.mData, &packed_data[17], MVT_LLUUID, 16);
LLViewerObject *objp = gObjectList.findObject(target_id);
if (objp)
@@ -153,7 +153,7 @@ void LLHUDEffectBeam::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
else
{
- htonmemcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
+ htolememcpy(new_target.mdV, &(packed_data[17]), MVT_LLVector3d, 24);
setTargetPos(new_target);
}
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index f46152dcec..6898dce7b1 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -269,29 +269,29 @@ void LLHUDEffectLookAt::packData(LLMessageSystem *mesgsys)
if (mSourceObject)
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
}
// pack both target object and position
// position interpreted as offset if target object is non-null
if (mTargetObject)
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
}
- htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
+ htolememcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
U8 lookAtTypePacked = (U8)mTargetType;
- htonmemcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1);
+ htolememcpy(&(packed_data[LOOKAT_TYPE]), &lookAtTypePacked, MVT_U8, 1);
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE);
@@ -325,7 +325,7 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum);
- htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
+ htolememcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
LLViewerObject *objp = gObjectList.findObject(source_id);
if (objp && objp->isAvatar())
@@ -338,11 +338,11 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
return;
}
- htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
+ htolememcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
objp = gObjectList.findObject(target_id);
- htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
+ htolememcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
if (objp)
{
@@ -358,7 +358,7 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
U8 lookAtTypeUnpacked = 0;
- htonmemcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1);
+ htolememcpy(&lookAtTypeUnpacked, &(packed_data[LOOKAT_TYPE]), MVT_U8, 1);
mTargetType = (ELookAtType)lookAtTypeUnpacked;
if (mTargetType == LOOKAT_TARGET_NONE)
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index cc772c8f5c..ecf6d42d69 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -107,28 +107,28 @@ void LLHUDEffectPointAt::packData(LLMessageSystem *mesgsys)
if (mSourceObject)
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), mSourceObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[SOURCE_AVATAR]), LLUUID::null.mData, MVT_LLUUID, 16);
}
// pack both target object and position
// position interpreted as offset if target object is non-null
if (mTargetObject)
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16);
}
else
{
- htonmemcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
+ htolememcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16);
}
- htonmemcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
+ htolememcpy(&(packed_data[TARGET_POS]), mTargetOffsetGlobal.mdV, MVT_LLVector3d, 24);
U8 pointAtTypePacked = (U8)mTargetType;
- htonmemcpy(&(packed_data[POINTAT_TYPE]), &pointAtTypePacked, MVT_U8, 1);
+ htolememcpy(&(packed_data[POINTAT_TYPE]), &pointAtTypePacked, MVT_U8, 1);
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE);
@@ -164,10 +164,10 @@ void LLHUDEffectPointAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
}
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum);
- htonmemcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
- htonmemcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
- htonmemcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
- htonmemcpy(&pointAtTypeUnpacked, &(packed_data[POINTAT_TYPE]), MVT_U8, 1);
+ htolememcpy(source_id.mData, &(packed_data[SOURCE_AVATAR]), MVT_LLUUID, 16);
+ htolememcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16);
+ htolememcpy(new_target.mdV, &(packed_data[TARGET_POS]), MVT_LLVector3d, 24);
+ htolememcpy(&pointAtTypeUnpacked, &(packed_data[POINTAT_TYPE]), MVT_U8, 1);
LLViewerObject *objp = gObjectList.findObject(source_id);
if (objp && objp->isAvatar())
diff --git a/indra/newview/llhudeffecttrail.cpp b/indra/newview/llhudeffecttrail.cpp
index fc6efdb840..2ba8aa422b 100644
--- a/indra/newview/llhudeffecttrail.cpp
+++ b/indra/newview/llhudeffecttrail.cpp
@@ -87,15 +87,15 @@ void LLHUDEffectSpiral::packData(LLMessageSystem *mesgsys)
if (mSourceObject)
{
- htonmemcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(packed_data, mSourceObject->mID.mData, MVT_LLUUID, 16);
}
if (mTargetObject)
{
- htonmemcpy(packed_data + 16, mTargetObject->mID.mData, MVT_LLUUID, 16);
+ htolememcpy(packed_data + 16, mTargetObject->mID.mData, MVT_LLUUID, 16);
}
if (!mPositionGlobal.isExactlyZero())
{
- htonmemcpy(packed_data + 32, mPositionGlobal.mdV, MVT_LLVector3d, 24);
+ htolememcpy(packed_data + 32, mPositionGlobal.mdV, MVT_LLVector3d, 24);
}
mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 56);
}
@@ -116,9 +116,9 @@ void LLHUDEffectSpiral::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData,
packed_data, EFFECT_SIZE, blocknum, EFFECT_SIZE);
- htonmemcpy(object_id.mData, packed_data, MVT_LLUUID, 16);
- htonmemcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16);
- htonmemcpy(mPositionGlobal.mdV, packed_data + 32, MVT_LLVector3d, 24);
+ htolememcpy(object_id.mData, packed_data, MVT_LLUUID, 16);
+ htolememcpy(target_object_id.mData, packed_data + 16, MVT_LLUUID, 16);
+ htolememcpy(mPositionGlobal.mdV, packed_data + 32, MVT_LLVector3d, 24);
LLViewerObject *objp = NULL;
diff --git a/indra/newview/llimagefiltersmanager.cpp b/indra/newview/llimagefiltersmanager.cpp
index c23cdc8103..3b8adc1610 100644
--- a/indra/newview/llimagefiltersmanager.cpp
+++ b/indra/newview/llimagefiltersmanager.cpp
@@ -1,6 +1,6 @@
/**
* @file llimagefiltersmanager.cpp
- * @brief Load image filters list and retrieve their path. Mostly used for Flickr UI at the moment.
+ * @brief Load image filters list and retrieve their path.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llimagefiltersmanager.h b/indra/newview/llimagefiltersmanager.h
index f1ed3cf1c3..d06212d85a 100644
--- a/indra/newview/llimagefiltersmanager.h
+++ b/indra/newview/llimagefiltersmanager.h
@@ -1,6 +1,6 @@
/**
* @file llimagefiltersmanager.h
- * @brief Load image filters list and retrieve their path. Mostly used for Flickr UI at the moment.
+ * @brief Load image filters list and retrieve their path.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 3606a439a6..61c8a3a898 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -29,6 +29,7 @@
#include "llimprocessing.h"
#include "llagent.h"
+#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llfirstuse.h"
#include "llfloaterreg.h"
@@ -715,7 +716,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
{
info = new LLOfferInfo();
- info->mIM = IM_GROUP_NOTICE;
+ info->mIM = dialog;
info->mFromID = from_id;
info->mFromGroup = from_group;
info->mTransactionID = session_id;
@@ -896,12 +897,18 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
if (is_muted)
{
// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
- LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
- fetch_item->startFetch();
- delete fetch_item;
-
- // Same as closing window
- info->forceResponse(IOR_DECLINE);
+ if (IM_INVENTORY_OFFERED == dialog)
+ {
+ LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
+ fetch_item->startFetch();
+ delete fetch_item;
+ // Same as closing window
+ info->forceResponse(IOR_DECLINE);
+ }
+ else
+ {
+ info->forceResponse(IOR_MUTE);
+ }
}
// old logic: busy mode must not affect interaction with objects (STORM-565)
// new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
@@ -1468,6 +1475,7 @@ void LLIMProcessing::requestOfflineMessages()
static BOOL requested = FALSE;
if (!requested
&& gMessageSystem
+ && !gDisconnected
&& LLMuteList::getInstance()->isLoaded()
&& isAgentAvatarValid()
&& gAgent.getRegion()
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e331a51bda..d5142a4496 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -843,7 +843,7 @@ void LLIMModel::LLIMSession::loadHistory()
std::list<LLSD> chat_history;
//involves parsing of a chat history
- LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+ LLLogChat::loadChatHistory(mHistoryFileName, chat_history, LLSD(), isGroupChat());
addMessagesFromHistory(chat_history);
}
}
@@ -907,6 +907,11 @@ bool LLIMModel::LLIMSession::isP2P()
return IM_NOTHING_SPECIAL == mType;
}
+bool LLIMModel::LLIMSession::isGroupChat()
+{
+ return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID));
+}
+
bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
{
return !mOtherParticipantIsAvatar;
@@ -964,6 +969,10 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
mHistoryFileName = LLCacheName::buildUsername(mName);
}
}
+ else if (isGroupChat())
+ {
+ mHistoryFileName = mName + GROUP_CHAT_SUFFIX;
+ }
}
//static
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 2a9e4679a8..79c831ebb6 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -91,6 +91,7 @@ public:
bool isOutgoingAdHoc() const;
bool isAdHoc();
bool isP2P();
+ bool isGroupChat();
bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 349ba6183b..6d2d533c9d 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4662,7 +4662,7 @@ bool move_task_inventory_callback(const LLSD& notification, const LLSD& response
{
LLInventoryObject::object_list_t inventory_objects;
object->getInventoryContents(inventory_objects);
- int contents_count = inventory_objects.size()-1; //subtract one for containing folder
+ int contents_count = inventory_objects.size();
LLInventoryCopyAndWearObserver* inventoryObserver = new LLInventoryCopyAndWearObserver(cat_and_wear->mCatID, contents_count, cat_and_wear->mFolderResponded,
cat_and_wear->mReplace);
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 16385928b4..e8bc915f22 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -42,7 +42,7 @@
#include "llviewerfoldertype.h"
#include "llradiogroup.h"
#include "llstartup.h"
-
+#include <boost/regex.hpp>
// linden library includes
#include "llclipboard.h"
#include "lltrans.h"
@@ -116,7 +116,39 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
break;
}
- bool passed = (mFilterSubString.size() ? desc.find(mFilterSubString) != std::string::npos : true);
+
+ bool passed = true;
+ if (!mExactToken.empty() && (mSearchType == SEARCHTYPE_NAME))
+ {
+ passed = false;
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ tokenizer tokens(desc, sep);
+
+ for (auto token_iter : tokens)
+ {
+ if (token_iter == mExactToken)
+ {
+ passed = true;
+ break;
+ }
+ }
+ }
+ else if ((mFilterTokens.size() > 0) && (mSearchType == SEARCHTYPE_NAME))
+ {
+ for (auto token_iter : mFilterTokens)
+ {
+ if (desc.find(token_iter) == std::string::npos)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ passed = (mFilterSubString.size() ? desc.find(mFilterSubString) != std::string::npos : true);
+ }
+
passed = passed && checkAgainstFilterType(listener);
passed = passed && checkAgainstPermissions(listener);
passed = passed && checkAgainstFilterLinks(listener);
@@ -693,6 +725,38 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
if (mFilterSubString != filter_sub_string_new)
{
+
+ mFilterTokens.clear();
+ if (filter_sub_string_new.find_first_of("+") != std::string::npos)
+ {
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("+");
+ tokenizer tokens(filter_sub_string_new, sep);
+
+ for (auto token_iter : tokens)
+ {
+ mFilterTokens.push_back(token_iter);
+ }
+ }
+
+ std::string old_token = mExactToken;
+ mExactToken.clear();
+ bool exact_token_changed = false;
+ if (mFilterTokens.empty() && filter_sub_string_new.size() > 2)
+ {
+ boost::regex mPattern = boost::regex("\"\\s*([^<]*)?\\s*\"",
+ boost::regex::perl | boost::regex::icase);
+ boost::match_results<std::string::const_iterator> matches;
+ mExactToken = (boost::regex_match(filter_sub_string_new, matches, mPattern) && matches[1].matched)
+ ? matches[1]
+ : LLStringUtil::null;
+ if ((old_token.empty() && !mExactToken.empty())
+ || (!old_token.empty() && mExactToken.empty()))
+ {
+ exact_token_changed = true;
+ }
+ }
+
// hitting BACKSPACE, for example
const BOOL less_restrictive = mFilterSubString.size() >= filter_sub_string_new.size()
&& !mFilterSubString.substr(0, filter_sub_string_new.size()).compare(filter_sub_string_new);
@@ -702,7 +766,11 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
&& !filter_sub_string_new.substr(0, mFilterSubString.size()).compare(mFilterSubString);
mFilterSubString = filter_sub_string_new;
- if (less_restrictive)
+ if (exact_token_changed)
+ {
+ setModified(FILTER_RESTART);
+ }
+ else if (less_restrictive)
{
setModified(FILTER_LESS_RESTRICTIVE);
}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 4a1fec8454..3f24211f41 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -327,6 +327,9 @@ private:
std::string mEmptyLookupMessage;
ESearchType mSearchType;
+
+ std::vector<std::string> mFilterTokens;
+ std::string mExactToken;
};
#endif
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d4993a1091..6f461673ee 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -291,7 +291,6 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible"))
{
getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
- getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
}
// hide marketplace listing box, unless we are a marketplace panel
if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible") && !mParams.use_marketplace_folders)
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 453bf17b11..0c64531783 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -67,6 +67,8 @@ const std::string LL_IM_FROM("from");
const std::string LL_IM_FROM_ID("from_id");
const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
+const std::string GROUP_CHAT_SUFFIX(" (group)");
+
const static char IM_SYMBOL_SEPARATOR(':');
const static std::string IM_SEPARATOR(std::string() + IM_SYMBOL_SEPARATOR + " ");
const static std::string NEW_LINE("\n");
@@ -355,7 +357,7 @@ void LLLogChat::saveHistory(const std::string& filename,
}
// static
-void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
+void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params, bool is_group)
{
if (file_name.empty())
{
@@ -368,10 +370,25 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (!fptr)
{
- fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (is_group)
+ {
+ std::string old_name(file_name);
+ old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
+ if (fptr)
+ {
+ fclose(fptr);
+ LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
+ }
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
+ }
if (!fptr)
{
- return; //No previous conversation with this name.
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ return; //No previous conversation with this name.
+ }
}
}
@@ -1053,12 +1070,28 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL
if (!fptr)
{
- fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ bool is_group = load_params.has("is_group") ? load_params["is_group"].asBoolean() : false;
+ if (is_group)
+ {
+ std::string old_name(file_name);
+ old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
+ if (fptr)
+ {
+ fclose(fptr);
+ LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
+ }
+ fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
+ }
if (!fptr)
{
- mNewLoad = false;
- (*mLoadEndSignal)(messages, file_name);
- return; //No previous conversation with this name.
+ fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+ if (!fptr)
+ {
+ mNewLoad = false;
+ (*mLoadEndSignal)(messages, file_name);
+ return; //No previous conversation with this name.
+ }
}
}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index b71a34ae0a..8b7fe14e16 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -106,7 +106,7 @@ public:
static void getListOfTranscriptFiles(std::vector<std::string>& list);
static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
- static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+ static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD(), bool is_group = false);
typedef boost::signals2::signal<void ()> save_history_signal_t;
boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
@@ -196,6 +196,7 @@ protected:
virtual ~LLChatLogParser() {};
};
+extern const std::string GROUP_CHAT_SUFFIX;
// LLSD map lookup constants
extern const std::string LL_IM_TIME; //("time");
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index eca34c0d4d..22cedf450e 100644
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
@@ -139,8 +139,11 @@ LLPointer<LLCredential> LLLoginHandler::initializeLoginInfo()
// so try to load it from the UserLoginInfo
result = loadSavedUserLoginInfo();
if (result.isNull())
- {
- result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ {
+ // Since legacy viewer store login info one per grid, newer viewers have to
+ // reuse same information to remember last user and for compatibility,
+ // but otherwise login info is stored in separate map in gSecAPIHandler
+ result = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
}
return result;
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index b399ab9bc4..0affe8efb4 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -202,12 +202,29 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
{
if (LLPanel::handleScrollWheel(x, y, clicks)) return TRUE;
if (mMediaSource && mMediaSource->hasMedia())
- mMediaSource->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
+ {
+ convertInputCoords(x, y);
+ mMediaSource->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(TRUE));
+ }
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
+//
+BOOL LLMediaCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ if (LLPanel::handleScrollHWheel(x, y, clicks)) return TRUE;
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ convertInputCoords(x, y);
+ mMediaSource->scrollWheel(x, y, clicks, 0, gKeyboard->currentMask(TRUE));
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// virtual
BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask)
{
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 11400c8274..958c76f261 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -92,6 +92,7 @@ public:
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+ virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks );
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
// navigation
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 8fc356c928..54409a6994 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -574,6 +574,8 @@ BOOL LLPanelStandStopFlying::postBuild()
//mStopFlyingButton->setCommitCallback(boost::bind(&LLFloaterMove::setFlyingMode, FALSE));
mStopFlyingButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStopFlyingButtonClick, this));
mStopFlyingButton->setVisible(FALSE);
+
+ gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLPanelStandStopFlying::updatePosition, this));
return TRUE;
}
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index b405d3dca2..6a79a0c68c 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -262,6 +262,7 @@ std::set<std::string> LLTransactionNotificationListItem::getTypes()
std::set<std::string> types;
types.insert("PaymentReceived");
types.insert("PaymentSent");
+ types.insert("UploadPayment");
return types;
}
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 6d0c30fbf3..c0342eef4e 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -764,6 +764,7 @@ void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType t
setClassifiedName(c_info->name);
setDescription(c_info->description);
setSnapshotId(c_info->snapshot_id);
+ setParcelId(c_info->parcel_id);
setPosGlobal(c_info->pos_global);
setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 0efb234015..e3d75d5604 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1153,7 +1153,7 @@ void LLPanelGroupMembersSubTab::onInviteMember(void *userdata)
void LLPanelGroupMembersSubTab::handleInviteMember()
{
- LLFloaterGroupInvite::showForGroup(mGroupID);
+ LLFloaterGroupInvite::showForGroup(mGroupID, NULL, false);
}
void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index e253557797..7ef3685cdb 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -77,6 +77,60 @@ LLPanelLogin *LLPanelLogin::sInstance = NULL;
BOOL LLPanelLogin::sCapslockDidNotification = FALSE;
BOOL LLPanelLogin::sCredentialSet = FALSE;
+// Helper functions
+
+LLPointer<LLCredential> load_user_credentials(std::string &user_key)
+{
+ if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
+ {
+ // user_key should be of "name Resident" format
+ return gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
+ }
+ else
+ {
+ // legacy (or legacy^2, since it also tries to load from settings)
+ return gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ }
+}
+
+// keys are lower case to be case insensitive so they are not always
+// identical to names which retain user input, like:
+// "AwEsOmE Resident" -> "awesome_resident"
+std::string get_user_key_from_name(const std::string &username)
+{
+ std::string key = username;
+ LLStringUtil::trim(key);
+ LLStringUtil::toLower(key);
+ if (!LLGridManager::getInstance()->isSystemGrid())
+ {
+ size_t separator_index = username.find_first_of(" ");
+ if (separator_index == username.npos)
+ {
+ // CRED_IDENTIFIER_TYPE_ACCOUNT
+ return key;
+ }
+ }
+ // CRED_IDENTIFIER_TYPE_AGENT
+ size_t separator_index = username.find_first_of(" ._");
+ std::string first = username.substr(0, separator_index);
+ std::string last;
+ if (separator_index != username.npos)
+ {
+ last = username.substr(separator_index + 1, username.npos);
+ LLStringUtil::trim(last);
+ }
+ else
+ {
+ // ...on Linden grids, single username users as considered to have
+ // last name "Resident"
+ // *TODO: Make login.cgi support "account_name" like above
+ last = "resident";
+ }
+
+ key = first + "_" + last;
+ return key;
+}
+
class LLLoginLocationAutoHandler : public LLCommandHandler
{
public:
@@ -168,6 +222,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mCallback(callback),
mCallbackData(cb_data),
mListener(new LLPanelLoginListener(this)),
+ mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")),
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
@@ -186,7 +241,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
login_holder->addChild(this);
}
- if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ if (mFirstLoginThisInstall)
{
buildFromFile( "panel_login_first.xml");
}
@@ -206,35 +261,39 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
sendChildToBack(getChildView("forgot_password_text"));
sendChildToBack(getChildView("sign_up_text"));
- LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
- updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
- favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
- favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
-
- LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
- server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
-
- // Load all of the grids, sorted, and then add a bar and the current grid at the top
- server_choice_combo->removeall();
-
- std::string current_grid = LLGridManager::getInstance()->getGrid();
- std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
- for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
- grid_choice != known_grids.end();
- grid_choice++)
- {
- if (!grid_choice->first.empty() && current_grid != grid_choice->first)
- {
- LL_DEBUGS("AppInit")<<"adding "<<grid_choice->first<<LL_ENDL;
- server_choice_combo->add(grid_choice->second, grid_choice->first);
- }
- }
- server_choice_combo->sortByName();
- LL_DEBUGS("AppInit")<<"adding current "<<current_grid<<LL_ENDL;
- server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
- current_grid,
- ADD_TOP);
- server_choice_combo->selectFirstItem();
+ std::string current_grid = LLGridManager::getInstance()->getGrid();
+ if (!mFirstLoginThisInstall)
+ {
+ LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
+ updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
+ favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
+
+ LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
+ server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this));
+
+ // Load all of the grids, sorted, and then add a bar and the current grid at the top
+ server_choice_combo->removeall();
+
+ std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids();
+ for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin();
+ grid_choice != known_grids.end();
+ grid_choice++)
+ {
+ if (!grid_choice->first.empty() && current_grid != grid_choice->first)
+ {
+ LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL;
+ server_choice_combo->add(grid_choice->second, grid_choice->first);
+ }
+ }
+ server_choice_combo->sortByName();
+
+ LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL;
+ server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(),
+ current_grid,
+ ADD_TOP);
+ server_choice_combo->selectFirstItem();
+ }
LLSLURL start_slurl(LLStartUp::getStartSLURL());
// The StartSLURL might have been set either by an explicit command-line
@@ -297,14 +356,30 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
loadLoginPage();
LLComboBox* username_combo(getChild<LLComboBox>("username_combo"));
- username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::addFavoritesToStartLocation, this));
+ username_combo->setTextChangedCallback(boost::bind(&LLPanelLogin::onUserNameTextEnty, this));
// STEAM-14: When user presses Enter with this field in focus, initiate login
- username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ username_combo->setCommitCallback(boost::bind(&LLPanelLogin::onUserListCommit, this));
+ username_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
username_combo->setKeystrokeOnEsc(TRUE);
+
+ if (!mFirstLoginThisInstall)
+ {
+ LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
+ remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
+ }
}
void LLPanelLogin::addFavoritesToStartLocation()
{
+ if (mFirstLoginThisInstall)
+ {
+ // first login panel has no favorites, just update name length and buttons
+ std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
+ mUsernameLength = user_defined_name.length();
+ updateLoginButtons();
+ return;
+ }
+
// Clear the combo.
LLComboBox* combo = getChild<LLComboBox>("start_location_combo");
if (!combo) return;
@@ -316,14 +391,14 @@ void LLPanelLogin::addFavoritesToStartLocation()
// Load favorites into the combo.
std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple();
+ LLStringUtil::trim(user_defined_name);
LLStringUtil::toLower(user_defined_name);
- std::replace(user_defined_name.begin(), user_defined_name.end(), '.', ' ');
std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites_" + LLGridManager::getInstance()->getGrid() + ".xml");
std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
mUsernameLength = user_defined_name.length();
updateLoginButtons();
- std::string::size_type index = user_defined_name.find(' ');
+ std::string::size_type index = user_defined_name.find_first_of(" ._");
if (index != std::string::npos)
{
std::string username = user_defined_name.substr(0, index);
@@ -332,6 +407,10 @@ void LLPanelLogin::addFavoritesToStartLocation()
{
user_defined_name = username;
}
+ else
+ {
+ user_defined_name = username + " " + lastname;
+ }
}
LLSD fav_llsd;
@@ -443,24 +522,6 @@ void LLPanelLogin::giveFocus()
}
// static
-void LLPanelLogin::showLoginWidgets()
-{
- if (sInstance)
- {
- // *NOTE: Mani - This may or may not be obselete code.
- // It seems to be part of the defunct? reg-in-client project.
- sInstance->getChildView("login_widgets")->setVisible( true);
- LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
-
- // *TODO: Append all the usual login parameters, like first_login=Y etc.
- std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
- web_browser->navigateTo( splash_screen_url, "text/html" );
- LLUICtrl* username_combo = sInstance->getChild<LLUICtrl>("username_combo");
- username_combo->setFocus(TRUE);
- }
-}
-
-// static
void LLPanelLogin::show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
void* callback_data)
@@ -480,9 +541,54 @@ void LLPanelLogin::show(const LLRect &rect,
gFocusMgr.setDefaultKeyboardFocus(sInstance);
}
+//static
+void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
+{
+ if (!sInstance)
+ {
+ LL_WARNS() << "Attempted fillFields with no login view shown" << LL_ENDL;
+ return;
+ }
+ if (sInstance->mFirstLoginThisInstall)
+ {
+ LLUICtrl* remember_check = sInstance->getChild<LLUICtrl>("remember_check");
+ remember_check->setValue(remember_psswrd);
+ // no list to populate
+ setFields(credential);
+ }
+ else
+ {
+ sInstance->getChild<LLUICtrl>("remember_name")->setValue(remember_user);
+ LLUICtrl* remember_password = sInstance->getChild<LLUICtrl>("remember_password");
+ remember_password->setValue(remember_psswrd);
+ remember_password->setEnabled(remember_user);
+ sInstance->populateUserList(credential);
+ }
+}
+
+//static
+void LLPanelLogin::resetFields()
+{
+ if (!sInstance)
+ {
+ // class not existing at this point might happen since this
+ // function is used to reset list in case of changes by external sources
+ return;
+ }
+ if (sInstance->mFirstLoginThisInstall)
+ {
+ // no list to populate
+ LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL;
+ }
+ else
+ {
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(cred);
+ }
+}
+
// static
-void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
- BOOL remember)
+void LLPanelLogin::setFields(LLPointer<LLCredential> credential)
{
if (!sInstance)
{
@@ -492,36 +598,43 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
sCredentialSet = TRUE;
LL_INFOS("Credentials") << "Setting login fields to " << *credential << LL_ENDL;
- LLSD identifier = credential->getIdentifier();
- if((std::string)identifier["type"] == "agent")
+ LLSD identifier = credential.notNull() ? credential->getIdentifier() : LLSD();
+
+ if(identifier.has("type") && (std::string)identifier["type"] == "agent")
{
+ // not nessesary for panel_login.xml, needed for panel_login_first.xml
std::string firstname = identifier["first_name"].asString();
std::string lastname = identifier["last_name"].asString();
std::string login_id = firstname;
- if (!lastname.empty() && lastname != "Resident")
+ if (!lastname.empty() && lastname != "Resident" && lastname != "resident")
{
// support traditional First Last name SLURLs
login_id += " ";
login_id += lastname;
}
- sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
+ sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
+ sInstance->mUsernameLength = login_id.length();
}
- else if((std::string)identifier["type"] == "account")
+ else if(identifier.has("type") && (std::string)identifier["type"] == "account")
{
- sInstance->getChild<LLComboBox>("username_combo")->setLabel((std::string)identifier["account_name"]);
+ std::string login_id = identifier["account_name"].asString();
+ sInstance->getChild<LLComboBox>("username_combo")->setLabel(login_id);
+ sInstance->mUsernameLength = login_id.length();
}
else
{
- sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
+ sInstance->getChild<LLComboBox>("username_combo")->setLabel(std::string());
+ sInstance->mUsernameLength = 0;
}
+
sInstance->addFavoritesToStartLocation();
// if the password exists in the credential, set the password field with
// a filler to get some stars
- LLSD authenticator = credential->getAuthenticator();
+ LLSD authenticator = credential.notNull() ? credential->getAuthenticator() : LLSD();
LL_INFOS("Credentials") << "Setting authenticator field " << authenticator["type"].asString() << LL_ENDL;
if(authenticator.isMap() &&
authenticator.has("secret") &&
- (authenticator["secret"].asString().size() > 0) && remember)
+ (authenticator["secret"].asString().size() > 0))
{
// This is a MD5 hex digest of a password.
@@ -535,38 +648,28 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential,
}
else
{
- sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ sInstance->mPasswordLength = 0;
}
- sInstance->getChild<LLUICtrl>("remember_check")->setValue(remember);
}
-
// static
void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
- BOOL& remember)
+ bool& remember_user,
+ bool& remember_psswrd)
{
if (!sInstance)
{
LL_WARNS() << "Attempted getFields with no login view shown" << LL_ENDL;
return;
}
-
- // load the credential so we can pass back the stored password or hash if the user did
- // not modify the password field.
-
- credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
LLSD identifier = LLSD::emptyMap();
LLSD authenticator = LLSD::emptyMap();
-
- if(credential.notNull())
- {
- authenticator = credential->getAuthenticator();
- }
- std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
- LLStringUtil::trim(username);
+ std::string username = sInstance->getChild<LLComboBox>("username_combo")->getSimple();
std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
+ LLStringUtil::trim(username);
LL_INFOS("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL;
// determine if the username is a first/last form or not.
@@ -586,6 +689,14 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
authenticator["type"] = CRED_AUTHENTICATOR_TYPE_CLEAR;
authenticator["secret"] = password;
}
+ else
+ {
+ credential = load_user_credentials(username);
+ if (credential.notNull())
+ {
+ authenticator = credential->getAuthenticator();
+ }
+ }
}
else
{
@@ -597,7 +708,7 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
if (separator_index != username.npos)
{
last = username.substr(separator_index+1, username.npos);
- LLStringUtil::trim(last);
+ LLStringUtil::trim(last);
}
else
{
@@ -625,10 +736,29 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential,
pass.hex_digest(md5pass);
authenticator["secret"] = md5pass;
}
+ else
+ {
+ std::string key = first + "_" + last;
+ LLStringUtil::toLower(key);
+ credential = load_user_credentials(key);
+ if (credential.notNull())
+ {
+ authenticator = credential->getAuthenticator();
+ }
+ }
}
}
credential = gSecAPIHandler->createCredential(LLGridManager::getInstance()->getGrid(), identifier, authenticator);
- remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
+ if (!sInstance->mFirstLoginThisInstall)
+ {
+ remember_psswrd = sInstance->getChild<LLUICtrl>("remember_password")->getValue();
+ remember_user = sInstance->getChild<LLUICtrl>("remember_name")->getValue();
+ }
+ else
+ {
+ remember_psswrd = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
+ remember_user = remember_psswrd; // on panel_login_first "remember_check" is named as 'remember me'
+ }
}
@@ -641,11 +771,8 @@ BOOL LLPanelLogin::areCredentialFieldsDirty()
}
else
{
- std::string username = sInstance->getChild<LLUICtrl>("username_combo")->getValue().asString();
- LLStringUtil::trim(username);
- std::string password = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
LLComboBox* combo = sInstance->getChild<LLComboBox>("username_combo");
- if(combo && combo->isDirty())
+ if (combo && combo->getCurrentIndex() == -1 && !combo->getValue().asString().empty())
{
return true;
}
@@ -898,8 +1025,8 @@ void LLPanelLogin::onClickConnect(void *)
{
sCredentialSet = FALSE;
LLPointer<LLCredential> cred;
- BOOL remember;
- getFields(cred, remember);
+ bool remember_1, remember_2;
+ getFields(cred, remember_1, remember_2);
std::string identifier_type;
cred->identifierType(identifier_type);
LLSD allowed_credential_types;
@@ -953,6 +1080,65 @@ void LLPanelLogin::onClickSignUp(void*)
}
// static
+void LLPanelLogin::onUserNameTextEnty(void*)
+{
+ sInstance->mPasswordModified = true;
+ sInstance->getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ sInstance->mPasswordLength = 0;
+ sInstance->addFavoritesToStartLocation(); //will call updateLoginButtons()
+}
+
+// static
+void LLPanelLogin::onUserListCommit(void*)
+{
+ if (sInstance)
+ {
+ LLComboBox* username_combo(sInstance->getChild<LLComboBox>("username_combo"));
+ static S32 ind = -1;
+ if (ind != username_combo->getCurrentIndex())
+ {
+ std::string user_key = username_combo->getSelectedValue();
+ LLPointer<LLCredential> cred = gSecAPIHandler->loadFromCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), user_key);
+ setFields(cred);
+ sInstance->mPasswordModified = false;
+ }
+ else
+ {
+ std::string pass = sInstance->getChild<LLUICtrl>("password_edit")->getValue().asString();
+ if (pass.empty())
+ {
+ sInstance->giveFocus();
+ }
+ else
+ {
+ onClickConnect(NULL);
+ }
+ }
+ }
+}
+
+// static
+// At the moment only happens if !mFirstLoginThisInstall
+void LLPanelLogin::onRememberUserCheck(void*)
+{
+ if (sInstance && !sInstance->mFirstLoginThisInstall)
+ {
+ LLCheckBoxCtrl* remember_name(sInstance->getChild<LLCheckBoxCtrl>("remember_name"));
+ LLCheckBoxCtrl* remember_psswrd(sInstance->getChild<LLCheckBoxCtrl>("remember_password"));
+ LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo"));
+
+ bool remember = remember_name->getValue().asBoolean();
+ if (user_combo->getCurrentIndex() != -1 && !remember)
+ {
+ remember = true;
+ remember_name->setValue(true);
+ LLNotificationsUtil::add("LoginCantRemoveUsername");
+ }
+ remember_psswrd->setEnabled(remember);
+ }
+}
+
+// static
void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
{
LLPanelLogin *self = (LLPanelLogin *)user_data;
@@ -976,12 +1162,37 @@ void LLPanelLogin::updateServer()
try
{
// if they've selected another grid, we should load the credentials
- // for that grid and set them to the UI.
- if(!sInstance->areCredentialFieldsDirty())
+ // for that grid and set them to the UI. But if there were any modifications to
+ // fields, modifications should carry over.
+ // Not sure if it should carry over password but it worked like this before login changes
+ // Example: you started typing in and found that your are under wrong grid,
+ // you switch yet don't lose anything
+ if (sInstance->areCredentialFieldsDirty())
{
- LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
- bool remember = sInstance->getChild<LLUICtrl>("remember_check")->getValue();
- sInstance->setFields(credential, remember);
+ // save modified creds
+ LLComboBox* user_combo = sInstance->getChild<LLComboBox>("username_combo");
+ LLLineEditor* pswd_edit = sInstance->getChild<LLLineEditor>("password_edit");
+ std::string username = user_combo->getSimple();
+ LLStringUtil::trim(username);
+ std::string password = pswd_edit->getValue().asString();
+
+ // populate dropbox and setFields
+ // Note: following call is related to initializeLoginInfo()
+ LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(credential);
+
+ // restore creds
+ user_combo->setTextEntry(username);
+ pswd_edit->setValue(password);
+ sInstance->mUsernameLength = username.length();
+ sInstance->mPasswordLength = password.length();
+ }
+ else
+ {
+ // populate dropbox and setFields
+ // Note: following call is related to initializeLoginInfo()
+ LLPointer<LLCredential> credential = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid());
+ sInstance->populateUserList(credential);
}
// update the login panel links
@@ -1011,14 +1222,82 @@ void LLPanelLogin::updateLoginButtons()
LLButton* login_btn = getChild<LLButton>("connect_btn");
login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
+
+ if (!mFirstLoginThisInstall)
+ {
+ LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
+ LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
+ if (user_combo->getCurrentIndex() != -1)
+ {
+ remember_name->setValue(true);
+ } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user
+ }
+}
+
+void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential)
+{
+ LLComboBox* user_combo = getChild<LLComboBox>("username_combo");
+ user_combo->removeall();
+ user_combo->clear();
+ mUsernameLength = 0;
+ mPasswordLength = 0;
+
+ if (gSecAPIHandler->hasCredentialMap("login_list", LLGridManager::getInstance()->getGrid()))
+ {
+ LLSecAPIHandler::credential_map_t credencials;
+ gSecAPIHandler->loadCredentialMap("login_list", LLGridManager::getInstance()->getGrid(), credencials);
+
+ LLSecAPIHandler::credential_map_t::iterator cr_iter = credencials.begin();
+ LLSecAPIHandler::credential_map_t::iterator cr_end = credencials.end();
+ while (cr_iter != cr_end)
+ {
+ if (cr_iter->second.notNull()) // basic safety in case of future changes
+ {
+ // cr_iter->first == user_id , to be able to be find it in case we select it
+ user_combo->add(LLPanelLogin::getUserName(cr_iter->second), cr_iter->first, ADD_BOTTOM, TRUE);
+ }
+ cr_iter++;
+ }
+
+ if (credential.isNull() || !user_combo->setSelectedByValue(LLSD(credential->userID()), true))
+ {
+ // selection failed, just deselect whatever might be selected
+ user_combo->setValue(std::string());
+ getChild<LLUICtrl>("password_edit")->setValue(std::string());
+ updateLoginButtons();
+ }
+ else
+ {
+ setFields(credential);
+ }
+ }
+ else
+ {
+ if (credential.notNull())
+ {
+ const LLSD &ident = credential->getIdentifier();
+ if (ident.isMap() && ident.has("type"))
+ {
+ user_combo->add(LLPanelLogin::getUserName(credential), credential->userID(), ADD_BOTTOM, TRUE);
+ setFields(credential);
+ }
+ else
+ {
+ updateLoginButtons();
+ }
+ }
+ else
+ {
+ updateLoginButtons();
+ }
+ }
}
+
void LLPanelLogin::onSelectServer()
{
// The user twiddled with the grid choice ui.
// apply the selection to the grid setting.
- LLPointer<LLCredential> credential;
-
LLComboBox* server_combo = getChild<LLComboBox>("server_combo");
LLSD server_combo_val = server_combo->getSelectedValue();
LL_INFOS("AppInit") << "grid "<<server_combo_val.asString()<< LL_ENDL;
@@ -1077,3 +1356,34 @@ bool LLPanelLogin::getShowFavorites()
{
return gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin");
}
+
+// static
+std::string LLPanelLogin::getUserName(LLPointer<LLCredential> &cred)
+{
+ if (cred.isNull())
+ {
+ return "unknown";
+ }
+ const LLSD &ident = cred->getIdentifier();
+
+ if (!ident.isMap())
+ {
+ return "unknown";
+ }
+ else if ((std::string)ident["type"] == "agent")
+ {
+ std::string second_name = ident["last_name"];
+ if (second_name == "resident" || second_name == "Resident")
+ {
+ return (std::string)ident["first_name"];
+ }
+ return (std::string)ident["first_name"] + " " + (std::string)ident["last_name"];
+ }
+ else if ((std::string)ident["type"] == "account")
+ {
+ return LLCacheName::cleanFullName((std::string)ident["account_name"]);
+ }
+
+ return "unknown";
+}
+
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c633582d89..c9b8e1b6fc 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -55,9 +55,9 @@ public:
void (*callback)(S32 option, void* user_data),
void* callback_data);
- static void setFields(LLPointer<LLCredential> credential, BOOL remember);
-
- static void getFields(LLPointer<LLCredential>& credential, BOOL& remember);
+ static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
+ static void resetFields();
+ static void getFields(LLPointer<LLCredential>& credential, bool& remember_user, bool& remember_psswrd);
static BOOL isCredentialSet() { return sCredentialSet; }
@@ -72,8 +72,6 @@ public:
void setSiteIsAlive( bool alive );
- void showLoginWidgets();
-
static void loadLoginPage();
static void giveFocus();
static void setAlwaysRefresh(bool refresh);
@@ -88,6 +86,9 @@ public:
// called from prefs when initializing panel
static bool getShowFavorites();
+ // extract name from cred in a format apropriate for username field
+ static std::string getUserName(LLPointer<LLCredential> &cred);
+
private:
friend class LLPanelLoginListener;
void addFavoritesToStartLocation();
@@ -95,11 +96,16 @@ private:
void onSelectServer();
void onLocationSLURL();
+ static void setFields(LLPointer<LLCredential> credential);
+
static void onClickConnect(void*);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
static void onClickSignUp(void*);
+ static void onUserNameTextEnty(void*);
+ static void onUserListCommit(void*);
+ static void onRememberUserCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
static void updateServerCombo();
@@ -107,6 +113,7 @@ private:
boost::scoped_ptr<LLPanelLoginListener> mListener;
void updateLoginButtons();
+ void populateUserList(LLPointer<LLCredential> credential);
void (*mCallback)(S32 option, void *userdata);
void* mCallbackData;
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index 2dca55514d..b654e928e2 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -43,6 +43,7 @@
#include "llbutton.h"
#include "lltextbox.h"
#include "llviewermedia.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerregion.h"
#include "llviewermediafocus.h"
@@ -83,10 +84,11 @@ LLPanelNearByMedia::LLPanelNearByMedia()
{
mHoverTimer.stop();
- mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay");
+ // This is just an initial value, mParcelAudioAutoStart does not affect ParcelMediaAutoPlayEnable
+ mParcelAudioAutoStart = gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0
+ && gSavedSettings.getBOOL("MediaTentativeAutoPlay");
- gSavedSettings.getControl(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING)->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
+ gSavedSettings.getControl("ParcelMediaAutoPlayEnable")->getSignal()->connect(boost::bind(&LLPanelNearByMedia::handleMediaAutoPlayChanged, this, _2));
mCommitCallbackRegistrar.add("MediaListCtrl.EnableAll", boost::bind(&LLPanelNearByMedia::onClickEnableAll, this));
mCommitCallbackRegistrar.add("MediaListCtrl.DisableAll", boost::bind(&LLPanelNearByMedia::onClickDisableAll, this));
@@ -177,9 +179,18 @@ BOOL LLPanelNearByMedia::postBuild()
void LLPanelNearByMedia::handleMediaAutoPlayChanged(const LLSD& newvalue)
{
- // update mParcelAudioAutoStart if AUTO_PLAY_MEDIA_SETTING changes
- mParcelAudioAutoStart = gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay");
+ // update mParcelAudioAutoStartMode if "ParcelMediaAutoPlayEnable" changes
+ S32 value = gSavedSettings.getS32("ParcelMediaAutoPlayEnable");
+ mParcelAudioAutoStart = value != 0
+ && gSavedSettings.getBOOL("MediaTentativeAutoPlay");
+
+ LLViewerParcelAskPlay *inst = LLViewerParcelAskPlay::getInstance();
+ if (value == 2 && !inst->hasData())
+ {
+ // Init if nessesary
+ inst->loadSettings();
+ }
+ inst->cancelNotification();
}
/*virtual*/
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 6702dae4d6..7756b92a3a 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1561,12 +1561,13 @@ void LLPanelObjectInventory::refresh()
//LL_INFOS() << "LLPanelObjectInventory::refresh()" << LL_ENDL;
BOOL has_inventory = FALSE;
const BOOL non_root_ok = TRUE;
- LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(NULL, non_root_ok);
- if(node)
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLSelectNode* node = selection->getFirstRootNode(NULL, non_root_ok);
+ if(node && node->mValid)
{
LLViewerObject* object = node->getObject();
- if(object && ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
- || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
+ if(object && ((selection->getRootObjectCount() == 1)
+ || (selection->getObjectCount() == 1)))
{
// determine if we need to make a request. Start with a
// default based on if we have inventory at all.
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 961e259947..2ef82d0cf9 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -675,6 +675,12 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
}
else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
{
+ if (mItem.isNull())
+ {
+ LL_WARNS() << "NULL landmark item" << LL_ENDL;
+ llassert(mItem.notNull());
+ return;
+ }
LLLandmark* landmark = gLandmarkList.getAsset(mItem->getAssetUUID());
if (!landmark)
return;
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 8105beae1b..3c74aed734 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -547,17 +547,17 @@ void LLPanelPrimMediaControls::updateShape()
switch (mScrollState)
{
case SCROLL_UP:
- media_impl->scrollWheel(0, -1, MASK_NONE);
+ media_impl->scrollWheel(0, 0, 0, -1, MASK_NONE);
break;
case SCROLL_DOWN:
- media_impl->scrollWheel(0, 1, MASK_NONE);
+ media_impl->scrollWheel(0, 0, 0, 1, MASK_NONE);
break;
case SCROLL_LEFT:
- media_impl->scrollWheel(1, 0, MASK_NONE);
+ media_impl->scrollWheel(0, 0, 1, 0, MASK_NONE);
// media_impl->handleKeyHere(KEY_LEFT, MASK_NONE);
break;
case SCROLL_RIGHT:
- media_impl->scrollWheel(-1, 0, MASK_NONE);
+ media_impl->scrollWheel(0, 0, -1, 0, MASK_NONE);
// media_impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
break;
case SCROLL_NONE:
@@ -1134,7 +1134,7 @@ void LLPanelPrimMediaControls::onScrollUp(void* user_data)
if(impl)
{
- impl->scrollWheel(0, -1, MASK_NONE);
+ impl->scrollWheel(0, 0, 0, -1, MASK_NONE);
}
}
void LLPanelPrimMediaControls::onScrollUpHeld(void* user_data)
@@ -1151,7 +1151,7 @@ void LLPanelPrimMediaControls::onScrollRight(void* user_data)
if(impl)
{
- impl->scrollWheel(-1, 0, MASK_NONE);
+ impl->scrollWheel(0, 0, -1, 0, MASK_NONE);
// impl->handleKeyHere(KEY_RIGHT, MASK_NONE);
}
}
@@ -1170,7 +1170,7 @@ void LLPanelPrimMediaControls::onScrollLeft(void* user_data)
if(impl)
{
- impl->scrollWheel(1, 0, MASK_NONE);
+ impl->scrollWheel(0, 0, 1, 0, MASK_NONE);
// impl->handleKeyHere(KEY_LEFT, MASK_NONE);
}
}
@@ -1189,7 +1189,7 @@ void LLPanelPrimMediaControls::onScrollDown(void* user_data)
if(impl)
{
- impl->scrollWheel(0, 1, MASK_NONE);
+ impl->scrollWheel(0, 0, 0, 1, MASK_NONE);
}
}
void LLPanelPrimMediaControls::onScrollDownHeld(void* user_data)
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 23747a8efd..1a3e946127 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -32,8 +32,6 @@
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
/**
* Provides several ways to save a snapshot.
@@ -58,8 +56,6 @@ private:
void onSaveToEmail();
void onSaveToInventory();
void onSaveToComputer();
- void onSendToTwitter();
- void onSendToFlickr();
LLFloaterSnapshotBase* mSnapshotFloater;
};
@@ -72,8 +68,7 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
- mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this));
- mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this));
+
LLGlobalEconomy::getInstance()->addObserver(this);
}
@@ -135,26 +130,3 @@ void LLPanelSnapshotOptions::onSaveToComputer()
openPanel("panel_snapshot_local");
}
-void LLPanelSnapshotOptions::onSendToTwitter()
-{
- LLFloaterReg::hideInstance("snapshot");
-
- LLFloaterTwitter* twitter_floater = dynamic_cast<LLFloaterTwitter*>(LLFloaterReg::getInstance("twitter"));
- if (twitter_floater)
- {
- twitter_floater->showPhotoPanel();
- }
- LLFloaterReg::showInstance("twitter");
-}
-
-void LLPanelSnapshotOptions::onSendToFlickr()
-{
- LLFloaterReg::hideInstance("snapshot");
-
- LLFloaterFlickr* flickr_floater = dynamic_cast<LLFloaterFlickr*>(LLFloaterReg::getInstance("flickr"));
- if (flickr_floater)
- {
- flickr_floater->showPhotoPanel();
- }
- LLFloaterReg::showInstance("flickr");
-}
diff --git a/indra/newview/llpanelvolumepulldown.cpp b/indra/newview/llpanelvolumepulldown.cpp
index 6792137350..f063d84272 100644
--- a/indra/newview/llpanelvolumepulldown.cpp
+++ b/indra/newview/llpanelvolumepulldown.cpp
@@ -140,7 +140,7 @@ void LLPanelVolumePulldown::updateMediaAutoPlayCheckbox(LLUICtrl* ctrl)
bool music_enabled = getChild<LLCheckBoxCtrl>("enable_music")->get();
bool media_enabled = getChild<LLCheckBoxCtrl>("enable_media")->get();
- getChild<LLCheckBoxCtrl>("media_auto_play_btn")->setEnabled(music_enabled || media_enabled);
+ getChild<LLCheckBoxCtrl>("media_auto_play_combo")->setEnabled(music_enabled || media_enabled);
}
}
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index d207f3b5b7..69b6b32923 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -464,7 +464,19 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id)=0;
-
+
+ // persist data in a protected store's map
+ virtual void addToProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem,
+ const LLSD& data)=0;
+
+ // remove data from protected store's map
+ virtual void removeFromProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem)=0;
+
+public:
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator)=0;
@@ -474,6 +486,42 @@ public:
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)=0;
virtual void deleteCredential(LLPointer<LLCredential> cred)=0;
+
+ // has map of credentials declared as specific storage
+ virtual bool hasCredentialMap(const std::string& storage,
+ const std::string& grid)=0;
+
+ // returns true if map is empty or does not exist
+ virtual bool emptyCredentialMap(const std::string& storage,
+ const std::string& grid)=0;
+
+ // load map of credentials from specific storage
+ typedef std::map<std::string, LLPointer<LLCredential> > credential_map_t;
+ virtual void loadCredentialMap(const std::string& storage,
+ const std::string& grid,
+ credential_map_t& credential_map)=0;
+
+ // load single username from map of credentials from specific storage
+ virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid)=0;
+
+ // add item to map of credentials from specific storage
+ virtual void addToCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred,
+ bool save_authenticator)=0;
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred)=0;
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid)=0;
+
+ virtual void removeCredentialMap(const std::string& storage,
+ const std::string& grid)=0;
};
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 9ab9e4a1a2..55e49100c3 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -52,6 +52,7 @@
#include "llmachineid.h"
+static const std::string DEFAULT_CREDENTIAL_STORAGE = "credential";
// 128 bits of salt data...
#define STORE_SALT_SIZE 16
@@ -1533,6 +1534,38 @@ void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type,
mProtectedDataMap[data_type][data_id] = data;
}
+// persist data in a protected store's map
+void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem,
+ const LLSD& data)
+{
+ if (!mProtectedDataMap.has(data_type) || !mProtectedDataMap[data_type].isMap()) {
+ mProtectedDataMap[data_type] = LLSD::emptyMap();
+ }
+
+ if (!mProtectedDataMap[data_type].has(data_id) || !mProtectedDataMap[data_type][data_id].isMap()) {
+ mProtectedDataMap[data_type][data_id] = LLSD::emptyMap();
+ }
+
+ mProtectedDataMap[data_type][data_id][map_elem] = data;
+}
+
+// remove data from protected store's map
+void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem)
+{
+ if (mProtectedDataMap.has(data_type) &&
+ mProtectedDataMap[data_type].isMap() &&
+ mProtectedDataMap[data_type].has(data_id) &&
+ mProtectedDataMap[data_type][data_id].isMap() &&
+ mProtectedDataMap[data_type][data_id].has(map_elem))
+ {
+ mProtectedDataMap[data_type][data_id].erase(map_elem);
+ }
+}
+
//
// Create a credential object from an identifier and authenticator. credentials are
// per grid.
@@ -1545,10 +1578,10 @@ LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string
return result;
}
-// Load a credential from the credential store, given the grid
+// Load a credential from default credential store, given the grid
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid)
{
- LLSD credential = getProtectedData("credential", grid);
+ LLSD credential = getProtectedData(DEFAULT_CREDENTIAL_STORAGE, grid);
LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
if(credential.isMap() &&
credential.has("identifier"))
@@ -1603,7 +1636,7 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
credential["authenticator"] = cred->getAuthenticator();
}
LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
- setProtectedData("credential", cred->getGrid(), credential);
+ setProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid(), credential);
//*TODO: If we're saving Agni credentials, should we write the
// credentials to the legacy password.dat/etc?
_writeProtectedData();
@@ -1613,11 +1646,150 @@ void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool sav
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred)
{
LLSD undefVal;
- deleteProtectedData("credential", cred->getGrid());
+ deleteProtectedData(DEFAULT_CREDENTIAL_STORAGE, cred->getGrid());
cred->setCredentialData(undefVal, undefVal);
_writeProtectedData();
}
+// has map of credentials declared as specific storage
+bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD credential = getProtectedData(storage, grid);
+
+ return credential.isMap();
+}
+
+// returns true if map is empty or does not exist
+bool LLSecAPIBasicHandler::emptyCredentialMap(const std::string& storage, const std::string& grid)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD credential = getProtectedData(storage, grid);
+
+ return !credential.isMap() || credential.size() == 0;
+}
+
+// Load map of credentials from specified credential store, given the grid
+void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD credential = getProtectedData(storage, grid);
+ if (credential.isMap())
+ {
+ LLSD::map_const_iterator crd_it = credential.beginMap();
+ for (; crd_it != credential.endMap(); crd_it++)
+ {
+ LLSD::String name = crd_it->first;
+ const LLSD &link_map = crd_it->second;
+ LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
+ if (link_map.has("identifier"))
+ {
+ LLSD identifier = link_map["identifier"];
+ LLSD authenticator;
+ if (link_map.has("authenticator"))
+ {
+ authenticator = link_map["authenticator"];
+ }
+ result->setCredentialData(identifier, authenticator);
+ }
+ credential_map[name] = result;
+ }
+ }
+}
+
+LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
+
+ LLSD credential = getProtectedData(storage, grid);
+ if (credential.isMap() && credential.has(userkey) && credential[userkey].has("identifier"))
+ {
+ LLSD identifier = credential[userkey]["identifier"];
+ LLSD authenticator;
+ if (credential[userkey].has("authenticator"))
+ {
+ authenticator = credential[userkey]["authenticator"];
+ }
+ result->setCredentialData(identifier, authenticator);
+ }
+
+ return result;
+}
+
+// add item to map of credentials from specific storage
+void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ std::string user_id = cred->userID();
+ LLSD credential = LLSD::emptyMap();
+ credential["identifier"] = cred->getIdentifier();
+ if (save_authenticator)
+ {
+ credential["authenticator"] = cred->getAuthenticator();
+ }
+ LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
+ addToProtectedMap(storage, cred->getGrid(), user_id, credential);
+
+ _writeProtectedData();
+}
+
+// remove item from map of credentials from specific storage
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD undefVal;
+ removeFromProtectedMap(storage, cred->getGrid(), cred->userID());
+ cred->setCredentialData(undefVal, undefVal);
+ _writeProtectedData();
+}
+
+// remove item from map of credentials from specific storage
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey)
+{
+ if (storage == DEFAULT_CREDENTIAL_STORAGE)
+ {
+ LL_ERRS() << "Storing maps in default, single-items storage is not allowed" << LL_ENDL;
+ }
+
+ LLSD undefVal;
+ LLPointer<LLCredential> cred = loadFromCredentialMap(storage, grid, userkey);
+ removeFromProtectedMap(storage, grid, userkey);
+ cred->setCredentialData(undefVal, undefVal);
+ _writeProtectedData();
+}
+
+// remove item from map of credentials from specific storage
+void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid)
+{
+ deleteProtectedData(storage, grid);
+ _writeProtectedData();
+}
+
// load the legacy hash for agni, and decrypt it given the
// mac address
std::string LLSecAPIBasicHandler::_legacyLoadPassword()
@@ -1656,15 +1828,18 @@ std::string LLSecAPIBasicCredential::userID() const
}
else if ((std::string)mIdentifier["type"] == "agent")
{
- return (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
+ std::string id = (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
+ LLStringUtil::toLower(id);
+ return id;
}
else if ((std::string)mIdentifier["type"] == "account")
{
- return (std::string)mIdentifier["account_name"];
+ std::string id = (std::string)mIdentifier["account_name"];
+ LLStringUtil::toLower(id);
+ return id;
}
return "unknown";
-
}
// return a printable user identifier
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index c35617f564..0bc7f5230f 100644
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
@@ -211,8 +211,9 @@ class LLSecAPIBasicCredential : public LLCredential
public:
LLSecAPIBasicCredential(const std::string& grid) : LLCredential(grid) {}
virtual ~LLSecAPIBasicCredential() {}
- // return a value representing the user id, (could be guid, name, whatever)
- virtual std::string userID() const;
+ // return a value representing the user id, used for server and voice
+ // (could be guid, name in format "name_resident", whatever)
+ virtual std::string userID() const;
// printible string identifying the credential.
virtual std::string asString() const;
@@ -246,7 +247,10 @@ public:
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id);
-
+
+ // protectedData functions technically should be pretected or private,
+ // they are not because of llsechandler_basic_test imlementation
+
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
@@ -259,19 +263,68 @@ public:
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id);
-
+
+ // persist data in a protected store's map
+ virtual void addToProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem,
+ const LLSD& data);
+
+ // remove data from protected store's map
+ virtual void removeFromProtectedMap(const std::string& data_type,
+ const std::string& data_id,
+ const std::string& map_elem);
+
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator);
-
+
+ // load single credencial from default storage
virtual LLPointer<LLCredential> loadCredential(const std::string& grid);
+ // save credencial to default storage
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
virtual void deleteCredential(LLPointer<LLCredential> cred);
-
+
+ // has map of credentials declared as specific storage
+ virtual bool hasCredentialMap(const std::string& storage,
+ const std::string& grid);
+
+ // returns true if map is empty or does not exist
+ virtual bool emptyCredentialMap(const std::string& storage,
+ const std::string& grid);
+
+ // load map of credentials from specific storage
+ virtual void loadCredentialMap(const std::string& storage,
+ const std::string& grid,
+ credential_map_t& credential_map);
+
+ // load single username from map of credentials from specific storage
+ virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid);
+
+ // add item to map of credentials from specific storage
+ virtual void addToCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred,
+ bool save_authenticator);
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ LLPointer<LLCredential> cred);
+
+ // remove item from map of credentials from specific storage
+ virtual void removeFromCredentialMap(const std::string& storage,
+ const std::string& grid,
+ const std::string& userid);
+
+ virtual void removeCredentialMap(const std::string& storage,
+ const std::string& grid);
+
+
protected:
void _readProtectedData();
void _writeProtectedData();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 90f8f84ea4..aee6bcb05e 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -153,6 +153,53 @@ struct LLDeRezInfo
// Imports
//
+//-----------------------------------------------------------------------------
+// ~LLSelectionCallbackData()
+//-----------------------------------------------------------------------------
+
+LLSelectionCallbackData::LLSelectionCallbackData()
+{
+ LLSelectMgr *instance = LLSelectMgr::getInstance();
+ LLObjectSelectionHandle selection = instance->getSelection();
+ if (!selection->getNumNodes())
+ {
+ return;
+ }
+ mSelectedObjects = new LLObjectSelection();
+
+ for (LLObjectSelection::iterator iter = selection->begin();
+ iter != selection->end();)
+ {
+ LLObjectSelection::iterator curiter = iter++;
+
+ LLSelectNode *nodep = *curiter;
+ LLViewerObject* objectp = nodep->getObject();
+
+ if (!objectp)
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_WORLD;
+ }
+ else
+ {
+ LLSelectNode* new_nodep = new LLSelectNode(*nodep);
+ mSelectedObjects->addNode(new_nodep);
+
+ if (objectp->isHUDAttachment())
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_HUD;
+ }
+ else if (objectp->isAttachment())
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_ATTACHMENT;
+ }
+ else
+ {
+ mSelectedObjects->mSelectType = SELECT_TYPE_WORLD;
+ }
+ }
+ }
+}
+
//
// Functions
@@ -4119,20 +4166,20 @@ void LLSelectMgr::packMultipleUpdate(LLSelectNode* node, void *user_data)
if (type & UPD_POSITION)
{
- htonmemcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
+ htolememcpy(&data[offset], &(object->getPosition().mV), MVT_LLVector3, 12);
offset += 12;
}
if (type & UPD_ROTATION)
{
LLQuaternion quat = object->getRotation();
LLVector3 vec = quat.packToVector3();
- htonmemcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
+ htolememcpy(&data[offset], &(vec.mV), MVT_LLQuaternion, 12);
offset += 12;
}
if (type & UPD_SCALE)
{
//LL_INFOS() << "Sending object scale " << object->getScale() << LL_ENDL;
- htonmemcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
+ htolememcpy(&data[offset], &(object->getScale().mV), MVT_LLVector3, 12);
offset += 12;
}
gMessageSystem->addBinaryDataFast(_PREHASH_Data, data, offset);
@@ -4475,9 +4522,19 @@ void LLSelectMgr::selectionSetObjectSaleInfo(const LLSaleInfo& sale_info)
void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
{
- LLViewerObject* attach_object = mSelectedObjects->getFirstRootObject();
+ sendAttach(mSelectedObjects, attachment_point, replace);
+}
+
+void LLSelectMgr::sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace)
+{
+ if (selection_handle.isNull())
+ {
+ return;
+ }
- if (!attach_object || !isAgentAvatarValid() || mSelectedObjects->mSelectType != SELECT_TYPE_WORLD)
+ LLViewerObject* attach_object = selection_handle->getFirstRootObject();
+
+ if (!attach_object || !isAgentAvatarValid() || selection_handle->mSelectType != SELECT_TYPE_WORLD)
{
return;
}
@@ -4495,6 +4552,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
}
sendListToRegions(
+ selection_handle,
"ObjectAttach",
packAgentIDAndSessionAndAttachment,
packObjectIDAndRotation,
@@ -4506,6 +4564,7 @@ void LLSelectMgr::sendAttach(U8 attachment_point, bool replace)
// After "ObjectAttach" server will unsubscribe us from properties updates
// so either deselect objects or resend selection after attach packet reaches server
// In case of build_mode LLPanelObjectInventory::refresh() will deal with selection
+ // Still unsubscribe even in case selection_handle is not current selection
deselectAll();
}
}
@@ -5047,7 +5106,17 @@ void LLSelectMgr::packPermissions(LLSelectNode* node, void *user_data)
void LLSelectMgr::sendListToRegions(const std::string& message_name,
void (*pack_header)(void *user_data),
void (*pack_body)(LLSelectNode* node, void *user_data),
- void (*log_func)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type)
+{
+ sendListToRegions(mSelectedObjects, message_name, pack_header, pack_body, log_func, user_data, send_type);
+}
+void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle,
+ const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
void *user_data,
ESendType send_type)
{
@@ -5073,7 +5142,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
return true;
}
} func;
- getSelection()->applyToNodes(&func);
+ selected_handle->applyToNodes(&func);
std::queue<LLSelectNode*> nodes_to_send;
@@ -5116,25 +5185,25 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name,
{
case SEND_ONLY_ROOTS:
if(message_name == "ObjectBuy")
- getSelection()->applyToRootNodes(&pushroots);
+ selected_handle->applyToRootNodes(&pushroots);
else
- getSelection()->applyToRootNodes(&pushall);
+ selected_handle->applyToRootNodes(&pushall);
break;
case SEND_INDIVIDUALS:
- getSelection()->applyToNodes(&pushall);
+ selected_handle->applyToNodes(&pushall);
break;
case SEND_ROOTS_FIRST:
// first roots...
- getSelection()->applyToNodes(&pushroots);
+ selected_handle->applyToNodes(&pushroots);
// then children...
- getSelection()->applyToNodes(&pushnonroots);
+ selected_handle->applyToNodes(&pushnonroots);
break;
case SEND_CHILDREN_FIRST:
// first children...
- getSelection()->applyToNodes(&pushnonroots);
+ selected_handle->applyToNodes(&pushnonroots);
// then roots...
- getSelection()->applyToNodes(&pushroots);
+ selected_handle->applyToNodes(&pushroots);
break;
default:
@@ -5357,7 +5426,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
}
else
{
- if (node->mInventorySerial != inv_serial)
+ if (node->mInventorySerial != inv_serial && node->getObject())
{
node->getObject()->dirtyInventory();
}
@@ -6686,8 +6755,7 @@ void LLSelectMgr::updateSelectionCenter()
if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid())
{
// reset hud ZOOM
- gAgentCamera.mHUDTargetZoom = 1.f;
- gAgentCamera.mHUDCurZoom = 1.f;
+ resetAgentHUDZoom();
}
mShowSelection = FALSE;
@@ -7060,8 +7128,11 @@ BOOL LLSelectMgr::setForceSelection(BOOL force)
void LLSelectMgr::resetAgentHUDZoom()
{
- gAgentCamera.mHUDTargetZoom = 1.f;
- gAgentCamera.mHUDCurZoom = 1.f;
+ if (gAgentCamera.mHUDTargetZoom != 1)
+ {
+ gAgentCamera.mHUDTargetZoom = 1.f;
+ gAgentCamera.mHUDCurZoom = 1.f;
+ }
}
void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 3e8bfdb00e..3bed484b58 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -239,6 +239,7 @@ class LLObjectSelection : public LLRefCount
{
friend class LLSelectMgr;
friend class LLSafeHandle<LLObjectSelection>;
+ friend class LLSelectionCallbackData;
protected:
~LLObjectSelection();
@@ -396,6 +397,16 @@ extern template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance()
// For use with getFirstTest()
struct LLSelectGetFirstTest;
+// temporary storage, Ex: to attach objects after autopilot
+class LLSelectionCallbackData
+{
+public:
+ LLSelectionCallbackData();
+ LLObjectSelectionHandle getSelection() { return mSelectedObjects; }
+private:
+ LLObjectSelectionHandle mSelectedObjects;
+};
+
class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
{
LLSINGLETON(LLSelectMgr);
@@ -740,6 +751,7 @@ public:
// canceled
void sendBuy(const LLUUID& buyer_id, const LLUUID& category_id, const LLSaleInfo sale_info);
void sendAttach(U8 attachment_point, bool replace);
+ void sendAttach(LLObjectSelectionHandle selection_handle, U8 attachment_point, bool replace);
void sendDetach();
void sendDropAttachment();
void sendLink();
@@ -787,6 +799,13 @@ private:
void (*log_func)(LLSelectNode* node, void *user_data),
void *user_data,
ESendType send_type);
+ void sendListToRegions( LLObjectSelectionHandle selected_handle,
+ const std::string& message_name,
+ void (*pack_header)(void *user_data),
+ void (*pack_body)(LLSelectNode* node, void *user_data),
+ void (*log_func)(LLSelectNode* node, void *user_data),
+ void *user_data,
+ ESendType send_type);
static void packAgentID( void *);
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 4ebcffa554..6e2b4a00fc 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -485,7 +485,7 @@ void LLSidepanelAppearance::fetchInventory()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (!attached_object) continue;
const LLUUID& item_id = attached_object->getAttachmentItemID();
if (item_id.isNull()) continue;
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 2503e2a5e2..d508621b41 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -49,6 +49,29 @@
#include "llviewerregion.h"
+class PropertiesChangedCallback : public LLInventoryCallback
+{
+public:
+ PropertiesChangedCallback(LLHandle<LLPanel> sidepanel_handle, LLUUID &item_id, S32 id)
+ : mHandle(sidepanel_handle), mItemId(item_id), mId(id)
+ {}
+
+ void fire(const LLUUID &inv_item)
+ {
+ // inv_item can be null for some reason
+ LLSidepanelItemInfo* sidepanel = dynamic_cast<LLSidepanelItemInfo*>(mHandle.get());
+ if (sidepanel)
+ {
+ // sidepanel waits only for most recent update
+ sidepanel->onUpdateCallback(mItemId, mId);
+ }
+ }
+private:
+ LLHandle<LLPanel> mHandle;
+ LLUUID mItemId;
+ S32 mId;
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLItemPropertiesObserver
//
@@ -68,7 +91,7 @@ public:
}
virtual void changed(U32 mask);
private:
- LLSidepanelItemInfo* mFloater;
+ LLSidepanelItemInfo* mFloater; // Not a handle because LLSidepanelItemInfo is managing LLItemPropertiesObserver
};
void LLItemPropertiesObserver::changed(U32 mask)
@@ -115,7 +138,7 @@ public:
S32 serial_num,
void* user_data);
private:
- LLSidepanelItemInfo* mFloater;
+ LLSidepanelItemInfo* mFloater; // Not a handle because LLSidepanelItemInfo is managing LLObjectInventoryObserver
};
/*virtual*/
@@ -138,6 +161,7 @@ LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p)
: LLSidepanelInventorySubpanel(p)
, mItemID(LLUUID::null)
, mObjectInventoryObserver(NULL)
+ , mUpdatePendingId(-1)
{
mPropertiesObserver = new LLItemPropertiesObserver(this);
}
@@ -168,19 +192,19 @@ BOOL LLSidepanelItemInfo::postBuild()
// owner permissions
// Permissions debug text
// group permissions
- getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckShareWithGroup")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
// everyone permissions
- getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckEveryoneCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
// next owner permissions
- getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
- getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
- getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this));
+ getChild<LLUICtrl>("CheckNextOwnerModify")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
+ getChild<LLUICtrl>("CheckNextOwnerCopy")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
+ getChild<LLUICtrl>("CheckNextOwnerTransfer")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitPermissions, this, _1));
// Mark for sale or not, and sale info
- getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("CheckPurchase")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
// Change sale type, and sale info
- getChild<LLUICtrl>("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("ComboBoxSaleType")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
// "Price" label for edit
- getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this));
+ getChild<LLUICtrl>("Edit Cost")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitSaleInfo, this, _1));
refresh();
return TRUE;
}
@@ -192,11 +216,16 @@ void LLSidepanelItemInfo::setObjectID(const LLUUID& object_id)
// Start monitoring changes in the object inventory to update
// selected inventory item properties in Item Profile panel. See STORM-148.
startObjectInventoryObserver();
+ mUpdatePendingId = -1;
}
void LLSidepanelItemInfo::setItemID(const LLUUID& item_id)
{
- mItemID = item_id;
+ if (mItemID != item_id)
+ {
+ mItemID = item_id;
+ mUpdatePendingId = -1;
+ }
}
const LLUUID& LLSidepanelItemInfo::getObjectID() const
@@ -209,6 +238,15 @@ const LLUUID& LLSidepanelItemInfo::getItemID() const
return mItemID;
}
+void LLSidepanelItemInfo::onUpdateCallback(const LLUUID& item_id, S32 received_update_id)
+{
+ if (mItemID == item_id && mUpdatePendingId == received_update_id)
+ {
+ mUpdatePendingId = -1;
+ refresh();
+ }
+}
+
void LLSidepanelItemInfo::reset()
{
LLSidepanelInventorySubpanel::reset();
@@ -242,24 +280,16 @@ void LLSidepanelItemInfo::refresh()
"LabelItemName",
"LabelItemDesc",
"LabelCreatorName",
- "LabelOwnerName",
- "CheckOwnerModify",
- "CheckOwnerCopy",
- "CheckOwnerTransfer",
- "CheckShareWithGroup",
- "CheckEveryoneCopy",
- "CheckNextOwnerModify",
- "CheckNextOwnerCopy",
- "CheckNextOwnerTransfer",
- "CheckPurchase",
- "Edit Cost"
+ "LabelOwnerName"
};
for(size_t t=0; t<LL_ARRAY_SIZE(no_item_names); ++t)
{
getChildView(no_item_names[t])->setEnabled(false);
}
-
+
+ setPropertiesFieldsEnabled(false);
+
const std::string hide_names[]={
"BaseMaskDebug",
"OwnerMaskDebug",
@@ -297,6 +327,11 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
llassert(item);
if (!item) return;
+ if (mUpdatePendingId != -1)
+ {
+ return;
+ }
+
// do not enable the UI for incomplete items.
BOOL is_complete = item->isFinished();
const BOOL cannot_restrict_permissions = LLInventoryType::cannotRestrictPermissions(item->getInventoryType());
@@ -726,6 +761,26 @@ void LLSidepanelItemInfo::stopObjectInventoryObserver()
mObjectInventoryObserver = NULL;
}
+void LLSidepanelItemInfo::setPropertiesFieldsEnabled(bool enabled)
+{
+ const std::string fields[] = {
+ "CheckOwnerModify",
+ "CheckOwnerCopy",
+ "CheckOwnerTransfer",
+ "CheckShareWithGroup",
+ "CheckEveryoneCopy",
+ "CheckNextOwnerModify",
+ "CheckNextOwnerCopy",
+ "CheckNextOwnerTransfer",
+ "CheckPurchase",
+ "Edit Cost"
+ };
+ for (size_t t = 0; t<LL_ARRAY_SIZE(fields); ++t)
+ {
+ getChildView(fields[t])->setEnabled(false);
+ }
+}
+
void LLSidepanelItemInfo::onClickCreator()
{
LLViewerInventoryItem* item = findItem();
@@ -793,10 +848,18 @@ void LLSidepanelItemInfo::onCommitDescription()
}
}
-// static
-void LLSidepanelItemInfo::onCommitPermissions()
+void LLSidepanelItemInfo::onCommitPermissions(LLUICtrl* ctrl)
+{
+ if (ctrl)
+ {
+ // will be enabled by response from server
+ ctrl->setEnabled(false);
+ }
+ updatePermissions();
+}
+
+void LLSidepanelItemInfo::updatePermissions()
{
- //LL_INFOS() << "LLSidepanelItemInfo::onCommitPermissions()" << LL_ENDL;
LLViewerInventoryItem* item = findItem();
if(!item) return;
@@ -884,19 +947,17 @@ void LLSidepanelItemInfo::onCommitPermissions()
}
// static
-void LLSidepanelItemInfo::onCommitSaleInfo()
+void LLSidepanelItemInfo::onCommitSaleInfo(LLUICtrl* ctrl)
{
+ if (ctrl)
+ {
+ // will be enabled by response from server
+ ctrl->setEnabled(false);
+ }
//LL_INFOS() << "LLSidepanelItemInfo::onCommitSaleInfo()" << LL_ENDL;
updateSaleInfo();
}
-// static
-void LLSidepanelItemInfo::onCommitSaleType()
-{
- //LL_INFOS() << "LLSidepanelItemInfo::onCommitSaleType()" << LL_ENDL;
- updateSaleInfo();
-}
-
void LLSidepanelItemInfo::updateSaleInfo()
{
LLViewerInventoryItem* item = findItem();
@@ -977,7 +1038,12 @@ void LLSidepanelItemInfo::onCommitChanges(LLPointer<LLViewerInventoryItem> item)
if (mObjectID.isNull())
{
// This is in the agent's inventory.
- item->updateServer(FALSE);
+ // Mark update as pending and wait only for most recent one in case user requested for couple
+ // Once update arrives or any of ids change drop pending id.
+ mUpdatePendingId++;
+ LLPointer<LLInventoryCallback> callback = new PropertiesChangedCallback(getHandle(), mItemID, mUpdatePendingId);
+ update_inventory_item(item.get(), callback);
+ //item->updateServer(FALSE);
gInventory.updateItem(item);
gInventory.notifyObservers();
}
@@ -1002,6 +1068,7 @@ void LLSidepanelItemInfo::onCommitChanges(LLPointer<LLViewerInventoryItem> item)
// prevents flashing in content tab and some duplicated request.
object->dirtyInventory();
}
+ setPropertiesFieldsEnabled(false);
}
}
}
@@ -1030,7 +1097,6 @@ void LLSidepanelItemInfo::save()
{
onCommitName();
onCommitDescription();
- onCommitPermissions();
- onCommitSaleInfo();
- onCommitSaleType();
+ updatePermissions();
+ updateSaleInfo();
}
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 74cf7afe35..5f29254182 100644
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
@@ -57,6 +57,9 @@ public:
const LLUUID& getObjectID() const;
const LLUUID& getItemID() const;
+ // if received update and item id (from callback) matches internal ones, update UI
+ void onUpdateCallback(const LLUUID& item_id, S32 received_update_id);
+
protected:
/*virtual*/ void refresh();
/*virtual*/ void save();
@@ -71,12 +74,16 @@ private:
void startObjectInventoryObserver();
void stopObjectInventoryObserver();
+ void setPropertiesFieldsEnabled(bool enabled);
LLUUID mItemID; // inventory UUID for the inventory item.
LLUUID mObjectID; // in-world task UUID, or null if in agent inventory.
LLItemPropertiesObserver* mPropertiesObserver; // for syncing changes to item
LLObjectInventoryObserver* mObjectInventoryObserver; // for syncing changes to items inside an object
-
+
+ // We can send multiple properties updates simultaneously, make sure only last response counts and there won't be a race condition.
+ S32 mUpdatePendingId;
+
//
// UI Elements
//
@@ -85,9 +92,9 @@ protected:
void onClickOwner();
void onCommitName();
void onCommitDescription();
- void onCommitPermissions();
- void onCommitSaleInfo();
- void onCommitSaleType();
+ void onCommitPermissions(LLUICtrl* ctrl);
+ void updatePermissions();
+ void onCommitSaleInfo(LLUICtrl* ctrl);
void updateSaleInfo();
void onCommitChanges(LLPointer<LLViewerInventoryItem> item);
};
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index f03c7abc4d..7fa06f51e3 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -174,9 +174,6 @@ BOOL LLSidepanelTaskInfo::postBuild()
void LLSidepanelTaskInfo::disableAll()
{
- mDAPermModify->setEnabled(FALSE);
- mDAPermModify->setValue(LLStringUtil::null);
-
mDACreatorName->setValue(LLStringUtil::null);
mDACreatorName->setEnabled(FALSE);
@@ -184,18 +181,42 @@ void LLSidepanelTaskInfo::disableAll()
mDAOwnerName->setValue(LLStringUtil::null);
mDAOwnerName->setEnabled(FALSE);
- mDAButtonSetGroup->setEnabled(FALSE);
-
mDAObjectName->setValue(LLStringUtil::null);
mDAObjectName->setEnabled(FALSE);
mDAName->setEnabled(FALSE);
mDADescription->setEnabled(FALSE);
mDAObjectDescription->setValue(LLStringUtil::null);
mDAObjectDescription->setEnabled(FALSE);
-
+
+ mDAPathfindingAttributes->setEnabled(FALSE);
+ mDAPathfindingAttributes->setValue(LLStringUtil::null);
+
+ mDAButtonSetGroup->setEnabled(FALSE);
+ mDAButtonDeed->setEnabled(FALSE);
+
+ mDAPermModify->setEnabled(FALSE);
+ mDAPermModify->setValue(LLStringUtil::null);
+ mDAEditCost->setValue(LLStringUtil::null);
+ mDAComboSaleType->setValue(LLSaleInfo::FS_COPY);
+
+ disablePermissions();
+
+ mDAB->setVisible(FALSE);
+ mDAO->setVisible(FALSE);
+ mDAG->setVisible(FALSE);
+ mDAE->setVisible(FALSE);
+ mDAN->setVisible(FALSE);
+ mDAF->setVisible(FALSE);
+
+ mOpenBtn->setEnabled(FALSE);
+ mPayBtn->setEnabled(FALSE);
+ mBuyBtn->setEnabled(FALSE);
+}
+
+void LLSidepanelTaskInfo::disablePermissions()
+{
mDACheckboxShareWithGroup->setValue(FALSE);
mDACheckboxShareWithGroup->setEnabled(FALSE);
- mDAButtonDeed->setEnabled(FALSE);
mDACheckboxAllowEveryoneMove->setValue(FALSE);
mDACheckboxAllowEveryoneMove->setEnabled(FALSE);
@@ -217,33 +238,17 @@ void LLSidepanelTaskInfo::disableAll()
//checkbox include in search
mDASearchCheck->setValue(FALSE);
mDASearchCheck->setEnabled(FALSE);
-
- mDAComboSaleType->setValue(LLSaleInfo::FS_COPY);
+
mDAComboSaleType->setEnabled(FALSE);
-
- mDAEditCost->setValue(LLStringUtil::null);
+
mDAEditCost->setEnabled(FALSE);
-
+
mDALabelClickAction->setEnabled(FALSE);
if (mDAComboClickAction)
{
mDAComboClickAction->setEnabled(FALSE);
mDAComboClickAction->clear();
}
-
- mDAPathfindingAttributes->setEnabled(FALSE);
- mDAPathfindingAttributes->setValue(LLStringUtil::null);
-
- mDAB->setVisible(FALSE);
- mDAO->setVisible(FALSE);
- mDAG->setVisible(FALSE);
- mDAE->setVisible(FALSE);
- mDAN->setVisible(FALSE);
- mDAF->setVisible(FALSE);
-
- mOpenBtn->setEnabled(FALSE);
- mPayBtn->setEnabled(FALSE);
- mBuyBtn->setEnabled(FALSE);
}
void LLSidepanelTaskInfo::refresh()
@@ -972,6 +977,12 @@ void LLSidepanelTaskInfo::onCommitPerm(LLUICtrl *ctrl, void *data, U8 field, U32
BOOL new_state = check->get();
LLSelectMgr::getInstance()->selectionSetObjectPermissions(field, new_state, perm);
+
+ LLSidepanelTaskInfo* self = (LLSidepanelTaskInfo*)data;
+ if (self)
+ {
+ self->disablePermissions();
+ }
}
// static
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index cbfb07874b..dc259cb22d 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -95,6 +95,7 @@ protected:
static void doClickAction(U8 click_action);
void disableAll();
+ void disablePermissions();
private:
LLNameBox* mLabelGroupName; // group name
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index f5fea9dece..8fef3ff1c0 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -34,8 +34,6 @@
#include "lleconomy.h"
#include "llfloaterperms.h"
#include "llfloaterreg.h"
-#include "llfloaterflickr.h"
-#include "llfloatertwitter.h"
#include "llimagefilter.h"
#include "llimagefiltersmanager.h"
#include "llimagebmp.h"
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c8c39ae00f..684d3bd421 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -158,6 +158,7 @@
#include "llviewermessage.h"
#include "llviewernetwork.h"
#include "llviewerobjectlist.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -236,7 +237,8 @@ LLSLURL LLStartUp::sStartSLURL;
static LLPointer<LLCredential> gUserCredential;
static std::string gDisplayName;
-static BOOL gRememberPassword = TRUE;
+static bool gRememberPassword = true;
+static bool gRememberUser = true;
static U64 gFirstSimHandle = 0;
static LLHost gFirstSim;
@@ -350,13 +352,6 @@ bool idle_startup()
gIdleCallbacks.callFunctions();
gViewerWindow->updateUI();
- // There is a crash on updateClass, this is an attempt to get more information
- if (LLMortician::graveyardCount())
- {
- std::stringstream log_stream;
- LLMortician::logClass(log_stream);
- LL_INFOS() << log_stream.str() << LL_ENDL;
- }
LLMortician::updateClass();
const std::string delims (" ");
@@ -701,19 +696,23 @@ bool idle_startup()
else if (gSavedSettings.getBOOL("AutoLogin"))
{
// Log into last account
- gRememberPassword = TRUE;
- gSavedSettings.setBOOL("RememberPassword", TRUE);
+ gRememberPassword = true;
+ gRememberUser = true;
+ gSavedSettings.setBOOL("RememberPassword", TRUE);
+ gSavedSettings.setBOOL("RememberUser", TRUE);
show_connect_box = false;
}
else if (gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
// Console provided login&password
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
+ gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = false;
}
else
{
gRememberPassword = gSavedSettings.getBOOL("RememberPassword");
+ gRememberUser = gSavedSettings.getBOOL("RememberUser");
show_connect_box = TRUE;
}
@@ -781,10 +780,7 @@ bool idle_startup()
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
- if (gUserCredential.notNull() && !LLPanelLogin::isCredentialSet())
- {
- LLPanelLogin::setFields( gUserCredential, gRememberPassword);
- }
+ LLPanelLogin::populateFields( gUserCredential, gRememberUser, gRememberPassword);
LLPanelLogin::giveFocus();
// MAINT-3231 Show first run dialog only for Desura viewer
@@ -873,7 +869,7 @@ bool idle_startup()
{
// TODO if not use viewer auth
// Load all the name information out of the login view
- LLPanelLogin::getFields(gUserCredential, gRememberPassword);
+ LLPanelLogin::getFields(gUserCredential, gRememberUser, gRememberPassword);
// end TODO
// HACK: Try to make not jump on login
@@ -885,14 +881,21 @@ bool idle_startup()
// STATE_LOGIN_SHOW state if we've gone backwards
mLoginStatePastUI = true;
- // save the credentials
- std::string userid = "unknown";
- if(gUserCredential.notNull())
- {
- userid = gUserCredential->userID();
- gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
- }
- gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
+ // save the credentials
+ std::string userid = "unknown";
+ if (gUserCredential.notNull())
+ {
+ userid = gUserCredential->userID();
+ if (gRememberUser)
+ {
+ gSecAPIHandler->addToCredentialMap("login_list", gUserCredential, gRememberPassword);
+ // Legacy viewers use this method to store user credentials, newer viewers
+ // reuse it to be compatible and to remember last session
+ gSecAPIHandler->saveCredential(gUserCredential, gRememberPassword);
+ }
+ }
+ gSavedSettings.setBOOL("RememberPassword", gRememberPassword);
+ gSavedSettings.setBOOL("RememberUser", gRememberUser);
LL_INFOS("AppInit") << "Attempting login as: " << userid << LL_ENDL;
gDebugInfo["LoginName"] = userid;
@@ -1423,6 +1426,10 @@ bool idle_startup()
// create a container's instance for start a controlling conversation windows
// by the voice's events
LLFloaterIMContainer::getInstance();
+ if (gSavedSettings.getS32("ParcelMediaAutoPlayEnable") == 2)
+ {
+ LLViewerParcelAskPlay::getInstance()->loadSettings();
+ }
// *Note: this is where gWorldMap used to be initialized.
@@ -1632,7 +1639,14 @@ bool idle_startup()
if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT)
{
LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
- LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ if (gRememberPassword)
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ }
+ else
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
+ }
reset_login();
}
return FALSE;
@@ -2367,7 +2381,14 @@ void use_circuit_callback(void**, S32 result)
{
// Make sure user knows something bad happened. JC
LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
- LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ if (gRememberPassword)
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ }
+ else
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
+ }
reset_login();
}
else
@@ -2694,6 +2715,15 @@ std::string& LLStartUp::getInitialOutfitName()
return sInitialOutfit;
}
+std::string LLStartUp::getUserId()
+{
+ if (gUserCredential.isNull())
+ {
+ return "";
+ }
+ return gUserCredential->userID();
+}
+
// Loads a bitmap to display during load
void init_start_screen(S32 location_id)
{
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index db37207022..5ce74b8fae 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -115,6 +115,7 @@ public:
static void saveInitialOutfit();
static std::string& getInitialOutfitName();
+ static std::string getUserId();
static bool dispatchURL();
// if we have a SLURL or sim string ("Ahern/123/45") that started
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 9eda33d3d2..b8c227334d 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -243,16 +243,24 @@ BOOL LLStatusBar::postBuild()
mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT);
mPanelNearByMedia->setVisible(FALSE);
+ updateBalancePanelPosition();
+
// Hook up and init for filtering
mFilterEdit = getChild<LLSearchEditor>( "search_menu_edit" );
mSearchPanel = getChild<LLPanel>( "menu_search_panel" );
- mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch"));
+ BOOL search_panel_visible = gSavedSettings.getBOOL("MenuSearch");
+ mSearchPanel->setVisible(search_panel_visible);
mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this));
collectSearchableItems();
gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2));
+ if (search_panel_visible)
+ {
+ updateMenuSearchPosition();
+ }
+
return TRUE;
}
@@ -363,17 +371,7 @@ void LLStatusBar::setBalance(S32 balance)
std::string label_str = getString("buycurrencylabel", string_args);
mBoxBalance->setValue(label_str);
- // Resize the L$ balance background to be wide enough for your balance plus the buy button
- {
- const S32 HPAD = 24;
- LLRect balance_rect = mBoxBalance->getTextBoundingRect();
- LLRect buy_rect = getChildView("buyL")->getRect();
- LLRect shop_rect = getChildView("goShop")->getRect();
- LLView* balance_bg_view = getChildView("balance_bg");
- LLRect balance_bg_rect = balance_bg_view->getRect();
- balance_bg_rect.mLeft = balance_bg_rect.mRight - (buy_rect.getWidth() + shop_rect.getWidth() + balance_rect.getWidth() + HPAD);
- balance_bg_view->setShape(balance_bg_rect);
- }
+ updateBalancePanelPosition();
// If the search panel is shown, move this according to the new balance width. Parcel text will reshape itself in setParcelInfoText
if (mSearchPanel && mSearchPanel->getVisible())
@@ -661,6 +659,19 @@ void LLStatusBar::updateMenuSearchPosition()
mSearchPanel->setShape( searchRect );
}
+void LLStatusBar::updateBalancePanelPosition()
+{
+ // Resize the L$ balance background to be wide enough for your balance plus the buy button
+ const S32 HPAD = 24;
+ LLRect balance_rect = mBoxBalance->getTextBoundingRect();
+ LLRect buy_rect = getChildView("buyL")->getRect();
+ LLRect shop_rect = getChildView("goShop")->getRect();
+ LLView* balance_bg_view = getChildView("balance_bg");
+ LLRect balance_bg_rect = balance_bg_view->getRect();
+ balance_bg_rect.mLeft = balance_bg_rect.mRight - (buy_rect.getWidth() + shop_rect.getWidth() + balance_rect.getWidth() + HPAD);
+ balance_bg_view->setShape(balance_bg_rect);
+}
+
// Implements secondlife:///app/balance/request to request a L$ balance
// update via UDP message system. JC
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 403d590aca..cad877f799 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -114,7 +114,8 @@ private:
std::unique_ptr< ll::statusbar::SearchData > mSearchData;
void collectSearchableItems();
void updateMenuSearchVisibility( const LLSD& data );
- void updateMenuSearchPosition();
+ void updateMenuSearchPosition(); // depends onto balance position
+ void updateBalancePanelPosition();
private:
LLTextBox *mTextTime;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e5af47ab6c..e2deb7ce1d 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -53,6 +53,7 @@ const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
+const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .004f; // 4ms. Would be better to autoadjust, but there is a major cache rework in progress.
class LLTextureCacheWorker : public LLWorkerClass
{
@@ -837,6 +838,7 @@ LLTextureCache::LLTextureCache(bool threaded)
mFastCachePoolp(NULL),
mFastCachePadBuffer(NULL)
{
+ mHeaderAPRFilePoolp = new LLVolatileAPRPool(); // is_local = true, because this pool is for headers, headers are under own mutex
}
LLTextureCache::~LLTextureCache()
@@ -845,6 +847,7 @@ LLTextureCache::~LLTextureCache()
writeUpdatedEntries() ;
delete mFastCachep;
delete mFastCachePoolp;
+ delete mHeaderAPRFilePoolp;
ll_aligned_free_16(mFastCachePadBuffer);
}
@@ -1013,10 +1016,11 @@ void LLTextureCache::purgeCache(ELLPath location, bool remove_dir)
if(LLFile::isdir(mTexturesDirName))
{
std::string file_name = gDirUtilp->getExpandedFilename(location, entries_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ // mHeaderAPRFilePoolp because we are under header mutex, and can be in main thread
+ LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
file_name = gDirUtilp->getExpandedFilename(location, cache_filename);
- LLAPRFile::remove(file_name, getLocalAPRFilePool());
+ LLAPRFile::remove(file_name, mHeaderAPRFilePoolp);
purgeAllTextures(true);
}
@@ -1093,7 +1097,7 @@ LLAPRFile* LLTextureCache::openHeaderEntriesFile(bool readonly, S32 offset)
{
llassert_always(mHeaderAPRFile == NULL);
apr_int32_t flags = readonly ? APR_READ|APR_BINARY : APR_READ|APR_WRITE|APR_BINARY;
- mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, getLocalAPRFilePool());
+ mHeaderAPRFile = new LLAPRFile(mHeaderEntriesFileName, flags, mHeaderAPRFilePoolp);
if(offset > 0)
{
mHeaderAPRFile->seek(APR_SET, offset);
@@ -1116,10 +1120,10 @@ void LLTextureCache::readEntriesHeader()
{
// mHeaderEntriesInfo initializes to default values so safe not to read it
llassert_always(mHeaderAPRFile == NULL);
- if (LLAPRFile::isExist(mHeaderEntriesFileName, getLocalAPRFilePool()))
+ if (LLAPRFile::isExist(mHeaderEntriesFileName, mHeaderAPRFilePoolp))
{
LLAPRFile::readEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ mHeaderAPRFilePoolp);
}
else //create an empty entries header.
{
@@ -1151,7 +1155,7 @@ void LLTextureCache::writeEntriesHeader()
if (!mReadOnly)
{
LLAPRFile::writeEx(mHeaderEntriesFileName, (U8*)&mHeaderEntriesInfo, 0, sizeof(EntriesInfo),
- getLocalAPRFilePool());
+ mHeaderAPRFilePoolp);
}
}
@@ -1669,6 +1673,91 @@ void LLTextureCache::purgeAllTextures(bool purge_directories)
LL_INFOS() << "The entire texture cache is cleared." << LL_ENDL ;
}
+void LLTextureCache::purgeTexturesLazy(F32 time_limit_sec)
+{
+ if (mReadOnly)
+ {
+ return;
+ }
+
+ if (!mThreaded)
+ {
+ LLAppViewer::instance()->pauseMainloopTimeout();
+ }
+
+ // time_limit doesn't account for lock time
+ LLMutexLock lock(&mHeaderMutex);
+
+ if (mPurgeEntryList.empty())
+ {
+ // Read the entries list and form list of textures to purge
+ std::vector<Entry> entries;
+ U32 num_entries = openAndReadEntries(entries);
+ if (!num_entries)
+ {
+ return; // nothing to purge
+ }
+
+ // Use mTexturesSizeMap to collect UUIDs of textures with bodies
+ typedef std::set<std::pair<U32, S32> > time_idx_set_t;
+ std::set<std::pair<U32, S32> > time_idx_set;
+ for (size_map_t::iterator iter1 = mTexturesSizeMap.begin();
+ iter1 != mTexturesSizeMap.end(); ++iter1)
+ {
+ if (iter1->second > 0)
+ {
+ id_map_t::iterator iter2 = mHeaderIDMap.find(iter1->first);
+ if (iter2 != mHeaderIDMap.end())
+ {
+ S32 idx = iter2->second;
+ time_idx_set.insert(std::make_pair(entries[idx].mTime, idx));
+ }
+ else
+ {
+ LL_ERRS("TextureCache") << "mTexturesSizeMap / mHeaderIDMap corrupted." << LL_ENDL;
+ }
+ }
+ }
+
+ S64 cache_size = mTexturesSizeTotal;
+ S64 purged_cache_size = (sCacheMaxTexturesSize * (S64)((1.f - TEXTURE_CACHE_PURGE_AMOUNT) * 100)) / 100;
+ for (time_idx_set_t::iterator iter = time_idx_set.begin();
+ iter != time_idx_set.end(); ++iter)
+ {
+ S32 idx = iter->second;
+ if (cache_size >= purged_cache_size)
+ {
+ cache_size -= entries[idx].mBodySize;
+ mPurgeEntryList.push_back(std::pair<S32, Entry>(idx, entries[idx]));
+ }
+ else
+ {
+ break;
+ }
+ }
+ LL_DEBUGS("TextureCache") << "Formed Purge list of " << mPurgeEntryList.size() << " entries" << LL_ENDL;
+ }
+ else
+ {
+ // Remove collected entried
+ LLTimer timer;
+ while (!mPurgeEntryList.empty() && timer.getElapsedTimeF32() < time_limit_sec)
+ {
+ S32 idx = mPurgeEntryList.back().first;
+ Entry entry = mPurgeEntryList.back().second;
+ mPurgeEntryList.pop_back();
+ // make sure record is still valid
+ id_map_t::iterator iter_header = mHeaderIDMap.find(entry.mID);
+ if (iter_header != mHeaderIDMap.end() && iter_header->second == idx)
+ {
+ std::string tex_filename = getTextureFileName(entry.mID);
+ removeEntry(idx, entry, tex_filename);
+ writeEntryToHeaderImmediately(idx, entry);
+ }
+ }
+ }
+}
+
void LLTextureCache::purgeTextures(bool validate)
{
if (mReadOnly)
@@ -1746,7 +1835,8 @@ void LLTextureCache::purgeTextures(bool validate)
if (uuididx == validate_idx)
{
LL_DEBUGS("TextureCache") << "Validating: " << filename << "Size: " << entries[idx].mBodySize << LL_ENDL;
- S32 bodysize = LLAPRFile::size(filename, getLocalAPRFilePool());
+ // mHeaderAPRFilePoolp because this is under header mutex in main thread
+ S32 bodysize = LLAPRFile::size(filename, mHeaderAPRFilePoolp);
if (bodysize != entries[idx].mBodySize)
{
LL_WARNS("TextureCache") << "TEXTURE CACHE BODY HAS BAD SIZE: " << bodysize << " != " << entries[idx].mBodySize
@@ -1928,11 +2018,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
}
if (mDoPurge)
{
- // NOTE: This may cause an occasional hiccup,
- // but it really needs to be done on the control thread
- // (i.e. here)
- purgeTextures(false);
- mDoPurge = FALSE;
+ // NOTE: Needs to be done on the control thread
+ // (i.e. here)
+ purgeTexturesLazy(TEXTURE_LAZY_PURGE_TIME_LIMIT);
+ mDoPurge = !mPurgeEntryList.empty();
}
LLMutexLock lock(&mWorkersMutex);
LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
@@ -2146,7 +2235,7 @@ void LLTextureCache::openFastCache(bool first_time)
{
mFastCachePadBuffer = (U8*)ll_aligned_malloc_16(TEXTURE_FAST_CACHE_ENTRY_SIZE);
}
- mFastCachePoolp = new LLVolatileAPRPool();
+ mFastCachePoolp = new LLVolatileAPRPool(); // is_local= true by default, so not thread safe by default
if (LLAPRFile::isExist(mFastCacheFileName, mFastCachePoolp))
{
mFastCachep = new LLAPRFile(mFastCacheFileName, APR_READ|APR_WRITE|APR_BINARY, mFastCachePoolp) ;
@@ -2230,7 +2319,9 @@ void LLTextureCache::removeCachedTexture(const LLUUID& id)
mTexturesSizeMap.erase(id);
}
mHeaderIDMap.erase(id);
- LLAPRFile::remove(getTextureFileName(id), getLocalAPRFilePool());
+ // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
+ // but getLocalAPRFilePool() is not safe, it might be in use by worker
+ LLAPRFile::remove(getTextureFileName(id), mHeaderAPRFilePoolp);
}
//called after mHeaderMutex is locked.
@@ -2242,7 +2333,10 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
{
if (entry.mBodySize == 0) // Always attempt to remove when mBodySize > 0.
{
- if (LLAPRFile::isExist(filename, getLocalAPRFilePool())) // Sanity check. Shouldn't exist when body size is 0.
+ // Sanity check. Shouldn't exist when body size is 0.
+ // We are inside header's mutex so mHeaderAPRFilePoolp is safe to use,
+ // but getLocalAPRFilePool() is not safe, it might be in use by worker
+ if (LLAPRFile::isExist(filename, mHeaderAPRFilePoolp))
{
LL_WARNS("TextureCache") << "Entry has body size of zero but file " << filename << " exists. Deleting this file, too." << LL_ENDL;
}
@@ -2262,7 +2356,7 @@ void LLTextureCache::removeEntry(S32 idx, Entry& entry, std::string& filename)
if (file_maybe_exists)
{
- LLAPRFile::remove(filename, getLocalAPRFilePool());
+ LLAPRFile::remove(filename, mHeaderAPRFilePoolp);
}
}
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 81ea7aeee2..6046f2b9df 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -139,7 +139,7 @@ public:
U32 getEntries() { return mHeaderEntriesInfo.mEntries; }
U32 getMaxEntries() { return sCacheMaxEntries; };
BOOL isInCache(const LLUUID& id) ;
- BOOL isInLocal(const LLUUID& id) ;
+ BOOL isInLocal(const LLUUID& id) ; //not thread safe at the moment
protected:
// Accessed by LLTextureCacheWorker
@@ -155,6 +155,7 @@ private:
void readHeaderCache();
void clearCorruptedCache();
void purgeAllTextures(bool purge_directories);
+ void purgeTexturesLazy(F32 time_limit_sec);
void purgeTextures(bool validate);
LLAPRFile* openHeaderEntriesFile(bool readonly, S32 offset);
void closeHeaderEntriesFile();
@@ -189,6 +190,11 @@ private:
LLMutex mFastCacheMutex;
LLAPRFile* mHeaderAPRFile;
LLVolatileAPRPool* mFastCachePoolp;
+
+ // mLocalAPRFilePoolp is not thread safe and is meant only for workers
+ // howhever mHeaderEntriesFileName is accessed not from workers' threads
+ // so it needs own pool (not thread safe by itself, relies onto header's mutex)
+ LLVolatileAPRPool* mHeaderAPRFilePoolp;
typedef std::map<handle_t, LLTextureCacheWorker*> handle_map_t;
handle_map_t mReaders;
@@ -225,6 +231,8 @@ private:
typedef std::map<S32, Entry> idx_entry_map_t;
idx_entry_map_t mUpdatedEntryMap;
+ typedef std::vector<std::pair<S32, Entry> > idx_entry_vector_t;
+ idx_entry_vector_t mPurgeEntryList;
// Statics
static F32 sHeaderCacheVersion;
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 941cb410fc..f882fd31ee 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -34,7 +34,6 @@
#include "llfontgl.h"
#include "lltextbox.h"
#include "llbutton.h"
-#include "llcheckboxctrl.h"
#include "llkeyboard.h"
#include "llfocusmgr.h"
#include "lliconctrl.h"
@@ -62,9 +61,8 @@ static const S32 HPAD = 25;
static const S32 BTN_HPAD = 8;
LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal)
- : LLToastPanel(notification),
+ : LLCheckBoxToastPanel(notification),
mDefaultOption( 0 ),
- mCheck(NULL),
mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH),
mLabel(notification->getName()),
mLineEditor(NULL)
@@ -347,20 +345,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
button_left += button_width + BTN_HPAD;
}
- std::string ignore_label;
-
- if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
- {
- setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label);
- }
- if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
- {
- setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label);
- }
- else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
- {
- setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label);
- }
+ setCheckBoxes(HPAD, VPAD);
// *TODO: check necessity of this code
//gFloaterView->adjustToFitScreen(this, FALSE);
@@ -380,46 +365,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
LLTransientFloaterMgr::GLOBAL, this);
}
-bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
-{
- mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
-
- if(!mCheck)
- {
- return false;
- }
-
- const LLFontGL* font = mCheck->getFont();
- const S32 LINE_HEIGHT = font->getLineHeight();
-
- std::vector<std::string> lines;
- boost::split(lines, check_title, boost::is_any_of("\n"));
-
- // Extend dialog for "check next time"
- S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD;
- S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
- max_msg_width = llmax(max_msg_width, check_width);
- S32 dialog_width = max_msg_width + 2 * HPAD;
-
- S32 dialog_height = LLToastPanel::getRect().getHeight();
- dialog_height += LINE_HEIGHT * lines.size();
- dialog_height += LINE_HEIGHT / 2;
-
- LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
-
- S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
-
- // set check_box's attributes
- LLRect check_rect;
- mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT*lines.size()));
- mCheck->setLabel(check_title);
- mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
-
- LLToastPanel::addChild(mCheck);
-
- return true;
-}
-
void LLToastAlertPanel::setVisible( BOOL visible )
{
// only make the "ding" sound if it's newly visible
@@ -569,16 +514,3 @@ void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button )
mNotification->respond(response); // new notification reponse
}
-
-void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl)
-{
- // checkbox sometimes means "hide and do the default" and
- // other times means "warn me again". Yuck. JC
- BOOL check = ctrl->getValue().asBoolean();
- if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
- {
- // question was "show again" so invert value to get "ignore"
- check = !check;
- }
- mNotification->setIgnored(check);
-}
diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h
index 15bf11d42c..9b4e054bf1 100644
--- a/indra/newview/lltoastalertpanel.h
+++ b/indra/newview/lltoastalertpanel.h
@@ -46,7 +46,7 @@ class LLLineEditor;
*/
class LLToastAlertPanel
- : public LLToastPanel
+ : public LLCheckBoxToastPanel
{
LOG_CLASS(LLToastAlertPanel);
public:
@@ -61,13 +61,11 @@ public:
virtual void draw();
virtual void setVisible( BOOL visible );
- bool setCheckBox( const std::string&, const std::string& );
void setCaution(BOOL val = TRUE) { mCaution = val; }
// If mUnique==TRUE only one copy of this message should exist
void setUnique(BOOL val = TRUE) { mUnique = val; }
void setEditTextArgs(const LLSD& edit_args);
- void onClickIgnore(LLUICtrl* ctrl);
void onButtonPressed(const LLSD& data, S32 button);
private:
@@ -91,7 +89,6 @@ private:
std::vector<ButtonData> mButtonData;
S32 mDefaultOption;
- LLCheckBoxCtrl* mCheck;
BOOL mCaution;
BOOL mUnique;
LLUIString mLabel;
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index a2116817a2..bccf88128d 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -33,6 +33,7 @@
// library includes
#include "lldbstrings.h"
+#include "llcheckboxctrl.h"
#include "lllslconstants.h"
#include "llnotifications.h"
#include "lluiconstants.h"
@@ -55,7 +56,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images)
-: LLToastPanel(notification),
+: LLCheckBoxToastPanel(notification),
LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>(notification->getID())
{
init(rect, show_images);
@@ -162,6 +163,11 @@ void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair
{
left = (max_width - btn_rect.getWidth()) / 2;
}
+ else if (left == 0 && buttons.size() == 2)
+ {
+ // Note: this and "size() == 1" shouldn't be inside the cycle, might be good idea to refactor whole placing process
+ left = (max_width - (btn_rect.getWidth() * 2) - h_pad) / 2;
+ }
else if (left + btn_rect.getWidth() > max_width)// whether there is still some place for button+h_pad in the mControlPanel
{
// looks like we need to add button to the next row
@@ -409,7 +415,20 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel
//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
mInfoPanel->setFollowsAll();
- snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
+
+ // Add checkbox (one of couple types) if nessesary.
+ setCheckBoxes(HPAD * 2, 0, mInfoPanel);
+ if (mCheck)
+ {
+ mCheck->setFollows(FOLLOWS_BOTTOM | FOLLOWS_LEFT);
+ }
+ // Snap to message, then to checkbox if present
+ snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
+ if (mCheck)
+ {
+ S32 new_panel_height = mCheck->getRect().getHeight() + getRect().getHeight() + VPAD;
+ reshape(getRect().getWidth(), new_panel_height);
+ }
// reshape the panel to its previous size
if (current_rect.notEmpty())
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index e4a75acfda..a5a637c6fa 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -47,7 +47,7 @@ class LLNotificationForm;
* @deprecated this class will be removed after all toast panel types are
* implemented in separate classes.
*/
-class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
+class LLToastNotifyPanel: public LLCheckBoxToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
{
public:
/**
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 7c624d5b50..100d5ee713 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "lldbstrings.h"
+#include "llcheckboxctrl.h"
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
@@ -34,6 +35,8 @@
#include "lltoastpanel.h"
#include "lltoastscriptquestion.h"
+#include <boost/algorithm/string.hpp>
+
//static
const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
// 'magic numbers', consider initializing (512+20) part from xml/notifications
@@ -145,3 +148,108 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
return res;
}
+
+LLCheckBoxToastPanel::LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf)
+: LLToastPanel(p_ntf),
+mCheck(NULL)
+{
+
+}
+
+void LLCheckBoxToastPanel::setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view)
+{
+ std::string ignore_label;
+ LLNotificationFormPtr form = mNotification->getForm();
+
+ if (form->getIgnoreType() == LLNotificationForm::IGNORE_CHECKBOX_ONLY)
+ {
+ // Normally text is only used to describe notification in preferences,
+ // but this one is not displayed in preferences and works on case by case
+ // basis.
+ // Display text if present, display 'always chose' if not.
+ std::string ignore_message = form->getIgnoreMessage();
+ if (ignore_message.empty())
+ {
+ ignore_message = LLNotifications::instance().getGlobalString("alwayschoose");
+ }
+ setCheckBox(ignore_message, ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+ else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+ if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+ else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+ {
+ setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
+ }
+}
+
+bool LLCheckBoxToastPanel::setCheckBox(const std::string& check_title,
+ const std::string& check_control,
+ const commit_signal_t::slot_type& cb,
+ const S32 &h_pad,
+ const S32 &v_pad,
+ LLView *parent_view)
+{
+ mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
+
+ if (!mCheck)
+ {
+ return false;
+ }
+
+ const LLFontGL* font = mCheck->getFont();
+ const S32 LINE_HEIGHT = font->getLineHeight();
+
+ std::vector<std::string> lines;
+ boost::split(lines, check_title, boost::is_any_of("\n"));
+
+ // Extend dialog for "check next time"
+ S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * h_pad;
+ S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
+ max_msg_width = llmax(max_msg_width, check_width);
+ S32 dialog_width = max_msg_width + 2 * h_pad;
+
+ S32 dialog_height = LLToastPanel::getRect().getHeight();
+ dialog_height += LINE_HEIGHT * lines.size();
+ dialog_height += LINE_HEIGHT / 2;
+
+ LLToastPanel::reshape(dialog_width, dialog_height, FALSE);
+
+ S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
+
+ // set check_box's attributes
+ LLRect check_rect;
+ // if we are part of the toast, we need to leave space for buttons
+ S32 msg_y = v_pad + (parent_view ? 0 : (BTN_HEIGHT + LINE_HEIGHT / 2));
+ mCheck->setRect(check_rect.setOriginAndSize(msg_x, msg_y, max_msg_width, LINE_HEIGHT*lines.size()));
+ mCheck->setLabel(check_title);
+ mCheck->setCommitCallback(cb);
+
+ if (parent_view)
+ {
+ // assume that width and height autoadjusts to toast
+ parent_view->addChild(mCheck);
+ }
+ else
+ {
+ LLToastPanel::addChild(mCheck);
+ }
+
+ return true;
+}
+
+void LLCheckBoxToastPanel::onCommitCheckbox(LLUICtrl* ctrl)
+{
+ BOOL check = ctrl->getValue().asBoolean();
+ if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+ {
+ // question was "show again" so invert value to get "ignore"
+ check = !check;
+ }
+ mNotification->setIgnored(check);
+}
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 6a9b72a5ae..f4c758ade9 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -64,4 +64,23 @@ protected:
S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
};
+class LLCheckBoxCtrl;
+
+// Wrapper with support for 'don't ask again' checkbox
+class LLCheckBoxToastPanel : public LLToastPanel
+{
+public:
+ LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf);
+ virtual ~LLCheckBoxToastPanel() {};
+
+ // set checkboxes acording to defaults from form
+ void setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
+ // set single checkbox
+ bool setCheckBox(const std::string&, const std::string&, const commit_signal_t::slot_type& cb, const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
+protected:
+ void onCommitCheckbox(LLUICtrl* ctrl);
+
+ LLCheckBoxCtrl* mCheck;
+};
+
#endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index b5d78f3654..c5e31ff8e6 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -115,6 +115,12 @@ BOOL LLTool::handleScrollWheel(S32 x, S32 y, S32 clicks)
return FALSE;
}
+BOOL LLTool::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ // by default, didn't handle it
+ return FALSE;
+}
+
BOOL LLTool::handleDoubleClick(S32 x,S32 y,MASK mask)
{
// LL_INFOS() << "LLTool::handleDoubleClick" << LL_ENDL;
diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h
index c5bad9d532..308983afda 100644
--- a/indra/newview/lltool.h
+++ b/indra/newview/lltool.h
@@ -57,6 +57,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index f66211ef34..7d77a8983f 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1728,6 +1728,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if(gInventory.isObjectDescendentOf(item->getUUID(), outbox_id))
{
+ // Legacy
return ACCEPT_NO;
}
@@ -2154,6 +2155,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
const LLUUID &outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
if(gInventory.isObjectDescendentOf(category->getUUID(), outbox_id))
{
+ // Legacy
return ACCEPT_NO;
}
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 3831f7d67d..a4806ceaf6 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -721,9 +721,14 @@ void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask)
!objectp->isHUDAttachment() &&
objectp->getRoot() == gAgentAvatarp->getRoot())
{
- // force focus to point in space where we were looking previously
- gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ // we are essentially editing object position
+ if (!gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // force focus to point in space where we were looking previously
+ // Example of use: follow cam scripts shouldn't affect you when movng objects arouns
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ }
}
else
{
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index f6eb290bc3..3fcf193dec 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -355,7 +355,7 @@ bool LLToolMgr::inBuildMode()
bool LLToolMgr::canAccessMarketplace()
{
- return (LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT) || gSavedSettings.getBOOL("InventoryOutboxDisplayBoth");
+ return (LLMarketplaceData::instance().getSLMStatus() != MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
void LLToolMgr::toggleMarketplace(const LLSD& sdname)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 54df5198c8..aeb8bdc496 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -208,6 +208,11 @@ BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks)
return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
}
+BOOL LLToolPie::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks);
+}
+
// True if you selected an object.
BOOL LLToolPie::handleLeftClickPick()
{
@@ -874,37 +879,9 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
static bool needs_tooltip(LLSelectNode* nodep)
{
- if (!nodep)
+ if (!nodep || !nodep->mValid)
return false;
-
- LLViewerObject* object = nodep->getObject();
- LLViewerObject *parent = (LLViewerObject *)object->getParent();
- if (object->flagHandleTouch()
- || (parent && parent->flagHandleTouch())
- || object->flagTakesMoney()
- || (parent && parent->flagTakesMoney())
- || object->flagAllowInventoryAdd()
- )
- {
- return true;
- }
-
- U8 click_action = final_click_action(object);
- if (click_action != 0)
- {
- return true;
- }
-
- if (nodep->mValid)
- {
- bool anyone_copy = anyone_copy_selection(nodep);
- bool for_sale = for_sale_selection(nodep);
- if (anyone_copy || for_sale)
- {
- return true;
- }
- }
- return false;
+ return true;
}
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 95d155a474..fe0acfe473 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -50,6 +50,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
virtual void render();
diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp
deleted file mode 100644
index b2d2fa9d77..0000000000
--- a/indra/newview/lltwitterconnect.cpp
+++ /dev/null
@@ -1,576 +0,0 @@
-/**
- * @file lltwitterconnect.h
- * @author Merov, Cho
- * @brief Connection to Twitter Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lltwitterconnect.h"
-#include "llflickrconnect.h"
-
-#include "llagent.h"
-#include "llcallingcard.h" // for LLAvatarTracker
-#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llurlaction.h"
-#include "llimagepng.h"
-#include "llimagejpeg.h"
-#include "lltrans.h"
-#include "llevents.h"
-#include "llviewerregion.h"
-
-#include "llfloaterwebcontent.h"
-#include "llfloaterreg.h"
-#include "llcorehttputil.h"
-
-boost::scoped_ptr<LLEventPump> LLTwitterConnect::sStateWatcher(new LLEventStream("TwitterConnectState"));
-boost::scoped_ptr<LLEventPump> LLTwitterConnect::sInfoWatcher(new LLEventStream("TwitterConnectInfo"));
-boost::scoped_ptr<LLEventPump> LLTwitterConnect::sContentWatcher(new LLEventStream("TwitterConnectContent"));
-
-// Local functions
-void log_twitter_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description)
-{
- // Note: 302 (redirect) is *not* an error that warrants logging
- if (status != 302)
- {
- LL_WARNS("TwitterConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL;
- }
-}
-
-void toast_user_for_twitter_success()
-{
- LLSD args;
- args["MESSAGE"] = LLTrans::getString("twitter_post_success");
- LLNotificationsUtil::add("TwitterConnect", args);
-}
-
-class LLTwitterConnectHandler : public LLCommandHandler
-{
-public:
- LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) {}
-
- bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (tokens.size() >= 1)
- {
- if (tokens[0].asString() == "connect")
- {
- if (tokens.size() >= 2 && tokens[1].asString() == "twitter")
- {
- // this command probably came from the twitter_web browser, so close it
- LLFloaterReg::hideInstance("twitter_web");
-
- // connect to twitter
- if (query_map.has("oauth_token"))
- {
- LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- else if (tokens.size() >= 2 && tokens[1].asString() == "flickr")
- {
- // this command probably came from the flickr_web browser, so close it
- LLFloaterReg::hideInstance("flickr_web");
-
- // connect to flickr
- if (query_map.has("oauth_token"))
- {
- LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier"));
- }
- return true;
- }
- }
- }
- return false;
- }
-};
-LLTwitterConnectHandler gTwitterConnectHandler;
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD body;
- if (!requestToken.empty())
- body["request_token"] = requestToken;
- if (!oauthVerifier.empty())
- body["oauth_verifier"] = oauthVerifier;
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, getTwitterConnectURL("/connection"), body, httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if ( status == LLCore::HttpStatus(HTTP_FOUND) )
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("FlickrConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openTwitterWeb(location);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << "Connection failed " << status.toString() << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- log_twitter_connect_error("Connect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-bool LLTwitterConnect::testShareStatus(LLSD &result)
-{
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status)
- return true;
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openTwitterWeb(location);
- }
- }
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
- connectToTwitter();
- }
- else
- {
- LL_WARNS("TwitterConnect") << "HTTP Status error " << status.toString() << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_POST_FAILED);
- log_twitter_connect_error("Share", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- return false;
-}
-
-void LLTwitterConnect::twitterShareCoro(std::string route, LLSD share)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getTwitterConnectURL(route, true), share, httpOpts);
-
- if (testShareStatus(result))
- {
- toast_user_for_twitter_success();
- LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_POSTED);
- }
-}
-
-void LLTwitterConnect::twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FlickrConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- std::string imageFormat;
- if (dynamic_cast<LLImagePNG*>(image.get()))
- {
- imageFormat = "png";
- }
- else if (dynamic_cast<LLImageJPEG*>(image.get()))
- {
- imageFormat = "jpg";
- }
- else
- {
- LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL;
- return;
- }
-
- // All this code is mostly copied from LLWebProfile::post()
- const std::string boundary = "----------------------------0123abcdefab";
-
- std::string contentType = "multipart/form-data; boundary=" + boundary;
- httpHeaders->append("Content-Type", contentType.c_str());
-
- LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); //
- LLCore::BufferArrayStream body(raw.get());
-
- // *NOTE: The order seems to matter.
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"status\"\r\n\r\n"
- << status << "\r\n";
-
- body << "--" << boundary << "\r\n"
- << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n"
- << "Content-Type: image/" << imageFormat << "\r\n\r\n";
-
- // Insert the image data.
- // *FIX: Treating this as a string will probably screw it up ...
- U8* image_data = image->getData();
- for (S32 i = 0; i < image->getDataSize(); ++i)
- {
- body << image_data[i];
- }
-
- body << "\r\n--" << boundary << "--\r\n";
-
- LLSD result = httpAdapter->postAndSuspend(httpRequest, getTwitterConnectURL("/share/photo", true), raw, httpOpts, httpHeaders);
-
- if (testShareStatus(result))
- {
- toast_user_for_twitter_success();
- LL_DEBUGS("TwitterConnect") << "Post successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_POSTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterDisconnectCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getTwitterConnectURL("/connection"), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status && (status != LLCore::HttpStatus(HTTP_NOT_FOUND)))
- {
- LL_WARNS("TwitterConnect") << "Disconnect failed!" << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_DISCONNECT_FAILED);
-
- log_twitter_connect_error("Disconnect", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_DEBUGS("TwitterConnect") << "Disconnect successful. " << LL_ENDL;
- clearInfo();
- setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterConnectedCoro(bool autoConnect)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setFollowRedirects(false);
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getTwitterConnectURL("/connection", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- if (status == LLCore::HttpStatus(HTTP_NOT_FOUND))
- {
- LL_DEBUGS("TwitterConnect") << "Not connected. " << LL_ENDL;
- if (autoConnect)
- {
- connectToTwitter();
- }
- else
- {
- setConnectionState(LLTwitterConnect::TWITTER_NOT_CONNECTED);
- }
- }
- else
- {
- LL_WARNS("TwitterConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL;
-
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_FAILED);
- log_twitter_connect_error("Connected", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- }
- else
- {
- LL_DEBUGS("TwitterConnect") << "Connect successful. " << LL_ENDL;
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTED);
- }
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-void LLTwitterConnect::twitterInfoCoro()
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
-
- httpOpts->setWantHeaders(true);
- httpOpts->setFollowRedirects(false);
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, getTwitterConnectURL("/info", true), httpOpts);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (status == LLCore::HttpStatus(HTTP_FOUND))
- {
- std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION];
- if (location.empty())
- {
- LL_WARNS("TwitterConnect") << "Missing Location header " << LL_ENDL;
- }
- else
- {
- openTwitterWeb(location);
- }
- }
- else if (!status)
- {
- LL_WARNS("TwitterConnect") << "Twitter Info failed: " << status.toString() << LL_ENDL;
- log_twitter_connect_error("Info", status.getStatus(), status.toString(),
- result.get("error_code"), result.get("error_description"));
- }
- else
- {
- LL_INFOS("TwitterConnect") << "Twitter: Info received" << LL_ENDL;
- result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
- storeInfo(result);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-LLTwitterConnect::LLTwitterConnect()
-: mConnectionState(TWITTER_NOT_CONNECTED),
- mConnected(false),
- mInfo(),
- mRefreshInfo(false),
- mReadFromMaster(false)
-{
-}
-
-void LLTwitterConnect::openTwitterWeb(std::string url)
-{
- LLFloaterWebContent::Params p;
- p.url(url);
- p.show_chrome(true);
- p.allow_back_forward_navigation(false);
- p.clean_browser(true);
- LLFloater *floater = LLFloaterReg::showInstance("twitter_web", p);
- //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems).
- //So when showing the internal web browser, set focus to it's containing floater "twitter_web". When a mouse event
- //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus.
- //twitter_web floater contains the "webbrowser" panel. JIRA: ACME-744
- gFocusMgr.setKeyboardFocus( floater );
-
- //LLUrlAction::openURLExternal(url);
-}
-
-std::string LLTwitterConnect::getTwitterConnectURL(const std::string& route, bool include_read_from_master)
-{
- std::string url("");
- LLViewerRegion *regionp = gAgent.getRegion();
- if (regionp)
- {
- //url = "http://pdp15.lindenlab.com/twitter/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO
- url = regionp->getCapability("TwitterConnect");
- url += route;
-
- if (include_read_from_master && mReadFromMaster)
- {
- url += "?read_from_master=true";
- }
- }
- return url;
-}
-
-void LLTwitterConnect::connectToTwitter(const std::string& request_token, const std::string& oauth_verifier)
-{
- setConnectionState(LLTwitterConnect::TWITTER_CONNECTION_IN_PROGRESS);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterConnectCoro",
- boost::bind(&LLTwitterConnect::twitterConnectCoro, this, request_token, oauth_verifier));
-}
-
-void LLTwitterConnect::disconnectFromTwitter()
-{
- setConnectionState(LLTwitterConnect::TWITTER_DISCONNECTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterDisconnectCoro",
- boost::bind(&LLTwitterConnect::twitterDisconnectCoro, this));
-}
-
-void LLTwitterConnect::checkConnectionToTwitter(bool auto_connect)
-{
- LLCoros::instance().launch("LLTwitterConnect::twitterConnectedCoro",
- boost::bind(&LLTwitterConnect::twitterConnectedCoro, this, auto_connect));
-}
-
-void LLTwitterConnect::loadTwitterInfo()
-{
- if(mRefreshInfo)
- {
- LLCoros::instance().launch("LLTwitterConnect::twitterInfoCoro",
- boost::bind(&LLTwitterConnect::twitterInfoCoro, this));
- }
-}
-
-void LLTwitterConnect::uploadPhoto(const std::string& image_url, const std::string& status)
-{
- LLSD body;
- body["image"] = image_url;
- body["status"] = status;
-
- setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
- boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/photo", body));
-}
-
-void LLTwitterConnect::uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& status)
-{
- setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterShareImageCoro",
- boost::bind(&LLTwitterConnect::twitterShareImageCoro, this, image, status));
-}
-
-void LLTwitterConnect::updateStatus(const std::string& status)
-{
- LLSD body;
- body["status"] = status;
-
- setConnectionState(LLTwitterConnect::TWITTER_POSTING);
-
- LLCoros::instance().launch("LLTwitterConnect::twitterShareCoro",
- boost::bind(&LLTwitterConnect::twitterShareCoro, this, "/share/status", body));
-}
-
-void LLTwitterConnect::storeInfo(const LLSD& info)
-{
- mInfo = info;
- mRefreshInfo = false;
-
- sInfoWatcher->post(info);
-}
-
-const LLSD& LLTwitterConnect::getInfo() const
-{
- return mInfo;
-}
-
-void LLTwitterConnect::clearInfo()
-{
- mInfo = LLSD();
-}
-
-void LLTwitterConnect::setDataDirty()
-{
- mRefreshInfo = true;
-}
-
-void LLTwitterConnect::setConnectionState(LLTwitterConnect::EConnectionState connection_state)
-{
- if(connection_state == TWITTER_CONNECTED)
- {
- mReadFromMaster = true;
- setConnected(true);
- setDataDirty();
- }
- else if(connection_state == TWITTER_NOT_CONNECTED)
- {
- setConnected(false);
- }
- else if(connection_state == TWITTER_POSTED)
- {
- mReadFromMaster = false;
- }
-
- if (mConnectionState != connection_state)
- {
- // set the connection state before notifying watchers
- mConnectionState = connection_state;
-
- LLSD state_info;
- state_info["enum"] = connection_state;
- sStateWatcher->post(state_info);
- }
-}
-
-void LLTwitterConnect::setConnected(bool connected)
-{
- mConnected = connected;
-}
diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h
deleted file mode 100644
index e77048cc35..0000000000
--- a/indra/newview/lltwitterconnect.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file lltwitterconnect.h
- * @author Merov, Cho
- * @brief Connection to Twitter Service
- *
- * $LicenseInfo:firstyear=2013&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2013, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLTWITTERCONNECT_H
-#define LL_LLTWITTERCONNECT_H
-
-#include "llsingleton.h"
-#include "llimage.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
-
-class LLEventPump;
-
-/**
- * @class LLTwitterConnect
- *
- * Manages authentication to, and interaction with, a web service allowing the
- * the viewer to post status updates and upload photos to Twitter.
- */
-class LLTwitterConnect : public LLSingleton<LLTwitterConnect>
-{
- LLSINGLETON(LLTwitterConnect);
- LOG_CLASS(LLTwitterConnect);
-public:
- enum EConnectionState
- {
- TWITTER_NOT_CONNECTED = 0,
- TWITTER_CONNECTION_IN_PROGRESS = 1,
- TWITTER_CONNECTED = 2,
- TWITTER_CONNECTION_FAILED = 3,
- TWITTER_POSTING = 4,
- TWITTER_POSTED = 5,
- TWITTER_POST_FAILED = 6,
- TWITTER_DISCONNECTING = 7,
- TWITTER_DISCONNECT_FAILED = 8
- };
-
- void connectToTwitter(const std::string& request_token = "", const std::string& oauth_verifier = ""); // Initiate the complete Twitter connection. Please use checkConnectionToTwitter() in normal use.
- void disconnectFromTwitter(); // Disconnect from the Twitter service.
- void checkConnectionToTwitter(bool auto_connect = false); // Check if an access token is available on the Twitter service. If not, call connectToTwitter().
-
- void loadTwitterInfo();
- void uploadPhoto(const std::string& image_url, const std::string& status);
- void uploadPhoto(LLPointer<LLImageFormatted> image, const std::string& status);
- void updateStatus(const std::string& status);
-
- void storeInfo(const LLSD& info);
- const LLSD& getInfo() const;
- void clearInfo();
- void setDataDirty();
-
- void setConnectionState(EConnectionState connection_state);
- void setConnected(bool connected);
- bool isConnected() { return mConnected; }
- bool isTransactionOngoing() { return ((mConnectionState == TWITTER_CONNECTION_IN_PROGRESS) || (mConnectionState == TWITTER_POSTING) || (mConnectionState == TWITTER_DISCONNECTING)); }
- EConnectionState getConnectionState() { return mConnectionState; }
-
- void openTwitterWeb(std::string url);
-
-private:
-
- std::string getTwitterConnectURL(const std::string& route = "", bool include_read_from_master = false);
-
- EConnectionState mConnectionState;
- BOOL mConnected;
- LLSD mInfo;
- bool mRefreshInfo;
- bool mReadFromMaster;
-
- static boost::scoped_ptr<LLEventPump> sStateWatcher;
- static boost::scoped_ptr<LLEventPump> sInfoWatcher;
- static boost::scoped_ptr<LLEventPump> sContentWatcher;
-
- bool testShareStatus(LLSD &result);
- void twitterConnectCoro(std::string requestToken, std::string oauthVerifier);
- void twitterDisconnectCoro();
- void twitterConnectedCoro(bool autoConnect);
- void twitterInfoCoro();
- void twitterShareCoro(std::string route, LLSD share);
- void twitterShareImageCoro(LLPointer<LLImageFormatted> image, std::string status);
-};
-
-#endif // LL_LLTWITTERCONNECT_H
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index d8526e63ca..6df849674f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1087,7 +1087,7 @@ void render_hud_attachments()
// clamp target zoom level to reasonable values
gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);
// smoothly interpolate current zoom level
- gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLSmoothInterpolation::getInterpolant(0.03f));
+ gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.getAgentHUDTargetZoom(), LLSmoothInterpolation::getInterpolant(0.03f));
if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index f475ab7d66..bbd5251ed2 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -67,8 +67,8 @@
#include "llfloaterexperiences.h"
#include "llfloaterexperiencepicker.h"
#include "llfloaterevent.h"
-#include "llfloaterflickr.h"
#include "llfloaterfonttest.h"
+#include "llfloaterforgetuser.h"
#include "llfloatergesture.h"
#include "llfloatergodtools.h"
#include "llfloatergridstatus.h"
@@ -132,7 +132,6 @@
#include "llfloatertos.h"
#include "llfloatertoybox.h"
#include "llfloatertranslationsettings.h"
-#include "llfloatertwitter.h"
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
@@ -235,6 +234,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("experience_search", "floater_experience_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterExperiencePicker>);
LLFloaterReg::add("font_test", "floater_font_test.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFontTest>);
+ LLFloaterReg::add("forget_username", "floater_forget_user.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterForgetUser>);
LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
@@ -352,11 +352,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
- LLFloaterReg::add("flickr_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
- LLFloaterReg::add("twitter_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
-
- LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
- LLFloaterReg::add("twitter", "floater_twitter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTwitter>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
LLFloaterUIPreviewUtil::registerFloater();
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 9d7da115ac..6ff02ffe66 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1745,7 +1745,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
{
std::string type_name = userdata.asString();
- if (("inbox" == type_name) || ("outbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
+ if (("inbox" == type_name) || ("category" == type_name) || ("current" == type_name) || ("outfit" == type_name) || ("my_otfts" == type_name))
{
LLFolderType::EType preferred_type = LLFolderType::lookup(type_name);
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index cf9243a871..8a597ed7e6 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -225,7 +225,7 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
iter != mAttachedObjects.end();
++iter)
{
- LLViewerObject *attached_object = (*iter);
+ LLViewerObject *attached_object = iter->get();
if (attached_object == object)
{
break;
@@ -327,7 +327,7 @@ void LLViewerJointAttachment::setAttachmentVisibility(BOOL visible)
iter != mAttachedObjects.end();
++iter)
{
- LLViewerObject *attached_obj = (*iter);
+ LLViewerObject *attached_obj = iter->get();
if (!attached_obj || attached_obj->mDrawable.isNull() ||
!(attached_obj->mDrawable->getSpatialBridge()))
continue;
@@ -366,7 +366,7 @@ S32 LLViewerJointAttachment::getNumAnimatedObjects() const
iter != mAttachedObjects.end();
++iter)
{
- const LLViewerObject *attached_object = *iter;
+ const LLViewerObject *attached_object = iter->get();
if (attached_object->isAnimatedObject())
{
count++;
@@ -384,7 +384,7 @@ void LLViewerJointAttachment::clampObjectPosition()
iter != mAttachedObjects.end();
++iter)
{
- if (LLViewerObject *attached_object = (*iter))
+ if (LLViewerObject *attached_object = iter->get())
{
// *NOTE: object can drift when hitting maximum radius
LLVector3 attachmentPos = attached_object->getPosition();
@@ -406,7 +406,7 @@ void LLViewerJointAttachment::calcLOD()
iter != mAttachedObjects.end();
++iter)
{
- if (LLViewerObject *attached_object = (*iter))
+ if (LLViewerObject *attached_object = iter->get())
{
maxarea = llmax(maxarea,attached_object->getMaxScale() * attached_object->getMidScale());
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
@@ -445,7 +445,7 @@ BOOL LLViewerJointAttachment::isObjectAttached(const LLViewerObject *viewer_obje
iter != mAttachedObjects.end();
++iter)
{
- const LLViewerObject* attached_object = (*iter);
+ const LLViewerObject* attached_object = iter->get();
if (attached_object == viewer_object)
{
return TRUE;
@@ -460,7 +460,7 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o
iter != mAttachedObjects.end();
++iter)
{
- const LLViewerObject* attached_object = (*iter);
+ const LLViewerObject* attached_object = iter->get();
if (attached_object->getAttachmentItemID() == object_id)
{
return attached_object;
@@ -475,7 +475,7 @@ LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_
iter != mAttachedObjects.end();
++iter)
{
- LLViewerObject* attached_object = (*iter);
+ LLViewerObject* attached_object = iter->get();
if (attached_object->getAttachmentItemID() == object_id)
{
return attached_object;
diff --git a/indra/newview/llviewerjointattachment.h b/indra/newview/llviewerjointattachment.h
index 9641ab4208..e5edf2c06b 100644
--- a/indra/newview/llviewerjointattachment.h
+++ b/indra/newview/llviewerjointattachment.h
@@ -95,7 +95,7 @@ public:
LLViewerObject *getAttachedObject(const LLUUID &object_id);
// list of attachments for this joint
- typedef std::vector<LLViewerObject *> attachedobjs_vec_t;
+ typedef std::vector<LLPointer<LLViewerObject> > attachedobjs_vec_t;
attachedobjs_vec_t mAttachedObjects;
protected:
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 6cfc22a4e5..99b54f66d3 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -57,6 +57,7 @@
#include "llviewercontrol.h"
#include "llviewermenufile.h" // LLFilePickerThread
#include "llviewernetwork.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
@@ -1018,6 +1019,8 @@ void LLViewerMedia::setAllMediaPaused(bool val)
}
}
+ LLParcel *agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
// Also do Parcel Media and Parcel Audio
if (!val)
{
@@ -1051,6 +1054,12 @@ void LLViewerMedia::setAllMediaPaused(bool val)
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}
+
+ // remove play choice for current parcel
+ if (agent_parcel && gAgent.getRegion())
+ {
+ LLViewerParcelAskPlay::getInstance()->resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID());
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2285,14 +2294,14 @@ void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button)
}
//////////////////////////////////////////////////////////////////////////////////////////
-void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, MASK mask)
+void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask)
{
scaleMouse(&x, &y);
mLastMouseX = x;
mLastMouseY = y;
if (mMediaSource)
{
- mMediaSource->scrollEvent(x, y, mask);
+ mMediaSource->scrollEvent(x, y, scroll_x, scroll_y, mask);
}
}
@@ -3754,7 +3763,7 @@ void LLViewerMediaImpl::setTextureID(LLUUID id)
bool LLViewerMediaImpl::isAutoPlayable() const
{
return (mMediaAutoPlay &&
- gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
+ gSavedSettings.getS32("ParcelMediaAutoPlayEnable") != 0 &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
}
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 014f9048f0..9467a138f0 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -79,7 +79,7 @@ class LLViewerMedia: public LLSingleton<LLViewerMedia>
public:
// String to get/set media autoplay in gSavedSettings
- static const char* AUTO_PLAY_MEDIA_SETTING;
+ static const char* AUTO_PLAY_MEDIA_SETTING;
static const char* SHOW_MEDIA_ON_OTHERS_SETTING;
static const char* SHOW_MEDIA_WITHIN_PARCEL_SETTING;
static const char* SHOW_MEDIA_OUTSIDE_PARCEL_SETTING;
@@ -235,7 +235,7 @@ public:
void mouseMove(const LLVector2& texture_coords, MASK mask);
void mouseDoubleClick(const LLVector2& texture_coords, MASK mask);
void mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button = 0);
- void scrollWheel(S32 x, S32 y, MASK mask);
+ void scrollWheel(S32 x, S32 y, S32 scroll_x, S32 scroll_y, MASK mask);
void mouseCapture();
void navigateBack();
@@ -320,6 +320,7 @@ public:
/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
+ /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; };
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) { return FALSE; };
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; };
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index f4a64a8e55..69ab0a71af 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -377,12 +377,7 @@ BOOL LLViewerMediaFocus::handleScrollWheel(S32 x, S32 y, S32 clicks)
LLViewerMediaImpl* media_impl = getFocusedMediaImpl();
if(media_impl && media_impl->hasMedia())
{
- // the scrollEvent() API's x and y are not the same as handleScrollWheel's x and y.
- // The latter is the position of the mouse at the time of the event
- // The former is the 'scroll amount' in x and y, respectively.
- // All we have for 'scroll amount' here is 'clicks'.
- // We're also not passed the keyboard modifier mask, but we can get that from gKeyboard.
- media_impl->getMediaPlugin()->scrollEvent(0, clicks, gKeyboard->currentMask(TRUE));
+ media_impl->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(TRUE));
retval = TRUE;
}
return retval;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index dc82719109..f859ced342 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -401,23 +401,20 @@ void set_merchant_SLM_menu()
void check_merchant_status(bool force)
{
- if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth"))
+ if (force)
{
- if (force)
- {
- // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
- }
- // Hide SLM related menu item
- gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
-
- // Also disable the toolbar button for Marketplace Listings
- LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
- gToolBarView->enableCommand(command->id(), false);
-
- // Launch an SLM test connection to get the merchant status
- LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
+ // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
}
+ // Hide SLM related menu item
+ gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
+
+ // Also disable the toolbar button for Marketplace Listings
+ LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
+ gToolBarView->enableCommand(command->id(), false);
+
+ // Launch an SLM test connection to get the merchant status
+ LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
}
void init_menus()
@@ -6672,10 +6669,10 @@ private:
static void onNearAttachObject(BOOL success, void *user_data);
void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
-
- struct CallbackData
+ class CallbackData : public LLSelectionCallbackData
{
- CallbackData(LLViewerJointAttachment* point, bool replace) : mAttachmentPoint(point), mReplace(replace) {}
+ public:
+ CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {}
LLViewerJointAttachment* mAttachmentPoint;
bool mReplace;
@@ -6716,8 +6713,8 @@ void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data)
// interpret 0 as "default location"
attachment_id = 0;
}
- LLSelectMgr::getInstance()->sendAttach(attachment_id, cb_data->mReplace);
- }
+ LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace);
+ }
LLObjectAttachToAvatar::setObjectSelection(NULL);
delete cb_data;
@@ -6840,7 +6837,7 @@ class LLAttachmentDetachFromPoint : public view_listener_t
iter != attachment->mAttachedObjects.end();
iter++)
{
- LLViewerObject *attached_object = (*iter);
+ LLViewerObject *attached_object = iter->get();
ids_to_remove.push_back(attached_object->getAttachmentItemID());
}
}
@@ -6866,7 +6863,7 @@ static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object)
{
LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
@@ -6979,7 +6976,7 @@ class LLAttachmentEnableDrop : public view_listener_t
{
// make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
// so check to see if the item is in the inventory already
- item = gInventory.getItem((*attachment_iter)->getAttachmentItemID());
+ item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID());
if (!item)
{
// Item does not exist, make an observer to enable the pie menu
@@ -7361,7 +7358,7 @@ void handle_dump_attachments(void*)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
BOOL visible = (attached_object != NULL &&
attached_object->mDrawable.notNull() &&
!attached_object->mDrawable->isRenderType(0));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index b0ad81614a..fe67182bc4 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1671,8 +1671,20 @@ void LLOfferInfo::fromLLSD(const LLSD& params)
*this = params;
}
-void LLOfferInfo::send_auto_receive_response(void)
-{
+void LLOfferInfo::sendReceiveResponse(bool accept, const LLUUID &destination_folder_id)
+{
+ if(IM_INVENTORY_OFFERED == mIM)
+ {
+ // add buddy to recent people list
+ LLRecentPeople::instance().add(mFromID);
+ }
+
+ if (mTransactionID.isNull())
+ {
+ // Not provided, message won't work
+ return;
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -1691,23 +1703,42 @@ void LLOfferInfo::send_auto_receive_response(void)
msg->addU32Fast(_PREHASH_ParentEstateID, 0);
msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
-
- // Auto Receive Message. The math for the dialog works, because the accept
+
+ // ACCEPT. The math for the dialog works, because the accept
// for inventory_offered, task_inventory_offer or
// group_notice_inventory is 1 greater than the offer integer value.
// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
- sizeof(mFolderID.mData));
- // send the message
- msg->sendReliable(mHost);
-
- if(IM_INVENTORY_OFFERED == mIM)
+ // Decline for inventory_offered, task_inventory_offer or
+ // group_notice_inventory is 2 greater than the offer integer value.
+
+ EInstantMessage im = mIM;
+ if (mIM == IM_GROUP_NOTICE_REQUESTED)
{
- // add buddy to recent people list
- LLRecentPeople::instance().add(mFromID);
+ // Request has no responder dialogs
+ im = IM_GROUP_NOTICE;
+ }
+
+ if (accept)
+ {
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(im + 1));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(destination_folder_id.mData),
+ sizeof(destination_folder_id.mData));
}
+ else
+ {
+ msg->addU8Fast(_PREHASH_Dialog, (U8)(im + 2));
+ msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
+ }
+ // send the message
+ msg->sendReliable(mHost);
+
+ // transaction id is usable only once
+ // Note: a bit of a hack, clicking group notice attachment will not close notice
+ // so we reset no longer usable transaction id to know not to send message again
+ // Once capabilities for responses will be implemented LLOfferInfo will have to
+ // remember that it already responded in another way and ignore IOR_DECLINE
+ mTransactionID.setNull();
}
void LLOfferInfo::handleRespond(const LLSD& notification, const LLSD& response)
@@ -1767,7 +1798,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
from_string = chatHistory_string = mFromName;
-
+
+ // accept goes to proper folder, decline gets accepted to trash, muted gets declined
+ bool accept_to_trash = true;
+
LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm());
switch(button)
@@ -1799,11 +1833,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
}
break;
case IM_GROUP_NOTICE:
+ case IM_GROUP_NOTICE_REQUESTED:
opener = new LLOpenTaskGroupOffer;
- send_auto_receive_response();
+ sendReceiveResponse(true, mFolderID);
break;
case IM_TASK_INVENTORY_OFFERED:
- case IM_GROUP_NOTICE_REQUESTED:
// This is an offer from a task or group.
// We don't use a new instance of an opener
// We instead use the singular observer gOpenTaskOffer
@@ -1838,6 +1872,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
{
modified_form->setElementEnabled("Mute", false);
}
+ accept_to_trash = false; // for notices, but IOR_MUTE normally doesn't happen for notices
// MUTE falls through to decline
case IOR_DECLINE:
{
@@ -1851,21 +1886,32 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
{
chat.mMuted = TRUE;
+ accept_to_trash = false; // will send decline message
}
// *NOTE dzaporozhan
// Disabled logging to old chat floater to fix crash in group notices - EXT-4149
// LLFloaterChat::addChatHistory(chat);
- LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
- discard_agent_offer->startFetch();
- if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))
+ if (mObjectID.notNull()) //make sure we can discard
{
- discard_agent_offer->done();
+ LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
+ discard_agent_offer->startFetch();
+ if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))
+ {
+ discard_agent_offer->done();
+ }
+ else
+ {
+ opener = discard_agent_offer;
+ }
}
- else
+ else if (mIM == IM_GROUP_NOTICE)
{
- opener = discard_agent_offer;
+ // group notice needs to request object to trash so that user will see it later
+ // Note: muted agent offers go to trash, not sure if we should do same for notices
+ LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ sendReceiveResponse(accept_to_trash, trash);
}
if (modified_form != NULL)
@@ -1878,9 +1924,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
}
default:
// close button probably
- // The item has already been fetched and is in your inventory, we simply won't highlight it
+ // In case of agent offers item has already been fetched and is in your inventory, we simply won't highlight it
// OR delete it if the notification gets killed, since we don't want that to be a vector for
// losing inventory offers.
+ if (mIM == IM_GROUP_NOTICE)
+ {
+ LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ sendReceiveResponse(true, trash);
+ }
break;
}
@@ -1925,29 +1976,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
}
}
}
-
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_MessageBlock);
- msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
- msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
- msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
- msg->addUUIDFast(_PREHASH_ID, mTransactionID);
- msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
- std::string name;
- LLAgentUI::buildFullname(name);
- msg->addStringFast(_PREHASH_FromAgentName, name);
- msg->addStringFast(_PREHASH_Message, "");
- msg->addU32Fast(_PREHASH_ParentEstateID, 0);
- msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
- msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
- LLInventoryObserver* opener = NULL;
-
+
std::string from_string; // Used in the pop-up.
std::string chatHistory_string; // Used in chat history.
+
if (mFromObject == TRUE)
{
if (mFromGroup)
@@ -1991,23 +2023,15 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
from_string = chatHistory_string = mFromName;
}
- bool is_do_not_disturb = gAgent.isDoNotDisturb();
-
+ LLUUID destination;
+ bool accept = true;
+
+ // If user accepted, accept to proper folder, if user discarded, accept to trash.
switch(button)
{
case IOR_ACCEPT:
- // ACCEPT. The math for the dialog works, because the accept
- // for inventory_offered, task_inventory_offer or
- // group_notice_inventory is 1 greater than the offer integer value.
- // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
- // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
- sizeof(mFolderID.mData));
- // send the message
- msg->sendReliable(mHost);
-
- //don't spam them if they are getting flooded
+ destination = mFolderID;
+ //don't spam user if flooded
if (check_offer_throttle(mFromName, true))
{
log_message = "<nolink>" + chatHistory_string + "</nolink> " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");
@@ -2015,66 +2039,24 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
args["MESSAGE"] = log_message;
LLNotificationsUtil::add("SystemMessageTip", args);
}
-
- // we will want to open this item when it comes back.
- LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
- << LL_ENDL;
- switch (mIM)
- {
- case IM_TASK_INVENTORY_OFFERED:
- case IM_GROUP_NOTICE:
- case IM_GROUP_NOTICE_REQUESTED:
- {
- // This is an offer from a task or group.
- // We don't use a new instance of an opener
- // We instead use the singular observer gOpenTaskOffer
- // Since it already exists, we don't need to actually do anything
- }
- break;
- default:
- LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
- break;
- } // end switch (mIM)
break;
-
case IOR_MUTE:
// MUTE falls through to decline
+ accept = false;
case IOR_DECLINE:
- // DECLINE. The math for the dialog works, because the decline
- // for inventory_offered, task_inventory_offer or
- // group_notice_inventory is 2 greater than the offer integer value.
- // Generates IM_INVENTORY_DECLINED, IM_TASK_INVENTORY_DECLINED,
- // or IM_GROUP_NOTICE_INVENTORY_DECLINED
default:
// close button probably (or any of the fall-throughs from above)
- msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
- msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
- // send the message
- msg->sendReliable(mHost);
-
- if (gSavedSettings.getBOOL("LogInventoryDecline"))
- {
- LLStringUtil::format_map_t log_message_args;
- log_message_args["DESC"] = mDesc;
- log_message_args["NAME"] = mFromName;
- log_message = LLTrans::getString("InvOfferDecline", log_message_args);
-
- LLSD args;
- args["MESSAGE"] = log_message;
- LLNotificationsUtil::add("SystemMessageTip", args);
- }
-
- if (is_do_not_disturb && (!mFromGroup && !mFromObject))
+ destination = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (accept && LLMuteList::getInstance()->isMuted(mFromID, mFromName))
{
- send_do_not_disturb_message(msg,mFromID);
+ // Note: muted offers are usually declined automatically,
+ // but user can mute object after receiving message
+ accept = false;
}
break;
}
-
- if(opener)
- {
- gInventory.addObserver(opener);
- }
+
+ sendReceiveResponse(accept, destination);
if(!mPersist)
{
@@ -4045,6 +4027,8 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
S32 num_source_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationSourceList);
+ LL_DEBUGS("Messaging", "Motion") << "Processing " << num_blocks << " Animations" << LL_ENDL;
+
//clear animation flags
avatarp->mSignaledAnimations.clear();
@@ -4057,8 +4041,6 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
- LL_DEBUGS("Messaging") << "Anim sequence ID: " << anim_sequence_id << LL_ENDL;
-
avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
// *HACK: Disabling flying mode if it has been enabled shortly before the agent
@@ -4097,6 +4079,14 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
avatarp->mAnimationSources.insert(LLVOAvatar::AnimationSourceMap::value_type(object_id, animation_id));
}
}
+ LL_DEBUGS("Messaging", "Motion") << "Anim sequence ID: " << anim_sequence_id
+ << " Animation id: " << animation_id
+ << " From block: " << object_id << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Messaging", "Motion") << "Anim sequence ID: " << anim_sequence_id
+ << " Animation id: " << animation_id << LL_ENDL;
}
}
}
@@ -5163,12 +5153,27 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
}
}
- // Error Notification can come with and without reason
- if (notificationID == "JoinGroupError" && llsdBlock.has("reason"))
- {
- LLNotificationsUtil::add("JoinGroupErrorReason", llsdBlock);
- return true;
- }
+ // Error Notification can come with and without reason
+ if (notificationID == "JoinGroupError")
+ {
+ if (llsdBlock.has("reason"))
+ {
+ LLNotificationsUtil::add("JoinGroupErrorReason", llsdBlock);
+ return true;
+ }
+ if (llsdBlock.has("group_id"))
+ {
+ LLGroupData agent_gdatap;
+ bool is_member = gAgent.getGroupData(llsdBlock["group_id"].asUUID(), agent_gdatap);
+ if (is_member)
+ {
+ LLSD args;
+ args["reason"] = LLTrans::getString("AlreadyInGroup");
+ LLNotificationsUtil::add("JoinGroupErrorReason", args);
+ return true;
+ }
+ }
+ }
LLNotificationsUtil::add(notificationID, llsdBlock);
return true;
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 2d6636f30d..78829a6a56 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -254,7 +254,7 @@ public:
/*virtual*/ void fromLLSD(const LLSD& params);
/*virtual*/ void handleRespond(const LLSD& notification, const LLSD& response);
- void send_auto_receive_response(void);
+ void send_auto_receive_response() { sendReceiveResponse(true, mFolderID); }
// TODO - replace all references with handleRespond()
bool inventory_offer_callback(const LLSD& notification, const LLSD& response);
@@ -264,6 +264,7 @@ private:
void initRespondFunctionMap();
std::string getSanitizedDescription();
+ void sendReceiveResponse(bool accept, const LLUUID &destination_folder_id);
typedef boost::function<bool (const LLSD&, const LLSD&)> respond_function_t;
typedef std::map<std::string, respond_function_t> respond_function_map_t;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index c7a77d4d2a..efd8a23a5f 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -142,6 +142,9 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
const U32 MAX_INV_FILE_READ_FAILS = 25;
const S32 MAX_OBJECT_BINARY_DATA_SIZE = 60 + 16;
+const F64 INVENTORY_UPDATE_WAIT_TIME_DESYNC = 5; // seconds
+const F64 INVENTORY_UPDATE_WAIT_TIME_OUTDATED = 1;
+
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
// static
@@ -269,6 +272,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mPixelArea(1024.f),
mInventory(NULL),
mInventorySerialNum(0),
+ mExpectedInventorySerialNum(0),
mInvRequestState(INVENTORY_REQUEST_STOPPED),
mInvRequestXFerId(0),
mInventoryDirty(FALSE),
@@ -1279,7 +1283,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
{
case (60 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1287,23 +1291,23 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
this_update_precision = 32;
// this is a terse update
// pos
- htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// vel
- htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// acc
- htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// theta
{
LLVector3 vec;
- htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
new_rot.unpackFromVector3(vec);
}
count += sizeof(LLVector3);
// omega
- htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
if (new_angv.isExactlyZero())
{
// reset rotation time
@@ -1319,7 +1323,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
break;
case(32 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1329,7 +1333,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// This is a terse 16 update, so treat data as an array of U16's.
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1340,7 +1344,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1351,7 +1355,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size)));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1362,7 +1366,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size)));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 4);
+ htolememcpy(valswizzle, &data[count], MVT_U16Quat, 4);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1374,7 +1378,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1570,7 +1574,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
{
case(60 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1578,23 +1582,23 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
// this is a terse 32 update
// pos
this_update_precision = 32;
- htonmemcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(new_pos_parent.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// vel
- htonmemcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getVelocity().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// acc
- htonmemcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)getAcceleration().mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
count += sizeof(LLVector3);
// theta
{
LLVector3 vec;
- htonmemcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy(vec.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
new_rot.unpackFromVector3(vec);
}
count += sizeof(LLVector3);
// omega
- htonmemcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
+ htolememcpy((void*)new_angv.mV, &data[count], MVT_LLVector3, sizeof(LLVector3));
if (new_angv.isExactlyZero())
{
// reset rotation time
@@ -1610,7 +1614,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
break;
case(32 + 16):
// pull out collision normal for avatar
- htonmemcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
+ htolememcpy(collision_plane.mV, &data[count], MVT_LLVector4, sizeof(LLVector4));
((LLVOAvatar*)this)->setFootPlane(collision_plane);
count += sizeof(LLVector4);
// fall through
@@ -1620,7 +1624,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
test_pos_parent.quantize16(-0.5f*size, 1.5f*size, MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1631,7 +1635,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_pos_parent.mV[VZ] = U16_to_F32(val[VZ], MIN_HEIGHT, MAX_HEIGHT);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1642,7 +1646,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1653,7 +1657,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16_to_F32(val[VZ], -size, size));
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Quat, 8);
+ htolememcpy(valswizzle, &data[count], MVT_U16Quat, 8);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -1665,7 +1669,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
new_rot.mQ[VW] = U16_to_F32(val[VW], -1.f, 1.f);
#ifdef LL_BIG_ENDIAN
- htonmemcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
+ htolememcpy(valswizzle, &data[count], MVT_U16Vec3, 6);
val = valswizzle;
#else
val = (U16 *) &data[count];
@@ -2802,13 +2806,13 @@ void LLViewerObject::doUpdateInventory(
{
// best guess.
perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), item->getPermissions().getGroup(), is_atomic);
- --mInventorySerialNum;
+ --mExpectedInventorySerialNum;
}
else
{
// dummy it up.
perm.setOwnerAndGroup(LLUUID::null, LLUUID::null, LLUUID::null, is_atomic);
- --mInventorySerialNum;
+ --mExpectedInventorySerialNum;
}
}
LLViewerInventoryItem* oldItem = item;
@@ -2816,7 +2820,11 @@ void LLViewerObject::doUpdateInventory(
new_item->setPermissions(perm);
mInventory->push_front(new_item);
doInventoryCallback();
- ++mInventorySerialNum;
+ ++mExpectedInventorySerialNum;
+ }
+ else if (is_new)
+ {
+ ++mExpectedInventorySerialNum;
}
}
@@ -2883,7 +2891,7 @@ void LLViewerObject::moveInventory(const LLUUID& folder_id,
if(!item->getPermissions().allowCopyBy(gAgent.getID()))
{
deleteInventoryItem(item_id);
- ++mInventorySerialNum;
+ ++mExpectedInventorySerialNum;
}
}
}
@@ -2974,6 +2982,9 @@ void LLViewerObject::fetchInventoryFromServer()
if (!isInventoryPending())
{
delete mInventory;
+ mInventory = NULL;
+
+ // Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -2983,11 +2994,44 @@ void LLViewerObject::fetchInventoryFromServer()
msg->addU32Fast(_PREHASH_LocalID, mLocalID);
msg->sendReliable(mRegionp->getHost());
- // this will get reset by dirtyInventory or doInventoryCallback
+ // This will get reset by doInventoryCallback or processTaskInv
mInvRequestState = INVENTORY_REQUEST_PENDING;
}
}
+void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
+{
+ // unless already waiting, drop previous request and shedule an update
+ if (mInvRequestState != INVENTORY_REQUEST_WAIT)
+ {
+ if (mInvRequestXFerId != 0)
+ {
+ // abort download.
+ gXferManager->abortRequestById(mInvRequestXFerId, -1);
+ mInvRequestXFerId = 0;
+ }
+ mInvRequestState = INVENTORY_REQUEST_WAIT; // affects isInventoryPending()
+ LLCoros::instance().launch("LLViewerObject::fetchInventoryDelayedCoro()",
+ boost::bind(&LLViewerObject::fetchInventoryDelayedCoro, mID, time_seconds));
+ }
+}
+
+//static
+void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds)
+{
+ llcoro::suspendUntilTimeout(time_seconds);
+ LLViewerObject *obj = gObjectList.findObject(task_inv);
+ if (obj)
+ {
+ // Might be good idea to prolong delay here in case expected serial changed.
+ // As it is, it will get a response with obsolete serial and will delay again.
+
+ // drop waiting state to unlock isInventoryPending()
+ obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
+ obj->fetchInventoryFromServer();
+ }
+}
+
LLControlAvatar *LLViewerObject::getControlAvatar()
{
return getRootEdit()->mControlAvatar.get();
@@ -3146,74 +3190,97 @@ S32 LLFilenameAndTask::sCount = 0;
// static
void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
{
- LLUUID task_id;
- msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
- LLViewerObject* object = gObjectList.findObject(task_id);
- if(!object)
- {
- LL_WARNS() << "LLViewerObject::processTaskInv object "
- << task_id << " does not exist." << LL_ENDL;
- return;
- }
+ LLUUID task_id;
+ msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
+ LLViewerObject* object = gObjectList.findObject(task_id);
+ if (!object)
+ {
+ LL_WARNS() << "LLViewerObject::processTaskInv object "
+ << task_id << " does not exist." << LL_ENDL;
+ return;
+ }
- LLFilenameAndTask* ft = new LLFilenameAndTask;
- ft->mTaskID = task_id;
- // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
- msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
+ LLFilenameAndTask* ft = new LLFilenameAndTask;
+ ft->mTaskID = task_id;
+ // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
+ msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
- if (ft->mSerial < object->mInventorySerialNum)
- {
- // viewer did some changes to inventory that were not saved yet.
- LL_DEBUGS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client serial: " << object->mInventorySerialNum << LL_ENDL;
- object->mInventorySerialNum = ft->mSerial;
- }
+ if (ft->mSerial == object->mInventorySerialNum
+ && ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // Loop Protection.
+ // We received same serial twice.
+ // Viewer did some changes to inventory that couldn't be saved server side
+ // or something went wrong to cause serial to be out of sync.
+ // Drop xfer and restart after some time, assign server's value as expected
+ LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL;
+ object->mExpectedInventorySerialNum = ft->mSerial;
+ object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_DESYNC);
+ }
+ else if (ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // Out of date message, record to current serial for loop protection, but do not load it
+ // Drop xfer and restart after some time
+ if (ft->mSerial < object->mInventorySerialNum)
+ {
+ LL_WARNS() << "Task serial decreased. Potentially out of order packet or desync." << LL_ENDL;
+ }
+ object->mInventorySerialNum = ft->mSerial;
+ object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
+ }
+ else if (ft->mSerial >= object->mExpectedInventorySerialNum)
+ {
+ // We received version we expected or newer. Load it.
+ object->mInventorySerialNum = ft->mSerial;
+ object->mExpectedInventorySerialNum = ft->mSerial;
- std::string unclean_filename;
- msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
- ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
+ std::string unclean_filename;
+ msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
+ ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
- if(ft->mFilename.empty())
- {
- LL_DEBUGS() << "Task has no inventory" << LL_ENDL;
- // mock up some inventory to make a drop target.
- if(object->mInventory)
- {
- object->mInventory->clear(); // will deref and delete it
- }
- else
- {
- object->mInventory = new LLInventoryObject::object_list_t();
- }
- LLPointer<LLInventoryObject> obj;
- obj = new LLInventoryObject(object->mID, LLUUID::null,
- LLAssetType::AT_CATEGORY,
- "Contents");
- object->mInventory->push_front(obj);
- object->doInventoryCallback();
- delete ft;
- return;
- }
- U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename),
- ft->mFilename, LL_PATH_CACHE,
- object->mRegionp->getHost(),
- TRUE,
- &LLViewerObject::processTaskInvFile,
- (void**)ft,
- LLXferManager::HIGH_PRIORITY);
- if (object->mInvRequestState == INVENTORY_XFER)
- {
- if (new_id > 0 && new_id != object->mInvRequestXFerId)
- {
- // we started new download.
- gXferManager->abortRequestById(object->mInvRequestXFerId, -1);
- object->mInvRequestXFerId = new_id;
- }
- }
- else
- {
- object->mInvRequestState = INVENTORY_XFER;
- object->mInvRequestXFerId = new_id;
- }
+ if (ft->mFilename.empty())
+ {
+ LL_DEBUGS() << "Task has no inventory" << LL_ENDL;
+ // mock up some inventory to make a drop target.
+ if (object->mInventory)
+ {
+ object->mInventory->clear(); // will deref and delete it
+ }
+ else
+ {
+ object->mInventory = new LLInventoryObject::object_list_t();
+ }
+ LLPointer<LLInventoryObject> obj;
+ obj = new LLInventoryObject(object->mID, LLUUID::null,
+ LLAssetType::AT_CATEGORY,
+ "Contents");
+ object->mInventory->push_front(obj);
+ object->doInventoryCallback();
+ delete ft;
+ return;
+ }
+ U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename),
+ ft->mFilename, LL_PATH_CACHE,
+ object->mRegionp->getHost(),
+ TRUE,
+ &LLViewerObject::processTaskInvFile,
+ (void**)ft,
+ LLXferManager::HIGH_PRIORITY);
+ if (object->mInvRequestState == INVENTORY_XFER)
+ {
+ if (new_id > 0 && new_id != object->mInvRequestXFerId)
+ {
+ // we started new download.
+ gXferManager->abortRequestById(object->mInvRequestXFerId, -1);
+ object->mInvRequestXFerId = new_id;
+ }
+ }
+ else
+ {
+ object->mInvRequestState = INVENTORY_XFER;
+ object->mInvRequestXFerId = new_id;
+ }
+ }
}
void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
@@ -3227,6 +3294,13 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
&& ft->mSerial >= object->mInventorySerialNum)
{
object->mInventorySerialNum = ft->mSerial;
+ LL_DEBUGS() << "Receiving inventory task file for serial " << object->mInventorySerialNum << " taskid: " << ft->mTaskID << LL_ENDL;
+ if (ft->mSerial < object->mExpectedInventorySerialNum)
+ {
+ // User managed to change something while inventory was loading
+ LL_DEBUGS() << "Processing file that is potentially out of date for task: " << ft->mTaskID << LL_ENDL;
+ }
+
if (object->loadTaskInvFile(ft->mFilename))
{
@@ -3376,7 +3450,7 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
msg->addUUIDFast(_PREHASH_ItemID, item_id);
msg->sendReliable(mRegionp->getHost());
deleteInventoryItem(item_id);
- ++mInventorySerialNum;
+ ++mExpectedInventorySerialNum;
}
bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 873b300489..e9ae26939a 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -474,6 +474,8 @@ public:
void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
+
+ // Get content except for root category
void getInventoryContents(LLInventoryObject::object_list_t& objects);
LLInventoryObject* getInventoryRoot();
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
@@ -623,9 +625,13 @@ private:
static void initObjectDataMap();
- // forms task inventory request if none are pending
+ // forms task inventory request if none are pending, marks request as pending
void fetchInventoryFromServer();
+ // forms task inventory request after some time passed, marks request as pending
+ void fetchInventoryDelayed(const F64 &time_seconds);
+ static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
+
public:
//
// Viewer-side only types - use the LL_PCODE_APP mask.
@@ -804,12 +810,14 @@ protected:
typedef std::list<LLInventoryCallbackInfo*> callback_list_t;
callback_list_t mInventoryCallbacks;
S16 mInventorySerialNum;
+ S16 mExpectedInventorySerialNum;
enum EInventoryRequestState
{
INVENTORY_REQUEST_STOPPED,
- INVENTORY_REQUEST_PENDING,
- INVENTORY_XFER
+ INVENTORY_REQUEST_WAIT, // delay before requesting
+ INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer()
+ INVENTORY_XFER // processed response from 'fetch', now doing an xfer
};
EInventoryRequestState mInvRequestState;
U64 mInvRequestXFerId;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 2bf04dc204..63e48d1dd0 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1921,7 +1921,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- if (LLViewerObject* attached_object = (*attachment_iter))
+ if (LLViewerObject* attached_object = attachment_iter->get())
{
mSelectPickList.insert(attached_object);
LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
diff --git a/indra/newview/llviewerparcelaskplay.cpp b/indra/newview/llviewerparcelaskplay.cpp
new file mode 100644
index 0000000000..d4aa783f12
--- /dev/null
+++ b/indra/newview/llviewerparcelaskplay.cpp
@@ -0,0 +1,301 @@
+/**
+ * @file llviewerparcelaskplay.cpp
+ * @brief stores data about parcel media user wants to auto-play and shows related notifications
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerparcelaskplay.h"
+
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llparcel.h"
+#include "llstartup.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llagent.h"
+#include "llsdserialize.h"
+
+#include <boost/lexical_cast.hpp>
+
+
+// class LLViewerParcelAskPlay
+
+LLViewerParcelAskPlay::LLViewerParcelAskPlay() :
+pNotification(NULL)
+{
+}
+
+LLViewerParcelAskPlay::~LLViewerParcelAskPlay()
+{
+
+}
+
+void LLViewerParcelAskPlay::initSingleton()
+{
+
+}
+void LLViewerParcelAskPlay::cleanupSingleton()
+{
+ cancelNotification();
+}
+
+void LLViewerParcelAskPlay::askToPlay(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, ask_callback cb)
+{
+ EAskPlayMode mode = getPlayMode(region_id, parcel_id);
+
+ switch (mode)
+ {
+ case ASK_PLAY_IGNORE:
+ cb(region_id, parcel_id, url, false);
+ break;
+ case ASK_PLAY_PLAY:
+ cb(region_id, parcel_id, url, true);
+ break;
+ case ASK_PLAY_ASK:
+ default:
+ {
+ // create or re-create notification
+ cancelNotification();
+
+ if (LLStartUp::getStartupState() > STATE_PRECACHE)
+ {
+ LLSD args;
+ args["URL"] = url;
+ LLSD payload;
+ payload["url"] = url; // or we can extract it from notification["substitutions"]
+ payload["parcel_id"] = parcel_id;
+ payload["region_id"] = region_id;
+ pNotification = LLNotificationsUtil::add("ParcelPlayingMedia", args, payload, boost::bind(onAskPlayResponse, _1, _2, cb));
+ }
+ else
+ {
+ // workaround: avoid 'new notifications arrived' on startup and just play
+ // (alternative: move to different channel, may be create new one...)
+ cb(region_id, parcel_id, url, true);
+ }
+ }
+ }
+}
+
+void LLViewerParcelAskPlay::cancelNotification()
+{
+ if (pNotification)
+ {
+ if (!pNotification->isCancelled())
+ {
+ // Force a responce
+ // Alternative is to mark notification as unique
+ pNotification->setIgnored(false);
+ LLNotifications::getInstance()->cancel(pNotification);
+ }
+ pNotification = NULL;
+ }
+}
+
+void LLViewerParcelAskPlay::resetCurrentParcelSetting()
+{
+ LLParcel *agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (agent_parcel && gAgent.getRegion())
+ {
+ LLViewerParcelAskPlay::resetSetting(gAgent.getRegion()->getRegionID(), agent_parcel->getLocalID());
+ }
+}
+
+void LLViewerParcelAskPlay::resetSetting(const LLUUID &region_id, const S32 &parcel_id)
+{
+ region_map_t::iterator found = mRegionMap.find(region_id);
+ if (found != mRegionMap.end())
+ {
+ found->second.erase(parcel_id);
+ }
+}
+
+void LLViewerParcelAskPlay::resetSettings()
+{
+ if (LLViewerParcelAskPlay::instanceExists())
+ {
+ LLViewerParcelAskPlay::getInstance()->mRegionMap.clear();
+ }
+ LLFile::remove(getAskPlayFilename());
+}
+
+void LLViewerParcelAskPlay::setSetting(const LLUUID &region_id, const S32 &parcel_id, const LLViewerParcelAskPlay::ParcelData &data)
+{
+ mRegionMap[region_id][parcel_id] = data;
+}
+
+LLViewerParcelAskPlay::ParcelData* LLViewerParcelAskPlay::getSetting(const LLUUID &region_id, const S32 &parcel_id)
+{
+ region_map_t::iterator found = mRegionMap.find(region_id);
+ if (found != mRegionMap.end())
+ {
+ parcel_data_map_t::iterator found_parcel = found->second.find(parcel_id);
+ if (found_parcel != found->second.end())
+ {
+ return &(found_parcel->second);
+ }
+ }
+ return NULL;
+}
+
+LLViewerParcelAskPlay::EAskPlayMode LLViewerParcelAskPlay::getPlayMode(const LLUUID &region_id, const S32 &parcel_id)
+{
+ EAskPlayMode mode = ASK_PLAY_ASK;
+ ParcelData* data = getSetting(region_id, parcel_id);
+ if (data)
+ {
+ mode = data->mMode;
+ // refresh date
+ data->mDate = LLDate::now();
+ }
+ return mode;
+}
+
+void LLViewerParcelAskPlay::setPlayMode(const LLUUID &region_id, const S32 &parcel_id, LLViewerParcelAskPlay::EAskPlayMode mode)
+{
+ ParcelData data;
+ data.mMode = mode;
+ data.mDate = LLDate::now();
+ setSetting(region_id, parcel_id, data);
+}
+
+//static
+void LLViewerParcelAskPlay::onAskPlayResponse(const LLSD& notification, const LLSD& response, ask_callback cb)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ LLUUID region_id = notification["payload"]["region_id"];
+ S32 parcel_id = notification["payload"]["parcel_id"];
+ std::string url = notification["payload"]["url"];
+
+ bool play = option == 1;
+
+ cb(region_id, parcel_id, url, play);
+
+ LLViewerParcelAskPlay *inst = getInstance();
+ bool save_choice = inst->pNotification->isIgnored(); // checkbox selected
+ if (save_choice)
+ {
+ EAskPlayMode mode = (play) ? ASK_PLAY_PLAY : ASK_PLAY_IGNORE;
+ inst->setPlayMode(region_id, parcel_id, mode);
+ }
+}
+
+// static
+std::string LLViewerParcelAskPlay::getAskPlayFilename()
+{
+ return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "media_autoplay.xml");
+}
+
+void LLViewerParcelAskPlay::loadSettings()
+{
+ mRegionMap.clear();
+
+ std::string path = getAskPlayFilename();
+ if (!gDirUtilp->fileExists(path))
+ {
+ return;
+ }
+
+ LLSD autoplay_llsd;
+ llifstream file;
+ file.open(path.c_str());
+ if (!file.is_open())
+ {
+ return;
+ }
+ S32 status = LLSDSerialize::fromXML(autoplay_llsd, file);
+ file.close();
+
+ if (status == LLSDParser::PARSE_FAILURE || !autoplay_llsd.isMap())
+ {
+ return;
+ }
+
+ for (LLSD::map_const_iterator iter_region = autoplay_llsd.beginMap();
+ iter_region != autoplay_llsd.endMap(); ++iter_region)
+ {
+ LLUUID region_id = LLUUID(iter_region->first);
+ mRegionMap[region_id] = parcel_data_map_t();
+
+ const LLSD &parcel_map = iter_region->second;
+
+ if (parcel_map.isMap())
+ {
+ for (LLSD::map_const_iterator iter_parcel = parcel_map.beginMap();
+ iter_parcel != parcel_map.endMap(); ++iter_parcel)
+ {
+ if (!iter_parcel->second.isMap())
+ {
+ break;
+ }
+ S32 parcel_id = boost::lexical_cast<S32>(iter_parcel->first.c_str());
+ ParcelData data;
+ data.mMode = (EAskPlayMode)(iter_parcel->second["mode"].asInteger());
+ data.mDate = iter_parcel->second["date"].asDate();
+ mRegionMap[region_id][parcel_id] = data;
+ }
+ }
+ }
+}
+
+void LLViewerParcelAskPlay::saveSettings()
+{
+ LLSD write_llsd;
+ std::string key;
+ for (region_map_t::iterator iter_region = mRegionMap.begin();
+ iter_region != mRegionMap.end(); ++iter_region)
+ {
+ if (iter_region->second.empty())
+ {
+ continue;
+ }
+ key = iter_region->first.asString();
+ write_llsd[key] = LLSD();
+
+ for (parcel_data_map_t::iterator iter_parcel = iter_region->second.begin();
+ iter_parcel != iter_region->second.end(); ++iter_parcel)
+ {
+ if ((iter_parcel->second.mDate.secondsSinceEpoch() + (F64SecondsImplicit)U32Days(30)) > LLTimer::getTotalSeconds())
+ {
+ // write unexpired parcels
+ std::string parcel_id = boost::lexical_cast<std::string>(iter_parcel->first);
+ write_llsd[key][parcel_id] = LLSD();
+ write_llsd[key][parcel_id]["mode"] = (LLSD::Integer)iter_parcel->second.mMode;
+ write_llsd[key][parcel_id]["date"] = iter_parcel->second.mDate;
+ }
+ }
+ }
+
+ llofstream file;
+ file.open(getAskPlayFilename().c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::toPrettyXML(write_llsd, file);
+ file.close();
+ }
+}
+
diff --git a/indra/newview/llviewerparcelaskplay.h b/indra/newview/llviewerparcelaskplay.h
new file mode 100644
index 0000000000..dc711917d2
--- /dev/null
+++ b/indra/newview/llviewerparcelaskplay.h
@@ -0,0 +1,89 @@
+/**
+ * @file llviewerparcelaskplay.h
+ * @brief stores data about parcel media user wants to auto-play and shows related notifications
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLVIEWERPARCELASKPLAY_H
+#define LLVIEWERPARCELASKPLAY_H
+
+#include "llnotificationptr.h"
+#include "lluuid.h"
+
+class LLViewerParcelAskPlay : public LLSingleton<LLViewerParcelAskPlay>
+{
+ LLSINGLETON(LLViewerParcelAskPlay);
+ ~LLViewerParcelAskPlay();
+ void initSingleton();
+ void cleanupSingleton();
+public:
+ // functor expects functor(region_id, parcel_id, url, play/stop)
+ typedef boost::function<void(const LLUUID&, const S32&, const std::string&, const bool&)> ask_callback;
+ void askToPlay(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, ask_callback cb);
+ void cancelNotification();
+
+ void resetCurrentParcelSetting();
+ void resetSetting(const LLUUID &region_id, const S32 &parcel_id);
+ static void resetSettings();
+
+ void loadSettings();
+ void saveSettings();
+
+ S32 hasData() { return !mRegionMap.empty(); } // subsitution for 'isInitialized'
+
+private:
+ enum EAskPlayMode{
+ ASK_PLAY_IGNORE = 0,
+ ASK_PLAY_PLAY,
+ ASK_PLAY_ASK
+ };
+
+ class ParcelData
+ {
+ public:
+ LLDate mDate;
+ EAskPlayMode mMode;
+ };
+
+ void setSetting(const LLUUID &region_id, const S32 &parcel_id, const ParcelData &data);
+ ParcelData* getSetting(const LLUUID &region_id, const S32 &parcel_id);
+ EAskPlayMode getPlayMode(const LLUUID &region_id, const S32 &parcel_id);
+ void setPlayMode(const LLUUID &region_id, const S32 &parcel_id, EAskPlayMode);
+
+ static void onAskPlayResponse(const LLSD& notification, const LLSD& response, ask_callback cb);
+
+ static std::string getAskPlayFilename();
+
+private:
+ // Variables
+
+ typedef std::map<S32, ParcelData> parcel_data_map_t;
+ typedef std::map<LLUUID, parcel_data_map_t> region_map_t;
+ region_map_t mRegionMap;
+
+ // only one notification is supposed to exists and be visible
+ LLNotificationPtr pNotification;
+};
+
+
+#endif // LLVIEWERPARCELASKPLAY_H
diff --git a/indra/newview/llviewerparcelmediaautoplay.cpp b/indra/newview/llviewerparcelmediaautoplay.cpp
index b5a76ccba2..36c7d436f6 100644
--- a/indra/newview/llviewerparcelmediaautoplay.cpp
+++ b/indra/newview/llviewerparcelmediaautoplay.cpp
@@ -24,17 +24,20 @@
* $/LicenseInfo$
*/
+
#include "llviewerprecompiledheaders.h"
+
#include "llviewerparcelmediaautoplay.h"
-#include "llviewerparcelmedia.h"
+
+#include "llparcel.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
-#include "llviewerregion.h"
-#include "llparcel.h"
+#include "llviewerparcelaskplay.h"
+#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
-#include "lluuid.h"
-#include "message.h"
+#include "llviewerregion.h"
#include "llviewertexturelist.h" // for texture stats
+#include "message.h"
#include "llagent.h"
#include "llmimetypes.h"
@@ -122,11 +125,28 @@ BOOL LLViewerParcelMediaAutoPlay::tick()
{
if (this_parcel)
{
- if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable"))
+ static LLCachedControl<S32> autoplay_mode(gSavedSettings, "ParcelMediaAutoPlayEnable");
+
+ switch (autoplay_mode())
{
- // and last but not least, only play when autoplay is enabled
- LLViewerParcelMedia::getInstance()->play(this_parcel);
- }
+ case 0:
+ // Disabled
+ break;
+ case 1:
+ // Play, default value for ParcelMediaAutoPlayEnable
+ LLViewerParcelMedia::getInstance()->play(this_parcel);
+ break;
+ case 2:
+ default:
+ {
+ // Ask
+ LLViewerParcelAskPlay::getInstance()->askToPlay(this_region->getRegionID(),
+ this_parcel->getLocalID(),
+ this_parcel->getMediaURL(),
+ onStartMusicResponse);
+ break;
+ }
+ }
}
mPlayed = TRUE;
@@ -139,5 +159,18 @@ BOOL LLViewerParcelMediaAutoPlay::tick()
return FALSE; // continue ticking forever please.
}
-
+//static
+void LLViewerParcelMediaAutoPlay::onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play)
+{
+ if (play)
+ {
+ LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+
+ // make sure we are still there
+ if (parcel->getLocalID() == parcel_id && gAgent.getRegion()->getRegionID() == region_id)
+ {
+ LLViewerParcelMedia::getInstance()->play(parcel);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparcelmediaautoplay.h b/indra/newview/llviewerparcelmediaautoplay.h
index 33565307f2..cf8e9a97e7 100644
--- a/indra/newview/llviewerparcelmediaautoplay.h
+++ b/indra/newview/llviewerparcelmediaautoplay.h
@@ -39,6 +39,9 @@ public:
static void playStarted();
private:
+ static void onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play);
+
+ private:
S32 mLastParcelID;
LLUUID mLastRegionID;
BOOL mPlayed;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 6cc88d0c0b..d91d0abb99 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -42,6 +42,7 @@
// Viewer includes
#include "llagent.h"
#include "llagentaccess.h"
+#include "llviewerparcelaskplay.h"
#include "llviewerwindow.h"
#include "llviewercontrol.h"
//#include "llfirstuse.h"
@@ -1832,6 +1833,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
// Only update stream if parcel changed (recreated) or music is playing (enabled)
if (!agent_parcel_update || gSavedSettings.getBOOL("MediaTentativeAutoPlay"))
{
+ LLViewerParcelAskPlay::getInstance()->cancelNotification();
std::string music_url_raw = parcel->getMusicURL();
// Trim off whitespace from front and back
@@ -1843,7 +1845,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
{
if (music_url.substr(0, 7) == "http://")
{
- optionally_start_music(music_url);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender());
+ optionally_start_music(music_url, parcel->mLocalID, region->getRegionID());
}
else
{
@@ -1864,25 +1867,61 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else
{
// Public land has no music
+ LLViewerParcelAskPlay::getInstance()->cancelNotification();
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}//if gAudiop
};
}
-void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
+//static
+void LLViewerParcelMgr::onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play)
{
- if (gSavedSettings.getBOOL("AudioStreamingMusic"))
+ if (play)
+ {
+ LL_INFOS("ParcelMgr") << "Starting parcel music " << url << LL_ENDL;
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(url);
+ }
+}
+
+void LLViewerParcelMgr::optionally_start_music(const std::string &music_url, const S32 &local_id, const LLUUID &region_id)
+{
+ static LLCachedControl<bool> streaming_music(gSavedSettings, "AudioStreamingMusic", true);
+ if (streaming_music)
{
+ static LLCachedControl<S32> autoplay_mode(gSavedSettings, "ParcelMediaAutoPlayEnable", 1);
+ static LLCachedControl<bool> tentative_autoplay(gSavedSettings, "MediaTentativeAutoPlay", true);
// only play music when you enter a new parcel if the UI control for this
// was not *explicitly* stopped by the user. (part of SL-4878)
LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel();
- if ((nearby_media_panel &&
- nearby_media_panel->getParcelAudioAutoStart()) ||
- // or they have expressed no opinion in the UI, but have autoplay on...
- (!nearby_media_panel &&
- gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
- gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
+
+ // ask mode //todo constants
+ if (autoplay_mode == 2)
+ {
+ // stop previous stream
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+
+ // if user set media to play - ask
+ if ((nearby_media_panel && nearby_media_panel->getParcelAudioAutoStart())
+ || (!nearby_media_panel && tentative_autoplay))
+ {
+ LLViewerParcelAskPlay::getInstance()->askToPlay(region_id,
+ local_id,
+ music_url,
+ onStartMusicResponse);
+ }
+ else
+ {
+ LLViewerParcelAskPlay::getInstance()->cancelNotification();
+ }
+ }
+ // autoplay
+ else if ((nearby_media_panel
+ && nearby_media_panel->getParcelAudioAutoStart())
+ // or they have expressed no opinion in the UI, but have autoplay on...
+ || (!nearby_media_panel
+ && autoplay_mode == 1
+ && tentative_autoplay))
{
LL_INFOS("ParcelMgr") << "Starting parcel music " << music_url << LL_ENDL;
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 29219843c9..288077fafc 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -268,7 +268,8 @@ public:
// *NOTE: Taken out 2005-03-21. Phoenix.
//void makeLandmarkAtSelection();
- static void optionally_start_music(const std::string& music_url);
+ static void onStartMusicResponse(const LLUUID &region_id, const S32 &parcel_id, const std::string &url, const bool &play);
+ static void optionally_start_music(const std::string &music_url, const S32 &local_id, const LLUUID &region_id);
static void processParcelOverlay(LLMessageSystem *msg, void **user_data);
static void processParcelProperties(LLMessageSystem *msg, void **user_data);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5b227c641b..75e707aaa3 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -2895,8 +2895,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("EstateAccess");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
- capabilityNames.append("FlickrConnect");
- capabilityNames.append("TwitterConnect");
capabilityNames.append("FetchLib2");
capabilityNames.append("FetchLibDescendents2");
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 15b2ac8acf..85d87a43af 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -359,16 +359,19 @@ void update_statistics()
record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Sort Draw State")));
record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Render Geometry")));
- LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
- if (cdp)
+ if (gAgent.getRegion() && isAgentAvatarValid())
{
- sample(LLStatViewer::SIM_PING, F64Milliseconds (cdp->getPingDelay()));
- gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
- gSimPingCount++;
- }
- else
- {
- sample(LLStatViewer::SIM_PING, U32Seconds(10));
+ LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
+ if (cdp)
+ {
+ sample(LLStatViewer::SIM_PING, F64Milliseconds(cdp->getPingDelay()));
+ gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
+ gSimPingCount++;
+ }
+ else
+ {
+ sample(LLStatViewer::SIM_PING, U32Seconds(10));
+ }
}
if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS))
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 61f4ee463d..f4c2e93a45 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -938,6 +938,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK
mLeftMouseDown = down;
buttonname = "Left Double Click";
break;
+ case LLMouseHandler::CLICK_BUTTON4:
+ buttonname = "Button 4";
+ break;
+ case LLMouseHandler::CLICK_BUTTON5:
+ buttonname = "Button 5";
+ break;
}
LLView::sMouseHandlerMessage.clear();
@@ -1115,7 +1121,7 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m
BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = TRUE;
- LLVoiceClient::getInstance()->middleMouseState(true);
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true);
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
// Always handled as far as the OS is concerned.
@@ -1267,17 +1273,47 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
return result;
}
-
+
BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask)
{
BOOL down = FALSE;
- LLVoiceClient::getInstance()->middleMouseState(false);
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false);
handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
// Always handled as far as the OS is concerned.
return TRUE;
}
+BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down)
+{
+ switch (button)
+ {
+ case 4:
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down);
+ handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down);
+ break;
+ case 5:
+ LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down);
+ handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down);
+ break;
+ default:
+ break;
+ }
+
+ // Always handled as far as the OS is concerned.
+ return TRUE;
+}
+
+BOOL LLViewerWindow::handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button)
+{
+ return handleOtherMouse(window, pos, mask, button, TRUE);
+}
+
+BOOL LLViewerWindow::handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button)
+{
+ return handleOtherMouse(window, pos, mask, button, FALSE);
+}
+
// WARNING: this is potentially called multiple times per frame
void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask)
{
@@ -1551,6 +1587,11 @@ void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks)
handleScrollWheel( clicks );
}
+void LLViewerWindow::handleScrollHWheel(LLWindow *window, S32 clicks)
+{
+ handleScrollHWheel(clicks);
+}
+
void LLViewerWindow::handleWindowBlock(LLWindow *window)
{
send_agent_pause();
@@ -2966,6 +3007,49 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
return;
}
+void LLViewerWindow::handleScrollHWheel(S32 clicks)
+{
+ LLUI::getInstance()->resetMouseIdleTimer();
+
+ LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
+ if (mouse_captor)
+ {
+ S32 local_x;
+ S32 local_y;
+ mouse_captor->screenPointToLocal(mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y);
+ mouse_captor->handleScrollHWheel(local_x, local_y, clicks);
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Horizontal Wheel handled by captor " << mouse_captor->getName() << LL_ENDL;
+ }
+ return;
+ }
+
+ LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
+ if (top_ctrl)
+ {
+ S32 local_x;
+ S32 local_y;
+ top_ctrl->screenPointToLocal(mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y);
+ if (top_ctrl->handleScrollHWheel(local_x, local_y, clicks)) return;
+ }
+
+ if (mRootView->handleScrollHWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks))
+ {
+ if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Horizontal Wheel" << LLView::sMouseHandlerMessage << LL_ENDL;
+ }
+ return;
+ }
+ else if (LLView::sDebugMouseHandling)
+ {
+ LL_INFOS() << "Scroll Horizontal Wheel not handled by view" << LL_ENDL;
+ }
+
+ return;
+}
+
void LLViewerWindow::addPopup(LLView* popup)
{
if (mPopupView)
@@ -3329,7 +3413,8 @@ void LLViewerWindow::updateUI()
LLRect screen_sticky_rect = mRootView->getLocalRect();
S32 local_x, local_y;
- if (gSavedSettings.getBOOL("DebugShowXUINames"))
+ static LLCachedControl<bool> debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0);
+ if (debug_show_xui_names)
{
LLToolTip::Params params;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 071a3632dd..385bbd57e5 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -192,7 +192,10 @@ public:
/*virtual*/ BOOL handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ BOOL handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
- /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
+ /*virtual*/ BOOL handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
+ /*virtual*/ BOOL handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button);
+ BOOL handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down);
/*virtual*/ LLWindowCallbacks::DragNDropResult handleDragNDrop(LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data);
void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
@@ -205,6 +208,7 @@ public:
/*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item);
/*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height);
/*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks);
+ /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks);
/*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask);
/*virtual*/ void handleWindowBlock(LLWindow *window);
/*virtual*/ void handleWindowUnblock(LLWindow *window);
@@ -323,6 +327,7 @@ public:
BOOL handleKey(KEY key, MASK mask);
BOOL handleKeyUp(KEY key, MASK mask);
void handleScrollWheel (S32 clicks);
+ void handleScrollHWheel (S32 clicks);
// add and remove views from "popup" layer
void addPopup(LLView* popup);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ca1216b89d..3b51d07f96 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -78,6 +78,7 @@
#include "llselectmgr.h"
#include "llsprite.h"
#include "lltargetingmotion.h"
+#include "lltoolmgr.h"
#include "lltoolmorph.h"
#include "llviewercamera.h"
#include "llviewertexlayer.h"
@@ -1376,7 +1377,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
++attachment_iter)
{
// Don't we need to look at children of attached_object as well?
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && !attached_object->isHUDAttachment())
{
const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object);
@@ -1799,7 +1800,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && !attached_object->isDead() && attachment->getValid())
{
@@ -1863,7 +1864,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
{
@@ -2687,7 +2688,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
BOOL visibleAttachment = visible || (attached_object &&
!(attached_object->mDrawable->getSpatialBridge() &&
attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
@@ -4568,7 +4569,7 @@ void LLVOAvatar::updateVisibility()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- if (LLViewerObject *attached_object = (*attachment_iter))
+ if (LLViewerObject *attached_object = attachment_iter->get())
{
if(attached_object->mDrawable->isVisible())
{
@@ -5646,7 +5647,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
}
else
{
- LL_WARNS() << "Failed to start motion!" << LL_ENDL;
+ LL_WARNS("Motion") << "Failed to start motion!" << LL_ENDL;
}
}
else //stop animation
@@ -5753,13 +5754,13 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
{
- LL_DEBUGS() << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
LLUUID remap_id = remapMotionID(id);
if (remap_id != id)
{
- LL_DEBUGS() << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
}
if (isSelf() && remap_id == ANIM_AGENT_AWAY)
@@ -5775,13 +5776,13 @@ BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
{
- LL_DEBUGS() << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL;
LLUUID remap_id = remapMotionID(id);
if (remap_id != id)
{
- LL_DEBUGS() << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
+ LL_DEBUGS("Motion") << "motion resultant " << remap_id.asString() << " " << gAnimLibrary.animationName(remap_id) << LL_ENDL;
}
if (isSelf())
@@ -5992,7 +5993,7 @@ void LLVOAvatar::rebuildAttachmentOverrides()
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
{
- LLViewerObject *vo = *at_it;
+ LLViewerObject *vo = at_it->get();
// Attached animated objects affect joints in their control
// avs, not the avs to which they are attached.
if (vo && !vo->isAnimatedObject())
@@ -6043,7 +6044,7 @@ void LLVOAvatar::updateAttachmentOverrides()
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
{
- LLViewerObject *vo = *at_it;
+ LLViewerObject *vo = at_it->get();
// Attached animated objects affect joints in their control
// avs, not the avs to which they are attached.
if (vo && !vo->isAnimatedObject())
@@ -7146,29 +7147,33 @@ void LLVOAvatar::lazyAttach()
for (U32 i = 0; i < mPendingAttachment.size(); i++)
{
LLPointer<LLViewerObject> cur_attachment = mPendingAttachment[i];
- if (cur_attachment->mDrawable)
+ // Object might have died while we were waiting for drawable
+ if (!cur_attachment->isDead())
{
- if (isSelf())
+ if (cur_attachment->mDrawable)
{
- const LLUUID& item_id = cur_attachment->getAttachmentItemID();
- LLViewerInventoryItem *item = gInventory.getItem(item_id);
- LL_DEBUGS("Avatar") << "ATT attaching object "
- << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ if (isSelf())
+ {
+ const LLUUID& item_id = cur_attachment->getAttachmentItemID();
+ LLViewerInventoryItem *item = gInventory.getItem(item_id);
+ LL_DEBUGS("Avatar") << "ATT attaching object "
+ << (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+ }
+ if (!attachObject(cur_attachment))
+ { // Drop it
+ LL_WARNS() << "attachObject() failed for "
+ << cur_attachment->getID()
+ << " item " << cur_attachment->getAttachmentItemID()
+ << LL_ENDL;
+ // MAINT-3312 backout
+ //still_pending.push_back(cur_attachment);
+ }
}
- if (!attachObject(cur_attachment))
- { // Drop it
- LL_WARNS() << "attachObject() failed for "
- << cur_attachment->getID()
- << " item " << cur_attachment->getAttachmentItemID()
- << LL_ENDL;
- // MAINT-3312 backout
- //still_pending.push_back(cur_attachment);
+ else
+ {
+ still_pending.push_back(cur_attachment);
}
}
- else
- {
- still_pending.push_back(cur_attachment);
- }
}
mPendingAttachment = still_pending;
@@ -7188,7 +7193,7 @@ void LLVOAvatar::resetHUDAttachments()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && attached_object->mDrawable.notNull())
{
gPipeline.markMoved(attached_object->mDrawable);
@@ -7320,6 +7325,19 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
{
gAgentCamera.changeCameraToMouselook();
}
+
+ if (gAgentCamera.getFocusOnAvatar() && LLToolMgr::getInstance()->inEdit())
+ {
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
+ if (node && node->mValid)
+ {
+ LLViewerObject* root_object = node->getObject();
+ if (root_object == sit_object)
+ {
+ LLFloaterTools::sPreviousFocusOnAvatar = true;
+ }
+ }
+ }
}
if (mDrawable.isNull())
@@ -7505,7 +7523,7 @@ LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) cons
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *attached_object = (*attachment_iter);
+ LLViewerObject *attached_object = attachment_iter->get();
if (attached_object &&
attached_object->getID() == target_id)
{
@@ -7927,7 +7945,7 @@ void LLVOAvatar::updateMeshVisibility()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject *objectp = (*attachment_iter);
+ LLViewerObject *objectp = attachment_iter->get();
if (objectp)
{
for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
@@ -8244,7 +8262,7 @@ void LLVOAvatar::updateMeshTextures()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- LLViewerObject* attached_object = (*attachment_iter);
+ LLViewerObject* attached_object = attachment_iter->get();
if (attached_object && !attached_object->isDead())
{
attached_object->refreshBakeTexture();
@@ -8482,7 +8500,7 @@ LLBBox LLVOAvatar::getHUDBBox() const
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
if (attached_object == NULL)
{
LL_WARNS() << "HUD attached object is NULL!" << LL_ENDL;
@@ -9848,7 +9866,7 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes)
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin();
attach_iter != attach_end; ++attach_iter)
{
- LLViewerObject* attached_object = *attach_iter;
+ LLViewerObject* attached_object = attach_iter->get();
LLVOVolume *volume = dynamic_cast<LLVOVolume*>(attached_object);
if (volume)
{
@@ -10366,7 +10384,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- const LLViewerObject* attached_object = (*attachment_iter);
+ const LLViewerObject* attached_object = attachment_iter->get();
accountRenderComplexityForObject(attached_object, max_attachment_complexity,
textures, cost, hud_complexity_list);
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index d8c8cb0461..cc590fc947 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -125,7 +125,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump)
mPTTDirty(true),
mPTT(true),
mUsePTT(true),
- mPTTIsMiddleMouse(false),
+ mPTTMouseButton(0),
mPTTKey(0),
mPTTIsToggle(false),
mUserPTTState(false),
@@ -639,13 +639,22 @@ bool LLVoiceClient::getPTTIsToggle()
void LLVoiceClient::setPTTKey(std::string &key)
{
+ // Value is stored as text for readability
if(key == "MiddleMouse")
{
- mPTTIsMiddleMouse = true;
+ mPTTMouseButton = LLMouseHandler::CLICK_MIDDLE;
+ }
+ else if(key == "MouseButton4")
+ {
+ mPTTMouseButton = LLMouseHandler::CLICK_BUTTON4;
+ }
+ else if (key == "MouseButton5")
+ {
+ mPTTMouseButton = LLMouseHandler::CLICK_BUTTON5;
}
else
{
- mPTTIsMiddleMouse = false;
+ mPTTMouseButton = 0;
if(!LLKeyboard::keyFromString(key, &mPTTKey))
{
// If the call failed, don't match any key.
@@ -682,7 +691,7 @@ void LLVoiceClient::keyDown(KEY key, MASK mask)
return;
}
- if (!mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
+ if (mPTTMouseButton == 0 && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
{
bool down = gKeyboard->getKeyDown(mPTTKey);
if (down)
@@ -694,7 +703,7 @@ void LLVoiceClient::keyDown(KEY key, MASK mask)
}
void LLVoiceClient::keyUp(KEY key, MASK mask)
{
- if (!mPTTIsMiddleMouse && (key == mPTTKey))
+ if (mPTTMouseButton == 0 && (key == mPTTKey))
{
bool down = gKeyboard->getKeyDown(mPTTKey);
if (!down)
@@ -703,9 +712,9 @@ void LLVoiceClient::keyUp(KEY key, MASK mask)
}
}
}
-void LLVoiceClient::middleMouseState(bool down)
+void LLVoiceClient::updateMouseState(S32 click, bool down)
{
- if(mPTTIsMiddleMouse && LLAgent::isActionAllowed("speak"))
+ if(mPTTMouseButton == click && LLAgent::isActionAllowed("speak"))
{
inputUserControlState(down);
}
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index f95b853c31..3d04e1f0db 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -417,8 +417,8 @@ public:
// PTT key triggering
void keyDown(KEY key, MASK mask);
void keyUp(KEY key, MASK mask);
- void middleMouseState(bool down);
-
+ void updateMouseState(S32 click, bool down);
+
boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
@@ -486,7 +486,7 @@ protected:
bool mPTT;
bool mUsePTT;
- bool mPTTIsMiddleMouse;
+ S32 mPTTMouseButton;
KEY mPTTKey;
bool mPTTIsToggle;
bool mUserPTTState;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bd73c234a6..bec33790bd 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -973,7 +973,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mDeferredLight.release();
}
- F32 scale = RenderShadowResolutionScale;
+ F32 scale = llmax(0.f, RenderShadowResolutionScale);
if (shadow_detail > 0)
{ //allocate 4 sun shadow maps
@@ -8685,10 +8685,24 @@ void LLPipeline::renderDeferredLighting()
}
const LLViewerObject *vobj = drawablep->getVObj();
- if(vobj && vobj->getAvatar()
- && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()))
+ if (vobj)
{
- continue;
+ LLVOAvatar *av = vobj->getAvatar();
+ if (av)
+ {
+ if (av->isTooComplex() || av->isInMuteList() || dist_vec(av->getPosition(), LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ const LLViewerObject *root_obj = drawablep->getParent() ? drawablep->getParent()->getVObj() : vobj;
+ if (root_obj && dist_vec(root_obj->getPosition(), LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip)
+ {
+ continue;
+ }
+ }
}
LLVector4a center;
@@ -11434,7 +11448,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
- if (LLViewerObject* attached_object = (*attachment_iter))
+ if (LLViewerObject* attached_object = attachment_iter->get())
{
markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
}
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a3f5515d6f..0d6e500584 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -133,7 +133,6 @@ with the same filename but different name
<texture name="Command_Chat_Icon" file_name="toolbar_icons/chat.png" preload="true" />
<texture name="Command_Compass_Icon" file_name="toolbar_icons/land.png" preload="true" />
<texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" />
- <texture name="Command_Flickr_Icon" file_name="toolbar_icons/flickr.png" preload="true" />
<texture name="Command_Gestures_Icon" file_name="toolbar_icons/gestures.png" preload="true" />
<texture name="Command_Grid_Status_Icon" file_name="toolbar_icons/grid_status.png" preload="true" />
<texture name="Command_HowTo_Icon" file_name="toolbar_icons/howto.png" preload="true" />
@@ -144,7 +143,6 @@ with the same filename but different name
<texture name="Command_MiniCart_Icon" file_name="toolbar_icons/mini_cart.png" preload="true" />
<texture name="Command_MiniMap_Icon" file_name="toolbar_icons/mini_map.png" preload="true" />
<texture name="Command_Move_Icon" file_name="toolbar_icons/move.png" preload="true" />
- <texture name="Command_Outbox_Icon" file_name="toolbar_icons/outbox.png" preload="true" />
<texture name="Command_People_Icon" file_name="toolbar_icons/people.png" preload="true" />
<texture name="Command_Picks_Icon" file_name="toolbar_icons/picks.png" preload="true" />
<texture name="Command_Places_Icon" file_name="toolbar_icons/places.png" preload="true" />
@@ -154,7 +152,6 @@ with the same filename but different name
<texture name="Command_Search_Icon" file_name="toolbar_icons/search.png" preload="true" />
<texture name="Command_Snapshot_Icon" file_name="toolbar_icons/snapshot.png" preload="true" />
<texture name="Command_Speak_Icon" file_name="toolbar_icons/speak.png" preload="true" />
- <texture name="Command_Twitter_Icon" file_name="toolbar_icons/twitter.png" preload="true" />
<texture name="Command_View_Icon" file_name="toolbar_icons/view.png" preload="true" />
<texture name="Command_Voice_Icon" file_name="toolbar_icons/nearbyvoice.png" preload="true" />
<texture name="Caret_Bottom_Icon" file_name="toolbar_icons/caret_bottom.png" preload="true" scale.left="1" scale.top="23" scale.right="15" scale.bottom="1" />
diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml
index 4dd64cba2a..8f55b3297f 100644
--- a/indra/newview/skins/default/xui/de/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/de/floater_about_land.xml
@@ -30,7 +30,7 @@
<floater.string name="Always">
Immer
</floater.string>
- <tab_container name="landtab" tab_min_width="40" width="489">
+ <tab_container name="landtab" tab_min_width="40">
<panel label="ALLGEMEIN" name="land_general_panel">
<panel.string name="new users only">
Nur neue Benutzer
diff --git a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
deleted file mode 100644
index 4070dee84c..0000000000
--- a/indra/newview/skins/default/xui/de/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="HÄNDLER-OUTBOX">
- <string name="OutboxFolderCount1">
- 1 Ordner
- </string>
- <string name="OutboxFolderCountN">
- [NUM] Ordner
- </string>
- <string name="OutboxImporting">
- Ordner übertragen...
- </string>
- <string name="OutboxInitializing">
- Initialisieren...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Laden...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Artikel hierher ziehen, um Ordner zu erstellen
- </text>
- </panel>
- <button label="In Marktplatz übertragen" name="outbox_import_btn" tool_tip="In meinen Marktplatz-Laden verschieben"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
deleted file mode 100644
index 4006022ffc..0000000000
--- a/indra/newview/skins/default/xui/de/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Legen Sie Artikel hier ab, um sie zum Verkauf in Ihrem Laden vorzubereiten"/>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 550a99fe0a..51c82c97f8 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -13,7 +13,7 @@
<item label="Mittel" name="Medium" value="1"/>
<item label="Groß" name="Large" value="2"/>
</combo_box>
- <check_box label="Blasen-Chat" name="bubble_text_chat"/>
+ <check_box label="Blasen-Chat" name="bubble_text_chat" left_delta="8"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
index ff0a6614bd..e0aa9fe4a9 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
@@ -3,10 +3,10 @@
<text name="preset_text">
(Keine)
</text>
- <text name="QualitySpeed">
+ <text name="QualitySpeed" top_delta="20">
Qualität und Geschwindigkeit:
</text>
- <text name="ShadersPrefText">
+ <text name="ShadersPrefText" top_delta="15">
Niedrig
</text>
<text name="ShadersPrefText2">
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index 9f853fd960..a143adfa06 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1800,7 +1800,7 @@ Only large parcels can be listed in search.
Music URL:
</text>
<line_editor
- follows="left|top"
+ follows="left|top|right"
height="23"
layout="topleft"
left="100"
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
index bac3ea86f1..6540f5e348 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_textures.xml
@@ -28,11 +28,13 @@
name="scroll_content_panel"
follows="left|top"
min_height="300"
+ min_width="300"
layout="topleft"
top="0"
background_visible="false"
left="0"
- height="680">
+ height="1165"
+ width="1015">
<text
type="string"
length="1"
@@ -102,6 +104,14 @@ Textures
name="hair_alpha"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Hair Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="hair_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -135,6 +145,14 @@ Textures
name="head_tattoo"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Head Unv Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="head_universal_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -160,6 +178,14 @@ Textures
name="eyes_alpha"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Eyes Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="eyes_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -225,6 +251,14 @@ Textures
name="upper_tattoo"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Upper Unv Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="upper_universal_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -298,6 +332,14 @@ Textures
name="lower_tattoo"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Lower Unv Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="lower_universal_tattoo"
+ top_delta="0"
+ width="92" />
<texture_picker
height="103"
@@ -315,6 +357,99 @@ Textures
name="skirt"
top_delta="0"
width="92" />
+ <texture_picker
+ height="103"
+ label="Skirt Tattoo"
+ layout="topleft"
+ left_pad="7"
+ name="skirt_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="Left Arm"
+ layout="topleft"
+ left="10"
+ name="leftarm-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="Left Arm Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="leftarm_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="Left Leg"
+ layout="topleft"
+ left="10"
+ name="leftleg-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="Left Leg Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="leftleg_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="AUX 1"
+ layout="topleft"
+ left="10"
+ name="aux1-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="AUX 1 Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="aux1_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="AUX 2"
+ layout="topleft"
+ left="10"
+ name="aux2-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="AUX 2 Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="aux2_tattoo"
+ top_delta="0"
+ width="92" />
+
+ <texture_picker
+ height="103"
+ label="AUX 3"
+ layout="topleft"
+ left="10"
+ name="aux3-baked"
+ top_delta="100"
+ width="92" />
+ <texture_picker
+ height="103"
+ label="AUX 3 Tattoo"
+ layout="topleft"
+ left_pad="21"
+ name="aux3_tattoo"
+ top_delta="0"
+ width="92" />
</panel>
</panel>
</scroll_container>
diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml
deleted file mode 100644
index 3b9c4894c1..0000000000
--- a/indra/newview/skins/default/xui/en/floater_flickr.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="false"
- help_topic="floater_flickr"
- layout="topleft"
- name="floater_flickr"
- save_rect="true"
- single_instance="true"
- reuse_instance="true"
- title="SHARE TO FLICKR"
- height="590"
- width="272">
- <panel
- height="590"
- width="272"
- visible="true"
- name="background"
- follows="all"
- top="0"
- left="0">
- <tab_container
- name="tabs"
- tab_group="1"
- tab_min_width="70"
- tab_height="21"
- tab_position="top"
- top="7"
- height="555"
- follows="all"
- halign="center">
- <panel
- filename="panel_flickr_photo.xml"
- class="llflickrphotopanel"
- follows="all"
- label="PHOTO"
- name="panel_flickr_photo"/>
- <panel
- filename="panel_flickr_account.xml"
- class="llflickraccountpanel"
- follows="all"
- label="ACCOUNT"
- name="panel_flickr_account"/>
- </tab_container>
- <panel
- name="connection_status_panel"
- follows="left|bottom|right"
- height="24">
- <text
- name="connection_error_text"
- type="string"
- follows="left|bottom|right"
- bottom="-5"
- left="10"
- width="250"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="DrYellow"
- font="SansSerif">
- Error
- </text>
- <loading_indicator
- follows="left|bottom|right"
- height="24"
- width="24"
- name="connection_loading_indicator"
- top_delta="-2"
- left="10"
- visible="true"/>
- <text
- name="connection_loading_text"
- type="string"
- follows="left|bottom|right"
- top_delta="2"
- left_pad="5"
- width="250"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="EmphasisColor"
- font="SansSerif">
- Loading...
- </text>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_forget_user.xml b/indra/newview/skins/default/xui/en/floater_forget_user.xml
new file mode 100644
index 0000000000..a9ec1b74a3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_forget_user.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ height="258"
+ layout="topleft"
+ name="groups"
+ help_topic="forget_username"
+ title="REMEMBERED USERNAMES"
+ width="280">
+ <scroll_list
+ height="173"
+ layout="topleft"
+ left="12"
+ name="user_list"
+ top="24"
+ width="256">
+ <scroll_list.columns
+ name="user"
+ width="248" />
+ </scroll_list>
+ <button
+ height="20"
+ label="Forget"
+ label_selected="Forget"
+ layout="topleft"
+ left_delta="90"
+ name="forget"
+ top_pad="8"
+ width="80" />
+ <check_box
+ height="20"
+ label="Also delete local data for this username"
+ layout="topleft"
+ left="15"
+ name="delete_data"
+ top_pad="5"
+ width="260"
+ tool_tip="Deletes local files: chat history, last session screenshot, browser cookies, teleport history, toolbar settings, e t c. Some of local files are shared between grids."/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
deleted file mode 100644
index 7802f65902..0000000000
--- a/indra/newview/skins/default/xui/en/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="true"
- height="440"
- help_topic="floater_merchant_outbox"
- min_width="300"
- min_height="200"
- name="floater_merchant_outbox"
- save_rect="true"
- save_visibility="false"
- reuse_instance="true"
- title="MERCHANT OUTBOX"
- width="333">
- <string name="OutboxFolderCount0"></string>
- <string name="OutboxFolderCount1">1 folder</string>
- <string name="OutboxFolderCountN">[NUM] folders</string>
- <string name="OutboxImporting">Sending folders...</string>
- <string name="OutboxInitializing">Initializing...</string>
- <panel
- name="panel_1"
- follows="all"
- layout="topleft"
- left="0"
- top="0"
- label=""
- height="440"
- width="333">
- <panel
- name="panel_2"
- follows="all"
- left="10"
- bottom="370"
- width="313"
- top="0"
- bg_opaque_color="InventoryBackgroundColor">
- <panel
- name="outbox_inventory_placeholder_panel"
- follows="all"
- layout="topleft"
- top="0"
- left="0"
- width="308"
- height="370"
- bg_opaque_color="InventoryBackgroundColor">
- <text
- name="outbox_inventory_placeholder_title"
- type="string"
- follows="top|left|right"
- layout="topleft"
- top="10"
- left="0"
- width="308"
- height="25"
- wrap="true"
- halign="center"
- font="SansSerifBold">
- Loading...
- </text>
- <text
- name="outbox_inventory_placeholder_text"
- type="string"
- follows="top|left|right"
- layout="topleft"
- top="35"
- left="0"
- width="308"
- height="130"
- wrap="true"
- halign="left" />
- </panel>
- </panel>
- <panel
- name="panel_3"
- follows="bottom|left|right"
- left="10"
- bottom="435"
- width="313"
- top="370">
- <panel
- name="outbox_generic_drag_target"
- mouse_opaque="false"
- follows="all"
- top="5"
- left="5"
- width="303"
- height="25"
- background_visible="false"
- bg_alpha_color="EmphasisColor_35"
- border="true"
- bevel_style="in"
- visible="true">
- <text
- name="text_1"
- type="string"
- follows="all"
- layout="topleft"
- top="6"
- height="20"
- left="5"
- width="293"
- halign="center"
- font="SansSerifMedium"
- font_shadow="hard"
- valign="top">
- Drag items here to create folders
- </text>
- </panel>
- <text
- name="outbox_folder_count"
- type="string"
- follows="all"
- layout="topleft"
- top="40"
- left="5"
- width="150"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- font="SansSerif"/>
- <button
- label="Send to Marketplace"
- tool_tip="Push to my Marketplace Storefront"
- is_toggle="false"
- name="outbox_import_btn"
- follows="bottom|right"
- tab_stop="false"
- halign="center"
- top="37"
- left="160"
- height="25"
- width="150"
- enabled="false" />
- </panel>
- <layout_stack name="import_progress_indicator" orientation="vertical" left="0" height="440" top="0" width="333" follows="all" visible="false">
- <layout_panel />
- <layout_panel height="24" auto_resize="false">
- <layout_stack orientation="horizontal" left="0" height="24" top="0" width="333" follows="all">
- <layout_panel width="0" />
- <layout_panel width="24" auto_resize="false">
- <loading_indicator
- height="24"
- layout="topleft"
- left="0"
- top="0"
- width="24" />
- </layout_panel>
- <layout_panel width="0" />
- </layout_stack>
- </layout_panel>
- <layout_panel />
- </layout_stack>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preview_trash.xml b/indra/newview/skins/default/xui/en/floater_preview_trash.xml
index 9e50e89ac9..3fa71e7bfe 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_trash.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_trash.xml
@@ -14,7 +14,7 @@
reuse_instance="true"
can_minimize="false">
<inventory_panel
- name="inventory_outbox"
+ name="inventory_trash"
start_folder.name="Trash"
show_empty_message="false"
start_folder.type="trash"
diff --git a/indra/newview/skins/default/xui/en/floater_twitter.xml b/indra/newview/skins/default/xui/en/floater_twitter.xml
deleted file mode 100644
index 5e8dfb8a52..0000000000
--- a/indra/newview/skins/default/xui/en/floater_twitter.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_close="true"
- can_resize="false"
- help_topic="floater_twitter"
- layout="topleft"
- name="floater_twitter"
- save_rect="true"
- single_instance="true"
- reuse_instance="true"
- title="TWITTER"
- height="462"
- width="272">
- <tab_container
- name="tabs"
- tab_group="1"
- tab_min_width="70"
- tab_height="21"
- tab_position="top"
- top="7"
- height="457"
- halign="center">
- <panel
- filename="panel_twitter_photo.xml"
- class="lltwitterphotopanel"
- follows="all"
- label="COMPOSE"
- name="panel_twitter_photo"/>
- <panel
- filename="panel_twitter_account.xml"
- class="lltwitteraccountpanel"
- follows="all"
- label="ACCOUNT"
- name="panel_twitter_account"/>
- </tab_container>
- <text
- name="connection_error_text"
- type="string"
- follows="left|bottom|right"
- bottom="-5"
- left="10"
- width="252"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="DrYellow"
- font="SansSerif">
- Error
- </text>
- <loading_indicator
- follows="left|bottom|right"
- height="24"
- width="24"
- name="connection_loading_indicator"
- top_delta="-2"
- left="10"
- visible="true"/>
- <text
- name="connection_loading_text"
- type="string"
- follows="left|bottom|right"
- top_delta="2"
- left_pad="5"
- width="223"
- height="20"
- wrap="true"
- halign="left"
- valign="center"
- text_color="EmphasisColor"
- font="SansSerif">
- Loading...
- </text>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
index c1458977ca..5cae643e44 100644
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -12,6 +12,16 @@
function="Gesture.Action.ToogleActiveState" />
</menu_item_call>
<menu_item_call
+ label="Rename"
+ layout="topleft"
+ name="rename">
+ <on_click
+ function="Gesture.Action.Rename" />
+ <on_enable
+ function="Gesture.EnableAction"
+ parameter="rename_gesture" />
+ </menu_item_call>
+ <menu_item_call
label="Copy"
layout="topleft"
name="copy_gesture">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 7bb7b5d62c..04b5d808ec 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -17,9 +17,11 @@
</menu_item_call>
<menu_item_call
label="Appearance..."
- name="ChangeOutfit">
+ name="ChangeOutfit"
+ shortcut="control|O">
<menu_item_call.on_click
- function="CustomizeAvatar" />
+ function="Floater.ToggleOrBringToFront"
+ parameter="appearance" />
<menu_item_call.on_enable
function="Edit.EnableCustomizeAvatar" />
</menu_item_call>
@@ -152,13 +154,16 @@
<menu_item_call.on_click
function="Tools.StopAllAnimations" />
</menu_item_call>
- <menu_item_call
+ <menu_item_check
label="Walk / run / fly..."
name="WalkRunFly">
- <menu_item_call.on_click
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="moveview" />
+ <menu_item_check.on_click
function="Floater.ToggleOrBringToFront"
parameter="moveview" />
- </menu_item_call>
+ </menu_item_check>
</menu>
<menu
@@ -306,21 +311,6 @@
parameter="conversation" />
</menu_item_check>
<menu_item_separator/>
- <menu_item_call
- label="Twitter..."
- name="Twitter">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="twitter"/>
- </menu_item_call>
- <menu_item_call
- label="Flickr..."
- name="Flickr">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="flickr"/>
- </menu_item_call>
- <menu_item_separator/>
<menu
label="Voice morphing"
name="VoiceMorphing"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f72767cceb..e3776cdc1a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2180,7 +2180,7 @@ Wrong chunk size in WAV file:
icon="alertmodal.tga"
name="SoundFileInvalidTooLong"
type="alertmodal">
-Audio file is too long (10 second maximum):
+Audio file is too long (30 second maximum):
[FILE]
<tag>fail</tag>
</notification>
@@ -2259,6 +2259,7 @@ Unable to create output file: [FILE]
icon="alertmodal.tga"
name="DoNotSupportBulkAnimationUpload"
type="alertmodal">
+ <unique/>
[APP_NAME] does not currently support bulk upload of BVH format animation files.
<tag>fail</tag>
</notification>
@@ -2480,6 +2481,13 @@ Sorry, but the system was unable to complete your region crossing in a timely fa
</notification>
<notification
icon="alertmodal.tga"
+ name="preexisting_tport"
+ type="alertmodal">
+ <tag>fail</tag>
+Sorry, but the system was unable to start your teleport. Please try again in a few minutes.
+ </notification>
+ <notification
+ icon="alertmodal.tga"
name="no_host"
type="alertmodal">
<tag>fail</tag>
@@ -3093,6 +3101,29 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
<notification
icon="alertmodal.tga"
+ label="Rename Gesture"
+ name="RenameGesture"
+ type="alertmodal">
+ New gesture name:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="new_name" type="text" width="300">
+ [NAME]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="RemoveFromFriends"
type="alertmodal">
<tag>friendship</tag>
@@ -3410,6 +3441,9 @@ Display settings have been set to recommended levels because of a change to the
icon="alertmodal.tga"
name="ErrorMessage"
type="alertmodal">
+ <unique>
+ <context>ERROR_MESSAGE</context>
+ </unique>
[ERROR_MESSAGE]
<tag>fail</tag>
<usetemplate
@@ -3518,6 +3552,26 @@ If this is your first time using [SECOND_LIFE], you will need to create an accou
<notification
icon="alertmodal.tga"
+ name="LoginCantRemoveUsername"
+ type="alertmodal">
+ <tag>fail</tag>
+Already remembered user can be forgotten from Me &gt; Preferences &gt; Advanced &gt; Remembered Usernames.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LoginCantRemoveCurUsername"
+ type="alertmodal">
+ <tag>confirm</tag>
+Forgetting the logged-in user requires you to log out.
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Confirm and log out"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="LoginPacketNeverReceived"
type="alertmodal">
<tag>fail</tag>
@@ -3547,6 +3601,42 @@ You can either check your Internet connection and try again in a few minutes, cl
<notification
icon="alertmodal.tga"
+ name="LoginPacketNeverReceivedNoTP"
+ type="alertmodal">
+ <tag>fail</tag>
+We&apos;re having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID].
+
+You can either check your Internet connection and try again in a few minutes or click Help to view the [SUPPORT_SITE].
+ <url option="1" name="url">
+ http://secondlife.com/support/
+ </url>
+ <form name="form">
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Help"
+ text="Help"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="LoginRemoveMultiGridUserData"
+ type="alertmodal">
+ <tag>confirm</tag>
+Local Data you are deleting is shared between multiple grids, are you sure you want to delete it?
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Confirm"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="WelcomeChooseSex"
type="alertmodal">
Your character will appear in a moment.
@@ -5999,6 +6089,34 @@ Would you like to turn off Do Not Disturb before completing this transaction?
</notification>
<notification
+ icon="notify.tga"
+ label="Parcel is Playing Media"
+ name="ParcelPlayingMedia"
+ persist="false"
+ type="notify">
+This location plays media:
+[URL]
+Would you like to play it?
+ <tag>confirm</tag>
+ <form name="form">
+ <ignore name="ignore"
+ checkbox_only="true"
+ text="Always choose this option for this land."/>
+ <button
+ ignore="Play Media"
+ index="1"
+ name="Yes"
+ text="Play"/>
+ <button
+ default="true"
+ ignore="Ignore Media"
+ index="0"
+ name="No"
+ text="Don't play"/>
+ </form>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="ConfirmDeleteProtectedCategory"
type="alertmodal">
@@ -6110,6 +6228,20 @@ Are you sure you want to permanently delete the contents of your Lost And Found?
<notification
icon="alertmodal.tga"
+ name="ConfirmReplaceLink"
+ type="alertmodal">
+You're about to replace '[TYPE]' body part link with the item which doesn't match the type.
+Are you sure you want to proceed?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before I replace link"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CopySLURL"
type="alertmodal">
The following SLurl has been copied to your clipboard:
@@ -6711,20 +6843,6 @@ Please select at least one type of content to search (General, Moderate, or Adul
<notification
icon="notify.tga"
- name="FlickrConnect"
- type="notifytip">
- [MESSAGE]
- </notification>
-
- <notification
- icon="notify.tga"
- name="TwitterConnect"
- type="notifytip">
- [MESSAGE]
- </notification>
-
- <notification
- icon="notify.tga"
name="PaymentReceived"
log_to_im="true"
persist="true"
diff --git a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
index 27c653bc35..d1175a9fe1 100644
--- a/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_classifieds_list_item.xml
@@ -32,7 +32,6 @@
width="308"/>
<texture_picker
allow_no_texture="true"
- border_enabled="true"
fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index 3509eaa285..e846edf1d4 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -144,7 +144,6 @@
follows="left|top|right"
height="100"
width="273"
- hide_scrollbar="false"
layout="topleft"
left="10"
top_pad="2"
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_account.xml b/indra/newview/skins/default/xui/en/panel_flickr_account.xml
deleted file mode 100644
index 5c2f335780..0000000000
--- a/indra/newview/skins/default/xui/en/panel_flickr_account.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<panel
- height="540"
- width="272"
- layout="topleft"
- name="panel_flickr_account">
- <string
- name="flickr_connected"
- value="You are connected to Flickr as:" />
- <string
- name="flickr_disconnected"
- value="Not connected to Flickr" />
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_caption_label"
- top="5"
- type="string">
- Not connected to Flickr.
- </text>
- <text
- layout="topleft"
- top_pad="2"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_name_label"
- parse_urls="true"
- type="string"/>
- <panel
- layout="topleft"
- name="panel_buttons"
- height="345"
- left="0">
- <button
- layout="topleft"
- follows="left|top|right"
- top_pad="9"
- visible="true"
- left="10"
- right="-10"
- height="23"
- label="Connect..."
- name="connect_btn"
- width="210">
- <commit_callback function="SocialSharing.Connect"/>
- </button>
-
- <button
- layout="topleft"
- follows="left|top|right"
- top_delta="0"
- left="10"
- right="-10"
- height="23"
- label="Disconnect"
- name="disconnect_btn"
- width="210"
- visible="false">
- <commit_callback function="SocialSharing.Disconnect"/>
- </button>
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- height="16"
- left="10"
- name="account_learn_more_label"
- top_pad="5"
- type="string">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Flickr/ta-p/2435609 Learn about posting to Flickr]
- </text>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
deleted file mode 100644
index 7fb2291423..0000000000
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ /dev/null
@@ -1,259 +0,0 @@
- <panel
- height="540"
- width="272"
- follows="all"
- layout="topleft"
- name="panel_flickr_photo">
- <combo_box
- control_name="FlickrPhotoResolution"
- follows="left|top"
- layout="topleft"
- top="7"
- left="10"
- name="resolution_combobox"
- tool_tip="Image resolution"
- height="21"
- width="124">
- <combo_box.item
- label="Current Window"
- name="CurrentWindow"
- value="[i0,i0]" />
- <combo_box.item
- label="640x480"
- name="640x480"
- value="[i640,i480]" />
- <combo_box.item
- label="800x600"
- name="800x600"
- value="[i800,i600]" />
- <combo_box.item
- label="1024x768"
- name="1024x768"
- value="[i1024,i768]" />
- </combo_box>
- <combo_box
- control_name="FlickrPhotoFilters"
- follows="left|top"
- layout="topleft"
- name="filters_combobox"
- tool_tip="Image filters"
- top_delta="0"
- left_pad="4"
- height="21"
- width="124">
- <combo_box.item
- label="No Filter"
- name="NoFilter"
- value="NoFilter" />
- </combo_box>
- <panel
- height="150"
- width="250"
- visible="true"
- name="thumbnail_placeholder"
- top_pad="5"
- follows="left|top|right"
- layout="topleft"
- right="-10"
- left="10">
- </panel>
- <text
- follows="left|top"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- height="14"
- top_pad="2"
- left="10"
- length="1"
- halign="center"
- name="working_lbl"
- translate="false"
- type="string"
- visible="true"
- width="251">
- Refreshing...
- </text>
- <view_border
- bevel_style="in"
- follows="left|top"
- layout="topleft"
- height="1"
- left="10"
- name="refresh_border"
- width="250"
- top_pad="0"/>
- <button
- follows="left|top"
- layout="topleft"
- height="23"
- label="Refresh"
- left="10"
- top_pad="5"
- name="new_snapshot_btn"
- tool_tip="Click to refresh"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.RefreshPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Preview"
- right="-10"
- top_delta="0"
- name="big_preview_btn"
- tool_tip="Click to toggle preview"
- is_toggle="true"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.BigPreview" />
- </button>
- <text
- length="1"
- follows="top|left|right"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- name="title_label"
- top_pad="10"
- type="string">
- Title:
- </text>
- <line_editor
- follows="left|top"
- layout="topleft"
- height="20"
- width="250"
- left="10"
- length="1"
- max_length="256"
- name="photo_title"
- type="string">
- </line_editor>
- <text
- length="1"
- follows="top|left|right"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- right="-10"
- name="description_label"
- top_pad="10"
- width="25"
- type="string">
- Description:
- </text>
- <text_editor
- follows="left|top"
- layout="topleft"
- height="50"
- width="249"
- left="10"
- length="1"
- max_length="700"
- name="photo_description"
- spellcheck="true"
- type="string"
- word_wrap="true">
- </text_editor>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="true"
- label="Include SL location at end of description"
- name="add_location_cb"
- left="9"
- height="16"
- top_pad="8"/>
- <text
- length="1"
- follows="top|left"
- layout="topleft"
- font="SansSerif"
- height="16"
- left="10"
- name="tags_label"
- top_pad="6"
- type="string">
- Tags:
- </text>
- <text
- length="1"
- follows="top|left"
- layout="topleft"
- font="SansSerifSmall"
- text_color="White_50"
- height="30"
- name="tags_help_label"
- left="51"
- top_pad="-16"
- type="string">
-Separate tags with spaces
-Use "" for multi-word tags
- </text>
- <text_editor
- follows="left|top"
- layout="topleft"
- height="50"
- width="249"
- left="10"
- length="1"
- max_length="700"
- name="photo_tags"
- type="string"
- word_wrap="true">
- </text_editor>
- <combo_box
- control_name="FlickrPhotoRating"
- follows="left|top"
- layout="topleft"
- top_pad="7"
- left="10"
- name="rating_combobox"
- tool_tip="Flickr content rating"
- height="21"
- width="250">
- <combo_box.item
- label="Safe Flickr rating"
- name="SafeRating"
- value="1" />
- <combo_box.item
- label="Moderate Flickr rating"
- name="ModerateRating"
- value="2" />
- <combo_box.item
- label="Restricted Flickr rating"
- name="RestrictedRating"
- value="3" />
- </combo_box>
- <button
- follows="left|top"
- layout="topleft"
- top_pad="7"
- left="10"
- height="23"
- label="Share"
- name="post_photo_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_photo_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 7759d4fdb2..ade004f9d0 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -33,7 +33,7 @@
auto_resize="false"
follows="left|right|top"
name="ui_container"
- width="1000"
+ width="1011"
left="0"
top="0"
height="172">
@@ -57,19 +57,15 @@
combo_editor.prevalidate_callback="ascii"
tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine"
name="username_combo"
- width="232">
+ width="206">
<combo_box.combo_editor
text_pad_left="8"
bg_image_always_focused="true"/>
- <combo_box.combo_button
- visible="false" />
- <combo_box.drop_down_button
- visible="false" />
</combo_box>
<line_editor
follows="left|top"
height="32"
- left_pad="-11"
+ left_pad="15"
max_length_chars="16"
text_pad_left="8"
name="password_edit"
@@ -119,36 +115,51 @@
width="120"
height="32"
left_pad="15"
- bottom_delta="0" />
+ bottom_delta="0" />
+ <text
+ follows="left|top"
+ font="SansSerifLarge"
+ font.style="BOLD"
+ text_color="EmphasisColor"
+ height="34"
+ name="sign_up_text"
+ left_pad="10"
+ width="200"
+ valign="center">
+ Sign up
+ </text>
<check_box
- control_name="RememberPassword"
follows="left|top"
font="SansSerifMedium"
left="185"
- bottom_delta="21"
+ bottom_delta="21"
height="24"
label="Remember me"
+ word_wrap="down"
check_button.bottom="3"
- name="remember_check"
- width="145" />
- <text
+ name="remember_name"
+ tool_tip="Already remembered user can be forgotten from Me &gt; Preferences &gt; Advanced &gt; Remembered Usernames."
+ width="198" />
+ <check_box
+ control_name="RememberPassword"
follows="left|top"
font="SansSerifMedium"
text_color="EmphasisColor"
height="16"
- name="forgot_password_text"
- left="408"
+ left="408"
bottom_delta="0"
- width="200">
- Forgotten password
- </text>
+ label="Remember password"
+ word_wrap="down"
+ check_button.bottom="3"
+ name="remember_password"
+ width="165" />
<combo_box
allow_text_entry="false"
font="SansSerifTiny"
follows="left|top"
height="26"
left="588"
- bottom_delta="10"
+ bottom_delta="8"
max_chars="128"
label="Select grid"
layout="topleft"
@@ -159,12 +170,13 @@
font="SansSerifMedium"
text_color="EmphasisColor"
height="16"
- name="sign_up_text"
+ name="forgot_password_text"
left="778"
- bottom_delta="-10"
- width="200">
- Sign up
- </text>
+ bottom_delta="-8"
+ width="120"
+ halign="center">
+ Password help
+ </text>
</layout_panel>
<layout_panel
height="172"
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
deleted file mode 100644
index b2d8bb874b..0000000000
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inventory_panel
- name="inventory_outbox"
- start_folder.name="Outbox"
- show_empty_message="false"
- start_folder.type="outbox"
- follows="all" layout="topleft"
- top="0" left="0" height="165" width="308"
- top_pad="0"
- bg_opaque_color="DkGray2"
- bg_alpha_color="DkGray2"
- background_visible="true"
- border="false"
- bevel_style="none"
- show_item_link_overlays="true"
- tool_tip="Drag and drop items here to prepare them for sale on your storefront"
- scroll.reserve_scroll_corner="false">
- <folder folder_arrow_image="Folder_Arrow"
- folder_indentation="8"
- item_height="20"
- item_top_pad="4"
- selection_image="Rounded_Square"
- left_pad="5"
- icon_pad="2"
- icon_width="16"
- text_pad="1"
- text_pad_right="4"
- arrow_size="12"
- max_folder_item_overlap="2"/>
- <item allow_wear="false"/>
-</inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 79d190e1e0..99c47eb825 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -103,7 +103,6 @@
height="100"
width="280"
parse_urls="true"
- hide_scrollbar="false"
layout="topleft"
left="10"
top_pad="2"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 43d580844f..4c0cdd321e 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -32,7 +32,6 @@
width="308" />
<texture_picker
allow_no_texture="true"
- border_enabled="true"
fallback_image="default_land_picture.j2c"
enabled="false"
follows="left|top"
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 4f0bb9d3b7..d0518aa245 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -143,6 +143,32 @@
name="ui_scale_slider"
top_pad="-14"
width="250" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left="33"
+ name="HUD Size:"
+ top_pad="20"
+ width="100">
+ HUD Scale:
+ </text>
+ <slider
+ control_name="HUDScaleFactor"
+ decimal_digits="2"
+ follows="left|top"
+ height="17"
+ increment="0.1"
+ initial_value="1"
+ layout="topleft"
+ left_pad="0"
+ max_val="2.0"
+ min_val="1.0"
+ name="ui_scale_slider"
+ top_pad="-14"
+ width="250" />
<check_box
control_name="ShowScriptErrors"
follows="left|top"
@@ -222,14 +248,27 @@
top_pad="5"
width="237"/>
<button
+ follows="top|left"
+ layout="topleft"
+ label="Remembered Usernames"
+ name="remembered_usernames"
height="20"
- label="Default Creation Permissions"
+ left="30"
+ top_pad="16"
+ width="200">
+ <button.commit_callback
+ function="Pref.RememberedUsernames" />
+ </button>
+ <button
+ follows="top|left"
layout="topleft"
+ label="Default Creation Permissions"
name="default_creation_permissions"
+ height="20"
left="30"
- top_pad = "20"
- width="250">
- <button.commit_callback
- function="Pref.PermsDefault" />
+ top_pad="16"
+ width="200">
+ <button.commit_callback
+ function="Pref.PermsDefault" />
</button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 9e7023d2f2..ece6c95080 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -99,6 +99,7 @@
label="Bubble Chat"
layout="topleft"
top_pad="4"
+ left_delta="0"
name="bubble_text_chat"
width="330">
</check_box>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 8f2e81b9f7..c2defdd772 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -13,6 +13,14 @@
name="middle_mouse">
Middle Mouse
</panel.string>
+ <panel.string
+ name="button4_mouse">
+ Mouse Button 4
+ </panel.string>
+ <panel.string
+ name="button5_mouse">
+ Mouse Button 5
+ </panel.string>
<slider
control_name="AudioLevelMaster"
follows="left|top"
@@ -314,17 +322,40 @@
name="enable_voice_check"
width="110"/>
<!-- -->
- <check_box
- name="media_auto_play_btn"
- control_name="ParcelMediaAutoPlayEnable"
- enabled_control="AudioStreamingMedia"
- value="true"
- follows="left|bottom|right"
- height="15"
- tool_tip="Check this to let media auto-play if it wants"
- label="Allow Media to auto-play"
- top_pad="1"
- left="25"/>
+ <text
+ follows="left|top"
+ layout="topleft"
+ height="15"
+ left="0"
+ top_pad="3"
+ width="120"
+ halign="right"
+ name="media_autoplay_label">
+ Media auto-play
+ </text>
+ <combo_box
+ control_name="ParcelMediaAutoPlayEnable"
+ enabled_control="AudioStreamingMedia"
+ follows="left|top"
+ layout="topleft"
+ height="23"
+ left_pad="7"
+ top_delta="-4"
+ name="media_auto_play_combo"
+ width="100">
+ <item
+ label="No"
+ name="autoplay_disabled"
+ value="0"/>
+ <item
+ label="Yes"
+ name="autoplay_enabled"
+ value="1"/>
+ <item
+ label="Ask"
+ name="autoplay_ask"
+ value="2"/>
+ </combo_box>
<check_box
name="media_show_on_others_btn"
control_name="MediaShowOnOthers"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 981b9ab881..2fe4cf8183 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -61,40 +61,6 @@
font="SansSerif"
halign="left"
height="22"
- image_overlay="Command_Twitter_Icon"
- image_overlay_alignment="left"
- image_top_pad="0"
- imgoverlay_label_space="10"
- label="Share to Twitter"
- layout="topleft"
- left_delta="0"
- name="send_to_twitter_btn"
- top_pad="5">
- <button.commit_callback
- function="Snapshot.SendToTwitter"/>
- </button>
- <button
- follows="left|top"
- font="SansSerif"
- halign="left"
- height="22"
- image_overlay="Command_Flickr_Icon"
- image_overlay_alignment="left"
- image_top_pad="0"
- imgoverlay_label_space="10"
- label="Share to Flickr"
- layout="topleft"
- left_delta="0"
- name="send_to_flickr_btn"
- top_pad="5">
- <button.commit_callback
- function="Snapshot.SendToFlickr"/>
- </button>
- <button
- follows="left|top"
- font="SansSerif"
- halign="left"
- height="22"
image_overlay="Snapshot_Email"
image_overlay_alignment="left"
image_top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_account.xml b/indra/newview/skins/default/xui/en/panel_twitter_account.xml
deleted file mode 100644
index b9049a0bba..0000000000
--- a/indra/newview/skins/default/xui/en/panel_twitter_account.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-<panel
- height="400"
- width="272"
- layout="topleft"
- name="panel_twitter_account">
- <string
- name="twitter_connected"
- value="You are connected to Twitter as:" />
- <string
- name="twitter_disconnected"
- value="Not connected to Twitter" />
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_caption_label"
- top="5"
- type="string">
- Not connected to Twitter.
- </text>
- <text
- layout="topleft"
- top_pad="2"
- length="1"
- follows="top|left"
- font="SansSerif"
- height="16"
- left="10"
- name="account_name_label"
- parse_urls="true"
- type="string"/>
- <panel
- layout="topleft"
- follows="top|left"
- name="panel_buttons"
- height="345"
- top_pad="3"
- left="0">
- <button
- layout="topleft"
- follows="left|top|right"
- top_pad="9"
- left="10"
- right="-10"
- visible="true"
- height="23"
- label="Connect..."
- name="connect_btn"
- width="210">
- <commit_callback function="SocialSharing.Connect"/>
- </button>
-
- <button
- layout="topleft"
- follows="left|top|right"
- top_delta="0"
- left="10"
- right="-10"
- height="23"
- label="Disconnect"
- name="disconnect_btn"
- width="210"
- visible="false">
- <commit_callback function="SocialSharing.Disconnect"/>
- </button>
- <text
- layout="topleft"
- length="1"
- follows="top|left"
- height="16"
- left="10"
- name="account_learn_more_label"
- top_pad="5"
- type="string">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Twitter/ta-p/2435453 Learn about posting to Twitter]
- </text>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
deleted file mode 100644
index 8774d09a03..0000000000
--- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml
+++ /dev/null
@@ -1,196 +0,0 @@
- <panel
- height="420"
- width="304"
- layout="topleft"
- name="panel_twitter_photo">
- <text
- length="1"
- layout="topleft"
- follows="top|left|right"
- font="SansSerif"
- height="16"
- left="10"
- name="status_label"
- top="5"
- type="string">
- What's happening?
- </text>
- <text
- length="1"
- follows="top|left"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- halign="right"
- height="16"
- width="30"
- left="227"
- name="status_counter_label"
- top="5"
- type="string">
- 140
- </text>
- <text_editor
- follows="left|top"
- layout="topleft"
- height="87"
- width="250"
- left="10"
- length="1"
- max_length="140"
- name="photo_status"
- spellcheck="true"
- type="string"
- word_wrap="true">
- </text_editor>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="true"
- label="Include SL location"
- name="add_location_cb"
- left="10"
- height="16"
- top_pad="8"/>
- <check_box
- follows="left|top"
- layout="topleft"
- initial_value="true"
- label="Include a photo"
- name="add_photo_cb"
- left="10"
- height="16"
- top_pad="1"/>
- <combo_box
- control_name="TwitterPhotoResolution"
- follows="left|top"
- layout="topleft"
- top_pad="5"
- left="10"
- name="resolution_combobox"
- tool_tip="Image resolution"
- height="21"
- width="124">
- <combo_box.item
- label="Current Window"
- name="CurrentWindow"
- value="[i0,i0]" />
- <combo_box.item
- label="640x480"
- name="640x480"
- value="[i640,i480]" />
- <combo_box.item
- label="800x600"
- name="800x600"
- value="[i800,i600]" />
- <combo_box.item
- label="1024x768"
- name="1024x768"
- value="[i1024,i768]" />
- </combo_box>
- <combo_box
- control_name="TwitterPhotoFilters"
- follows="right|top"
- layout="topleft"
- name="filters_combobox"
- tool_tip="Image filters"
- top_delta="0"
- right="-10"
- height="21"
- width="124">
- <combo_box.item
- label="No Filter"
- name="NoFilter"
- value="NoFilter" />
- </combo_box>
- <panel
- layout="topleft"
- height="150"
- width="250"
- visible="true"
- name="thumbnail_placeholder"
- top_pad="5"
- right="-10"
- follows="left|top|right"
- left="10">
- </panel>
- <text
- follows="left|top"
- layout="topleft"
- font="SansSerif"
- text_color="EmphasisColor"
- height="14"
- top_pad="2"
- left="10"
- length="1"
- halign="center"
- name="working_lbl"
- translate="false"
- type="string"
- visible="true"
- width="251">
- Refreshing...
- </text>
- <view_border
- bevel_style="in"
- follows="left|top"
- layout="topleft"
- height="1"
- left="10"
- name="refresh_border"
- width="250"
- top_pad="0"/>
- <button
- follows="left|top"
- layout="topleft"
- height="23"
- label="Refresh"
- left="10"
- top_pad="5"
- name="new_snapshot_btn"
- tool_tip="Click to refresh"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.RefreshPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Preview"
- right="-10"
- top_delta="0"
- name="big_preview_btn"
- tool_tip="Click to toggle preview"
- is_toggle="true"
- visible="true"
- width="100" >
- <button.commit_callback
- function="SocialSharing.BigPreview" />
- </button>
- <button
- follows="left|top"
- layout="topleft"
- top_pad="3"
- left="10"
- height="23"
- label="Tweet"
- name="post_photo_btn"
- width="100">
- <button.commit_callback
- function="SocialSharing.SendPhoto" />
- </button>
- <button
- follows="right|top"
- layout="topleft"
- height="23"
- label="Cancel"
- name="cancel_photo_btn"
- right="-10"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="SocialSharing.Cancel" />
- </button>
- </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9eedc45aa9..e1aff135a5 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -201,21 +201,7 @@ Please try logging in again in a minute.</string>
<string name="YouHaveBeenDisconnected">You have been disconnected from the region you were in.</string>
<string name="SentToInvalidRegion">You were sent to an invalid region.</string>
<string name="TestingDisconnect">Testing viewer disconnect</string>
-
- <!-- SLShare: Flickr and Twitter -->
- <string name="SocialFlickrConnecting">Connecting to Flickr...</string>
- <string name="SocialFlickrPosting">Posting...</string>
- <string name="SocialFlickrDisconnecting">Disconnecting from Flickr...</string>
- <string name="SocialFlickrErrorConnecting">Problem connecting to Flickr</string>
- <string name="SocialFlickrErrorPosting">Problem posting to Flickr</string>
- <string name="SocialFlickrErrorDisconnecting">Problem disconnecting from Flickr</string>
- <string name="SocialTwitterConnecting">Connecting to Twitter...</string>
- <string name="SocialTwitterPosting">Posting...</string>
- <string name="SocialTwitterDisconnecting">Disconnecting from Twitter...</string>
- <string name="SocialTwitterErrorConnecting">Problem connecting to Twitter</string>
- <string name="SocialTwitterErrorPosting">Problem posting to Twitter</string>
- <string name="SocialTwitterErrorDisconnecting">Problem disconnecting from Twitter</string>
-
+
<!-- SLShare: User Friendly Filter Names Translation -->
<string name="BlackAndWhite">Black &amp; White</string>
<string name="Colors1970">1970&apos;s Colors</string>
@@ -2637,6 +2623,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="Debits">Debits</string>
<string name="Total">Total</string>
<string name="NoGroupDataFound">No group data found for group </string>
+ <string name="AlreadyInGroup">You are already in this group </string>
<!-- floater IM bonus_info: When a Linden with Admin/god status receives a new IM this displays the estate (Mainland vs. teen grid) of the source avatar.
This is to help Lindens when answering questions. -->
@@ -2820,7 +2807,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="BuyingCosts">Buying this costs L$ [AMOUNT]</string>
<string name="UnknownFileExtension">
Unknown file extension .%s
-Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
+Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim
</string>
<string name="MuteObject2">Block</string>
<string name="MuteAvatar">Block</string>
@@ -3655,13 +3642,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Drag items from inventory here
</string>
- <string name="flickr_post_success">
- You posted to Flickr.
- </string>
- <string name="twitter_post_success">
- You posted to Twitter.
- </string>
-
<string name="no_session_message">
(IM Session Doesn't Exist)
</string>
@@ -4087,7 +4067,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Label">Conversations</string>
<string name="Command_Compass_Label">Compass</string>
<string name="Command_Destinations_Label">Destinations</string>
- <string name="Command_Flickr_Label">Flickr</string>
<string name="Command_Gestures_Label">Gestures</string>
<string name="Command_Grid_Status_Label">Grid status</string>
<string name="Command_HowTo_Label">How to</string>
@@ -4097,7 +4076,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_MarketplaceListings_Label">Marketplace</string>
<string name="Command_MiniMap_Label">Mini-map</string>
<string name="Command_Move_Label">Walk / run / fly</string>
- <string name="Command_Outbox_Label">Merchant outbox</string>
<string name="Command_People_Label">People</string>
<string name="Command_Picks_Label">Picks</string>
<string name="Command_Places_Label">Places</string>
@@ -4107,7 +4085,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Search_Label">Search</string>
<string name="Command_Snapshot_Label">Snapshot</string>
<string name="Command_Speak_Label">Speak</string>
- <string name="Command_Twitter_Label">Twitter</string>
<string name="Command_View_Label">Camera controls</string>
<string name="Command_Voice_Label">Voice settings</string>
@@ -4119,7 +4096,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Conversations_Tooltip">Converse with everyone</string>
<string name="Command_Compass_Tooltip">Compass</string>
<string name="Command_Destinations_Tooltip">Destinations of interest</string>
- <string name="Command_Flickr_Tooltip">Upload to Flickr</string>
<string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
<string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
<string name="Command_HowTo_Tooltip">How to do common tasks</string>
@@ -4129,7 +4105,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_MarketplaceListings_Tooltip">Sell your creation</string>
<string name="Command_MiniMap_Tooltip">Show nearby people</string>
<string name="Command_Move_Tooltip">Moving your avatar</string>
- <string name="Command_Outbox_Tooltip">Transfer items to your marketplace for sale</string>
<string name="Command_People_Tooltip">Friends, groups, and nearby people</string>
<string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
<string name="Command_Places_Tooltip">Places you've saved</string>
@@ -4139,7 +4114,6 @@ Try enclosing path to the editor with double quotes.
<string name="Command_Search_Tooltip">Find places, events, people</string>
<string name="Command_Snapshot_Tooltip">Take a picture</string>
<string name="Command_Speak_Tooltip">Speak with people nearby using your microphone</string>
- <string name="Command_Twitter_Tooltip">Twitter</string>
<string name="Command_View_Tooltip">Changing camera angle</string>
<string name="Command_Voice_Tooltip">Volume controls for calls and people near you in world</string>
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
index 5a9a16d344..57f8bb542d 100644
--- a/indra/newview/skins/default/xui/en/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -39,6 +39,9 @@ Go to &apos;Welcome Island Public&apos; to repeat the tutorial.
<message name="expired_region_handoff">
Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
</message>
+ <message name="preexisting_tport">
+ Sorry, but the system was unable to start your teleport. Please try again in a few minutes.
+ </message>
<message name="no_host">
Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
</message>
diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml
index 998d2a8863..57a1b2ec1e 100644
--- a/indra/newview/skins/default/xui/es/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_about_land.xml
@@ -362,7 +362,7 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
Foto:
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Pulse para elegir una imagen"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Los avatares de otras parcelas pueden ver a los avatares de esta parcela y chatear con ellos
</text>
<check_box label="Ver los avatares" name="SeeAvatarsCheck" tool_tip="Permite que los avatares de otras parcelas vean a los avatares de ésta y chateen con ellos, y también que tú puedas verles y chatear con ellos." top="170"/>
@@ -444,7 +444,7 @@ los media:
<panel.string name="estate_override">
Una o más de esta opciones está configurada a nivel del estado
</panel.string>
- <check_box label="Cualquiera puede visitar (Si no seleccionas esta opción, se crearán líneas de prohibición)" name="public_access"/>
+ <check_box label="Cualquiera puede visitar" name="public_access" tool_tip="Si no seleccionas esta opción, se crearán líneas de prohibición"/>
<check_box label="Debe ser mayor de 18 [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Para poder acceder a esta parcela los Residentes deben ser mayores de 18 años. Para más información, consulta [SUPPORT_SITE]."/>
<check_box label="Debe haber información archivada sobre el pago [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Para poder acceder a esta parcela los Residentes deben haber aportado información de pago en su cuenta. Para más información, ver [SUPPORT_SITE]."/>
<check_box label="Permitir grupo [GROUP] sin restricciones" name="GroupCheck" tool_tip="Elija el grupo en la pestaña General."/>
diff --git a/indra/newview/skins/default/xui/es/floater_buy_currency.xml b/indra/newview/skins/default/xui/es/floater_buy_currency.xml
index 2c8848265f..dbff3fcf0e 100644
--- a/indra/newview/skins/default/xui/es/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/es/floater_buy_currency.xml
@@ -60,7 +60,7 @@ no el objeto.
</text>
<button label="Comprar ahora" name="buy_btn"/>
<button label="Cancelar" name="cancel_btn"/>
- <text left="5" name="info_cannot_buy" right="-5">
+ <text name="info_cannot_buy" left="150" font="SansSerifBig">
No se pudo hacer la compra
</text>
<button label="Ir a la web" name="error_web"/>
diff --git a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
deleted file mode 100644
index b74c5fca5c..0000000000
--- a/indra/newview/skins/default/xui/es/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="BUZÓN DE SALIDA DE COMERCIANTE">
- <string name="OutboxFolderCount1">
- 1 carpeta
- </string>
- <string name="OutboxFolderCountN">
- [NUM] carpetas
- </string>
- <string name="OutboxImporting">
- Enviando carpetas...
- </string>
- <string name="OutboxInitializing">
- Inicializando...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Cargando...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Arrastra aquí artículos para crear carpetas
- </text>
- </panel>
- <button label="Enviar al Mercado" name="outbox_import_btn" tool_tip="Poner en el escaparate de Mi Mercado"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
deleted file mode 100644
index 9e2f3c3adc..0000000000
--- a/indra/newview/skins/default/xui/es/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Arrastra y coloca aquí los objetos que desees preparar para venderlos en tu tienda"/>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index f7e036efd7..388a5d84d2 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -13,7 +13,7 @@
<item label="Medio" name="Medium" value="1"/>
<item label="Grande" name="Large" value="2"/>
</combo_box>
- <check_box label="Bocadillos del chat" name="bubble_text_chat"/>
+ <check_box label="Bocadillos del chat" name="bubble_text_chat" left_delta="30"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
index 1b191d3e46..36888850c4 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
@@ -30,7 +30,7 @@
<combo_box.item label="Preguntarme cuando una actualización opcional está disponible para instalar" name="Install_ask"/>
<combo_box.item label="Instalar sólo actualizaciones obligatorias" name="Install_manual"/>
</combo_box>
- <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test"/>
+ <check_box label="Admitir candidatos a la versión comercial a la hora de realizar actualizaciones" name="update_willing_to_test" left_delta="-20"/>
<check_box label="Mostrar las notas de la versión después de la actualización" name="update_show_release_notes"/>
<text name="Proxy Settings:">
Configuración de proxy:
diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml
index 219857eb99..fb65e71ee1 100644
--- a/indra/newview/skins/default/xui/fr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml
@@ -366,10 +366,10 @@ Seules les parcelles de grande taille peuvent apparaître dans la recherche.
Photo :
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Cliquez pour sélectionner une image"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Les avatars sur d&apos;autres parcelles peuvent voir et chatter avec les avatars sur cette parcelle.
</text>
- <check_box label="Voir les avatars" name="SeeAvatarsCheck" tool_tip="Permettre aux avatars présents sur d&apos;autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/>
+ <check_box label="Voir les avatars" name="SeeAvatarsCheck" top="170" tool_tip="Permettre aux avatars présents sur d&apos;autres parcelles de voir et chatter avec les avatars présents sur cette parcelle et à vous de les voir et de chatter avec eux."/>
<text name="landing_point">
Lieu d&apos;arrivée : [LANDING]
</text>
@@ -449,7 +449,7 @@ musique :
<panel.string name="estate_override">
Au moins une de ces options est définie au niveau du domaine.
</panel.string>
- <check_box label="Tout le monde peut rendre visite (Des lignes d&apos;interdiction seront créées si cette case n&apos;est pas cochée)" name="public_access"/>
+ <check_box label="Tout le monde peut rendre visite" tool_tip="Des lignes d&apos;interdiction seront créées si cette case n&apos;est pas cochée" name="public_access"/>
<check_box label="Doit avoir plus de 18 ans [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Pour accéder à cette parcelle, les résidents doivent avoir au moins 18 ans. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
<check_box label="Les infos de paiement doivent être enregistrées dans le dossier [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Pour pouvoir accéder à cette parcelle, les résidents doivent avoir enregistré des informations de paiement. Consultez le [SUPPORT_SITE] pour plus d&apos;informations."/>
<check_box label="Autoriser le groupe [GROUP] sans restrictions" name="GroupCheck" tool_tip="Définir le groupe à l&apos;onglet Général."/>
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index 148a5a35d2..c295172abf 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
@@ -60,7 +60,7 @@ le Lindex...
</text>
<button label="Acheter" name="buy_btn"/>
<button label="Annuler" name="cancel_btn"/>
- <text left="5" name="info_cannot_buy" right="-5" width="200">
+ <text name="info_cannot_buy" left="160" width="200">
Achat impossible
</text>
<button label="Accéder au Web" name="error_web"/>
diff --git a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
deleted file mode 100644
index 0f657e9e5b..0000000000
--- a/indra/newview/skins/default/xui/fr/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="BOÎTE D&apos;ENVOI VENDEUR">
- <string name="OutboxFolderCount1">
- 1 dossier
- </string>
- <string name="OutboxFolderCountN">
- [NUM] dossiers
- </string>
- <string name="OutboxImporting">
- Envoi de dossiers...
- </string>
- <string name="OutboxInitializing">
- Initialisation...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Chargement...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Faites glisser des éléments ici pour créer des dossiers
- </text>
- </panel>
- <button label="Envoyer vers la Place du marché" name="outbox_import_btn" tool_tip="Vers ma vitrine de la Place du marché"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
deleted file mode 100644
index d947dbceb8..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Glisser-déposer des articles ici afin de les préparer à la vente sur votre vitrine."/>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 422243445b..a0f2e0eba7 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -13,7 +13,7 @@
<item label="Moyenne" name="Medium" value="1"/>
<item label="Grande" name="Large" value="2"/>
</combo_box>
- <check_box label="Bulles de chat" name="bubble_text_chat"/>
+ <check_box label="Bulles de chat" name="bubble_text_chat" left_delta="45"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/it/floater_about_land.xml b/indra/newview/skins/default/xui/it/floater_about_land.xml
index 0a7837e122..70909b1f7c 100644
--- a/indra/newview/skins/default/xui/it/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_about_land.xml
@@ -367,11 +367,11 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
Fotografia:
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Clicca per scegliere una immagine"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Gli avatar di altri lotti possono vedere gli avatar che si trovano in questo lotto e chattare con loro
</text>
- <check_box label="Vedi avatar" name="SeeAvatarsCheck" tool_tip="Consente ad avatar in altri lotti di vedere e chattare con avatar in questo lotto e viceversa."/>
- <text name="landing_point">
+ <check_box label="Vedi avatar" top="170" name="SeeAvatarsCheck" tool_tip="Consente ad avatar in altri lotti di vedere e chattare con avatar in questo lotto e viceversa."/>
+ <text name="landing_point" width="225">
Punto di atterraggio: [LANDING]
</text>
<button label="Imposta" label_selected="Imposta" name="Set" tool_tip="Imposta il punto di atterraggio dove arrivano i visitatori. Impostalo nel punto dove si trova il tuo avatar in questo terreno." width="60"/>
@@ -449,7 +449,7 @@ Media:
<panel.string name="estate_override">
Una o più di queste impostazioni sono già impostate a livello regionale
</panel.string>
- <check_box label="Chiunque può visitare (Se si rimuove la selezione vengono create linee di espulsione)" name="public_access"/>
+ <check_box label="Chiunque può visitare" tool_tip="Se si rimuove la selezione vengono create linee di espulsione" name="public_access"/>
<check_box label="È necessario avere più di 18 anni [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Per poter visitare questo lotto i Residenti devono avere almeno 18 anni. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
<check_box label="È necessario aver registrato le informazioni di pagamento [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Per poter visitare questo lotto i Residenti devono aver fornito informazioni di pagamento a Linden Lab. Vedi [SUPPORT_SITE] per maggiori informazioni."/>
<check_box label="Consenti gruppo [GRUPPO] senza restrizioni" name="GroupCheck" tool_tip="Imposta il gruppo nel pannello generale."/>
diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency.xml b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
index 743969f557..53a2057455 100644
--- a/indra/newview/skins/default/xui/it/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/it/floater_buy_currency.xml
@@ -60,7 +60,7 @@ l&apos;oggetto.
</text>
<button label="Acquista" name="buy_btn"/>
<button label="Annulla" name="cancel_btn"/>
- <text left="5" name="info_cannot_buy" right="-5">
+ <text name="info_cannot_buy" left="160" font="SansSerifBig">
Non in grado di acquistare
</text>
<button label="Continua sul Web" name="error_web"/>
diff --git a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
deleted file mode 100644
index 7a1f7f0a0c..0000000000
--- a/indra/newview/skins/default/xui/it/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="CASELLA IN USCITA DEL RIVENDITORE">
- <string name="OutboxFolderCount1">
- 1 cartella
- </string>
- <string name="OutboxFolderCountN">
- [NUM] cartelle
- </string>
- <string name="OutboxImporting">
- Invio cartelle...
- </string>
- <string name="OutboxInitializing">
- Inizializzazione...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Caricamento in corso...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Trascina elementi qui per creare cartelle
- </text>
- </panel>
- <button label="Invia a Marketplace" name="outbox_import_btn" tool_tip="Push su negozio Marketplace"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
deleted file mode 100644
index af5e05336e..0000000000
--- a/indra/newview/skins/default/xui/it/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Trascina gli oggetti qui per prepararli per la vendita nel tuo negozio"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
deleted file mode 100644
index 2edb3c624c..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="マーチャントアウトボックス">
- <string name="OutboxFolderCount1">
- 1 個のフォルダ
- </string>
- <string name="OutboxFolderCountN">
- [NUM] 個のフォルダ
- </string>
- <string name="OutboxImporting">
- フォルダを送信中...
- </string>
- <string name="OutboxInitializing">
- 初期化中...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- ロード中...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- ここにアイテムをドラッグして、フォルダを作成する
- </text>
- </panel>
- <button label="マーケットプレイスに送信" name="outbox_import_btn" tool_tip="自分のマーケットプレイス店頭に移動"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
deleted file mode 100644
index 1a14283113..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="アイテムをここにドラッグアンドドロップすると、あなたの店頭に並びます"/>
diff --git a/indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml
deleted file mode 100644
index 9cc88ba288..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="SKRZYNKA NADAWCZA KUPCA">
- <string name="OutboxFolderCountN">
- Folderów: [NUM]
- </string>
- <string name="OutboxImporting">
- Wysyłanie folderów...
- </string>
- <string name="OutboxInitializing">
- Inicjalizacja...
- </string>
- <panel name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Ładowanie...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Przeciągaj tu przedmioty by tworzyć foldery
- </text>
- </panel>
- <button label="Wyślij na Marketplace" tool_tip="Wyślij na witrynę Marketplace" name="outbox_import_btn" />
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml
deleted file mode 100644
index 01d0455215..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inventory_panel name="inventory_outbox" tool_tip="Przeciągnij i upuść tutaj przedmioty, aby przygotować je do sprzedaży na Twojej witrynie Marketplace" />
diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml
index ef71baa0b6..0e7d0798c7 100644
--- a/indra/newview/skins/default/xui/pt/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml
@@ -362,11 +362,11 @@ Apenas lotes maiores podem ser listados na busca.
Foto:
</text>
<texture_picker label="" name="snapshot_ctrl" tool_tip="Clique para escolher uma imagem"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Avatares em outros lotes podem ver e conversar com avatares neste lote
</text>
- <check_box label="Ver avatares" name="SeeAvatarsCheck" tool_tip="Permite que os avatares em outros lotes vejam e batam papo com avatares neste lote. Você poderá vê-los e conversar com eles."/>
- <text name="landing_point">
+ <check_box label="Ver avatares" name="SeeAvatarsCheck" top="170" tool_tip="Permite que os avatares em outros lotes vejam e batam papo com avatares neste lote. Você poderá vê-los e conversar com eles."/>
+ <text name="landing_point" width="225">
Ponto de Aterrissagem: [LANDING]
</text>
<button label="Definir" label_selected="Definir" name="Set" tool_tip="Define o ponto de aterrissagem de visitantes. Define para o ponto em que seu avatar se encontra neste lote."/>
diff --git a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
deleted file mode 100644
index 3beada1fc0..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="CAIXA DE SAÍDA DO LOJISTA">
- <string name="OutboxFolderCount1">
- 1 pasta
- </string>
- <string name="OutboxFolderCountN">
- [NUM] pasta(s)
- </string>
- <string name="OutboxImporting">
- Enviando pastas...
- </string>
- <string name="OutboxInitializing">
- Iniciando...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Carregando...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Arraste itens para cá para criar pastas
- </text>
- </panel>
- <button label="Enviar para Mercado" name="outbox_import_btn" tool_tip="Enviar para a frente da minha loja do mercado"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
deleted file mode 100644
index 442622035a..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Arraste e solte os itens aqui para prepará-los para venda na frente da sua loja"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_about_land.xml b/indra/newview/skins/default/xui/ru/floater_about_land.xml
index 1ae6df76d9..fb17896551 100644
--- a/indra/newview/skins/default/xui/ru/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about_land.xml
@@ -338,7 +338,7 @@
<check_box label="Все" name="check other scripts" tool_tip="Если установлен флажок, то жители могут выполнять скрипты на вашем участке, включая приложения."/>
<check_box label="Группа" name="check group scripts" tool_tip="Если установлен флажок, то члены группы могут выполнять скрипты на вашем участке, включая приложения."/>
<check_box label="Безопасно (нет повреждений)" name="check safe" tool_tip="Если отмечено, то земля считается безопасной, отключены боевые повреждения. Если не отмечено, то боевые повреждения включены."/>
- <check_box label="Не толкать" name="PushRestrictCheck" tool_tip="Запрещает скриптам функцию толкания. Этот параметр может оказаться полезным для предотвращения нежелательного поведения на вашей земле."/>
+ <check_box label="Не толкать" name="PushRestrictCheck" left_pad="44" tool_tip="Запрещает скриптам функцию толкания. Этот параметр может оказаться полезным для предотвращения нежелательного поведения на вашей земле."/>
<check_box label="Показать место в поиске (L$30/неделя)" name="ShowDirectoryCheck" tool_tip="Позволить людям видеть участок в результатах поиска"/>
<combo_box name="land category">
<combo_box.item label="Любая категория" name="item0"/>
@@ -360,11 +360,11 @@
Снимок:
</text>
<texture_picker name="snapshot_ctrl" tool_tip="Щелкните для выбора изображения"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" left="283">
Аватары с других участков могут видеть аватары на этом участке и общаться с ними
</text>
- <check_box label="Видны аватары" name="SeeAvatarsCheck" tool_tip="Аватары с других участков смогут видеть аватары на этом участке и общаться с ними в чате, а вы также сможете видеть их и общаться с ними."/>
- <text name="landing_point">
+ <check_box label="Видны аватары" left="262" name="SeeAvatarsCheck" tool_tip="Аватары с других участков смогут видеть аватары на этом участке и общаться с ними в чате, а вы также сможете видеть их и общаться с ними."/>
+ <text name="landing_point" width="225">
В точку телепортации: [LANDING]
</text>
<button label="Задать" label_selected="Задать" name="Set" tool_tip="Установить точку телепортации, в которую будут прибывать посетители, Ставится в месте вашего аватара на этом участке."/>
@@ -372,7 +372,7 @@
<text name="Teleport Routing: ">
Вариант телепортации:
</text>
- <combo_box name="landing type" tool_tip="Вариант телепортации – выберите, каким образом будет производиться телепортация на вашу землю">
+ <combo_box name="landing type" width="150" tool_tip="Вариант телепортации – выберите, каким образом будет производиться телепортация на вашу землю">
<combo_box.item label="В черном списке" name="Blocked"/>
<combo_box.item label="В точку телепортации" name="LandingPoint"/>
<combo_box.item label="В любое место" name="Anywhere"/>
@@ -439,7 +439,7 @@
<panel.string name="estate_override">
Часть этих параметров установлена на уровне землевладения
</panel.string>
- <check_box label="Доступ открыт для всех (При снятия выделения будет создана запись в строке запрета)" name="public_access"/>
+ <check_box label="Доступ открыт для всех" tool_tip="При снятия выделения будет создана запись в строке запрета" name="public_access"/>
<check_box label="Должен быть 18 и старше [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Доступ к этому участку имеют только жители 18 лет и старше. Более подробная информация находится здесь: [SUPPORT_SITE]."/>
<check_box label="Информация о платежах должна быть в файле [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Для доступа к этому участку у жителя должна быть зарегистрирована информация об оплате. Более подробная информация находится здесь: [SUPPORT_SITE]."/>
<check_box label="Разрешить группе [GROUP] без всяких ограничений" name="GroupCheck" tool_tip="Группа устанавливается на основной вкладке."/>
diff --git a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
deleted file mode 100644
index 1d3ff3f5ed..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="ТОРГОВЫЕ ИСХОДЯЩИЕ">
- <string name="OutboxFolderCount1">
- 1 папка
- </string>
- <string name="OutboxFolderCountN">
- [NUM] папки
- </string>
- <string name="OutboxImporting">
- Отправка папок....
- </string>
- <string name="OutboxInitializing">
- Инициализация...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Загрузка...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Перетаскивайте предметы для создания папок
- </text>
- </panel>
- <button label="Отправить в торговый центр" name="outbox_import_btn" tool_tip="Выставить на витрину моего магазина"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index 08accc39fe..1e4f9e9abb 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -1436,9 +1436,9 @@
<usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Создать аккаунт..."/>
</notification>
<notification name="LoginPacketNeverReceived">
- Возникли неполадки при подключении. Возможно, проблема с вашим подключением к интернету или [SECOND_LIFE_GRID].
+ Возникли неполадки при подключении. Возможно, проблема с вашим подключением к интернету или [SECOND_LIFE_GRID] временно недоступна.
-Варианты ваших действий: проверьте подключение к интернету и повторите попытку через несколько минут, нажмите кнопку «Справка» для перехода к [SUPPORT_SITE] или кнопку «Телепортация», чтобы телепортироваться домой.
+Вы можете проверить подключение к интернету, повторить попытку через несколько минут, нажать кнопку «Справка» для перехода на [SUPPORT_SITE] или нажать кнопку «Телепортация», чтобы телепортироваться домой.
<url name="url">
http://secondlife.com/support/
</url>
diff --git a/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
deleted file mode 100644
index 0095d48af9..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Перетащите вещи сюда, чтобы подготовить их для размещения на витрине вашего магазина"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
index c2fcac8840..03a714f266 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
@@ -5,15 +5,15 @@
<check_box initial_value="true" label="Воспроизводить анимацию ввода текста при общении" name="play_typing_animation"/>
<check_box label="Отправлять мне сообщения по почте, когда меня нет в сети" name="send_im_to_email"/>
<check_box label="Только друзья и группы могут звонить мне и отправлять IM" name="voice_call_friends_only_check"/>
- <text name="font_size">
+ <text name="font_size" left="361">
Размер шрифта:
</text>
- <combo_box name="chat_font_size">
+ <combo_box name="chat_font_size" left="361">
<item label="Мелкий" name="Small" value="0"/>
<item label="Средний" name="Medium" value="1"/>
<item label="Крупный" name="Large" value="2"/>
</combo_box>
- <check_box label="Чат в пузырьках" name="bubble_text_chat"/>
+ <check_box label="Чат в пузырьках" name="bubble_text_chat" left_delta="19"/>
</panel>
<panel name="im_notification_settings">
<text name="friend_ims">
diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
index d4d0ef9e7c..137e047d97 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_setup.xml
@@ -14,7 +14,7 @@
<text name="Web:">
Браузер:
</text>
- <radio_group name="preferred_browser_behavior">
+ <radio_group name="preferred_browser_behavior" left_delta="30">
<radio_item label="Используйте встроенный браузер для всех ссылок" name="internal" tool_tip="Будет использоваться браузер, заданный в системе по умолчанию. Не рекомендуется, если [APP_NAME] работает в полноэкранном режиме." value="0"/>
<radio_item label="Для ссылок Second Life следует использовать только встроенный браузер" name="external" tool_tip="Используйте встроенный браузер для справки, веб-ссылок и т.д. Для ссылок LindenLab/Second Life следует использовать только встроенный браузер." value="1"/>
<radio_item label="Для всех ссылок следует использовать встроенный браузер" name="external_all" tool_tip="Для просмотра справки, ссылок на веб-страницы и т. д. будет использоваться встроенный браузер. Этот браузер открывается как новое окно в [APP_NAME]." value="2"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_about_land.xml b/indra/newview/skins/default/xui/tr/floater_about_land.xml
index 48b16e2fde..1101e5055a 100644
--- a/indra/newview/skins/default/xui/tr/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about_land.xml
@@ -360,10 +360,10 @@ Sadece büyük parseller aramada görünür.
Anlık Görüntü:
</text>
<texture_picker name="snapshot_ctrl" tool_tip="Bir resim seçmek için tıklayın"/>
- <text name="allow_see_label">
+ <text name="allow_see_label" top="170">
Diğer parsellerdeki avatarlar bu parseldeki avatarları görebilir ve onlarla sohbet edebilir
</text>
- <check_box label="Avatarları Gör" name="SeeAvatarsCheck" tool_tip="Diğer parsellerdeki avatarların bu parseldeki avatarları görmesine ve onlarla sohbet etmesine, sizin de onları görüp, onlarla sohbet etmenize imkan tanır."/>
+ <check_box label="Avatarları Gör" name="SeeAvatarsCheck" top="170" tool_tip="Diğer parsellerdeki avatarların bu parseldeki avatarları görmesine ve onlarla sohbet etmesine, sizin de onları görüp, onlarla sohbet etmenize imkan tanır."/>
<text name="landing_point">
İniş Noktası: [LANDING]
</text>
diff --git a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
deleted file mode 100644
index e5643f3bf6..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="SATICI GİDEN KUTUSU">
- <string name="OutboxFolderCount1">
- 1 klasör
- </string>
- <string name="OutboxFolderCountN">
- [NUM] klasör
- </string>
- <string name="OutboxImporting">
- Klasörler gönderiliyor...
- </string>
- <string name="OutboxInitializing">
- Başlatılıyor...
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- Yükleniyor...
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- Klasör oluşturmak için öğeleri buraya sürükleyin
- </text>
- </panel>
- <button label="Pazaryerine Gönder" name="outbox_import_btn" tool_tip="Pazaryeri Vitrinime Gönder"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
deleted file mode 100644
index a947eee150..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="Öğeleri vitrininizde satışa hazırlamak için sürükleyip buraya bırakın"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml b/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml
deleted file mode 100644
index e6a70a7724..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_merchant_outbox" title="商家發件匣">
- <string name="OutboxFolderCount1">
- 1 個資料夾
- </string>
- <string name="OutboxFolderCountN">
- [NUM] 個資料夾
- </string>
- <string name="OutboxImporting">
- 正在傳送資料夾…
- </string>
- <string name="OutboxInitializing">
- 正在初始化…
- </string>
- <panel label="" name="panel_1">
- <panel name="panel_2">
- <panel name="outbox_inventory_placeholder_panel">
- <text name="outbox_inventory_placeholder_title">
- 載入中…
- </text>
- </panel>
- </panel>
- <panel name="panel_3">
- <panel name="outbox_generic_drag_target">
- <text name="text_1">
- 把物項拖曳到這裡,可建立資料夾
- </text>
- </panel>
- <button label="送往第二人生購物市集" name="outbox_import_btn" tool_tip="推到我第二人生購物市集的店面"/>
- </panel>
- </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
deleted file mode 100644
index 8de0bb0e4d..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<outbox_inventory_panel name="inventory_outbox" tool_tip="將物項拖曳並置放到這裡,準備在你的商店出售"/>
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index d7e87ed52e..caa3016d2e 100644
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -60,12 +60,22 @@ LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert
LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain) { return NULL; }
LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id) { return NULL; }
void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type, const std::string& data_id, const LLSD& data) {}
+void LLSecAPIBasicHandler::addToProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem, const LLSD& data) {}
+void LLSecAPIBasicHandler::removeFromProtectedMap(const std::string& data_type, const std::string& data_id, const std::string& map_elem) {}
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type, const std::string& data_id) { return LLSD(); }
void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type, const std::string& data_id) {}
LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid, const LLSD& identifier, const LLSD& authenticator) { return NULL; }
LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid) { return NULL; }
void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator) {}
void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred) {}
+bool LLSecAPIBasicHandler::hasCredentialMap(const std::string& storage, const std::string& grid) { return false; }
+bool LLSecAPIBasicHandler::emptyCredentialMap(const std::string& storage, const std::string& grid) { return false; }
+void LLSecAPIBasicHandler::loadCredentialMap(const std::string& storage, const std::string& grid, credential_map_t& credential_map) {}
+LLPointer<LLCredential> LLSecAPIBasicHandler::loadFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) { return NULL; }
+void LLSecAPIBasicHandler::addToCredentialMap(const std::string& storage, LLPointer<LLCredential> cred, bool save_authenticator) {}
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, LLPointer<LLCredential> cred) {}
+void LLSecAPIBasicHandler::removeFromCredentialMap(const std::string& storage, const std::string& grid, const std::string& userkey) {}
+void LLSecAPIBasicHandler::removeCredentialMap(const std::string& storage, const std::string& grid) {}
// -------------------------------------------------------------------------------------------
// TUT
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index a4cda0ba78..a403760670 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1332,7 +1332,6 @@ class DarwinManifest(ViewerManifest):
print "Converting temp disk image to final disk image"
self.run_command(['hdiutil', 'convert', sparsename, '-format', 'UDZO',
'-imagekey', 'zlib-level=9', '-o', finalname])
- self.run_command(['hdiutil', 'internet-enable', '-yes', finalname])
# get rid of the temp file
self.package_file = finalname
self.remove(sparsename)