summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt22
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/commands.xml6
-rw-r--r--indra/newview/app_settings/key_bindings.xml1
-rw-r--r--indra/newview/app_settings/settings.xml57
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl13
-rw-r--r--indra/newview/character/avatar_skeleton.xml214
-rw-r--r--indra/newview/cube.dae103
-rw-r--r--indra/newview/installers/windows/installer_template.nsi36
-rw-r--r--indra/newview/installers/windows/lang_da.nsibin11992 -> 12802 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsi4
-rw-r--r--indra/newview/installers/windows/lang_en-us.nsibin11666 -> 12480 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_es.nsibin12976 -> 13790 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_fr.nsibin13492 -> 14302 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_it.nsibin12714 -> 13528 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ja.nsibin9880 -> 10698 bytes
-rw-r--r--indra/newview/installers/windows/lang_pl.nsibin12312 -> 13122 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pt-br.nsibin13136 -> 13970 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ru.nsibin12450 -> 13264 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_tr.nsibin12360 -> 13174 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_zh.nsibin9324 -> 10144 bytes
-rw-r--r--indra/newview/llagent.cpp7
-rw-r--r--indra/newview/llagentpicksinfo.h4
-rw-r--r--indra/newview/llappearancemgr.cpp12
-rw-r--r--indra/newview/llappviewer.cpp121
-rw-r--r--indra/newview/llappviewer.h21
-rw-r--r--indra/newview/llavataractions.cpp163
-rw-r--r--indra/newview/llavataractions.h28
-rw-r--r--indra/newview/llavatarlist.cpp108
-rw-r--r--indra/newview/llavatarlist.h26
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp254
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h21
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp28
-rw-r--r--indra/newview/llcallingcard.cpp4
-rw-r--r--indra/newview/llchatbar.cpp2
-rw-r--r--indra/newview/llchathistory.cpp57
-rw-r--r--indra/newview/llcolorswatch.cpp18
-rw-r--r--indra/newview/llconversationloglist.cpp3
-rw-r--r--indra/newview/llconversationmodel.cpp1
-rw-r--r--indra/newview/llconversationview.cpp47
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.cpp7
-rw-r--r--indra/newview/lldonotdisturbnotificationstorage.h1
-rw-r--r--indra/newview/lldrawable.h1
-rw-r--r--indra/newview/lldrawpoolalpha.cpp11
-rw-r--r--indra/newview/lldynamictexture.cpp4
-rw-r--r--indra/newview/llenvironment.cpp2
-rw-r--r--indra/newview/llfasttimerview.cpp14
-rw-r--r--indra/newview/llfavoritesbar.cpp43
-rw-r--r--indra/newview/llfloater360capture.cpp7
-rw-r--r--indra/newview/llfloater360capture.h1
-rw-r--r--indra/newview/llfloateravatarpicker.cpp3
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp10
-rw-r--r--indra/newview/llfloaterchatvoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterclassified.cpp71
-rw-r--r--indra/newview/llfloaterclassified.h (renamed from indra/newview/llfloaterwebprofile.h)54
-rw-r--r--indra/newview/llfloatercolorpicker.cpp24
-rw-r--r--indra/newview/llfloatercolorpicker.h5
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp129
-rw-r--r--indra/newview/llfloatercreatelandmark.h3
-rw-r--r--indra/newview/llfloaterdisplayname.cpp200
-rw-r--r--indra/newview/llfloaterdisplayname.h (renamed from indra/newview/llpanelme.h)28
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp1
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp1
-rw-r--r--indra/newview/llfloatergesture.cpp2
-rw-r--r--indra/newview/llfloaterhoverheight.cpp13
-rw-r--r--indra/newview/llfloaterimcontainer.cpp19
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp7
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp14
-rw-r--r--indra/newview/llfloaterland.cpp6
-rw-r--r--indra/newview/llfloaterland.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.cpp148
-rw-r--r--indra/newview/llfloatermap.h1
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp20
-rw-r--r--indra/newview/llfloatermediasettings.cpp12
-rw-r--r--indra/newview/llfloatermediasettings.h1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp39
-rw-r--r--indra/newview/llfloatermodelpreview.h1
-rw-r--r--indra/newview/llfloateroutfitsnapshot.cpp1
-rw-r--r--indra/newview/llfloaterpay.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp111
-rw-r--r--indra/newview/llfloaterpreference.h5
-rw-r--r--indra/newview/llfloaterprofile.cpp170
-rw-r--r--indra/newview/llfloaterprofile.h66
-rw-r--r--indra/newview/llfloaterprofiletexture.cpp223
-rw-r--r--indra/newview/llfloaterprofiletexture.h81
-rw-r--r--indra/newview/llfloaterregioninfo.cpp13
-rw-r--r--indra/newview/llfloaterreporter.cpp55
-rw-r--r--indra/newview/llfloaterreporter.h6
-rw-r--r--indra/newview/llfloatersearch.cpp61
-rw-r--r--indra/newview/llfloatersearch.h4
-rw-r--r--indra/newview/llfloatertools.cpp945
-rw-r--r--indra/newview/llfloatertools.h20
-rw-r--r--indra/newview/llfloaterurlentry.cpp10
-rw-r--r--indra/newview/llfloatervoicevolume.cpp2
-rw-r--r--indra/newview/llfloaterwebprofile.cpp81
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterworldmap.cpp110
-rw-r--r--indra/newview/llfloaterworldmap.h9
-rw-r--r--indra/newview/llfriendcard.cpp57
-rw-r--r--indra/newview/llfriendcard.h1
-rw-r--r--indra/newview/llgesturemgr.h2
-rw-r--r--indra/newview/llgroupactions.cpp2
-rw-r--r--indra/newview/llgrouplist.cpp309
-rw-r--r--indra/newview/llgrouplist.h30
-rw-r--r--indra/newview/llgroupmgr.cpp4
-rw-r--r--indra/newview/llhudtext.cpp2
-rw-r--r--indra/newview/llimview.cpp82
-rw-r--r--indra/newview/llimview.h5
-rw-r--r--indra/newview/llinspect.cpp16
-rw-r--r--indra/newview/llinspect.h2
-rw-r--r--indra/newview/llinspectavatar.cpp15
-rw-r--r--indra/newview/llinspectgroup.cpp13
-rw-r--r--indra/newview/llinspectobject.cpp14
-rw-r--r--indra/newview/llinspectremoteobject.cpp12
-rw-r--r--indra/newview/llinspecttoast.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp42
-rw-r--r--indra/newview/llinventoryfunctions.cpp155
-rw-r--r--indra/newview/llinventoryfunctions.h4
-rw-r--r--indra/newview/llinventorylistitem.cpp32
-rw-r--r--indra/newview/llinventorymodel.cpp156
-rw-r--r--indra/newview/llinventorymodel.h30
-rw-r--r--indra/newview/lllegacyatmospherics.cpp20
-rw-r--r--indra/newview/lllocalbitmaps.cpp60
-rw-r--r--indra/newview/lllocalbitmaps.h3
-rw-r--r--indra/newview/lllocationinputctrl.h2
-rw-r--r--indra/newview/lllogininstance.cpp86
-rw-r--r--indra/newview/lllogininstance.h1
-rw-r--r--indra/newview/llmarketplacefunctions.cpp43
-rw-r--r--indra/newview/llmarketplacefunctions.h3
-rw-r--r--indra/newview/llmediadataclient.cpp3
-rw-r--r--indra/newview/llmeshrepository.cpp42
-rw-r--r--indra/newview/llmeshrepository.h5
-rw-r--r--indra/newview/llmodelpreview.cpp319
-rw-r--r--indra/newview/llmodelpreview.h31
-rw-r--r--indra/newview/llmutelist.cpp2
-rw-r--r--indra/newview/llnamelistctrl.cpp19
-rw-r--r--indra/newview/llnamelistctrl.h1
-rw-r--r--indra/newview/llnavigationbar.cpp11
-rwxr-xr-xindra/newview/llnavigationbar.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp602
-rw-r--r--indra/newview/llnetmap.h54
-rw-r--r--indra/newview/lloutfitgallery.cpp1
-rw-r--r--indra/newview/llpanelavatar.cpp224
-rw-r--r--indra/newview/llpanelavatar.h183
-rw-r--r--indra/newview/llpanelblockedlist.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp625
-rw-r--r--indra/newview/llpanelclassified.h134
-rw-r--r--indra/newview/llpaneleditwearable.cpp4
-rw-r--r--indra/newview/llpanelexperiences.h1
-rw-r--r--indra/newview/llpanelface.cpp1746
-rw-r--r--indra/newview/llpanelface.h54
-rw-r--r--indra/newview/llpanelimcontrolpanel.cpp4
-rw-r--r--indra/newview/llpanellandaudio.cpp9
-rw-r--r--indra/newview/llpanellandaudio.h1
-rw-r--r--indra/newview/llpanellandmarks.cpp52
-rw-r--r--indra/newview/llpanellandmarks.h2
-rw-r--r--indra/newview/llpanelme.cpp67
-rw-r--r--indra/newview/llpanelmediasettingsgeneral.cpp6
-rw-r--r--indra/newview/llpanelobject.cpp327
-rw-r--r--indra/newview/llpanelobject.h27
-rw-r--r--indra/newview/llpanelobjectinventory.cpp15
-rw-r--r--indra/newview/llpanelpick.cpp620
-rw-r--r--indra/newview/llpanelpick.h264
-rw-r--r--indra/newview/llpanelpicks.cpp1484
-rw-r--r--indra/newview/llpanelpicks.h315
-rw-r--r--indra/newview/llpanelplaceinfo.cpp12
-rw-r--r--indra/newview/llpanelplaceinfo.h3
-rw-r--r--indra/newview/llpanelplaces.cpp42
-rw-r--r--indra/newview/llpanelplaces.h6
-rw-r--r--indra/newview/llpanelprofile.cpp2654
-rw-r--r--indra/newview/llpanelprofile.h411
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp1513
-rw-r--r--indra/newview/llpanelprofileclassifieds.h340
-rw-r--r--indra/newview/llpanelprofilepicks.cpp883
-rw-r--r--indra/newview/llpanelprofilepicks.h248
-rw-r--r--indra/newview/llpanelvolume.cpp301
-rw-r--r--indra/newview/llpanelvolume.h13
-rw-r--r--indra/newview/llparticipantlist.cpp170
-rw-r--r--indra/newview/llparticipantlist.h4
-rw-r--r--indra/newview/llpatchvertexarray.cpp2
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp12
-rw-r--r--indra/newview/llpersistentnotificationstorage.h1
-rw-r--r--indra/newview/llphysicsshapebuilderutil.cpp13
-rw-r--r--indra/newview/llphysicsshapebuilderutil.h1
-rw-r--r--indra/newview/llpresetsmanager.cpp2
-rw-r--r--indra/newview/llpreviewnotecard.cpp5
-rw-r--r--indra/newview/llpreviewscript.cpp5
-rw-r--r--indra/newview/llpreviewtexture.cpp15
-rw-r--r--indra/newview/llpreviewtexture.h2
-rw-r--r--indra/newview/llrecentpeople.cpp37
-rw-r--r--indra/newview/llrecentpeople.h13
-rw-r--r--indra/newview/llremoteparcelrequest.cpp7
-rw-r--r--indra/newview/llsceneview.cpp10
-rw-r--r--indra/newview/llsearchableui.h12
-rw-r--r--indra/newview/llselectmgr.cpp128
-rw-r--r--indra/newview/llselectmgr.h24
-rw-r--r--indra/newview/llspatialpartition.cpp69
-rw-r--r--indra/newview/llspeakers.cpp2
-rw-r--r--indra/newview/llspeakers.h8
-rw-r--r--indra/newview/llstartup.cpp32
-rw-r--r--indra/newview/lltexturecache.cpp3
-rw-r--r--indra/newview/lltexturectrl.cpp94
-rw-r--r--indra/newview/lltexturectrl.h14
-rw-r--r--indra/newview/lltoastalertpanel.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.cpp9
-rw-r--r--indra/newview/lltooldraganddrop.h3
-rw-r--r--indra/newview/lltoolpie.cpp3
-rw-r--r--indra/newview/lltoolplacer.cpp2
-rw-r--r--indra/newview/llviewerassetupload.cpp62
-rw-r--r--indra/newview/llvieweraudio.h2
-rw-r--r--indra/newview/llviewercontrol.cpp327
-rw-r--r--indra/newview/llviewerdisplay.cpp1
-rw-r--r--indra/newview/llviewerdisplayname.cpp226
-rw-r--r--indra/newview/llviewerdisplayname.h55
-rw-r--r--indra/newview/llviewerfloaterreg.cpp12
-rw-r--r--indra/newview/llviewermedia.cpp38
-rw-r--r--indra/newview/llviewermedia.h3
-rw-r--r--indra/newview/llviewermenu.cpp165
-rw-r--r--indra/newview/llviewermessage.cpp27
-rw-r--r--indra/newview/llviewerobject.cpp17
-rw-r--r--indra/newview/llviewerobjectlist.cpp3
-rw-r--r--indra/newview/llvieweroctree.cpp4
-rw-r--r--indra/newview/llvieweroctree.h17
-rw-r--r--indra/newview/llviewerparcelmgr.cpp19
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.cpp80
-rw-r--r--indra/newview/llviewerparceloverlay.h7
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.cpp107
-rw-r--r--indra/newview/llviewerregion.h16
-rw-r--r--indra/newview/llviewershadermgr.cpp33
-rw-r--r--indra/newview/llviewershadermgr.h6
-rw-r--r--indra/newview/llviewerstats.cpp1
-rw-r--r--indra/newview/llviewertexturelist.cpp16
-rw-r--r--indra/newview/llviewertexturelist.h7
-rw-r--r--indra/newview/llviewerwindow.cpp20
-rw-r--r--indra/newview/llvoavatar.cpp103
-rw-r--r--indra/newview/llvoavatar.h10
-rw-r--r--indra/newview/llvoavatarself.cpp2
-rw-r--r--indra/newview/llvocache.cpp52
-rw-r--r--indra/newview/llvoicechannel.cpp23
-rw-r--r--indra/newview/llvoiceclient.cpp6
-rw-r--r--indra/newview/llvoiceclient.h1
-rw-r--r--indra/newview/llvoicevivox.cpp56
-rw-r--r--indra/newview/llvoicevivox.h2
-rw-r--r--indra/newview/llvopartgroup.cpp6
-rw-r--r--indra/newview/llvovolume.cpp129
-rw-r--r--indra/newview/llvovolume.h16
-rw-r--r--indra/newview/llwebprofile.cpp2
-rw-r--r--indra/newview/llworld.cpp5
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.cpp277
-rw-r--r--indra/newview/llworldmapview.h43
-rw-r--r--indra/newview/llxmlrpctransaction.cpp10
-rw-r--r--indra/newview/pipeline.cpp10
-rw-r--r--indra/newview/skins/default/colors.xml28
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Off.pngbin0 -> 231 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardMenu_Press.pngbin0 -> 224 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.pngbin0 -> 218 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.pngbin0 -> 217 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.pngbin0 -> 215 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/CopyBright.pngbin0 -> 519 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Offline.pngbin0 -> 208 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Friend_Online.pngbin0 -> 189 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.pngbin0 -> 1608 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.pngbin0 -> 1287 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.pngbin0 -> 1356 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.pngbin0 -> 1137 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.pngbin0 -> 1312 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.pngbin0 -> 1150 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/avaline_default_icon.jpgbin3951 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.pngbin0 -> 507 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.pngbin0 -> 639 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.pngbin0 -> 485 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.pngbin0 -> 609 bytes
-rw-r--r--indra/newview/skins/default/textures/map_ui_collapse_icon.pngbin0 -> 300 bytes
-rw-r--r--indra/newview/skins/default/textures/map_ui_expand_icon.pngbin0 -> 284 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml25
-rw-r--r--indra/newview/skins/default/xui/da/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/da/panel_region_texture.xml4
-rw-r--r--indra/newview/skins/default/xui/da/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/da/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/de/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/de/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/de/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/de/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/de/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/de/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/de/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/de/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml24
-rw-r--r--indra/newview/skins/default/xui/en/floater_classified.xml (renamed from indra/newview/skins/default/xui/en/floater_picks.xml)13
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_display_name.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_texture.xml208
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_permissions.xml76
-rw-r--r--indra/newview/skins/default/xui/en/floater_profile_texture.xml88
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml7
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml185
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml93
-rw-r--r--indra/newview/skins/default/xui/en/inspect_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_icon.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_self.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_color.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_features.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_light.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_object.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_size.xml37
-rw-r--r--indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml21
-rw-r--r--indra/newview/skins/default/xui/en/menu_gesture_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_im_conversation.xml7
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml19
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml120
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_other.xml171
-rw-r--r--indra/newview/skins/default/xui/en/menu_profile_self.xml85
-rw-r--r--indra/newview/skins/default/xui/en/menu_url_agent.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml25
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml103
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_classified_info.xml37
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_classified.xml354
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml239
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_profile.xml472
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item_short.xml110
-rw-r--r--indra/newview/skins/default/xui/en/panel_me.xml19
-rw-r--r--indra/newview/skins/default/xui/en/panel_pick_info.xml190
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml227
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classified.xml830
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_classifieds.xml142
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_firstlife.xml103
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_notes.xml65
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_pick.xml314
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_picks.xml154
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml549
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_web.xml36
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml84
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml22
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/es/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/es/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/es/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/es/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/es/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/fr/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/es/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/fr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/fr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_photo.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_facebook_status.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/es/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/fr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/it/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/it/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/it/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/it/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/it/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_friends.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_photo.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_facebook_status.xml10
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/it/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/it/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/ja/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ja/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ja/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_photo.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_facebook_status.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ja/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_snapshot_options.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/pl/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/pl/strings.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/pt/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/pt/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml (renamed from indra/newview/skins/default/xui/it/floater_picks.xml)2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/pt/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml38
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/ru/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/ru/floater_report_abuse.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/panel_edit_classified.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_friends.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_photo.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_place.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_facebook_status.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/ru/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/tr/floater_facebook.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/tr/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/tr/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_friends.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_photo.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_place.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_facebook_status.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_general.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/tr/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_terrain.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml36
-rw-r--r--indra/newview/skins/default/xui/zh/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/zh/floater_profile.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_snapshot.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_name_field.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_classified.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_me.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_people.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classified.xml110
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_interests.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_notes.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_pick.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_picks.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml77
-rw-r--r--indra/newview/skins/default/xui/zh/panel_profile_web.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_terrain.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml36
-rwxr-xr-xindra/newview/viewer_manifest.py3
561 files changed, 21627 insertions, 9926 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c577d062f9..7d78ec9e3c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -234,12 +234,14 @@ set(viewer_SOURCE_FILES
llfloatercamera.cpp
llfloatercamerapresets.cpp
llfloaterchatvoicevolume.cpp
+ llfloaterclassified.cpp
llfloatercolorpicker.cpp
llfloaterconversationlog.cpp
llfloaterconversationpreview.cpp
llfloatercreatelandmark.cpp
llfloaterdeleteprefpreset.cpp
llfloaterdestinations.cpp
+ llfloaterdisplayname.cpp
llfloatereditenvironmentbase.cpp
llfloatereditextdaycycle.cpp
llfloaterenvironmentadjust.cpp
@@ -295,9 +297,11 @@ set(viewer_SOURCE_FILES
llfloaterpay.cpp
llfloaterperms.cpp
llfloaterpostprocess.cpp
+ llfloaterprofile.cpp
llfloaterpreference.cpp
llfloaterpreferenceviewadvanced.cpp
llfloaterpreviewtrash.cpp
+ llfloaterprofiletexture.cpp
llfloaterproperties.cpp
llfloaterregiondebugconsole.cpp
llfloaterregioninfo.cpp
@@ -330,7 +334,6 @@ set(viewer_SOURCE_FILES
llfloatervoiceeffect.cpp
llfloatervoicevolume.cpp
llfloaterwebcontent.cpp
- llfloaterwebprofile.cpp
llfloaterwhitelistentry.cpp
llfloaterwindowsize.cpp
llfloaterworldmap.cpp
@@ -476,7 +479,6 @@ set(viewer_SOURCE_FILES
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
- llpanelme.cpp
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
@@ -486,8 +488,6 @@ set(viewer_SOURCE_FILES
llpanelpeople.cpp
llpanelpeoplemenus.cpp
llpanelpermissions.cpp
- llpanelpick.cpp
- llpanelpicks.cpp
llpanelplaceinfo.cpp
llpanelplaceprofile.cpp
llpanelplaces.cpp
@@ -496,6 +496,8 @@ set(viewer_SOURCE_FILES
llpanelpresetspulldown.cpp
llpanelprimmediacontrols.cpp
llpanelprofile.cpp
+ llpanelprofileclassifieds.cpp
+ llpanelprofilepicks.cpp
llpanelsnapshot.cpp
llpanelsnapshotinventory.cpp
llpanelsnapshotlocal.cpp
@@ -657,6 +659,7 @@ set(viewer_SOURCE_FILES
llviewercontrol.cpp
llviewercontrollistener.cpp
llviewerdisplay.cpp
+ llviewerdisplayname.cpp
llviewerfloaterreg.cpp
llviewerfoldertype.cpp
llviewergenericmessage.cpp
@@ -870,12 +873,14 @@ set(viewer_HEADER_FILES
llfloatercamerapresets.h
llfloatercamera.h
llfloaterchatvoicevolume.h
+ llfloaterclassified.h
llfloatercolorpicker.h
llfloaterconversationlog.h
llfloaterconversationpreview.h
llfloatercreatelandmark.h
llfloaterdeleteprefpreset.h
llfloaterdestinations.h
+ llfloaterdisplayname.h
llfloatereditenvironmentbase.h
llfloatereditextdaycycle.h
llfloaterenvironmentadjust.h
@@ -934,9 +939,11 @@ set(viewer_HEADER_FILES
llfloaterpay.h
llfloaterperms.h
llfloaterpostprocess.h
+ llfloaterprofile.h
llfloaterpreference.h
llfloaterpreferenceviewadvanced.h
llfloaterpreviewtrash.h
+ llfloaterprofiletexture.h
llfloaterproperties.h
llfloaterregiondebugconsole.h
llfloaterregioninfo.h
@@ -969,7 +976,6 @@ set(viewer_HEADER_FILES
llfloatervoiceeffect.h
llfloatervoicevolume.h
llfloaterwebcontent.h
- llfloaterwebprofile.h
llfloaterwhitelistentry.h
llfloaterwindowsize.h
llfloaterworldmap.h
@@ -1105,7 +1111,6 @@ set(viewer_HEADER_FILES
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
- llpanelme.h
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
@@ -1115,8 +1120,6 @@ set(viewer_HEADER_FILES
llpanelpeople.h
llpanelpeoplemenus.h
llpanelpermissions.h
- llpanelpick.h
- llpanelpicks.h
llpanelplaceinfo.h
llpanelplaceprofile.h
llpanelplaces.h
@@ -1125,6 +1128,8 @@ set(viewer_HEADER_FILES
llpanelpresetspulldown.h
llpanelprimmediacontrols.h
llpanelprofile.h
+ llpanelprofileclassifieds.h
+ llpanelprofilepicks.h
llpanelsnapshot.h
llpanelteleporthistory.h
llpaneltiptoast.h
@@ -1287,6 +1292,7 @@ set(viewer_HEADER_FILES
llviewercontrol.h
llviewercontrollistener.h
llviewerdisplay.h
+ llviewerdisplayname.h
llviewerfloaterreg.h
llviewerfoldertype.h
llviewergenericmessage.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 28179fc1f5..4aa5a3a58e 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.2
+6.6.8
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 3dfe3f6634..2644f5f449 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -167,10 +167,8 @@
icon="Command_Picks_Icon"
label_ref="Command_Picks_Label"
tooltip_ref="Command_Picks_Tooltip"
- execute_function="Floater.ToggleOrBringToFront"
- execute_parameters="picks"
- is_running_function="Floater.IsOpen"
- is_running_parameters="picks"
+ execute_function="Avatar.TogglePicks"
+ is_running_function="Avatar.IsPicksTabOpen"
/>
<command name="places"
available_in_toybox="true"
diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml
index 55babc88bc..8d5349550f 100644
--- a/indra/newview/app_settings/key_bindings.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -85,7 +85,6 @@
<binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
<binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
- <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
<binding key="" mask="NONE" mouse="LMB" command="script_trigger_lbutton"/>
</third_person>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 16d8cd9f06..6861153d43 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -544,17 +544,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AvalinePhoneSeparator</key>
- <map>
- <key>Comment</key>
- <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>-</string>
- </map>
<key>AvatarAxisDeadZone0</key>
<map>
<key>Comment</key>
@@ -1371,7 +1360,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>20.0</real>
+ <real>40.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
@@ -4758,7 +4747,7 @@
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
+ <string>https://search.[GRID]/?query_term=[QUERY]&amp;search_type=[TYPE][COLLECTION]&amp;maturity=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
</map>
<key>GuidebookURL</key>
<map>
@@ -5806,6 +5795,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DiskCacheVersion</key>
+ <map>
+ <key>Comment</key>
+ <string>Version number of disk cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>LocalFileSystemBrowsingEnabled</key>
<map>
<key>Comment</key>
@@ -6808,6 +6808,9 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
+ <!-- *HACK: On first run, set this to 0 for new users,
+ otherwise the default is 1 to maintain consistent experience
+ for existing users. Hardcoded in llnetmap.cpp -->
<integer>1</integer>
</map>
<key>MiniMapScale</key>
@@ -6821,6 +6824,17 @@
<key>Value</key>
<real>128.0</real>
</map>
+ <key>MiniMapShowPropertyLines</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to show parcel borders on the MiniMap.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
<key>MouseSensitivity</key>
<map>
<key>Comment</key>
@@ -7099,13 +7113,13 @@
<key>NonvisibleObjectsInMemoryTime</key>
<map>
<key>Comment</key>
- <string>Number of frames non-visible objects stay in memory before being removed. 0 means never to remove.</string>
+ <string>Number of frames non-visible objects stay in memory before being removed. 0 means max.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>300</integer>
+ <integer>64</integer>
</map>
<key>NoPreload</key>
<map>
@@ -11022,7 +11036,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>1024</integer>
+ <integer>2048</integer>
</map>
<key>SceneLoadLowMemoryBound</key>
<map>
@@ -15737,6 +15751,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>AllowSelectAvatar</key>
+ <map>
+ <key>Comment</key>
+ <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>WebProfileFloaterRect</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 02d83925ea..b26194f278 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2;
uniform float env_intensity;
uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
#endif
@@ -227,11 +227,12 @@ void main()
vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
diffcol.rgb *= vertex_color.rgb;
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-
- // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
- float bias = 0.001953125; // 1/512, or half an 8-bit quantization
- if (diffcol.a < minimum_alpha-bias)
+#ifdef HAS_ALPHA_MASK
+#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND
+ if (diffcol.a*vertex_color.a < minimum_alpha)
+#else
+ if (diffcol.a < minimum_alpha)
+#endif
{
discard;
}
diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml
index 2241a12545..6cfc0b0be2 100644
--- a/indra/newview/character/avatar_skeleton.xml
+++ b/indra/newview/character/avatar_skeleton.xml
@@ -2,15 +2,15 @@
<bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/>
- <bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
<collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
- <bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/>
<collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/>
@@ -23,58 +23,58 @@
<bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
- <bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -86,29 +86,29 @@
<collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -123,49 +123,49 @@
<collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/>
- <bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
- <bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@@ -200,30 +200,30 @@
</bone>
</bone>
</bone>
- <bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
- <bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
- <bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
- <bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
+ <bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
+ <bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae
new file mode 100644
index 0000000000..085b2c7309
--- /dev/null
+++ b/indra/newview/cube.dae
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+ <asset>
+ <contributor>
+ modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26
+ </contributor>
+ <created>2018-10-25T16:29:03Z</created>
+ <modified>2022-02-18T00:00:00Z</modified>
+ <unit meter="1.000000"/>
+ <up_axis>Y_UP</up_axis>
+ </asset>
+
+ <library_materials>
+ <material id="Blue" name="Blue">
+ <instance_effect url="#effect_Blue"/>
+ </material>
+ </library_materials>
+
+
+ <library_effects>
+ <effect id="effect_Blue">
+ <profile_COMMON>
+ <technique sid="common">
+ <phong>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <color>0.137255 0.403922 0.870588 1</color>
+ </diffuse>
+ <specular>
+ <color>0.5 0.5 0.5 1</color>
+ </specular>
+ <shininess>
+ <float>16</float>
+ </shininess>
+ <transparent opaque="A_ONE">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ <index_of_refraction>
+ <float>1</float>
+ </index_of_refraction>
+ </phong>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ </library_effects>
+
+
+ <library_geometries>
+ <geometry id="F1" name="default_physics_shape">
+ <mesh>
+
+ <source id="cube-vertex-positions">
+ <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array>
+ <technique_common>
+ <accessor source="#ID2-array" count="24" stride="3">
+ <param name="X" type="float"/>
+ <param name="Y" type="float"/>
+ <param name="Z" type="float"/>
+ </accessor>
+ </technique_common>
+ </source>
+
+ <vertices id="cube-vertices">
+ <input semantic="POSITION" source="#cube-vertex-positions"/>
+ </vertices>
+
+ <triangles count="12" material="geometryElement5">
+ <input semantic="VERTEX" offset="0" source="#cube-vertices"/>
+ <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p>
+ </triangles>
+
+ </mesh>
+ </geometry>
+ </library_geometries>
+ <library_visual_scenes>
+
+
+ <visual_scene id="reportScene">
+ <!-- No Spaces allowed in Name -->
+ <node id="F1" name="Face1">
+ <instance_geometry url="#F1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="geometryElement5" target="#Blue"/>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ </node>
+ </visual_scene>
+ </library_visual_scenes>
+
+
+ <scene>
+ <instance_visual_scene url="#reportScene"/>
+ </scene>
+
+
+</COLLADA>
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 7513908cb4..60e26274cb 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -351,11 +351,29 @@ DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
ClearErrors
+INSTALL_FILES_START:
+
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
%%INSTALL_FILES%%
+IfErrors 0 INSTALL_FILES_DONE
+ StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START
+ # MB_ABORTRETRYIGNORE does not accept IDIGNORE
+ Goto INSTALL_FILES_DONE
+
+INSTALL_FILES_CANCEL:
+ # We are quiting, cleanup.
+ # Silence warnings from RemoveProgFilesOnInst.
+ StrCpy $SKIP_DIALOGS "true"
+ Call RemoveProgFilesOnInst
+ MessageBox MB_OK $(ErrorSecondLifeInstallSupport)
+ Quit
+
+INSTALL_FILES_DONE:
+
# Pass the installer's language to the client to use as a default
StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)"
@@ -622,7 +640,9 @@ Function RemoveProgFilesOnInst
Push $0
StrCpy $0 0
-PREINSTALLREMOVE:
+ClearErrors
+
+PREINSTALL_REMOVE:
# Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
Delete "$INSTDIR\$INSTEXE"
@@ -642,17 +662,17 @@ RMDir /r "$INSTDIR\llplugin"
IntOp $0 $0 + 1
-IfErrors 0 PREINSTALLDONE
- IntCmp $0 1 PREINSTALLREMOVE #try again once
- StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE
- MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE
+IfErrors 0 PREINSTALL_DONE
+ IntCmp $0 1 PREINSTALL_REMOVE #try again once
+ StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE
+ MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE
# MB_ABORTRETRYIGNORE does not accept IDIGNORE
- Goto PREINSTALLDONE
+ Goto PREINSTALL_DONE
-PREINSTALLFAIL:
+PREINSTALL_FAIL:
Quit
-PREINSTALLDONE:
+PREINSTALL_DONE:
# We are no longer including release notes with the viewer, so remove them.
Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk"
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 648ddbfb85..73f23086be 100644
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index 188c30197a..7cc70e4c76 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
@@ -73,6 +73,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer
; CheckNetworkConnection
LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..."
+; error during installation
+LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert."
+LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com."
+
; ask to remove user's data files
LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren."
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 0639d51e10..2eaf97d023 100644
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index ee30651a38..364cc9f67e 100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 7cd90ec314..2f34c0c87a 100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index 194062da9a..51214d3a9c 100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index a54005ba14..296703d1a3 100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 355d806866..299645bbb7 100644
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index 97f5d2b44a..542c8654b5 100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index 65a9f4846d..4e53a4957d 100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index e71886cc66..bae5029ad1 100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index f5f0c6cbdf..7922d9df52 100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 7f6f6e5997..5250369813 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -96,6 +96,7 @@
#include "stringize.h"
#include "boost/foreach.hpp"
#include "llcorehttputil.h"
+#include "lluiusage.h"
using namespace LLAvatarAppearanceDefines;
@@ -574,6 +575,8 @@ void LLAgent::ageChat()
//-----------------------------------------------------------------------------
void LLAgent::moveAt(S32 direction, bool reset)
{
+ LLUIUsage::instance().logCommand("Agent.MoveAt");
+
mMoveTimer.reset();
LLFirstUse::notMoving(false);
@@ -716,6 +719,9 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
if ((getControlFlags() & mask) == mask)
{
+ // Rotation into both directions should cancel out
+ // But keep sending controls to simulator,
+ // it's needed for script based controls
gAgentCamera.setYawKey(0);
}
@@ -4023,6 +4029,7 @@ void LLAgent::startTeleportRequest()
}
if (hasPendingTeleportRequest())
{
+ LLUIUsage::instance().logCommand("Agent.StartTeleportRequest");
mTeleportCanceled.reset();
if (!isMaturityPreferenceSyncedWithServer())
{
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index f981e08ff7..21df036cb7 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -74,10 +74,10 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
-private:
-
void onServerRespond(LLAvatarPicks* picks);
+private:
+
/**
* Sets number of Picks.
*/
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 39c9fa1bca..909f32cd21 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -60,6 +60,7 @@
#include "llappviewer.h"
#include "llcoros.h"
#include "lleventcoro.h"
+#include "lluiusage.h"
#include "llavatarpropertiesprocessor.h"
@@ -1426,6 +1427,9 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
bool replace,
LLPointer<LLInventoryCallback> cb)
{
+ LL_DEBUGS("UIUsage") << "wearItemsOnAvatar" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.WearItem");
+
bool first = true;
LLInventoryObject::const_object_list_t items_to_link;
@@ -2761,6 +2765,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
<< "'" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.WearCategory");
if (gAgentCamera.cameraCustomizeAvatar())
{
@@ -3968,6 +3973,8 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo
{
if (!isAgentAvatarValid()) return;
+ LLUIUsage::instance().logCommand("Avatar.CreateNewOutfit");
+
LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL;
gAgentWearables.notifyLoadingStarted();
@@ -4006,6 +4013,9 @@ void LLAppearanceMgr::wearBaseOutfit()
void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
+ LL_DEBUGS("UIUsage") << "removeItemsFromAvatar" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Avatar.RemoveItem");
+
if (ids_to_remove.empty())
{
LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
@@ -4485,6 +4495,8 @@ public:
"Quick Appearance");
if ( gInventory.getCategory( folder_uuid ) != NULL )
{
+ // Assume this is coming from the predefined avatars web floater
+ LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance");
LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 92a5fe5893..e98e18a96e 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -557,7 +557,7 @@ static void settings_to_globals()
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
- LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
+ LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
@@ -1450,6 +1450,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
// give listeners a chance to run
llcoro::suspend();
+ // if one of our coroutines threw an uncaught exception, rethrow it now
+ LLCoros::instance().rethrow();
}
if (!LLApp::isExiting())
@@ -2490,10 +2492,24 @@ bool LLAppViewer::initConfiguration()
//Load settings files list
std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
LLXMLNodePtr root;
- BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
+ BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL);
if (!success)
{
- LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ if (gDirUtilp->fileExists(settings_file_list))
+ {
+ LL_ERRS() << "Cannot load default configuration file settings_files.xml. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_ERRS() << "Default configuration file settings_files.xml not found. "
+ << "Please reinstall viewer from https://secondlife.com/support/downloads/ "
+ << "and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
}
mSettingsLocationList = new SettingsFiles();
@@ -2716,19 +2732,14 @@ bool LLAppViewer::initConfiguration()
if (clp.hasOption("graphicslevel"))
{
- // User explicitly requested --graphicslevel on the command line. We
- // expect this switch has already set RenderQualityPerformance. Check
- // that value for validity.
- U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
- if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
- {
- // graphicslevel is valid: save it and engage it later. Capture
- // the requested value separately from the settings variable
- // because, if this is the first run, LLViewerWindow's constructor
- // will call LLFeatureManager::applyRecommendedSettings(), which
- // overwrites this settings variable!
- mForceGraphicsLevel = graphicslevel;
- }
+ // User explicitly requested --graphicslevel on the command line. We
+ // expect this switch has already set RenderQualityPerformance. Check
+ // that value for validity later.
+ // Capture the requested value separately from the settings variable
+ // because, if this is the first run, LLViewerWindow's constructor
+ // will call LLFeatureManager::applyRecommendedSettings(), which
+ // overwrites this settings variable!
+ mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance");
}
LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
@@ -3086,7 +3097,7 @@ bool LLAppViewer::initWindow()
// Initialize GL stuff
//
- if (mForceGraphicsLevel)
+ if (mForceGraphicsLevel && (LLFeatureManager::instance().isValidGraphicsLevel(*mForceGraphicsLevel)))
{
LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
@@ -3296,9 +3307,18 @@ LLSD LLAppViewer::getViewerInfo() const
info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined";
if(LLVoiceClient::getInstance()->voiceEnabled())
{
- LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ const std::string build_version = version.mBuildVersion;
std::ostringstream version_string;
- version_string << version.serverType << " " << version.serverVersion << std::endl;
+ if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(),
+ version.serverVersion.begin()))
+ { // Normal case: Show type and build version.
+ version_string << version.serverType << " " << build_version << std::endl;
+ }
+ else
+ { // Mismatch: Show both versions.
+ version_string << version.serverVersion << "/" << build_version << std::endl;
+ }
info["VOICE_VERSION"] = version_string.str();
}
else
@@ -3491,7 +3511,7 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
+ gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
// Some things are cached in LLAgent.
if (gAgent.isInitialized())
@@ -4262,6 +4282,15 @@ U32 LLAppViewer::getTextureCacheVersion()
}
//static
+U32 LLAppViewer::getDiskCacheVersion()
+{
+ // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes.
+ const U32 DISK_CACHE_VERSION = 1;
+
+ return DISK_CACHE_VERSION ;
+}
+
+//static
U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
@@ -4281,21 +4310,30 @@ bool LLAppViewer::initCache()
// initialize the new disk cache using saved settings
const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName");
+ const U32 MB = 1024 * 1024;
+ const uintmax_t MIN_CACHE_SIZE = 256 * MB;
+ const uintmax_t MAX_CACHE_SIZE = 9984ll * MB;
+ const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB;
+ const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
+ const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
+ const F64 texture_cache_percent = 100.0 - disk_cache_percent;
+
// note that the maximum size of this cache is defined as a percentage of the
// total cache size - the 'CacheSize' pref - for all caches.
- const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize");
- const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
- const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100;
- const uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024;
+ const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100);
const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo");
bool texture_cache_mismatch = false;
+ bool remove_vfs_files = false;
if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
texture_cache_mismatch = true;
if(!read_only)
{
gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
+
+ //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed
+ remove_vfs_files = true;
}
}
@@ -4337,11 +4375,23 @@ bool LLAppViewer::initCache()
}
const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name);
- LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info);
+ LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info);
if (!read_only)
{
- if (mPurgeCache)
+ if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion())
+ {
+ LLDiskCache::getInstance()->clearCache();
+ remove_vfs_files = true;
+ gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion());
+ }
+
+ if (remove_vfs_files)
+ {
+ LLDiskCache::getInstance()->removeOldVFSFiles();
+ }
+
+ if (mPurgeCache)
{
LLSplashScreen::update(LLTrans::getString("StartupClearingCache"));
purgeCache();
@@ -4360,18 +4410,10 @@ bool LLAppViewer::initCache()
LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache"));
// Init the texture cache
- // Allocate 80% of the cache size for textures
- const S32 MB = 1024 * 1024;
- const S64 MIN_CACHE_SIZE = 256 * MB;
- const S64 MAX_CACHE_SIZE = 9984ll * MB;
-
- S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
- cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE);
-
- S64 texture_cache_size = cache_size;
+ // Allocate the remaining percent which is not allocated to the disk cache
+ const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100);
- S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
- texture_cache_size -= extra;
+ LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
@@ -5061,8 +5103,7 @@ void LLAppViewer::idle()
audio_update_wind(false);
// this line actually commits the changes we've made to source positions, etc.
- const F32 max_audio_decode_time = 0.002f; // 2 ms decode time
- gAudiop->idle(max_audio_decode_time);
+ gAudiop->idle();
}
}
@@ -5423,7 +5464,7 @@ void LLAppViewer::disconnectViewer()
gFloaterView->restoreAll();
}
- if (LLSelectMgr::getInstance())
+ if (LLSelectMgr::instanceExists())
{
LLSelectMgr::getInstance()->deselectAll();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 7ab21f35cd..f28a90c703 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -130,6 +130,7 @@ public:
static U32 getTextureCacheVersion() ;
static U32 getObjectCacheVersion() ;
+ static U32 getDiskCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
@@ -153,16 +154,16 @@ public:
void removeMarkerFiles();
void removeDumpDir();
- // LLAppViewer testing helpers.
- // *NOTE: These will potentially crash the viewer. Only for debugging.
- virtual void forceErrorLLError();
- virtual void forceErrorBreakpoint();
- virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInfiniteLoop();
- virtual void forceErrorSoftwareException();
- virtual void forceErrorDriverCrash();
- virtual void forceErrorCoroutineCrash();
- virtual void forceErrorThreadCrash();
+ // LLAppViewer testing helpers.
+ // *NOTE: These will potentially crash the viewer. Only for debugging.
+ virtual void forceErrorLLError();
+ virtual void forceErrorBreakpoint();
+ virtual void forceErrorBadMemoryAccess();
+ virtual void forceErrorInfiniteLoop();
+ virtual void forceErrorSoftwareException();
+ virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 1797d2dd6e..3e450e6dec 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -48,6 +48,7 @@
#include "llfloatergroups.h"
#include "llfloaterreg.h"
#include "llfloaterpay.h"
+#include "llfloaterprofile.h"
#include "llfloatersidepanelcontainer.h"
#include "llfloaterwebcontent.h"
#include "llfloaterworldmap.h"
@@ -62,11 +63,14 @@
#include "llnotificationsutil.h" // for LLNotificationsUtil
#include "llpaneloutfitedit.h"
#include "llpanelprofile.h"
+#include "llparcel.h"
#include "llrecentpeople.h"
#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "llviewermessage.h" // for handle_lure
+#include "llviewernetwork.h" //LLGridManager
+#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
#include "lltrans.h"
#include "llcallingcard.h"
@@ -74,6 +78,7 @@
#include "llsidepanelinventory.h"
#include "llavatarname.h"
#include "llagentui.h"
+#include "lluiusage.h"
// Flags for kick message
const U32 KICK_FLAGS_DEFAULT = 0x0;
@@ -81,6 +86,19 @@ const U32 KICK_FLAGS_FREEZE = 1 << 0;
const U32 KICK_FLAGS_UNFREEZE = 1 << 1;
+std::string getProfileURL(const std::string& agent_name, bool feed_only)
+{
+ std::string url = "[WEB_PROFILE_URL][AGENT_NAME][FEED_ONLY]";
+ LLSD subs;
+ subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
+ subs["AGENT_NAME"] = agent_name;
+ subs["FEED_ONLY"] = feed_only ? "/?feed_only=true" : "";
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLStringUtil::toLower(url);
+ return url;
+}
+
+
// static
void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
{
@@ -96,7 +114,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
payload["id"] = id;
payload["name"] = name;
- LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
+ LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
// add friend to recent people list
LLRecentPeople::instance().add(id);
@@ -316,57 +334,144 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
make_ui_sound("UISndStartIM");
}
-static const char* get_profile_floater_name(const LLUUID& avatar_id)
+// static
+void LLAvatarActions::showProfile(const LLUUID& avatar_id)
{
- // Use different floater XML for our profile to be able to save its rect.
- return avatar_id == gAgentID ? "my_profile" : "profile";
+ if (avatar_id.notNull())
+ {
+ LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id));
+ }
}
-static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
+// static
+void LLAvatarActions::showPicks(const LLUUID& avatar_id)
{
- std::string url = getProfileURL(av_name.getAccountName());
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick();
+ }
+ }
+}
- // PROFILES: open in webkit window
- LLFloaterWebContent::Params p;
- p.url(url).id(agent_id.asString());
- LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
+// static
+void LLAvatarActions::showPick(const LLUUID& avatar_id, const LLUUID& pick_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showPick(pick_id);
+ }
+ }
+}
+
+// static
+void LLAvatarActions::createPick()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ LLViewerRegion* region = gAgent.getRegion();
+ if (profilefloater && region)
+ {
+ LLPickData data;
+ data.pos_global = gAgent.getPositionGlobal();
+ data.sim_name = region->getName();
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ data.name = parcel->getName();
+ data.desc = parcel->getDesc();
+ data.snapshot_id = parcel->getSnapshotID();
+ data.parcel_id = parcel->getID();
+ }
+ else
+ {
+ data.name = region->getName();
+ }
+
+ profilefloater->createPick(data);
+ }
}
// static
-void LLAvatarActions::showProfile(const LLUUID& id)
+bool LLAvatarActions::isPickTabSelected(const LLUUID& avatar_id)
{
- if (id.notNull())
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ if (profilefloater)
+ {
+ return profilefloater->isPickTabSelected();
+ }
+ }
+ return false;
+}
+
+// static
+void LLAvatarActions::showClassifieds(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified();
+ }
+ }
+}
+
+// static
+void LLAvatarActions::showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit)
+{
+ if (avatar_id.notNull())
{
- LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_show_profile, _1, _2));
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", avatar_id)));
+ if (profilefloater)
+ {
+ profilefloater->showClassified(classified_id, edit);
+ }
}
}
+// static
+void LLAvatarActions::createClassified()
+{
+ LLFloaterProfile* profilefloater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgent.getID())));
+ if (profilefloater)
+ {
+ profilefloater->createClassified();
+ }
+}
+
//static
-bool LLAvatarActions::profileVisible(const LLUUID& id)
+bool LLAvatarActions::profileVisible(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- return browser && browser->isShown();
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ return floater && floater->isShown();
}
//static
-LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& id)
+LLFloater* LLAvatarActions::getProfileFloater(const LLUUID& avatar_id)
{
- LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*>
- (LLFloaterReg::findInstance(get_profile_floater_name(id), LLSD().with("id", id)));
- return browser;
+ LLFloaterProfile* floater = LLFloaterReg::findTypedInstance<LLFloaterProfile>("profile", LLSD().with("id", avatar_id));
+ return floater;
}
//static
-void LLAvatarActions::hideProfile(const LLUUID& id)
+void LLAvatarActions::hideProfile(const LLUUID& avatar_id)
{
LLSD sd;
- sd["id"] = id;
- LLFloater* browser = getProfileFloater(id);
- if (browser)
+ sd["id"] = avatar_id;
+ LLFloater* floater = getProfileFloater(avatar_id);
+ if (floater)
{
- browser->closeFloater();
+ floater->closeFloater();
}
}
@@ -990,7 +1095,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
}
// static
-void LLAvatarActions::toggleBlock(const LLUUID& id)
+bool LLAvatarActions::toggleBlock(const LLUUID& id)
{
LLAvatarName av_name;
LLAvatarNameCache::get(id, &av_name);
@@ -1000,10 +1105,12 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
{
LLMuteList::getInstance()->remove(mute);
+ return false;
}
else
{
LLMuteList::getInstance()->add(mute);
+ return true;
}
}
@@ -1312,6 +1419,8 @@ bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& respo
void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
{
const LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ LLUIUsage::instance().logCommand("Agent.SendFriendRequest");
+
send_improved_im(target_id,
target_name,
message,
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 7c721076c8..86183cc119 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -38,6 +38,8 @@ class LLInventoryPanel;
class LLFloater;
class LLView;
+std::string getProfileURL(const std::string& agent_name, bool feed_only = false);
+
/**
* Friend-related actions (add, remove, offer teleport, etc)
*/
@@ -91,13 +93,20 @@ public:
*/
static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
- /**
- * Show avatar profile.
- */
- static void showProfile(const LLUUID& id);
- static void hideProfile(const LLUUID& id);
- static bool profileVisible(const LLUUID& id);
- static LLFloater* getProfileFloater(const LLUUID& id);
+ /**
+ * Show avatar profile.
+ */
+ static void showProfile(const LLUUID& avatar_id);
+ static void showPicks(const LLUUID& avatar_id);
+ static void showPick(const LLUUID& avatar_id, const LLUUID& pick_id);
+ static void createPick();
+ static void showClassifieds(const LLUUID& avatar_id);
+ static void showClassified(const LLUUID& avatar_id, const LLUUID& classified_id, bool edit = false);
+ static void createClassified();
+ static void hideProfile(const LLUUID& avatar_id);
+ static bool profileVisible(const LLUUID& avatar_id);
+ static bool isPickTabSelected(const LLUUID& avatar_id);
+ static LLFloater* getProfileFloater(const LLUUID& avatar_id);
/**
* Show avatar on world map.
@@ -126,9 +135,10 @@ public:
static void shareWithAvatars(LLView * panel);
/**
- * Block/unblock the avatar.
+ * Block/unblock the avatar by id.
+ * Returns true if blocked, returns false if unblocked
*/
- static void toggleBlock(const LLUUID& id);
+ static bool toggleBlock(const LLUUID& id);
/**
* Mute/unmute avatar.
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index b0715a3afd..c0990d9d11 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/)
}
}
-void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name)
-{
- LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL;
- LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
- item->setAvatarId(item_id, session_id, true, false);
- item->setName(item_name);
- item->showLastInteractionTime(mShowLastInteractionTime);
- item->showSpeakingIndicator(mShowSpeakingIndicator);
- item->setOnline(false);
-
- addItem(item, item_id);
- mIDs.push_back(item_id);
- sort();
-}
-
//////////////////////////////////////////////////////////////////////////
// PROTECTED SECTION
//////////////////////////////////////////////////////////////////////////
@@ -296,18 +281,10 @@ void LLAvatarList::refresh()
{
// *NOTE: If you change the UI to show a different string,
// be sure to change the filter code below.
- if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
- {
- const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
- addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
- }
- else
- {
- std::string display_name = getAvatarName(av_name);
- addNewItem(buddy_id,
- display_name.empty() ? waiting_str : display_name,
- LLAvatarTracker::instance().isBuddyOnline(buddy_id));
- }
+ std::string display_name = getAvatarName(av_name);
+ addNewItem(buddy_id,
+ display_name.empty() ? waiting_str : display_name,
+ LLAvatarTracker::instance().isBuddyOnline(buddy_id));
modified = true;
nadded++;
@@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- if ( mContextMenu && !isAvalineItemSelected())
+ if ( mContextMenu)
{
uuid_vec_t selected_uuids;
getSelectedUUIDs(selected_uuids);
@@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
-bool LLAvatarList::isAvalineItemSelected()
-{
- std::vector<LLPanel*> selected_items;
- getSelectedItems(selected_items);
- std::vector<LLPanel*>::iterator it = selected_items.begin();
-
- for(; it != selected_items.end(); ++it)
- {
- if (dynamic_cast<LLAvalineListItem*>(*it))
- return true;
- }
-
- return false;
-}
-
void LLAvatarList::setVisible(BOOL visible)
{
if ( visible == FALSE && mContextMenu )
@@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_
}
return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2);
}
-
-/************************************************************************/
-/* class LLAvalineListItem */
-/************************************************************************/
-LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false)
-, mIsHideNumber(hide_number)
-{
- // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called.
- buildFromFile( "panel_avatar_list_item.xml");
-}
-
-BOOL LLAvalineListItem::postBuild()
-{
- BOOL rv = LLAvatarListItem::postBuild();
-
- if (rv)
- {
- setOnline(true);
- showLastInteractionTime(false);
- setShowProfileBtn(false);
- setShowInfoBtn(false);
- mAvatarIcon->setValue("Avaline_Icon");
- mAvatarIcon->setToolTip(std::string(""));
- }
- return rv;
-}
-
-// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number
-void LLAvalineListItem::setName(const std::string& name)
-{
- if (mIsHideNumber)
- {
- static U32 order = 0;
- typedef std::map<LLUUID, U32> avaline_callers_nums_t;
- static avaline_callers_nums_t mAvalineCallersNums;
-
- llassert(getAvatarId() != LLUUID::null);
-
- const LLUUID &uuid = getAvatarId();
-
- if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end())
- {
- mAvalineCallersNums[uuid] = ++order;
- LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL;
- }
- LLStringUtil::format_map_t args;
- args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]);
- std::string hidden_name = LLTrans::getString("AvalineCaller", args);
-
- LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL;
- LLAvatarListItem::setAvatarName(hidden_name);
- LLAvatarListItem::setAvatarToolTip(hidden_name);
- }
- else
- {
- const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
- LLAvatarListItem::setAvatarName(formatted_phone);
- LLAvatarListItem::setAvatarToolTip(formatted_phone);
- }
-}
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 1a672c279b..48b0e70454 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -98,7 +98,6 @@ public:
virtual S32 notifyParent(const LLSD& info);
- void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name);
void handleDisplayNamesOptionChanged();
void setShowCompleteName(bool show) { mShowCompleteName = show;};
@@ -118,8 +117,6 @@ protected:
private:
- bool isAvalineItemSelected();
-
bool mIgnoreOnlineStatus;
bool mShowLastInteractionTime;
bool mDirty;
@@ -189,27 +186,4 @@ protected:
virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
};
-/**
- * Represents Avaline caller in Avatar list in Voice Control Panel and group chats.
- */
-class LLAvalineListItem : public LLAvatarListItem
-{
-public:
-
- /**
- * Constructor
- *
- * @param hide_number - flag indicating if number should be hidden.
- * In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc.
- */
- LLAvalineListItem(bool hide_number = true);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setName(const std::string& name);
-
-private:
- bool mIsHideNumber;
-};
-
#endif // LL_LLAVATARLIST_H
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index f41eb3daf4..dd0d06a8c8 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -36,6 +36,7 @@
#include "llstartup.h"
// Linden library includes
+#include "llavataractions.h" // for getProfileUrl
#include "lldate.h"
#include "lltrans.h"
#include "llui.h" // LLUI::getLanguage()
@@ -94,54 +95,98 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
}
}
-
-void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method)
+void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
+ // this is the startup state when send_complete_agent_movement() message is sent.
+ // Before this messages won't work so don't bother trying
+ if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
+ {
+ return;
+ }
+
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+
// Suppress duplicate requests while waiting for a response from the network
if (isPendingRequest(avatar_id, type))
{
// waiting for a response, don't re-request
return;
}
- // indicate we're going to make a request
- addPendingRequest(avatar_id, type);
- std::vector<std::string> strings;
- strings.push_back( avatar_id.asString() );
- send_generic_message(method, strings);
+ std::string cap;
+
+ switch (type)
+ {
+ case APT_PROPERTIES:
+ // indicate we're going to make a request
+ sendAvatarPropertiesRequestMessage(avatar_id);
+ // can use getRegionCapability("AgentProfile"), but it is heavy
+ // initAgentProfileCapRequest(avatar_id, cap);
+ break;
+ case APT_PICKS:
+ case APT_GROUPS:
+ case APT_NOTES:
+ if (cap.empty())
+ {
+ // indicate we're going to make a request
+ sendGenericRequest(avatar_id, type, method);
+ }
+ else
+ {
+ initAgentProfileCapRequest(avatar_id, cap);
+ }
+ break;
+ default:
+ sendGenericRequest(avatar_id, type, method);
+ break;
+ }
}
-void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method)
{
- // this is the startup state when send_complete_agent_movement() message is sent.
- // Before this, the AvatarPropertiesRequest message
- // won't work so don't bother trying
- if (LLStartUp::getStartupState() <= STATE_AGENT_SEND)
- {
- return;
- }
+ // indicate we're going to make a request
+ addPendingRequest(avatar_id, type);
- if (isPendingRequest(avatar_id, APT_PROPERTIES))
- {
- // waiting for a response, don't re-request
- return;
- }
- // indicate we're going to make a request
- addPendingRequest(avatar_id, APT_PROPERTIES);
+ std::vector<std::string> strings;
+ strings.push_back(avatar_id.asString());
+ send_generic_message(method, strings);
+}
- LLMessageSystem *msg = gMessageSystem;
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
- msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->addUUIDFast( _PREHASH_AvatarID, avatar_id);
- gAgent.sendReliableMessage();
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
+{
+ addPendingRequest(avatar_id, APT_PROPERTIES);
+ addPendingRequest(avatar_id, APT_PICKS);
+ addPendingRequest(avatar_id, APT_GROUPS);
+ addPendingRequest(avatar_id, APT_NOTES);
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
+}
+
+void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
+{
+ sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
{
- sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
+ sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
}
void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
@@ -174,7 +219,7 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData*
return;
}
- LL_INFOS() << "Sending avatarinfo update" << LL_ENDL;
+ LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
// This value is required by sendAvatarPropertiesUpdate method.
//A profile should never be mature. (From the original code)
@@ -266,6 +311,113 @@ bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avata
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
+// static
+void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ LLAvatarPropertiesProcessor* self = getInstance();
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->removePendingRequest(agent_id, APT_NOTES);
+ return;
+ }
+
+ // Avatar Data
+
+ LLAvatarData avatar_data;
+ std::string birth_date;
+
+ avatar_data.agent_id = agent_id;
+ avatar_data.avatar_id = agent_id;
+ avatar_data.image_id = result["sl_image_id"].asUUID();
+ avatar_data.fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data.partner_id = result["partner_id"].asUUID();
+ avatar_data.about_text = result["sl_about_text"].asString();
+ avatar_data.fl_about_text = result["fl_about_text"].asString();
+ avatar_data.born_on = result["member_since"].asDate();
+ avatar_data.profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data.flags = 0;
+ avatar_data.caption_index = 0;
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PROPERTIES);
+ self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_PICKS);
+ self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ self->removePendingRequest(agent_id, APT_GROUPS);
+ self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ // Request processed, no longer pending
+ self->removePendingRequest(agent_id, APT_NOTES);
+ self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
+}
+
void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
{
LLAvatarData avatar_data;
@@ -312,6 +464,21 @@ void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* m
That will suppress the warnings and be compatible with old server versions.
WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
*/
+
+ LLInterestsData interests_data;
+
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
+ msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
+ msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
+ msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
+ msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
+
+ LLAvatarPropertiesProcessor* self = getInstance();
+ // Request processed, no longer pending
+ self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
+ self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@@ -385,7 +552,7 @@ void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg,
void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
{
LLAvatarPicks avatar_picks;
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.target_id);
+ msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
@@ -551,6 +718,29 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
+void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
+{
+ if(!interests_data)
+ {
+ return;
+ }
+
+ LLMessageSystem* msg = gMessageSystem;
+
+ msg->newMessage(_PREHASH_AvatarInterestsUpdate);
+ msg->nextBlockFast( _PREHASH_AgentData);
+ msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
+ msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
+ msg->nextBlockFast( _PREHASH_PropertiesData);
+ msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
+ msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
+ msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
+ msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
+ msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
+
+ gAgent.sendReliableMessage();
+}
+
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
if (!new_pick) return;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index b063048c26..f778634d25 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -56,10 +56,22 @@ enum EAvatarProcessorType
APT_PICKS,
APT_PICK_INFO,
APT_TEXTURES,
+ APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
+struct LLInterestsData
+{
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ U32 want_to_mask;
+ std::string want_to_text;
+ U32 skills_mask;
+ std::string skills_text;
+ std::string languages_text;
+};
+
struct LLAvatarData
{
LLUUID agent_id;
@@ -223,6 +235,8 @@ public:
void sendClassifiedDelete(const LLUUID& classified_id);
+ void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
+
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
static std::string accountType(const LLAvatarData* avatar_data);
@@ -234,6 +248,8 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+ static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
+
static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
@@ -252,7 +268,10 @@ public:
protected:
- void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method);
+ void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
+ void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index fe94cd27b6..275f17b02a 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -320,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
// make sure we won't re-report, coro will update timer with correct time later
regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS);
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ try
+ {
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
@@ -343,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
// make sure we won't re-request, coro will update timer with correct time later
regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST);
- // First send a request to get the latest data
- std::string coroname =
- LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
- boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ try
+ {
+ // First send a request to get the latest data
+ std::string coroname =
+ LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro",
+ boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle()));
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
+ }
}
}
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 8d1e9a438e..1ad2157df0 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -53,6 +53,7 @@
#include "llviewerobjectlist.h"
#include "llvoavatar.h"
#include "llavataractions.h"
+#include "lluiusage.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
@@ -294,6 +295,8 @@ void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const
void LLAvatarTracker::terminateBuddy(const LLUUID& id)
{
LL_DEBUGS() << "LLAvatarTracker::terminateBuddy()" << LL_ENDL;
+ LLUIUsage::instance().logCommand("Agent.TerminateFriendship");
+
LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id);
if(!buddy) return;
mBuddyInfo.erase(id);
@@ -640,6 +643,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
if(mBuddyInfo.find(agent_related) != mBuddyInfo.end())
{
(mBuddyInfo[agent_related])->setRightsTo(new_rights);
+ mChangedBuddyIDs.insert(agent_related);
}
}
else
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index e400609a74..72f667a0b8 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -568,8 +568,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
// how to chat
gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
- LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command
-
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index bdd516e1de..7ff24f64ac 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -48,6 +48,7 @@
#include "llspeakers.h" //for LLIMSpeakerMgr
#include "lltrans.h"
#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
#include "llfloatersidepanelcontainer.h"
#include "llmutelist.h"
#include "llstylemap.h"
@@ -118,6 +119,7 @@ public:
mSourceType(CHAT_SOURCE_UNKNOWN),
mFrom(),
mSessionID(),
+ mCreationTime(time_corrected()),
mMinUserNameWidth(0),
mUserNameFont(NULL),
mUserNameTextBox(NULL),
@@ -403,6 +405,48 @@ public:
{
LLAvatarActions::pay(getAvatarId());
}
+ else if (level == "report_abuse")
+ {
+ std::string time_string;
+ if (mTime > 0) // have frame time
+ {
+ time_t current_time = time_corrected();
+ time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime;
+
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] ["
+ + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "]";
+
+ LLSD substitution;
+
+ substitution["datetime"] = (S32)message_time;
+ LLStringUtil::format(time_string, substitution);
+ }
+ else
+ {
+ // From history. This might be empty or not full.
+ // See LLChatLogParser::parse
+ time_string = getChild<LLTextBox>("time_box")->getValue().asString();
+
+ // Just add current date if not full.
+ // Should be fine since both times are supposed to be stl
+ if (!time_string.empty() && time_string.size() < 7)
+ {
+ time_string = "[" + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] " + time_string;
+
+ LLSD substitution;
+ // To avoid adding today's date to yesterday's timestamp,
+ // use creation time instead of current time
+ substitution["datetime"] = (S32)mCreationTime;
+ LLStringUtil::format(time_string, substitution);
+ }
+ }
+ LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText);
+ }
else if(level == "block_unblock")
{
LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat);
@@ -477,6 +521,10 @@ public:
{
return canModerate(userdata);
}
+ else if (level == "report_abuse")
+ {
+ return gAgentID != mAvatarID;
+ }
else if (level == "can_ban_member")
{
return canBanGroupMember(getAvatarId());
@@ -634,6 +682,12 @@ public:
mSessionID = chat.mSessionID;
mSourceType = chat.mSourceType;
+ // To be able to report a message, we need a copy of it's text
+ // and it's easier to store text directly than trying to get
+ // it from a lltextsegment or chat's mEditor
+ mText = chat.mText;
+ mTime = chat.mTime;
+
//*TODO overly defensive thing, source type should be maintained out there
if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()))
{
@@ -983,6 +1037,9 @@ protected:
EChatSourceType mSourceType;
std::string mFrom;
LLUUID mSessionID;
+ std::string mText;
+ F64 mTime; // IM's frame time
+ time_t mCreationTime; // Views's time
S32 mMinUserNameWidth;
const LLFontGL* mUserNameFont;
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 80d810d159..036ff17074 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
pickerp->getCurG (),
pickerp->getCurB (),
subject->mColor.mV[VALPHA] ); // keep current alpha
- subject->mColor = updatedColor;
- subject->setControlValue(updatedColor.getValue());
- pickerp->setRevertOnCancel(TRUE);
+
+ bool color_changed = subject->mColor != updatedColor;
+ if (color_changed)
+ {
+ subject->mColor = updatedColor;
+ subject->setControlValue(updatedColor.getValue());
+ }
+
if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback)
{
subject->mOnCancelCallback( subject, LLSD());
@@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op )
// just commit change
subject->onCommit ();
}
+
+ if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT)
+ {
+ // both select and cancel close LLFloaterColorPicker
+ // but COLOR_CHANGE does not
+ subject->setFocus(TRUE);
+ }
}
}
}
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 86e23e7c83..97b16a5e93 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
"can_invite_to_group" == command_name ||
"can_share" == command_name ||
"can_block" == command_name ||
- "can_pay" == command_name)
+ "can_pay" == command_name ||
+ "report_abuse" == command_name)
{
return is_p2p;
}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a685639427..9ec4fb085b 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
items.push_back(std::string("map"));
items.push_back(std::string("share"));
items.push_back(std::string("pay"));
+ items.push_back(std::string("report_abuse"));
items.push_back(std::string("block_unblock"));
items.push_back(std::string("MuteText"));
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 20fa6d490b..48c7df40df 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -272,9 +272,9 @@ BOOL LLConversationViewSession::postBuild()
default:
break;
}
- }
- refresh();
+ refresh(); // requires vmi
+ }
return TRUE;
}
@@ -490,17 +490,20 @@ void LLConversationViewSession::refresh()
{
// Refresh the session view from its model data
LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
- vmi->resetRefresh();
+ if (vmi)
+ {
+ vmi->resetRefresh();
- if (mSessionTitle)
- {
- if (!highlightFriendTitle(vmi))
- {
- LLStyle::Params title_style;
- title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
- mSessionTitle->setText(vmi->getDisplayName(), title_style);
- }
- }
+ if (mSessionTitle)
+ {
+ if (!highlightFriendTitle(vmi))
+ {
+ LLStyle::Params title_style;
+ title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
+ mSessionTitle->setText(vmi->getDisplayName(), title_style);
+ }
+ }
+ }
// Update all speaking indicators
LLSpeakingIndicatorManager::updateSpeakingIndicators();
@@ -524,8 +527,11 @@ void LLConversationViewSession::refresh()
}
requestArrange();
- // Do the regular upstream refresh
- LLFolderViewFolder::refresh();
+ if (vmi)
+ {
+ // Do the regular upstream refresh
+ LLFolderViewFolder::refresh();
+ }
}
void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
@@ -627,8 +633,11 @@ BOOL LLConversationViewParticipant::postBuild()
}
updateChildren();
- LLFolderViewItem::postBuild();
- refresh();
+ if (getViewModelItem())
+ {
+ LLFolderViewItem::postBuild();
+ refresh();
+ }
return TRUE;
}
@@ -712,10 +721,10 @@ void LLConversationViewParticipant::refresh()
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+
+ // Do the regular upstream refresh
+ LLFolderViewItem::refresh();
}
-
- // Do the regular upstream refresh
- LLFolderViewItem::refresh();
}
void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 7d4961c598..4d9ef99319 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
{
}
+void LLDoNotDisturbNotificationStorage::reset()
+{
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+}
+
void LLDoNotDisturbNotificationStorage::initialize()
{
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"));
+ reset();
getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index c6f0bf1ab5..237d58b4de 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -61,6 +61,7 @@ public:
void loadNotifications();
void updateNotifications();
void removeNotification(const char * name, const LLUUID& id);
+ void reset();
protected:
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 2372ea01a6..2a0f4c93ac 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -133,6 +133,7 @@ public:
inline LLFace* getFace(const S32 i) const;
inline S32 getNumFaces() const;
face_list_t& getFaces() { return mFaces; }
+ const face_list_t& getFaces() const { return mFaces; }
//void removeFace(const S32 i); // SJB: Avoid using this, it's slow
LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index e674707c01..6c1abb24c9 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -58,6 +58,7 @@ static BOOL deferred_render = FALSE;
// minimum alpha before discarding a fragment
static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
+
// minimum alpha before discarding a fragment when rendering impostors
static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f;
@@ -147,6 +148,10 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ {
+ prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials
+ }
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);
@@ -215,9 +220,15 @@ void LLDrawPoolAlpha::render(S32 pass)
{
minimum_alpha = MINIMUM_IMPOSTOR_ALPHA;
}
+
prepare_forward_shader(fullbright_shader, minimum_alpha);
prepare_forward_shader(simple_shader, minimum_alpha);
+ for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ {
+ prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha);
+ }
+
//first pass -- rigged only and drawn to depth buffer
forwardRender(true);
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 63e7887d81..361a7666fa 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
}
- if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
+ if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
{ //using offscreen render target, just use the bottom left corner
mOrigin.set(0, 0);
}
@@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
+ bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
if (use_fbo)
{
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index b76dc6a961..1300cf3658 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -2641,7 +2641,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3
if (!water.isUndefined())
{
- environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time));
+ environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time));
}
if (updateenvironment)
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 1605e4133d..9bb3bac104 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -504,20 +504,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
is.close();
}
- //get time domain
- LLSD::Real cur_total_time = 0.0;
-
- for (U32 i = 0; i < cur_data.size(); ++i)
- {
- cur_total_time += cur_data[i]["Total"]["Time"].asReal();
- }
-
- LLSD::Real base_total_time = 0.0;
- for (U32 i = 0; i < base_data.size(); ++i)
- {
- base_total_time += base_data[i]["Total"]["Time"].asReal();
- }
-
//allocate raw scratch space
LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index a02bb56489..70e8437190 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -471,7 +471,25 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
}
// check if we are dragging an existing item from the favorites bar
- if (item && mDragItemId == item->getUUID())
+ bool existing_drop = false;
+ if (item && mDragItemId == item->getUUID())
+ {
+ // There is a chance of mDragItemId being obsolete
+ // ex: can happen if something interrupts viewer, which
+ // results in viewer not geting a 'mouse up' signal
+ for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
+ {
+ LLViewerInventoryItem* currItem = *i;
+
+ if (currItem->getUUID() == mDragItemId)
+ {
+ existing_drop = true;
+ break;
+ }
+ }
+ }
+
+ if (existing_drop)
{
*accept = ACCEPT_YES_SINGLE;
@@ -500,6 +518,7 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
if (mItems.empty())
{
setLandingTab(NULL);
+ mLastTab = NULL;
}
handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
}
@@ -515,6 +534,12 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
{
+ if (mItems.empty())
+ {
+ // Isn't supposed to be empty
+ return;
+ }
+
// Identify the button hovered and the side to drop
LLFavoriteLandmarkButton* dest = dynamic_cast<LLFavoriteLandmarkButton*>(mLandingTab);
bool insert_before = true;
@@ -787,6 +812,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
if(mItems.empty())
{
mBarLabel->setVisible(TRUE);
+ mLastTab = NULL;
}
else
{
@@ -833,6 +859,10 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
dynamic_cast<LLFavoriteLandmarkButton*> (*cur_it);
if (button)
{
+ if (mLastTab == button)
+ {
+ mLastTab = NULL;
+ }
removeChild(button);
delete button;
}
@@ -870,6 +900,17 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
mLastTab = last_new_button;
}
+ if (!mLastTab && mItems.size() > 0)
+ {
+ // mMoreTextBox was removed, so LLFavoriteLandmarkButtons
+ // should be the only ones in the list
+ LLFavoriteLandmarkButton* button = dynamic_cast<LLFavoriteLandmarkButton*> (childs->back());
+ if (button)
+ {
+ mLastTab = button;
+ }
+ }
+
mFirstDropDownItem = j;
// Chevron button
if (mFirstDropDownItem < mItems.size())
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index ffbb0bbee9..c075f7e8bd 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild()
// by default each time vs restoring the last value
mQualityRadioGroup->setSelectedIndex(0);
+ return true;
+}
+
+void LLFloater360Capture::onOpen(const LLSD& key)
+{
// Construct a URL pointing to the first page to load. Although
// we do not use this page for anything (after some significant
// design changes), we retain the code to load the start page
@@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild()
// We do an initial capture when the floater is opened, albeit at a 'preview'
// quality level (really low resolution, but really fast)
onCapture360ImagesBtn();
-
- return true;
}
// called when the user choose a quality level using
diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h
index 6da7ee074a..8f765c0b1b 100644
--- a/indra/newview/llfloater360capture.h
+++ b/indra/newview/llfloater360capture.h
@@ -47,6 +47,7 @@ class LLFloater360Capture:
~LLFloater360Capture();
BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
void changeInterestListMode(bool send_everything);
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index ab95bc06b8..0186c4aebe 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mNumResultsReturned(0),
mNearMeListComplete(FALSE),
mCloseOnSelect(FALSE),
+ mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
mContextConeInAlpha(0.f),
mContextConeOutAlpha(0.f),
@@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe()
for(U32 i=0; i<avatar_ids.size(); i++)
{
LLUUID& av = avatar_ids[i];
- if(av == gAgent.getID()) continue;
+ if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue;
LLSD element;
element["id"] = av; // value
LLAvatarName av_name;
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index a3037ed651..ed3dc37043 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild()
loaderp->serialize(dp);
dp.reset();
LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
- BOOL success = motionp && motionp->deserialize(dp, mMotionID);
+ BOOL success = motionp && motionp->deserialize(dp, mMotionID, false);
LL_INFOS("BVH") << "Done" << LL_ENDL;
delete []buffer;
@@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT
mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
mDummyAvatar->mSpecialRenderMode = 1;
mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- mDummyAvatar->hideSkirt();
+
+ // on idle overall apperance update will set skirt to visible, so either
+ // call early or account for mSpecialRenderMode in updateMeshVisibility
+ mDummyAvatar->updateOverallAppearance();
+ mDummyAvatar->hideHair();
+ mDummyAvatar->hideSkirt();
// stop extraneous animations
mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
@@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render()
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
avatarp->dirtyMesh();
+ gPipeline.enableLightsPreview();
avatarPoolp->renderAvatars(avatarp); // renders only one avatar
}
}
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
index 45aea00a49..67c412dfa6 100644
--- a/indra/newview/llfloaterchatvoicevolume.cpp
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -35,7 +35,7 @@ LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
{
LLInspect::onOpen(key);
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(key);
}
LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
diff --git a/indra/newview/llfloaterclassified.cpp b/indra/newview/llfloaterclassified.cpp
new file mode 100644
index 0000000000..3520b0f67a
--- /dev/null
+++ b/indra/newview/llfloaterclassified.cpp
@@ -0,0 +1,71 @@
+/**
+ * @file llfloaterclassified.cpp
+ * @brief LLFloaterClassified for displaying classifieds.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llfloaterclassified.h"
+
+LLFloaterClassified::LLFloaterClassified(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLFloaterClassified::~LLFloaterClassified()
+{
+}
+
+void LLFloaterClassified::onOpen(const LLSD& key)
+{
+ LLPanel* panel = findChild<LLPanel>("main_panel", true);
+ if (panel)
+ {
+ panel->onOpen(key);
+ }
+ if (key.has("classified_name"))
+ {
+ setTitle(key["classified_name"].asString());
+ }
+ LLFloater::onOpen(key);
+}
+
+BOOL LLFloaterClassified::postBuild()
+{
+ return TRUE;
+}
+
+
+bool LLFloaterClassified::matchesKey(const LLSD& key)
+{
+ bool is_mkey_valid = mKey.has("classified_id");
+ bool is_key_valid = key.has("classified_id");
+ if (is_mkey_valid && is_key_valid)
+ {
+ return key["classified_id"].asUUID() == mKey["classified_id"].asUUID();
+ }
+ return is_mkey_valid == is_key_valid;
+}
+
+// eof
diff --git a/indra/newview/llfloaterwebprofile.h b/indra/newview/llfloaterclassified.h
index 4c355e401b..2c95d82b2c 100644
--- a/indra/newview/llfloaterwebprofile.h
+++ b/indra/newview/llfloaterclassified.h
@@ -1,59 +1,45 @@
-/**
- * @file llfloaterwebprofile.h
- * @brief Avatar profile floater.
+/**
+ * @file llfloaterclassified.h
+ * @brief LLFloaterClassified for displaying classifieds.
*
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * Copyright (C) 2022, 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_LLFLOATERWEBPROFILE_H
-#define LL_LLFLOATERWEBPROFILE_H
-
-#include "llfloaterwebcontent.h"
-#include "llviewermediaobserver.h"
+#ifndef LL_LLFLOATERCLASSIFIED_H
+#define LL_LLFLOATERCLASSIFIED_H
-#include <string>
+#include "llfloater.h"
-class LLMediaCtrl;
-
-/**
- * Displays avatar profile web page.
- */
-class LLFloaterWebProfile
-: public LLFloaterWebContent
+class LLFloaterClassified : public LLFloater
{
- LOG_CLASS(LLFloaterWebProfile);
+ LOG_CLASS(LLFloaterClassified);
public:
- typedef LLFloaterWebContent::Params Params;
+ LLFloaterClassified(const LLSD& key);
+ virtual ~LLFloaterClassified();
- LLFloaterWebProfile(const Params& key);
+ void onOpen(const LLSD& key) override;
+ BOOL postBuild() override;
- /*virtual*/ void onOpen(const LLSD& key);
- /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
-
- static LLFloater* create(const LLSD& key);
-
-private:
- void applyPreferredRect();
+ bool matchesKey(const LLSD& key) override;
};
-#endif // LL_LLFLOATERWEBPROFILE_H
-
+#endif // LL_LLFLOATERCLASSIFIED_H
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 1a784223c2..ba91277c79 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -173,7 +173,6 @@ void LLFloaterColorPicker::showUI ()
openFloater(getKey());
setVisible ( TRUE );
setFocus ( TRUE );
- setRevertOnCancel(FALSE);
// HACK: if system color picker is required - close the SL one we made and use default system dialog
if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) )
@@ -185,15 +184,23 @@ void LLFloaterColorPicker::showUI ()
// code that will get switched in for default system color picker
if ( swatch )
{
+ // Todo: this needs to be threaded for viewer not to timeout
LLColor4 curCol = swatch->get ();
send_agent_pause();
- getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
+ bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] );
send_agent_resume();
- setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
- setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] );
-
- LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE );
+ if (commit)
+ {
+ setOrigRgb(curCol[0], curCol[1], curCol[2]);
+ setCurRgb(curCol[0], curCol[1], curCol[2]);
+
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT);
+ }
+ else
+ {
+ LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL);
+ }
}
closeFloater();
@@ -391,10 +398,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data )
if ( self )
{
- if(self->getRevertOnCancel())
- {
- self->cancelSelection ();
- }
+ self->cancelSelection();
self->closeFloater();
}
}
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 16974a872e..39dbc5b763 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -104,9 +104,6 @@ class LLFloaterColorPicker
void setMouseDownInSwatch (BOOL mouse_down_in_swatch);
BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; }
- void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; };
- BOOL getRevertOnCancel () { return mRevertOnCancel; }
-
BOOL isColorChanged ();
// called when text entries (RGB/HSL etc.) are changed by user
@@ -149,8 +146,6 @@ class LLFloaterColorPicker
BOOL mMouseDownInHueRegion;
BOOL mMouseDownInSwatch;
- BOOL mRevertOnCancel;
-
const S32 mRGBViewerImageLeft;
const S32 mRGBViewerImageTop;
const S32 mRGBViewerImageWidth;
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index 6b1d9306fb..7def855d83 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -46,19 +46,60 @@
typedef std::pair<LLUUID, std::string> folder_pair_t;
-class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
+class LLLandmarksInventoryObserver : public LLInventoryObserver
{
public:
LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
mFloater(create_landmark_floater)
{}
+ void changed(U32 mask) override
+ {
+ if (mFloater->getItem())
+ {
+ checkChanged(mask);
+ }
+ else
+ {
+ checkCreated(mask);
+ }
+ }
+
protected:
- /*virtual*/ void done()
+ void checkCreated(U32 mask)
{
+ if (gInventory.getAddedIDs().empty())
+ {
+ return;
+ }
+
+ if (!(mask & LLInventoryObserver::ADD) ||
+ !(mask & LLInventoryObserver::CREATE) ||
+ !(mask & LLInventoryObserver::UPDATE_CREATE))
+ {
+ return;
+ }
+
mFloater->setItem(gInventory.getAddedIDs());
}
+ void checkChanged(U32 mask)
+ {
+ if (gInventory.getChangedIDs().empty())
+ {
+ return;
+ }
+
+ if ((mask & LLInventoryObserver::LABEL) ||
+ (mask & LLInventoryObserver::INTERNAL) ||
+ (mask & LLInventoryObserver::REMOVE) ||
+ (mask & LLInventoryObserver::STRUCTURE) ||
+ (mask & LLInventoryObserver::REBUILD))
+ {
+ mFloater->updateItem(gInventory.getChangedIDs(), mask);
+ }
+ }
+
private:
LLFloaterCreateLandmark* mFloater;
};
@@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild()
getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
+ mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+ mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); });
+
mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
return TRUE;
@@ -204,6 +248,33 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
}
}
+void LLFloaterCreateLandmark::onCommitTextChanges()
+{
+ if (mItem.isNull())
+ {
+ return;
+ }
+ std::string current_title_value = mLandmarkTitleEditor->getText();
+ std::string item_title_value = mItem->getName();
+ std::string current_notes_value = mNotesEditor->getText();
+ std::string item_notes_value = mItem->getDescription();
+
+ LLStringUtil::trim(current_title_value);
+ LLStringUtil::trim(current_notes_value);
+
+ if (!current_title_value.empty() &&
+ (item_title_value != current_title_value || item_notes_value != current_notes_value))
+ {
+ LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
+ new_item->rename(current_title_value);
+ new_item->setDescription(current_notes_value);
+ LLPointer<LLInventoryCallback> cb;
+ LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
+ gInventory.accountForUpdate(up);
+ update_inventory_item(new_item, cb);
+ }
+}
+
void LLFloaterCreateLandmark::onCreateFolderClicked()
{
LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
@@ -278,6 +349,8 @@ void LLFloaterCreateLandmark::onSaveClicked()
new_item->updateParentOnServer(FALSE);
}
+ removeObserver();
+
gInventory.updateItem(new_item);
gInventory.notifyObservers();
@@ -286,6 +359,7 @@ void LLFloaterCreateLandmark::onSaveClicked()
void LLFloaterCreateLandmark::onCancelClicked()
{
+ removeObserver();
if (!mItem.isNull())
{
LLUUID item_id = mItem->getUUID();
@@ -314,10 +388,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
if(!getItem())
{
- removeObserver();
mItem = item;
+ mAssetID = mItem->getAssetUUID();
+ setVisibleAndFrontmost(true);
break;
}
}
}
}
+
+void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)
+{
+ if (!getItem())
+ {
+ return;
+ }
+
+ LLUUID landmark_id = getItem()->getUUID();
+
+ for (uuid_set_t::const_iterator item_iter = items.begin();
+ item_iter != items.end();
+ ++item_iter)
+ {
+ const LLUUID& item_id = (*item_iter);
+ if (landmark_id == item_id)
+ {
+ if (getItem() != gInventory.getItem(item_id))
+ {
+ // item is obsolete or removed
+ closeFloater();
+ }
+
+ LLUUID folder_id = mFolderCombo->getValue().asUUID();
+ if (folder_id != mItem->getParentUUID())
+ {
+ // user moved landmark in inventory,
+ // assume that we are done all other changes should already be commited
+ closeFloater();
+ }
+
+ if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID())
+ {
+ closeFloater();
+ }
+
+ if (mask & LLInventoryObserver::LABEL)
+ {
+ mLandmarkTitleEditor->setText(mItem->getName());
+ }
+
+ if (mask & LLInventoryObserver::INTERNAL)
+ {
+ mNotesEditor->setText(mItem->getDescription());
+ }
+ }
+ }
+}
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
index 74ac5e651c..d84f5ae1fc 100644
--- a/indra/newview/llfloatercreatelandmark.h
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -49,6 +49,7 @@ public:
void onOpen(const LLSD& key);
void setItem(const uuid_set_t& items);
+ void updateItem(const uuid_set_t& items, U32 mask);
LLInventoryItem* getItem() { return mItem; }
@@ -56,6 +57,7 @@ private:
void setLandmarkInfo(const LLUUID &folder_id);
void removeObserver();
void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
+ void onCommitTextChanges();
void onCreateFolderClicked();
void onSaveClicked();
void onCancelClicked();
@@ -66,6 +68,7 @@ private:
LLLineEditor* mLandmarkTitleEditor;
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
+ LLUUID mAssetID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
new file mode 100644
index 0000000000..3b0c67415a
--- /dev/null
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file llfloaterdisplayname.cpp
+ * @author Leyla Farazha
+ * @brief Implementation of the LLFloaterDisplayName class.
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 "llfloaterreg.h"
+#include "llfloater.h"
+
+#include "llnotificationsutil.h"
+#include "llviewerdisplayname.h"
+
+#include "llnotifications.h"
+#include "llfloaterdisplayname.h"
+#include "llavatarnamecache.h"
+
+#include "llagent.h"
+
+
+class LLFloaterDisplayName : public LLFloater
+{
+public:
+ LLFloaterDisplayName(const LLSD& key);
+ virtual ~LLFloaterDisplayName() { }
+ /*virtual*/ BOOL postBuild();
+ void onSave();
+ void onCancel();
+ /*virtual*/ void onOpen(const LLSD& key);
+
+private:
+
+ void onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content);
+};
+
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+ LLFloater(key)
+{
+}
+
+void LLFloaterDisplayName::onOpen(const LLSD& key)
+{
+ getChild<LLUICtrl>("display_name_editor")->clear();
+ getChild<LLUICtrl>("display_name_confirm")->clear();
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get(gAgent.getID(), &av_name);
+
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
+
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // ...can't update until some time in the future
+ F64 next_update_local_secs =
+ av_name.mNextUpdate - LLStringOps::getLocalTimeOffset();
+ LLDate next_update_local(next_update_local_secs);
+ // display as "July 18 12:17 PM"
+ std::string next_update_string =
+ next_update_local.toHTTPDateString("%B %d %I:%M %p");
+ getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string);
+ getChild<LLUICtrl>("lockout_text")->setVisible(true);
+ getChild<LLUICtrl>("save_btn")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(false);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(false);
+ getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE);
+
+ }
+ else
+ {
+ getChild<LLUICtrl>("lockout_text")->setVisible(false);
+ getChild<LLUICtrl>("save_btn")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_editor")->setEnabled(true);
+ getChild<LLUICtrl>("display_name_confirm")->setEnabled(true);
+
+ }
+}
+
+BOOL LLFloaterDisplayName::postBuild()
+{
+ getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));
+ getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));
+
+ center();
+
+ return TRUE;
+}
+
+void LLFloaterDisplayName::onCacheSetName(bool success,
+ const std::string& reason,
+ const LLSD& content)
+{
+ if (success)
+ {
+ // Inform the user that the change took place, but will take a while
+ // to percolate.
+ LLSD args;
+ args["DISPLAY_NAME"] = content["display_name"];
+ LLNotificationsUtil::add("SetDisplayNameSuccess", args);
+ return;
+ }
+
+ // Request failed, notify the user
+ std::string error_tag = content["error_tag"].asString();
+ LL_INFOS() << "set name failure error_tag " << error_tag << LL_ENDL;
+
+ // We might have a localized string for this message
+ // error_args will usually be empty from the server.
+ if (!error_tag.empty()
+ && LLNotifications::getInstance()->templateExists(error_tag))
+ {
+ LLNotificationsUtil::add(error_tag);
+ return;
+ }
+
+ // The server error might have a localized message for us
+ std::string lang_code = LLUI::getLanguage();
+ LLSD error_desc = content["error_description"];
+ if (error_desc.has( lang_code ))
+ {
+ LLSD args;
+ args["MESSAGE"] = error_desc[lang_code].asString();
+ LLNotificationsUtil::add("GenericAlert", args);
+ return;
+ }
+
+ // No specific error, throw a generic one
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+}
+
+void LLFloaterDisplayName::onCancel()
+{
+ setVisible(false);
+}
+
+void LLFloaterDisplayName::onSave()
+{
+ std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
+ std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString();
+
+ if (display_name_utf8.compare(display_name_confirm))
+ {
+ LLNotificationsUtil::add("SetDisplayNameMismatch");
+ return;
+ }
+
+ const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes
+ LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8);
+ if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH)
+ {
+ LLSD args;
+ args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH);
+ LLNotificationsUtil::add("SetDisplayNameFailedLength", args);
+ return;
+ }
+
+ if (LLAvatarNameCache::getInstance()->hasNameLookupURL())
+ {
+ LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+ }
+ else
+ {
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ }
+
+ setVisible(false);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// LLInspectObjectUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterDisplayNameUtil::registerFloater()
+{
+ LLFloaterReg::add("display_name", "floater_display_name.xml",
+ &LLFloaterReg::build<LLFloaterDisplayName>);
+}
diff --git a/indra/newview/llpanelme.h b/indra/newview/llfloaterdisplayname.h
index 60e9d4317d..a00bf56712 100644
--- a/indra/newview/llpanelme.h
+++ b/indra/newview/llfloaterdisplayname.h
@@ -1,6 +1,5 @@
/**
- * @file llpanelme.h
- * @brief Side tray "Me" (My Profile) panel
+ * @file llfloaterdisplayname.h
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -24,27 +23,16 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLPANELMEPROFILE_H
-#define LL_LLPANELMEPROFILE_H
+#ifndef LLFLOATERDISPLAYNAME_H
+#define LLFLOATERDISPLAYNAME_H
-#include "llpanel.h"
-#include "llpanelprofile.h"
-/**
-* Panel for displaying Agent's Picks and Classifieds panel.
-* LLPanelMe allows user to edit his picks and classifieds.
-*/
-class LLPanelMe : public LLPanelProfile
+namespace LLFloaterDisplayNameUtil
{
- LOG_CLASS(LLPanelMe);
+ // Register with LLFloaterReg
+ void registerFloater();
+}
-public:
- LLPanelMe();
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-};
-
-#endif // LL_LLPANELMEPROFILE_H
+#endif
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 24673d5a7c..297ad24359 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(dayclone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index fec218ca3b..aa9a2c164a 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -296,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
if (ctrl_action == ACTION_SAVE)
{
doApplyUpdateInventory(setting_clone);
+ clearDirtyFlag();
}
else if (ctrl_action == ACTION_SAVEAS)
{
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 6e326ff3cf..d17889bed1 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -122,7 +122,7 @@ LLFloaterGesture::LLFloaterGesture(const LLSD& key)
mObserver = new LLFloaterGestureObserver(this);
LLGestureMgr::instance().addObserver(mObserver);
- mCommitCallbackRegistrar.add("Gesture.Action.ToogleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
+ mCommitCallbackRegistrar.add("Gesture.Action.ToggleActiveState", boost::bind(&LLFloaterGesture::onActivateBtnClick, this));
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));
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 42c5e40761..a00fc4aa84 100644
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)
// static
void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)
{
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 value = sldrCtrl->getValueF32();
- LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
- LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
- gAgentAvatarp->setHoverOffset(offset, false);
+ if (isAgentAvatarValid())
+ {
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
+ F32 value = sldrCtrl->getValueF32();
+ LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset, false);
+ }
}
// Do send-to-the-server work when slider drag completes, or new
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 1525bb9952..703b5d0011 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -45,6 +45,7 @@
#include "llflashtimer.h"
#include "llfloateravatarpicker.h"
#include "llfloaterpreference.h"
+#include "llfloaterreporter.h"
#include "llimview.h"
#include "llnotificationsutil.h"
#include "lltoolbarview.h"
@@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
{
LLAvatarActions::pay(userID);
}
+ else if ("report_abuse" == command)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(userID, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(userID, "not avaliable");
+ }
+ }
else if ("block_unblock" == command)
{
LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat);
@@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
}
// Handle all other options
- if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+ if (("can_invite" == item)
+ || ("can_chat_history" == item)
+ || ("can_share" == item)
+ || ("can_pay" == item)
+ || ("report_abuse" == item))
{
// Those menu items are enable only if a single avatar is selected
return is_single_select;
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 3a850d4b68..4cceddeefb 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -698,7 +698,6 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha
void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
{
- LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command
// Look for "/20 foo" channel chats.
S32 channel = 0;
LLWString out_text = stripChannelNumber(wtext, &channel);
@@ -858,6 +857,12 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
{
+ LL_DEBUGS("UIUsage") << "Nearby chat, text " << utf8_out_text << " type " << type << " channel " << channel << LL_ENDL;
+ if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) // prune back some redundant logging
+ {
+ LLUIUsage::instance().logCommand("Chat.SendNearby"); // pseuo-command
+ }
+
LLMessageSystem* msg = gMessageSystem;
if (channel >= 0)
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 34499ac170..93a0b39e02 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -551,7 +551,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
{
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
- if (widget)
+ if (widget && widget->getViewModelItem())
{
widget->refresh();
}
@@ -576,8 +576,11 @@ void LLFloaterIMSessionTab::refreshConversation()
{
participants_uuids.push_back(widget_it->first);
}
- widget_it->second->refresh();
- widget_it->second->setVisible(TRUE);
+ if (widget_it->second->getViewModelItem())
+ {
+ widget_it->second->refresh();
+ widget_it->second->setVisible(TRUE);
+ }
++widget_it;
}
if (is_ad_hoc || mIsP2PChat)
@@ -1126,7 +1129,10 @@ void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
for (; it != it_end; ++it)
{
LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
- selected_uuids.push_back(conversation_item->getUUID());
+ if (conversation_item)
+ {
+ selected_uuids.push_back(conversation_item->getUUID());
+ }
}
}
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index d78f80ad12..1a98ab9d76 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -3056,7 +3056,8 @@ BOOL LLPanelLandCovenant::postBuild()
{
mLastRegionID = LLUUID::null;
mNextUpdateTime = 0;
-
+ mTextEstateOwner = getChild<LLTextBox>("estate_owner_text");
+ mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend);
return TRUE;
}
@@ -3164,8 +3165,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)
LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
if (self)
{
- LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text");
- if (editor) editor->setText(name);
+ self->mTextEstateOwner->setText(name);
}
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 5d9b411f04..684950d88b 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -413,6 +413,7 @@ protected:
private:
LLUUID mLastRegionID;
F64 mNextUpdateTime; //seconds since client start
+ LLTextBox* mTextEstateOwner;
};
#endif
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index fc2da772f3..fd1af7ccc0 100644..100755
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -51,7 +51,7 @@
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
-const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
+const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;
//
// Member functions
@@ -77,35 +77,44 @@ LLFloaterMap::~LLFloaterMap()
BOOL LLFloaterMap::postBuild()
{
- mMap = getChild<LLNetMap>("Net Map");
- if (gSavedSettings.getBOOL("DoubleClickTeleport"))
- {
- mMap->setToolTipMsg(getString("AltToolTipMsg"));
- }
- else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
- {
- mMap->setToolTipMsg(getString("ToolTipMsg"));
- }
- sendChildToBack(mMap);
-
- mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
- mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
- mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
- mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
- mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
- mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
- mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
- mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
-
- updateMinorDirections();
-
- // Get the drag handle all the way in back
- sendChildToBack(getDragHandle());
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(this, FALSE);
-
- return TRUE;
+ mMap = getChild<LLNetMap>("Net Map");
+ mMap->setToolTipMsg(getString("ToolTipMsg"));
+ mMap->setParcelNameMsg(getString("ParcelNameMsg"));
+ mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg"));
+ mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg"));
+ mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg"));
+ mMap->setRegionNameMsg(getString("RegionNameMsg"));
+ mMap->setToolTipHintMsg(getString("ToolTipHintMsg"));
+ mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg"));
+ sendChildToBack(mMap);
+
+ mTextBoxNorth = getChild<LLTextBox>("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox>("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox>("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox>("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest");
+
+ mTextBoxNorth->reshapeToFitText();
+ mTextBoxEast->reshapeToFitText();
+ mTextBoxWest->reshapeToFitText();
+ mTextBoxSouth->reshapeToFitText();
+ mTextBoxSouthEast->reshapeToFitText();
+ mTextBoxNorthEast->reshapeToFitText();
+ mTextBoxSouthWest->reshapeToFitText();
+ mTextBoxNorthWest->reshapeToFitText();
+
+ updateMinorDirections();
+
+ // Get the drag handle all the way in back
+ sendChildToBack(getDragHandle());
+
+ // keep onscreen
+ gFloaterView->adjustToFitScreen(this, false);
+
+ return true;
}
BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
-void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
+void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation)
{
- // Rotation is in radians.
- // Rotation of 0 means x = 1, y = 0 on the unit circle.
-
- F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2;
- F32 map_half_width = (F32)(getRect().getWidth() / 2) ;
- F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
- F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
- F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
-
- // Inset by a little to account for position display.
- radius -= 8.f;
-
- text_box->setOrigin(
- ll_round(map_half_width - text_half_width + radius * cos( rotation )),
- ll_round(map_half_height - text_half_height + radius * sin( rotation )) );
+ // Rotation is in radians.
+ // Rotation of 0 means x = 1, y = 0 on the unit circle.
+
+ F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2);
+ F32 map_half_width = (F32) (getRect().getWidth() / 2);
+ F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2);
+ F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2);
+ F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2);
+ F32 pos_half_height = map_half_height - text_half_height - extra_padding;
+ F32 pos_half_width = map_half_width - text_half_width - extra_padding;
+
+ F32 corner_angle = atan2(pos_half_height, pos_half_width);
+ F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI));
+ if (rotation < 0)
+ {
+ rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top;
+ }
+ F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO));
+ bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle;
+
+ F32 part_x = cos(rotation);
+ F32 part_y = sin(rotation);
+ F32 y;
+ F32 x;
+ if (at_left_right_edge)
+ {
+ x = std::copysign(pos_half_width, part_x);
+ y = x * part_y / part_x;
+ }
+ else
+ {
+ y = std::copysign(pos_half_height, part_y);
+ x = y * part_x / part_y;
+ }
+
+ text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height));
}
void LLFloaterMap::updateMinorDirections()
@@ -218,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
updateMinorDirections();
}
-void LLFloaterMap::handleZoom(const LLSD& userdata)
-{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- mMap->setScale(scale);
- }
-}
-
LLFloaterMap* LLFloaterMap::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index ff2fb20535..929b1795aa 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -48,7 +48,6 @@ public:
/*virtual*/ void draw();
private:
- void handleZoom(const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 524162ba51..e755e9924c 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView()
// Update the top message or flip to the tabs and folders view
// *TODO : check those messages and create better appropriate ones in strings.xml
- if (mRootFolderId.notNull())
+ if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE)
+ {
+ std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason();
+ if (reason.empty())
+ {
+ text = LLTrans::getString("InventoryMarketplaceConnectionError");
+ }
+ else
+ {
+ LLSD args;
+ args["[REASON]"] = reason;
+ text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args);
+ }
+
+ title = LLTrans::getString("InventoryOutboxErrorTitle");
+ tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
+ }
+ else if (mRootFolderId.notNull())
{
// "Marketplace listings is empty!" message strings
text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs);
diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp
index 2afd889609..b34961e8a2 100644
--- a/indra/newview/llfloatermediasettings.cpp
+++ b/indra/newview/llfloatermediasettings.cpp
@@ -157,6 +157,18 @@ void LLFloaterMediaSettings::apply()
}
////////////////////////////////////////////////////////////////////////////////
+void LLFloaterMediaSettings::onOpen(const LLSD& key)
+{
+ if (mPanelMediaSettingsGeneral)
+ {
+ // media is expensive, so only load it when nessesary.
+ // If we need to preload it, set volume to 0 and any pause
+ // if applicable, then unpause here
+ mPanelMediaSettingsGeneral->updateMediaPreview();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose(bool app_quitting)
{
if(mPanelMediaSettingsGeneral)
diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h
index f93512eb3a..151e43e6b9 100644
--- a/indra/newview/llfloatermediasettings.h
+++ b/indra/newview/llfloatermediasettings.h
@@ -42,6 +42,7 @@ public:
~LLFloaterMediaSettings();
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
static LLFloaterMediaSettings* getInstance();
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index fe5120376c..66a245b779 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -467,22 +467,25 @@ void LLFloaterModelPreview::loadHighLodModel()
loadModel(3);
}
-void LLFloaterModelPreview::loadModel(S32 lod)
+void LLFloaterModelPreview::prepareToLoadModel(S32 lod)
{
mModelPreview->mLoading = true;
if (lod == LLModel::LOD_PHYSICS)
{
// loading physics from file
mModelPreview->mPhysicsSearchLOD = lod;
+ mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false;
}
-
+}
+void LLFloaterModelPreview::loadModel(S32 lod)
+{
+ prepareToLoadModel(lod);
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)
{
- mModelPreview->mLoading = true;
-
+ prepareToLoadModel(lod);
mModelPreview->loadModel(file_name, lod, force_disable_slm);
}
@@ -507,6 +510,15 @@ void LLFloaterModelPreview::onClickCalculateBtn()
toggleCalculateButton(false);
mUploadBtn->setEnabled(false);
+
+ //disable "simplification" UI
+ LLPanel* simplification_panel = getChild<LLPanel>("physics simplification");
+ LLView* child = simplification_panel->getFirstChild();
+ while (child)
+ {
+ child->setEnabled(false);
+ child = simplification_panel->findNextSibling(child);
+ }
}
// Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function
@@ -741,7 +753,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
{
case LLModelPreview::MESH_OPTIMIZER_AUTO:
case LLModelPreview::MESH_OPTIMIZER_SLOPPY:
- case LLModelPreview::MESH_OPTIMIZER_COMBINE:
+ case LLModelPreview::MESH_OPTIMIZER_PRECISE:
mModelPreview->onLODMeshOptimizerParamCommit(lod, enforce_tri_limit, mode);
break;
default:
@@ -1063,11 +1075,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
}
S32 file_mode = iface->getItemCount() - 1;
- if (which_mode < file_mode)
+ S32 cube_mode = file_mode - 1;
+ if (which_mode < cube_mode)
{
S32 which_lod = num_lods - which_mode;
sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
}
+ else if (which_mode == cube_mode)
+ {
+ std::string path = gDirUtilp->getAppRODataDir();
+ gDirUtilp->append(path, "cube.dae");
+ sInstance->loadModel(LLModel::LOD_PHYSICS, path);
+ }
LLModelPreview *model_preview = sInstance->mModelPreview;
if (model_preview)
@@ -1662,15 +1681,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
{
if (lod == LLModel::LOD_PHYSICS)
- {
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");
if (lod_combo)
{
- lod_combo->setCurrentByIndex(5);
+ lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);
}
}
else
-{
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_combo)
{
@@ -1745,7 +1764,7 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
S32 index = lod_source_combo->getCurrentIndex();
if (index == LLModelPreview::MESH_OPTIMIZER_AUTO
|| index == LLModelPreview::MESH_OPTIMIZER_SLOPPY
- || index == LLModelPreview::MESH_OPTIMIZER_COMBINE)
+ || index == LLModelPreview::MESH_OPTIMIZER_PRECISE)
{ //rebuild LoD to update triangle counts
onLODParamCommit(lod, true);
}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 1e147cd555..bda042186b 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -221,6 +221,7 @@ private:
void resetUploadOptions();
void clearLogTab();
+ void prepareToLoadModel(S32 lod);
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp
index dccef88e41..ad5e97e067 100644
--- a/indra/newview/llfloateroutfitsnapshot.cpp
+++ b/indra/newview/llfloateroutfitsnapshot.cpp
@@ -42,7 +42,6 @@
#include "llviewercontrol.h"
#include "lltoolfocus.h"
#include "lltoolmgr.h"
-#include "llwebprofile.h"
///----------------------------------------------------------------------------
/// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 87973c2286..94261b2e4e 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,7 +72,7 @@ struct LLGiveMoneyInfo
mFloater(floater), mAmount(amount){}
};
-typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
+typedef std::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
///----------------------------------------------------------------------------
/// Class LLFloaterPay
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 8d19aa36bb..273810e8d4 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -333,60 +333,59 @@ void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType t
const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
- storeAvatarProperties( pAvatarData );
- processProfileProperties( pAvatarData );
+ mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
+ mAvatarDataInitialized = true;
+ getChild<LLUICtrl>("online_searchresults")->setValue(mAllowPublish);
}
}
}
-void LLFloaterPreference::storeAvatarProperties( const LLAvatarData* pAvatarData )
+void LLFloaterPreference::saveAvatarProperties( void )
{
- if (LLStartUp::getStartupState() == STATE_STARTED)
- {
- mAvatarProperties.avatar_id = pAvatarData->avatar_id;
- mAvatarProperties.image_id = pAvatarData->image_id;
- mAvatarProperties.fl_image_id = pAvatarData->fl_image_id;
- mAvatarProperties.about_text = pAvatarData->about_text;
- mAvatarProperties.fl_about_text = pAvatarData->fl_about_text;
- mAvatarProperties.profile_url = pAvatarData->profile_url;
- mAvatarProperties.flags = pAvatarData->flags;
- mAvatarProperties.allow_publish = pAvatarData->flags & AVATAR_ALLOW_PUBLISH;
+ const bool allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
- mAvatarDataInitialized = true;
- }
-}
+ if ((LLStartUp::getStartupState() == STATE_STARTED)
+ && mAvatarDataInitialized
+ && (allowPublish != mAllowPublish))
+ {
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
+ {
+ mAllowPublish = allowPublish;
-void LLFloaterPreference::processProfileProperties(const LLAvatarData* pAvatarData )
-{
- getChild<LLUICtrl>("online_searchresults")->setValue( (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH) );
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(saveAvatarPropertiesCoro, cap_url, allowPublish));
+ }
+ }
}
-void LLFloaterPreference::saveAvatarProperties( void )
+void LLFloaterPreference::saveAvatarPropertiesCoro(const std::string cap_url, bool allow_publish)
{
- const BOOL allowPublish = getChild<LLUICtrl>("online_searchresults")->getValue();
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
- if (allowPublish)
- {
- mAvatarProperties.flags |= AVATAR_ALLOW_PUBLISH;
- }
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
- //
- // NOTE: We really don't want to send the avatar properties unless we absolutely
- // need to so we can avoid the accidental profile reset bug, so, if we're
- // logged in, the avatar data has been initialized and we have a state change
- // for the "allow publish" flag, then set the flag to its new value and send
- // the properties update.
- //
- // NOTE: The only reason we can not remove this update altogether is because of the
- // "allow publish" flag, the last remaining profile setting in the viewer
- // that doesn't exist in the web profile.
- //
- if ((LLStartUp::getStartupState() == STATE_STARTED) && mAvatarDataInitialized && (allowPublish != mAvatarProperties.allow_publish))
- {
- mAvatarProperties.allow_publish = allowPublish;
+ std::string finalUrl = cap_url + "/" + gAgentID.asString();
+ LLSD data;
+ data["allow_publish"] = allow_publish;
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate( &mAvatarProperties );
- }
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("Preferences") << "Failed to put agent information " << data << " for id " << gAgentID << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("Preferences") << "Agent id: " << gAgentID << " Data: " << data << " Result: " << httpResults << LL_ENDL;
}
BOOL LLFloaterPreference::postBuild()
@@ -938,7 +937,7 @@ void LLFloaterPreference::onBtnOK(const LLSD& userdata)
else
{
// Show beep, pop up dialog, etc.
- LL_INFOS() << "Can't close preferences!" << LL_ENDL;
+ LL_INFOS("Preferences") << "Can't close preferences!" << LL_ENDL;
}
LLPanelLogin::updateLocationSelectorsVisibility();
@@ -1200,7 +1199,6 @@ void LLFloaterPreference::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
shaders &&
- gGLManager.mHasFramebufferObject &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
@@ -1251,7 +1249,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
- gGLManager.mHasFramebufferObject &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
@@ -1385,8 +1382,7 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
}
// disabled deferred
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
- !gGLManager.mHasFramebufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
{
ctrl_shadows->setEnabled(FALSE);
ctrl_shadows->setValue(0);
@@ -1793,13 +1789,13 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Unable to parse file " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Unable to parse file " << filename << LL_ENDL;
return false;
}
if (!root->hasName("labels"))
{
- LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " is not a valid definition file" << LL_ENDL;
return false;
}
@@ -1819,7 +1815,7 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
}
else
{
- LL_WARNS() << filename << " failed to load" << LL_ENDL;
+ LL_WARNS("Preferences") << filename << " failed to load" << LL_ENDL;
return false;
}
@@ -2725,7 +2721,7 @@ bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filena
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2752,7 +2748,7 @@ bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
LLScrollListCtrl::Contents contents;
if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
{
- LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+ LL_WARNS("Preferences") << "Failed to load " << filename << LL_ENDL;
return false;
}
LLXUIParser parser;
@@ -2858,7 +2854,7 @@ void LLPanelPreferenceControls::populateControlTable()
{
// Either unknown mode or MODE_SAVED_SETTINGS
// It doesn't have UI or actual settings yet
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
// Searchable columns were removed, mark searchables for an update
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
@@ -2898,7 +2894,7 @@ void LLPanelPreferenceControls::populateControlTable()
}
else
{
- LL_WARNS() << "Unimplemented mode" << LL_ENDL;
+ LL_WARNS("Preferences") << "Unimplemented mode" << LL_ENDL;
}
// explicit update to make sure table is ready for llsearchableui
@@ -2953,10 +2949,15 @@ void LLPanelPreferenceControls::cancel()
if (mConflictHandler[i].hasUnsavedChanges())
{
mConflictHandler[i].clear();
+ if (mEditingMode == i)
+ {
+ // cancel() can be called either when preferences floater closes
+ // or when child floater closes (like advanced graphical settings)
+ // in which case we need to clear and repopulate table
+ regenerateControls();
+ }
}
}
- pControlsTable->clearRows();
- pControlsTable->clearColumns();
}
void LLPanelPreferenceControls::saveSettings()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 5ef2ca68d3..542df18ddb 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -100,9 +100,8 @@ public:
static void updateShowFavoritesCheckbox(bool val);
void processProperties( void* pData, EAvatarProcessorType type );
- void processProfileProperties(const LLAvatarData* pAvatarData );
- void storeAvatarProperties( const LLAvatarData* pAvatarData );
void saveAvatarProperties( void );
+ static void saveAvatarPropertiesCoro(const std::string url, bool allow_publish);
void selectPrivacyPanel();
void selectChatPanel();
void getControlNames(std::vector<std::string>& names);
@@ -213,7 +212,7 @@ private:
bool mOriginalHideOnlineStatus;
std::string mDirectoryVisibility;
- LLAvatarData mAvatarProperties;
+ bool mAllowPublish; // Allow showing agent in search
std::string mSavedCameraPreset;
std::string mSavedGraphicsPreset;
LOG_CLASS(LLFloaterPreference);
diff --git a/indra/newview/llfloaterprofile.cpp b/indra/newview/llfloaterprofile.cpp
new file mode 100644
index 0000000000..6ccdace6c5
--- /dev/null
+++ b/indra/newview/llfloaterprofile.cpp
@@ -0,0 +1,170 @@
+/**
+ * @file llfloaterprofile.cpp
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llfloaterprofile.h"
+
+#include "llagent.h" //gAgent
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+LLFloaterProfile::LLFloaterProfile(const LLSD& key)
+ : LLFloater(key),
+ mAvatarId(key["id"].asUUID()),
+ mNameCallbackConnection()
+{
+ mDefaultRectForGroup = false;
+}
+
+LLFloaterProfile::~LLFloaterProfile()
+{
+ if (mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection.disconnect();
+ }
+}
+
+void LLFloaterProfile::onOpen(const LLSD& key)
+{
+ mPanelProfile->onOpen(key);
+
+ // Update the avatar name.
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLFloaterProfile::postBuild()
+{
+ mPanelProfile = findChild<LLPanelProfile>(PANEL_PROFILE_VIEW);
+
+ return TRUE;
+}
+
+void LLFloaterProfile::onClickCloseBtn(bool app_quitting)
+{
+ if (!app_quitting)
+ {
+ if (mPanelProfile->hasUnpublishedClassifieds())
+ {
+ LLNotificationsUtil::add("ProfileUnpublishedClassified", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, false));
+ }
+ else if (mPanelProfile->hasUnsavedChanges())
+ {
+ LLNotificationsUtil::add("ProfileUnsavedChanges", LLSD(), LLSD(),
+ boost::bind(&LLFloaterProfile::onUnsavedChangesCallback, this, _1, _2, true));
+ }
+ else
+ {
+ closeFloater();
+ }
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLFloaterProfile::onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (can_save)
+ {
+ // savable content
+
+ if (option == 0) // Save
+ {
+ mPanelProfile->commitUnsavedChanges();
+ closeFloater();
+ }
+ if (option == 1) // Discard
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+ else
+ {
+ // classifieds
+
+ if (option == 0) // Ok
+ {
+ closeFloater();
+ }
+ // else cancel
+ }
+
+}
+
+void LLFloaterProfile::createPick(const LLPickData &data)
+{
+ mPanelProfile->createPick(data);
+}
+
+void LLFloaterProfile::showPick(const LLUUID& pick_id)
+{
+ mPanelProfile->showPick(pick_id);
+}
+
+bool LLFloaterProfile::isPickTabSelected()
+{
+ return mPanelProfile->isPickTabSelected();
+}
+
+void LLFloaterProfile::refreshName()
+{
+ if (!mNameCallbackConnection.connected())
+ {
+ mNameCallbackConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLFloaterProfile::onAvatarNameCache, this, _1, _2));
+ }
+
+ LLPanelProfileSecondLife *panel = findChild<LLPanelProfileSecondLife>("panel_profile_secondlife");
+ if (panel)
+ {
+ panel->refreshName();
+ }
+}
+
+void LLFloaterProfile::showClassified(const LLUUID& classified_id, bool edit)
+{
+ mPanelProfile->showClassified(classified_id, edit);
+}
+
+void LLFloaterProfile::createClassified()
+{
+ mPanelProfile->createClassified();
+}
+
+void LLFloaterProfile::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mNameCallbackConnection.disconnect();
+ setTitle(av_name.getCompleteName());
+}
+
+// eof
diff --git a/indra/newview/llfloaterprofile.h b/indra/newview/llfloaterprofile.h
new file mode 100644
index 0000000000..b3ed02fc2c
--- /dev/null
+++ b/indra/newview/llfloaterprofile.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloaterprofile.h
+ * @brief Avatar profile floater.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_LLFLOATERPROFILE_H
+#define LL_LLFLOATERPROFILE_H
+
+#include "llavatarnamecache.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llfloater.h"
+
+class LLPanelProfile;
+
+class LLFloaterProfile : public LLFloater
+{
+ LOG_CLASS(LLFloaterProfile);
+public:
+ LLFloaterProfile(const LLSD& key);
+ virtual ~LLFloaterProfile();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+ void onUnsavedChangesCallback(const LLSD& notification, const LLSD& response, bool can_save);
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ void refreshName();
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+private:
+ LLAvatarNameCache::callback_connection_t mNameCallbackConnection;
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ LLPanelProfile* mPanelProfile;
+
+ LLUUID mAvatarId;
+};
+
+#endif // LL_LLFLOATERPROFILE_H
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
new file mode 100644
index 0000000000..bf1f56a6d1
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -0,0 +1,223 @@
+/**
+ * @file llfloaterprofiletexture.cpp
+ * @brief LLFloaterProfileTexture class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llfloaterprofiletexture.h"
+
+#include "llbutton.h"
+#include "llfloaterreg.h"
+#include "llpreview.h" // fors constants
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "lltextureview.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+
+
+LLFloaterProfileTexture::LLFloaterProfileTexture(LLView* owner)
+ : LLFloater(LLSD())
+ , mUpdateDimensions(TRUE)
+ , mLastHeight(0)
+ , mLastWidth(0)
+ , mImage(NULL)
+ , mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_texture.xml");
+}
+
+LLFloaterProfileTexture::~LLFloaterProfileTexture()
+{
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+
+// virtual
+BOOL LLFloaterProfileTexture::postBuild()
+{
+ mProfileIcon = getChild<LLIconCtrl>("profile_pic");
+
+ mCloseButton = getChild<LLButton>("close_btn");
+ mCloseButton->setCommitCallback([this](LLUICtrl*, void*) { closeFloater(); }, nullptr);
+
+ return TRUE;
+}
+
+// virtual
+void LLFloaterProfileTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLFloater::reshape(width, height, called_from_parent);
+}
+
+// It takes a while until we get height and width information.
+// When we receive it, reshape the window accordingly.
+void LLFloaterProfileTexture::updateDimensions()
+{
+ if (mImage.isNull())
+ {
+ return;
+ }
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ return;
+ }
+
+ S32 img_width = mImage->getFullWidth();
+ S32 img_height = mImage->getFullHeight();
+
+ if (mAssetStatus != LLPreview::PREVIEW_ASSET_LOADED
+ || mLastWidth != img_width
+ || mLastHeight != img_height)
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ // Asset has been fully loaded
+ mUpdateDimensions = TRUE;
+ }
+
+ mLastHeight = img_height;
+ mLastWidth = img_width;
+
+ // Reshape the floater only when required
+ if (mUpdateDimensions)
+ {
+ mUpdateDimensions = FALSE;
+
+ LLRect old_floater_rect = getRect();
+ LLRect old_image_rect = mProfileIcon->getRect();
+ S32 width = old_floater_rect.getWidth() - old_image_rect.getWidth() + mLastWidth;
+ S32 height = old_floater_rect.getHeight() - old_image_rect.getHeight() + mLastHeight;
+
+ const F32 MAX_DIMENTIONS = 512; // most profiles are supposed to be 256x256
+
+ S32 biggest_dim = llmax(width, height);
+ if (biggest_dim > MAX_DIMENTIONS)
+ {
+ F32 scale_down = MAX_DIMENTIONS / (F32)biggest_dim;
+ width *= scale_down;
+ height *= scale_down;
+ }
+
+ //reshape floater
+ reshape(width, height);
+
+ gFloaterView->adjustToFitScreen(this, FALSE);
+ }
+}
+
+void LLFloaterProfileTexture::draw()
+{
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+
+ LLFloater::draw();
+}
+
+void LLFloaterProfileTexture::onOpen(const LLSD& key)
+{
+ mCloseButton->setFocus(true);
+}
+
+void LLFloaterProfileTexture::resetAsset()
+{
+ mProfileIcon->setValue("Generic_Person_Large");
+ mImageID = LLUUID::null;
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+}
+void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
+{
+ if (mImageID != image_id)
+ {
+ if (mImage.notNull())
+ {
+ mImage->setBoostLevel(mImageOldBoostLevel);
+ mImage = NULL;
+ }
+ }
+ else
+ {
+ return;
+ }
+
+ mProfileIcon->setValue(image_id);
+ mImageID = image_id;
+ mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ mImageOldBoostLevel = mImage->getBoostLevel();
+
+ if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
+ {
+ mImage->setLoadedCallback(LLFloaterProfileTexture::onTextureLoaded,
+ 0, TRUE, FALSE, new LLHandle<LLFloater>(getHandle()), &mCallbackTextureList);
+
+ mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADING;
+ }
+ else
+ {
+ mAssetStatus = LLPreview::PREVIEW_ASSET_LOADED;
+ }
+
+ mUpdateDimensions = TRUE;
+ updateDimensions();
+}
+
+// static
+void LLFloaterProfileTexture::onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ LLHandle<LLFloater>* handle = (LLHandle<LLFloater>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLFloaterProfileTexture* floater = static_cast<LLFloaterProfileTexture*>(handle->get());
+ if (floater && success)
+ {
+ floater->mUpdateDimensions = TRUE;
+ floater->updateDimensions();
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
diff --git a/indra/newview/llfloaterprofiletexture.h b/indra/newview/llfloaterprofiletexture.h
new file mode 100644
index 0000000000..66a61213dd
--- /dev/null
+++ b/indra/newview/llfloaterprofiletexture.h
@@ -0,0 +1,81 @@
+/**
+ * @file llfloaterprofiletexture.h
+ * @brief LLFloaterProfileTexture class definition
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_LLFLOATERPROFILETEXTURE_H
+#define LL_LLFLOATERPROFILETEXTURE_H
+
+#include "llfloater.h"
+#include "llviewertexture.h"
+
+class LLButton;
+class LLImageRaw;
+class LLIconCtrl;
+
+class LLFloaterProfileTexture : public LLFloater
+{
+public:
+ LLFloaterProfileTexture(LLView* owner);
+ ~LLFloaterProfileTexture();
+
+ void draw() override;
+ void onOpen(const LLSD& key) override;
+
+ void resetAsset();
+ void loadAsset(const LLUUID &image_id);
+
+
+ static void onTextureLoaded(
+ BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+protected:
+ BOOL postBuild() override;
+
+private:
+ void updateDimensions();
+
+ LLUUID mImageID;
+ LLPointer<LLViewerFetchedTexture> mImage;
+ S32 mImageOldBoostLevel;
+ S32 mAssetStatus;
+ F32 mContextConeOpacity;
+ S32 mLastHeight;
+ S32 mLastWidth;
+ BOOL mUpdateDimensions;
+
+ LLHandle<LLView> mOwnerHandle;
+ LLIconCtrl* mProfileIcon;
+ LLButton* mCloseButton;
+
+ LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
+};
+#endif // LL_LLFLOATERPROFILETEXTURE_H
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 296e155d28..07d4dcae38 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -47,6 +47,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llavataractions.h"
#include "llavatarname.h"
#include "llfloateravatarpicker.h"
#include "llbutton.h"
@@ -1322,6 +1323,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data)
BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
{
+ static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024;
for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i)
{
std::string buffer;
@@ -1343,17 +1345,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainBitDepth", args);
return FALSE;
}
- if (width > 512 || height > 512)
+ if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE)
{
LLSD args;
args["TEXTURE_NUM"] = i+1;
args["TEXTURE_SIZE_X"] = width;
args["TEXTURE_SIZE_Y"] = height;
+ args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE;
LLNotificationsUtil::add("InvalidTerrainSize", args);
return FALSE;
@@ -1826,7 +1830,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
setCtrlsEnabled(god || owner || manager);
getChildView("apply_btn")->setEnabled(FALSE);
-
+ getChildView("estate_owner")->setEnabled(TRUE);
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
@@ -1888,6 +1892,8 @@ BOOL LLPanelEstateInfo::postBuild()
getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
+ getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
+
return LLPanelRegionInfo::postBuild();
}
@@ -2134,6 +2140,7 @@ BOOL LLPanelEstateCovenant::postBuild()
{
mEstateNameText = getChild<LLTextBox>("estate_name_text");
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
+ mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
LLButton* reset_button = getChild<LLButton>("reset_covenant");
@@ -3683,7 +3690,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin
if (!search_string.empty())
{
listCtrl->setSearchColumn(0); // name column
- listCtrl->selectItemByPrefix(search_string, FALSE);
+ listCtrl->searchItems(search_string, false, true);
}
else
{
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index b73755cf4e..2df4ca973d 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -54,6 +54,7 @@
#include "llbutton.h"
#include "llfloaterreg.h"
#include "lltexturectrl.h"
+#include "lltexteditor.h"
#include "llscrolllistctrl.h"
#include "lldispatcher.h"
#include "llviewerobject.h"
@@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter()
mPosition.setVec(0.0f, 0.0f, 0.0f);
- std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
- mMCDList.clear();
-
delete mResourceDatap;
}
@@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin
show(avatar_id, avatar_name);
}
+// static
+void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description)
+{
+ show(avatar_id, avatar_name);
+
+ LLStringUtil::format_map_t args;
+ args["[MSG_TIME]"] = time;
+ args["[MSG_DESCRIPTION]"] = description;
+
+ LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
+ if (self)
+ {
+ std::string description = self->getString("chat_report_format", args);
+ self->getChild<LLUICtrl>("details_edit")->setValue(description);
+ }
+}
+
void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id)
{
getChild<LLUICtrl>("object_name")->setValue(object_name);
@@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting)
mSnapshotTimer.stop();
gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting);
}
-
-
-// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// self->getChild<LLUICtrl>("details_edit")->setValue(description);
-
-// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer());
-// self->mMCDList.clear();
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
-
-// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd)
-// {
-// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
-// if (self)
-// {
-// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit");
-// if (text)
-// {
-// text->insertText(description);
-// }
-// if (mcd)
-// {
-// self->mMCDList.push_back(new LLMeanCollisionData(mcd));
-// }
-// }
-// }
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index c678df7155..b6c70e866d 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -93,6 +93,7 @@ public:
static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null);
static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name);
+ static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description);
static void showFromExperience(const LLUUID& experience_id);
static void onClickSend (void *userdata);
@@ -101,8 +102,6 @@ public:
void onClickSelectAbuser ();
static void closePickTool (void *userdata);
static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status);
- static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
- static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL);
void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id);
@@ -114,10 +113,8 @@ private:
static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null);
void takeScreenshot(bool use_prev_screenshot = false);
- void sendReportViaCaps(std::string url);
void uploadImage();
bool validateReport();
- void setReporterID();
LLSD gatherReport();
void sendReportViaLegacy(const LLSD & report);
void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
@@ -144,7 +141,6 @@ private:
BOOL mPicking;
LLVector3 mPosition;
BOOL mCopyrightWarningSeen;
- std::list<LLMeanCollisionData*> mMCDList;
std::string mDefaultSummary;
LLResourceData* mResourceDatap;
boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 2e1fbb09e0..bb3ed77772 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -57,10 +57,10 @@ public:
const size_t parts = tokens.size();
// get the (optional) category for the search
- std::string category;
+ std::string collection;
if (parts > 0)
{
- category = tokens[0].asString();
+ collection = tokens[0].asString();
}
// get the (optional) search string
@@ -72,7 +72,7 @@ public:
// create the LLSD arguments for the search floater
LLFloaterSearch::Params p;
- p.search.category = category;
+ p.search.collection = collection;
p.search.query = LLURI::unescape(search_text);
// open the search floater and perform the requested search
@@ -83,8 +83,9 @@ public:
LLSearchHandler gSearchHandler;
LLFloaterSearch::SearchQuery::SearchQuery()
-: category("category", ""),
- query("query")
+: category("category", ""),
+ collection("collection", ""),
+ query("query")
{}
LLFloaterSearch::LLFloaterSearch(const Params& key) :
@@ -93,16 +94,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) :
{
// declare a map that transforms a category name into
// the URL suffix that is used to search that category
- mCategoryPaths = LLSD::emptyMap();
- mCategoryPaths["all"] = "search";
- mCategoryPaths["people"] = "search/people";
- mCategoryPaths["places"] = "search/places";
- mCategoryPaths["events"] = "search/events";
- mCategoryPaths["groups"] = "search/groups";
- mCategoryPaths["wiki"] = "search/wiki";
- mCategoryPaths["land"] = "land";
- mCategoryPaths["destinations"] = "destinations";
- mCategoryPaths["classifieds"] = "classifieds";
+
+ mSearchType.insert("standard");
+ mSearchType.insert("land");
+ mSearchType.insert("classified");
+
+ mCollectionType.insert("events");
+ mCollectionType.insert("destinations");
+ mCollectionType.insert("places");
+ mCollectionType.insert("groups");
+ mCollectionType.insert("people");
}
BOOL LLFloaterSearch::postBuild()
@@ -157,31 +158,49 @@ void LLFloaterSearch::search(const SearchQuery &p)
// work out the subdir to use based on the requested category
LLSD subs;
- if (mCategoryPaths.has(p.category))
+ if (mSearchType.find(p.category) != mSearchType.end())
{
- subs["CATEGORY"] = mCategoryPaths[p.category].asString();
+ subs["TYPE"] = p.category;
}
else
{
- subs["CATEGORY"] = mCategoryPaths["all"].asString();
+ subs["TYPE"] = "standard";
}
// add the search query string
subs["QUERY"] = LLURI::escape(p.query);
+ subs["COLLECTION"] = "";
+ if (subs["TYPE"] == "standard")
+ {
+ if (mCollectionType.find(p.collection) != mCollectionType.end())
+ {
+ subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection);
+ }
+ else
+ {
+ std::string collection_args("");
+ for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it)
+ {
+ collection_args += "&collection_chosen=" + std::string(*it);
+ }
+ subs["COLLECTION"] = collection_args;
+ }
+ }
+
// add the user's preferred maturity (can be changed via prefs)
std::string maturity;
if (gAgent.prefersAdult())
{
- maturity = "42"; // PG,Mature,Adult
+ maturity = "gma"; // PG,Mature,Adult
}
else if (gAgent.prefersMature())
{
- maturity = "21"; // PG,Mature
+ maturity = "gm"; // PG,Mature
}
else
{
- maturity = "13"; // PG
+ maturity = "g"; // PG
}
subs["MATURITY"] = maturity;
diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h
index 35b268e1b2..cc77ce696f 100644
--- a/indra/newview/llfloatersearch.h
+++ b/indra/newview/llfloatersearch.h
@@ -49,6 +49,7 @@ public:
struct SearchQuery : public LLInitParam::Block<SearchQuery>
{
Optional<std::string> category;
+ Optional<std::string> collection;
Optional<std::string> query;
SearchQuery();
@@ -84,7 +85,8 @@ public:
private:
/*virtual*/ BOOL postBuild();
- LLSD mCategoryPaths;
+ std::set<std::string> mSearchType;
+ std::set<std::string> mCollectionType;
U8 mSearchGodLevel;
};
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 0429749e11..b6acba6558 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -46,7 +46,6 @@
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
-#include "llmediactrl.h"
#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llpanelcontents.h"
@@ -240,7 +239,6 @@ BOOL LLFloaterTools::postBuild()
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
- mTitleMedia = getChild<LLMediaCtrl>("title_media");
mBtnLink = getChild<LLButton>("link_btn");
mBtnUnlink = getChild<LLButton>("unlink_btn");
@@ -329,7 +327,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCheckSnapToGrid(NULL),
mBtnGridOptions(NULL),
- mTitleMedia(NULL),
mComboGridMode(NULL),
mCheckStretchUniform(NULL),
mCheckStretchTexture(NULL),
@@ -369,8 +366,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mLandImpactsObserver(NULL),
mDirty(TRUE),
- mHasSelection(TRUE),
- mNeedMediaTitle(TRUE)
+ mHasSelection(TRUE)
{
gFloaterTools = this;
@@ -394,9 +390,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
- mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
- mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
@@ -480,30 +473,61 @@ void LLFloaterTools::refresh()
else
#endif
{
- F32 link_cost = LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost();
- S32 link_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ F32 link_cost = selection->getSelectedLinksetCost();
+ S32 link_count = selection->getRootObjectCount();
+ S32 object_count = selection->getObjectCount();
- LLCrossParcelFunctor func;
- if (LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
- {
- // Selection crosses parcel bounds.
- // We don't display remaining land capacity in this case.
- const LLStringExplicit empty_str("");
- childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", empty_str);
- }
- else
- {
- LLViewerObject* selected_object = mObjectSelection->getFirstObject();
- if (selected_object)
- {
- // Select a parcel at the currently selected object's position.
- LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
- }
- else
- {
- LL_WARNS() << "Failed to get selected object" << LL_ENDL;
- }
- }
+ LLCrossParcelFunctor func;
+ if (!LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, true))
+ {
+ // Unless multiple parcels selected, higlight parcel object is at.
+ LLViewerObject* selected_object = mObjectSelection->getFirstObject();
+ if (selected_object)
+ {
+ // Select a parcel at the currently selected object's position.
+ LLViewerParcelMgr::getInstance()->selectParcelAt(selected_object->getPositionGlobal());
+ }
+ else
+ {
+ LL_WARNS() << "Failed to get selected object" << LL_ENDL;
+ }
+ }
+
+ if (object_count == 1)
+ {
+ // "selection_faces" shouldn't be visible if not LLToolFace::getInstance()
+ // But still need to be populated in case user switches
+
+ std::string faces_str = "";
+
+ for (LLObjectSelection::iterator iter = selection->begin(); iter != selection->end();)
+ {
+ LLObjectSelection::iterator nextiter = iter++; // not strictly needed, we have only one object
+ LLSelectNode* node = *nextiter;
+ LLViewerObject* object = (*nextiter)->getObject();
+ if (!object)
+ continue;
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ if (!faces_str.empty())
+ {
+ faces_str += ", ";
+ }
+ faces_str += llformat("%d", te);
+ }
+ }
+ }
+
+ childSetTextArg("selection_faces", "[FACES_STRING]", faces_str);
+ }
+
+ bool show_faces = (object_count == 1)
+ && LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ getChildView("selection_faces")->setVisible(show_faces);
LLStringUtil::format_map_t selection_args;
selection_args["OBJ_COUNT"] = llformat("%.1d", link_count);
@@ -522,7 +546,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
- refreshMedia();
+ mPanelFace->refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
@@ -549,9 +573,6 @@ void LLFloaterTools::draw()
mDirty = FALSE;
}
- // grab media name/title and update the UI widget
- updateMediaTitle();
-
// mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts"));
LLFloater::draw();
}
@@ -824,7 +845,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty();
getChildView("selection_count")->setVisible(!land_visible && have_selection);
- getChildView("remaining_capacity")->setVisible(!land_visible && have_selection);
+ getChildView("selection_faces")->setVisible(LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()
+ && LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1);
getChildView("selection_empty")->setVisible(!land_visible && !have_selection);
mTab->setVisible(!land_visible);
@@ -874,8 +896,7 @@ void LLFloaterTools::onClose(bool app_quitting)
LLViewerJoystick::getInstance()->moveAvatar(false);
// destroy media source used to grab media title
- if( mTitleMedia )
- mTitleMedia->unloadMediaSource();
+ mPanelFace->unloadMedia();
// Different from handle_reset_view in that it doesn't actually
// move the camera if EditCameraMovement is not set.
@@ -1095,7 +1116,7 @@ void LLFloaterTools::onClickGridOptions()
{
LLFloater* floaterp = LLFloaterReg::showInstance("build_options");
// position floater next to build tools, not over
- floaterp->setRect(gFloaterView->findNeighboringPosition(this, floaterp));
+ floaterp->setShape(gFloaterView->findNeighboringPosition(this, floaterp), true);
}
// static
@@ -1128,51 +1149,6 @@ void LLFloaterTools::onFocusReceived()
LLFloater::onFocusReceived();
}
-// Media stuff
-void LLFloaterTools::refreshMedia()
-{
- getMediaState();
-}
-
-bool LLFloaterTools::selectedMediaEditable()
-{
- U32 owner_mask_on;
- U32 owner_mask_off;
- U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
- &owner_mask_on, &owner_mask_off );
- U32 group_mask_on;
- U32 group_mask_off;
- U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
- &group_mask_on, &group_mask_off );
- U32 everyone_mask_on;
- U32 everyone_mask_off;
- S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
- &everyone_mask_on, &everyone_mask_off );
-
- bool selected_Media_editable = false;
-
- // if perms we got back are valid
- if ( valid_owner_perms &&
- valid_group_perms &&
- valid_everyone_perms )
- {
-
- if ( ( owner_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) ||
- ( group_mask_on & PERM_MODIFY ) )
- {
- selected_Media_editable = true;
- }
- else
- // user is NOT allowed to press the RESET button
- {
- selected_Media_editable = false;
- };
- };
-
- return selected_Media_editable;
-}
-
void LLFloaterTools::updateLandImpacts()
{
LLParcel *parcel = mParcelSelection->getParcel();
@@ -1181,26 +1157,6 @@ void LLFloaterTools::updateLandImpacts()
return;
}
- S32 rezzed_prims = parcel->getSimWidePrimCount();
- S32 total_capacity = parcel->getSimWideMaxPrimCapacity();
- LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if (region)
- {
- S32 max_tasks_per_region = (S32)region->getMaxTasks();
- total_capacity = llmin(total_capacity, max_tasks_per_region);
- }
- std::string remaining_capacity_str = "";
-
- bool show_mesh_cost = gMeshRepo.meshRezEnabled();
- if (show_mesh_cost)
- {
- LLStringUtil::format_map_t remaining_capacity_args;
- remaining_capacity_args["LAND_CAPACITY"] = llformat("%d", total_capacity - rezzed_prims);
- remaining_capacity_str = getString("status_remaining_capacity", remaining_capacity_args);
- }
-
- childSetTextArg("remaining_capacity", "[CAPACITY_STRING]", remaining_capacity_str);
-
// Update land impacts info in the weights floater
LLFloaterObjectWeights* object_weights_floater = LLFloaterReg::findTypedInstance<LLFloaterObjectWeights>("object_weights");
if(object_weights_floater)
@@ -1209,784 +1165,3 @@ void LLFloaterTools::updateLandImpacts()
}
}
-void LLFloaterTools::getMediaState()
-{
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- LLViewerObject* first_object = selected_objects->getFirstObject();
- LLTextBox* media_info = getChild<LLTextBox>("media_info");
-
- if( !(first_object
- && first_object->getPCode() == LL_PCODE_VOLUME
- &&first_object->permModify()
- ))
- {
- getChildView("add_media")->setEnabled(FALSE);
- media_info->clear();
- clearMediaSettings();
- return;
- }
-
- std::string url = first_object->getRegion()->getCapability("ObjectMedia");
- bool has_media_capability = (!url.empty());
-
- if(!has_media_capability)
- {
- getChildView("add_media")->setEnabled(FALSE);
- LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
- clearMediaSettings();
- return;
- }
-
- BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
- && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
- || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
- bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
-
- // Check modify permissions and whether any selected objects are in
- // the process of being fetched. If they are, then we're not editable
- if (editable)
- {
- LLObjectSelection::iterator iter = selected_objects->begin();
- LLObjectSelection::iterator end = selected_objects->end();
- for ( ; iter != end; ++iter)
- {
- LLSelectNode* node = *iter;
- LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
- if (NULL != object)
- {
- if (!object->permModify())
- {
- LL_INFOS("LLFloaterToolsMedia")
- << "Selection not editable due to lack of modify permissions on object id "
- << object->getID() << LL_ENDL;
-
- editable = false;
- break;
- }
- // XXX DISABLE this for now, because when the fetch finally
- // does come in, the state of this floater doesn't properly
- // update. Re-selecting fixes the problem, but there is
- // contention as to whether this is a sufficient solution.
-// if (object->isMediaDataBeingFetched())
-// {
-// LL_INFOS("LLFloaterToolsMedia")
-// << "Selection not editable due to media data being fetched for object id "
-// << object->getID() << LL_ENDL;
-//
-// editable = false;
-// break;
-// }
- }
- }
- }
-
- // Media settings
- bool bool_has_media = false;
- struct media_functor : public LLSelectedTEGetFunctor<bool>
- {
- bool get(LLViewerObject* object, S32 face)
- {
- LLTextureEntry *te = object->getTE(face);
- if (te)
- {
- return te->hasMedia();
- }
- return false;
- }
- } func;
-
-
- // check if all faces have media(or, all dont have media)
- LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media );
-
- const LLMediaEntry default_media_data;
-
- struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
- {
- functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- LLMediaEntry get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return *(object->getTE(face)->getMediaData());
- return mMediaEntry;
- };
-
- const LLMediaEntry& mMediaEntry;
-
- } func_media_data(default_media_data);
-
- LLMediaEntry media_data_get;
- LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get ));
-
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- std::string media_title = "";
- // update UI depending on whether "object" (prim or face) has media
- // and whether or not you are allowed to edit it.
-
- getChildView("add_media")->setEnabled(editable);
- // IF all the faces have media (or all dont have media)
- if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo )
- {
- // TODO: get media title and set it.
- media_info->clear();
- // if identical is set, all faces are same (whether all empty or has the same media)
- if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) )
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- // else all faces might be empty.
- }
- else // there' re Different Medias' been set on on the faces.
- {
- media_title = multi_media_info_str;
- }
-
- getChildView("delete_media")->setEnabled(bool_has_media && editable );
- // TODO: display a list of all media on the face - use 'identical' flag
- }
- else // not all face has media but at least one does.
- {
- // seleted faces have not identical value
- LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data );
-
- if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
- {
- media_title = multi_media_info_str;
- }
- else
- {
- // Media data is valid
- if(media_data_get!=default_media_data)
- {
- // initial media title is the media URL (until we get the name)
- media_title = media_data_get.getHomeURL();
- }
- }
-
- getChildView("delete_media")->setEnabled(TRUE);
- }
-
- navigateToTitleMedia(media_title);
- media_info->setText(media_title);
-
- // load values for media settings
- updateMediaSettings();
-
- LLFloaterMediaSettings::initValues(mMediaSettings, editable );
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to add media to a prim or prim face
-void LLFloaterTools::onClickBtnAddMedia()
-{
- // check if multiple faces are selected
- if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
- {
- LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
- }
- else
- {
- onClickBtnEditMedia();
- }
-}
-
-// static
-bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- gFloaterTools->onClickBtnEditMedia();
- break;
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to edit existing media settings on a prim or prim face
-// TODO: test if there is media on the item and only allow editing if present
-void LLFloaterTools::onClickBtnEditMedia()
-{
- refreshMedia();
- LLFloaterReg::showInstance("media_settings");
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// called when a user wants to delete media from a prim or prim face
-void LLFloaterTools::onClickBtnDeleteMedia()
-{
- LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
-}
-
-
-// static
-bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- switch( option )
- {
- case 0: // "Yes"
- LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() );
- if(LLFloaterReg::instanceVisible("media_settings"))
- {
- LLFloaterReg::hideInstance("media_settings");
- }
- break;
-
- case 1: // "No"
- default:
- break;
- }
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::clearMediaSettings()
-{
- LLFloaterMediaSettings::clearValues(false);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::navigateToTitleMedia( const std::string url )
-{
- std::string multi_media_info_str = LLTrans::getString("Multiple Media");
- if (url.empty() || multi_media_info_str == url)
- {
- // nothing to show
- mNeedMediaTitle = false;
- }
- else if (mTitleMedia)
- {
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
-
- if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin?
- {
- // if it's a movie, we don't want to hear it
- media_plugin->setVolume( 0 );
- };
-
- // check if url changed or if we need a new media source
- if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
- {
- mTitleMedia->navigateTo( url );
- }
-
- // flag that we need to update the title (even if no request were made)
- mNeedMediaTitle = true;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaTitle()
-{
- // only get the media name if we need it
- if ( ! mNeedMediaTitle )
- return;
-
- // get plugin impl
- LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
- if ( media_plugin )
- {
- // get the media name (asynchronous - must call repeatedly)
- std::string media_title = media_plugin->getMediaName();
-
- // only replace the title if what we get contains something
- if ( ! media_title.empty() )
- {
- // update the UI widget
- LLTextBox* media_title_field = getChild<LLTextBox>("media_info");
- if ( media_title_field )
- {
- media_title_field->setText( media_title );
-
- // stop looking for a title when we get one
- // FIXME: check this is the right approach
- mNeedMediaTitle = false;
- };
- };
- };
-}
-
-//////////////////////////////////////////////////////////////////////////////
-//
-void LLFloaterTools::updateMediaSettings()
-{
- bool identical( false );
- std::string base_key( "" );
- std::string value_str( "" );
- int value_int = 0;
- bool value_bool = false;
- LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
- // TODO: (CP) refactor this using something clever or boost or both !!
-
- const LLMediaEntry default_media_data;
-
- // controls
- U8 value_u8 = default_media_data.getControls();
- struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
- {
- functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
-
- U8 get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getControls();
- return mMediaEntry.getControls();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_controls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
- base_key = std::string( LLMediaEntry::CONTROLS_KEY );
- mMediaSettings[ base_key ] = value_u8;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // First click (formerly left click)
- value_bool = default_media_data.getFirstClickInteract();
- struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getFirstClickInteract();
- return mMediaEntry.getFirstClickInteract();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_first_click(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
- base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Home URL
- value_str = default_media_data.getHomeURL();
- struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHomeURL();
- return mMediaEntry.getHomeURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_home_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
- base_key = std::string( LLMediaEntry::HOME_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Current URL
- value_str = default_media_data.getCurrentURL();
- struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
- {
- functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::string get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getCurrentURL();
- return mMediaEntry.getCurrentURL();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_current_url(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
- base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
- mMediaSettings[ base_key ] = value_str;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto zoom
- value_bool = default_media_data.getAutoZoom();
- struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
- {
-
- functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoZoom();
- return mMediaEntry.getAutoZoom();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_zoom(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto play
- //value_bool = default_media_data.getAutoPlay();
- // set default to auto play TRUE -- angela EXT-5172
- value_bool = true;
- struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoPlay();
- //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_play(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
-
- // Auto scale
- // set default to auto scale TRUE -- angela EXT-5172
- //value_bool = default_media_data.getAutoScale();
- value_bool = true;
- struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoScale();
- // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
- return true;
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_scale(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Auto loop
- value_bool = default_media_data.getAutoLoop();
- struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAutoLoop();
- return mMediaEntry.getAutoLoop();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_auto_loop(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
- base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // width pixels (if not auto scaled)
- value_int = default_media_data.getWidthPixels();
- struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWidthPixels();
- return mMediaEntry.getWidthPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_width_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
- base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // height pixels (if not auto scaled)
- value_int = default_media_data.getHeightPixels();
- struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
- {
- functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- int get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getHeightPixels();
- return mMediaEntry.getHeightPixels();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_height_pixels(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
- base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
- mMediaSettings[ base_key ] = value_int;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Enable Alt image
- value_bool = default_media_data.getAltImageEnable();
- struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getAltImageEnable();
- return mMediaEntry.getAltImageEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_enable_alt_image(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
- base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - owner control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
- struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_owner_control(default_media_data);
- identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_interact(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - group control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
- struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_group_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone interact
- value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_interact(default_media_data);
- identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // Perms - anyone control
- value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
- return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE );
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_perms_anyone_control(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
- base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist enable
- value_bool = default_media_data.getWhiteListEnable();
- struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
- {
- functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
-
- bool get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteListEnable();
- return mMediaEntry.getWhiteListEnable();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_enable(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
- base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
- mMediaSettings[ base_key ] = value_bool;
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-
- // security - whitelist URLs
- std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
- struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
- {
- functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {}
-
- std::vector<std::string> get( LLViewerObject* object, S32 face )
- {
- if ( object )
- if ( object->getTE(face) )
- if ( object->getTE(face)->getMediaData() )
- return object->getTE(face)->getMediaData()->getWhiteList();
- return mMediaEntry.getWhiteList();
- };
-
- const LLMediaEntry &mMediaEntry;
-
- } func_whitelist_urls(default_media_data);
- identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
- base_key = std::string( LLMediaEntry::WHITELIST_KEY );
- mMediaSettings[ base_key ].clear();
- std::vector< std::string >::iterator iter = value_vector_str.begin();
- while( iter != value_vector_str.end() )
- {
- std::string white_list_url = *iter;
- mMediaSettings[ base_key ].append( white_list_url );
- ++iter;
- };
-
- mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
-}
-
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index ffff564ad4..3bb6492a6e 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -44,7 +44,6 @@ class LLRadioGroup;
class LLSlider;
class LLTabContainer;
class LLTextBox;
-class LLMediaCtrl;
class LLTool;
class LLParcelSelection;
class LLObjectSelection;
@@ -98,11 +97,6 @@ public:
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
- void onClickBtnDeleteMedia();
- void onClickBtnAddMedia();
- void onClickBtnEditMedia();
- void clearMediaSettings();
- bool selectedMediaEditable();
void updateLandImpacts();
static void setGridMode(S32 mode);
@@ -111,13 +105,6 @@ public:
private:
void refresh();
- void refreshMedia();
- void getMediaState();
- void updateMediaSettings();
- void navigateToTitleMedia( const std::string url ); // navigate if changed
- void updateMediaTitle();
- static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
- static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
void onClickGridOptions();
@@ -193,19 +180,12 @@ public:
LLParcelSelectionHandle mParcelSelection;
LLObjectSelectionHandle mObjectSelection;
- LLMediaCtrl *mTitleMedia;
- bool mNeedMediaTitle;
-
private:
BOOL mDirty;
BOOL mHasSelection;
std::map<std::string, std::string> mStatusText;
-
-protected:
- LLSD mMediaSettings;
-
public:
static bool sShowObjectCost;
static bool sPreviousFocusOnAvatar;
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index d5c2ad5f81..917d6dfcd0 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
- else
- {
- LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
- if(panel_face)
- {
- panel_face->setMediaType(mime_type);
- panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
- }
-
- }
getChildView("loading_label")->setVisible( false);
closeFloater();
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 59e1f49f81..23f19dd5aa 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -127,7 +127,7 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(data);
getChild<LLUICtrl>("avatar_name")->setValue("");
updateVolumeControls();
diff --git a/indra/newview/llfloaterwebprofile.cpp b/indra/newview/llfloaterwebprofile.cpp
deleted file mode 100644
index 891bb90c0e..0000000000
--- a/indra/newview/llfloaterwebprofile.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file llfloaterwebprofile.cpp
- * @brief Avatar profile floater.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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 "llfloaterwebprofile.h"
-
-#include "llviewercontrol.h"
-
-LLFloaterWebProfile::LLFloaterWebProfile(const Params& key) :
- LLFloaterWebContent(key)
-{
-}
-
-void LLFloaterWebProfile::onOpen(const LLSD& key)
-{
- Params p(key);
- p.show_chrome(true);
- p.window_class("profile");
- p.allow_address_entry(false);
- p.trusted_content(true);
- LLFloaterWebContent::onOpen(p);
- applyPreferredRect();
-}
-
-// virtual
-void LLFloaterWebProfile::handleReshape(const LLRect& new_rect, bool by_user)
-{
- LL_DEBUGS() << "handleReshape: " << new_rect << LL_ENDL;
-
- if (by_user && !isMinimized())
- {
- LL_DEBUGS() << "Storing new rect" << LL_ENDL;
- gSavedSettings.setRect("WebProfileFloaterRect", new_rect);
- }
-
- LLFloaterWebContent::handleReshape(new_rect, by_user);
-}
-
-LLFloater* LLFloaterWebProfile::create(const LLSD& key)
-{
- LLFloaterWebContent::Params p(key);
- preCreate(p);
- return new LLFloaterWebProfile(p);
-}
-
-void LLFloaterWebProfile::applyPreferredRect()
-{
- const LLRect preferred_rect = gSavedSettings.getRect("WebProfileFloaterRect");
- LL_DEBUGS() << "Applying preferred rect: " << preferred_rect << LL_ENDL;
-
- // Don't override position that may have been set by floater stacking code.
- LLRect new_rect = getRect();
- new_rect.setLeftTopAndSize(
- new_rect.mLeft, new_rect.mTop,
- preferred_rect.getWidth(), preferred_rect.getHeight());
- setShape(new_rect);
-}
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 2c84cd1f93..01bfae8934 100644..100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -45,6 +45,7 @@
//#include "llfirstuse.h"
#include "llfloaterreg.h" // getTypedInstance()
#include "llfocusmgr.h"
+#include "lliconctrl.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llinventorymodelbackgroundfetch.h"
@@ -81,7 +82,6 @@
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
-static const F32 MAP_ZOOM_TIME = 0.2f;
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
@@ -284,7 +284,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
BOOL LLFloaterWorldMap::postBuild()
{
- mPanel = getChild<LLPanel>("objects_mapview");
+ mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
@@ -305,13 +305,13 @@ BOOL LLFloaterWorldMap::postBuild()
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
- mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
- getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal);
+ F32 slider_zoom = mMapView->getZoom();
+ getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);
+
+ getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
setDefaultBtn(NULL);
- mZoomTimer.stop();
-
onChangeMaturity();
return TRUE;
@@ -321,7 +321,7 @@ BOOL LLFloaterWorldMap::postBuild()
LLFloaterWorldMap::~LLFloaterWorldMap()
{
// All cleaned up by LLView destructor
- mPanel = NULL;
+ mMapView = NULL;
// Inventory deletes all observers on shutdown
mInventory = NULL;
@@ -359,17 +359,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
mIsClosing = FALSE;
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->clearLastClick();
+ mMapView->clearLastClick();
{
// reset pan on show, so it centers on you again
if (!center_on_target)
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, true);
}
- map_panel->updateVisibleBlocks();
+ mMapView->updateVisibleBlocks();
// Reload items as they may have changed
LLWorldMap::getInstance()->reloadItems();
@@ -417,18 +415,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (!isMinimized() && isFrontmost())
- {
- if(mPanel->pointInView(x, y))
- {
- F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal();
- slider_value += ((F32)clicks * -0.3333f);
- getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value));
- return TRUE;
- }
- }
-
- return LLFloater::handleScrollWheel(x, y, clicks);
+ if (!isMinimized() && isFrontmost())
+ {
+ S32 map_x = x - mMapView->getRect().mLeft;
+ S32 map_y = y - mMapView->getRect().mBottom;
+ if (mMapView->pointInView(map_x, map_y))
+ {
+ F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal();
+ F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f);
+ getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom));
+ mMapView->zoomWithPivot(slider_zoom, map_x, map_y);
+ return true;
+ }
+ }
+
+ return LLFloater::handleScrollWheel(x, y, clicks);
}
@@ -507,26 +508,13 @@ void LLFloaterWorldMap::draw()
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
-
- //RN: snaps to zoom value because interpolation caused jitter in the text rendering
- if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
- {
- mZoomTimer.start();
- }
- F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
- if (interp > 1.f)
- {
- interp = 1.f;
- mZoomTimer.stop();
- }
- mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
- F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
- LLWorldMapView::setScale( map_scale );
+
+ mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal());
// Enable/disable checkboxes depending on the zoom level
// If above threshold level (i.e. low res) -> Disable all checkboxes
// If under threshold level (i.e. high res) -> Enable all checkboxes
- bool enable = LLWorldMapView::showRegionInfo();
+ bool enable = mMapView->showRegionInfo();
getChildView("people_chk")->setEnabled(enable);
getChildView("infohub_chk")->setEnabled(enable);
getChildView("telehub_chk")->setEnabled(enable);
@@ -1005,7 +993,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
{
mTrackedStatus = LLTracker::TRACKING_NOTHING;
LLCtrlListInterface *list = mListFriendCombo;
- if (list)
+ if (list && list->getSelectedValue().asString() != "None")
{
list->selectByValue( "None" );
}
@@ -1025,9 +1013,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
S32 world_height_regions = MAX_VISIBLE_REGIONS;
// Find how much space we have to display the world
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)mPanel;
- LLRect view_rect = map_panel->getRect();
+ LLRect view_rect = mMapView->getRect();
// View size in pixels
S32 view_width = view_rect.getWidth();
@@ -1295,9 +1281,9 @@ void LLFloaterWorldMap::onShowTargetBtn()
void LLFloaterWorldMap::onShowAgentBtn()
{
- LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
- // Set flag so user's location will be displayed if not tracking anything else
- mSetToUserPosition = TRUE;
+ mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate
+ // Set flag so user's location will be displayed if not tracking anything else
+ mSetToUserPosition = true;
}
void LLFloaterWorldMap::onClickTeleportBtn()
@@ -1315,6 +1301,22 @@ void LLFloaterWorldMap::onCopySLURL()
LLNotificationsUtil::add("CopySLURL", args);
}
+void LLFloaterWorldMap::onExpandCollapseBtn()
+{
+ LLLayoutStack* floater_stack = getChild<LLLayoutStack>("floater_map_stack");
+ LLLayoutPanel* controls_panel = getChild<LLLayoutPanel>("controls_lp");
+
+ bool toggle_collapse = !controls_panel->isCollapsed();
+ floater_stack->collapsePanel(controls_panel, toggle_collapse);
+ floater_stack->updateLayout();
+
+ std::string image_name = getString(toggle_collapse ? "expand_icon" : "collapse_icon");
+ std::string tooltip = getString(toggle_collapse ? "expand_tooltip" : "collapse_tooltip");
+ getChild<LLIconCtrl>("expand_collapse_icon")->setImage(LLUI::getUIImage(image_name));
+ getChild<LLIconCtrl>("expand_collapse_icon")->setToolTip(tooltip);
+ getChild<LLPanel>("expand_btn_panel")->setToolTip(tooltip);
+}
+
// protected
void LLFloaterWorldMap::centerOnTarget(BOOL animate)
{
@@ -1349,9 +1351,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
pos_global.clearVec();
}
- LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- !animate);
+ F64 map_scale = (F64)mMapView->getScale();
+ mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)),
+ -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)),
+ !animate, 0.1f);
mWaitingForTracker = FALSE;
}
@@ -1581,7 +1584,7 @@ void LLFloaterWorldMap::onTeleportFinished()
{
if(isInVisibleChain())
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, TRUE);
}
}
@@ -1656,9 +1659,8 @@ void LLFloaterWorldMap::onChangeMaturity()
void LLFloaterWorldMap::onFocusLost()
{
- gViewerWindow->showCursor();
- LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->mPanning = FALSE;
+ gViewerWindow->showCursor();
+ mMapView->mPanning = false;
}
LLPanelHideBeacon::LLPanelHideBeacon() :
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 14a9c26fb9..3702226d23 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -44,6 +44,7 @@ class LLInventoryObserver;
class LLItemInfo;
class LLLineEditor;
class LLTabContainer;
+class LLWorldMapView;
class LLFloaterWorldMap : public LLFloater
{
@@ -130,6 +131,8 @@ protected:
void onShowAgentBtn();
void onCopySLURL();
+ void onExpandCollapseBtn();
+
void centerOnTarget(BOOL animate);
void updateLocation();
@@ -154,11 +157,7 @@ protected:
void onTeleportFinished();
private:
- LLPanel* mPanel; // Panel displaying the map
-
- // Ties to LLWorldMapView::sMapScale, in pixels per region
- F32 mCurZoomVal;
- LLFrameTimer mZoomTimer;
+ LLWorldMapView* mMapView; // Panel displaying the map
// update display of teleport destination coordinates - pos is in global coordinates
void updateTeleportCoordsDisplay( const LLVector3d& pos );
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0be748ace9..e395da7f1e 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders()
/************************************************************************/
/* Private Methods */
/************************************************************************/
-const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
+const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const
{
- const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+ if (parent_id.isNull())
+ {
+ return LLUUID::null;
+ }
- std::string friendFolderName = get_friend_folder_name();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(parent_id, cats, items);
- return findChildFolderUUID(callingCardsFolderID, friendFolderName);
+ if (!cats || !items || cats->size() == 0)
+ {
+ // call failed
+ return LLUUID::null;
+ }
+
+ if (cats->size() > 1)
+ {
+ const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id);
+ if (friendFolder)
+ {
+ LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL;
+ }
+ }
+
+ for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin();
+ iter != cats->end();
+ ++iter)
+ {
+ const LLInventoryCategory* category = (*iter);
+ if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD)
+ {
+ return category->getUUID();
+ }
+ }
+
+ return LLUUID::null;
}
-const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+// Inventorry ->
+// Calling Cards - >
+// Friends - > (the only expected folder)
+// All (the only expected folder)
+
+const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const
{
- LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
+ const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+ return findFirstCallingCardSubfolder(callingCardsFolderID);
+}
- std::string friendAllSubfolderName = get_friend_all_subfolder_name();
+const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const
+{
+ LLUUID friendFolderUUID = findFriendFolderUUIDImpl();
- return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName);
+ return findFirstCallingCardSubfolder(friendFolderUUID);
}
const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index 2fb912a930..f5679d7d85 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -116,6 +116,7 @@ private:
}
const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const;
+ const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const;
const LLUUID& findFriendFolderUUIDImpl() const;
const LLUUID& findFriendAllSubfolderUUIDImpl() const;
const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID);
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 91ab445273..7c8e8279c2 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -185,7 +185,7 @@ private:
std::set<LLUUID> mLoadingAssets;
// LLEventHost interface
- boost::shared_ptr<LLGestureListener> mListener;
+ std::shared_ptr<LLGestureListener> mListener;
};
#endif
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e7bc2a9268..84a1278767 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL;
// static
void LLGroupActions::search()
{
- LLFloaterReg::showInstance("search");
+ LLFloaterReg::showInstance("search", LLSD().with("collection", "groups"));
}
// static
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 62414d3bbb..32af2592d3 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -45,7 +45,6 @@
#include "llvoiceclient.h"
static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
-S32 LLGroupListItem::sIconWidth = 0;
class LLGroupComparator : public LLFlatListView::ItemComparator
{
@@ -65,21 +64,81 @@ public:
}
};
-static const LLGroupComparator GROUP_COMPARATOR;
+class LLSharedGroupComparator : public LLFlatListView::ItemComparator
+{
+public:
+ LLSharedGroupComparator() {};
+
+ /*virtual*/ bool compare(const LLPanel* item1, const LLPanel* item2) const
+ {
+ const LLGroupListItem* group_item1 = static_cast<const LLGroupListItem*>(item1);
+ std::string name1 = group_item1->getGroupName();
+ bool item1_shared = gAgent.isInGroup(group_item1->getGroupID(), true);
+
+ const LLGroupListItem* group_item2 = static_cast<const LLGroupListItem*>(item2);
+ std::string name2 = group_item2->getGroupName();
+ bool item2_shared = gAgent.isInGroup(group_item2->getGroupID(), true);
+ if (item2_shared != item1_shared)
+ {
+ return item1_shared;
+ }
+
+ LLStringUtil::toUpper(name1);
+ LLStringUtil::toUpper(name2);
+
+ return name1 < name2;
+ }
+};
+
+static LLGroupComparator GROUP_COMPARATOR;
+static LLSharedGroupComparator SHARED_GROUP_COMPARATOR;
+
+LLGroupList::Params::Params()
+: for_agent("for_agent", true)
+{
+}
LLGroupList::LLGroupList(const Params& p)
: LLFlatListViewEx(p)
+ , mForAgent(p.for_agent)
, mDirty(true) // to force initial update
+ , mShowIcons(false)
+ , mShowNone(true)
{
- // Listen for agent group changes.
- gAgent.addListener(this, "new group");
-
- mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
setCommitOnSelectionChange(true);
// Set default sort order.
- setComparator(&GROUP_COMPARATOR);
+ if (mForAgent)
+ {
+ setComparator(&GROUP_COMPARATOR);
+ }
+ else
+ {
+ // shared groups first
+ setComparator(&SHARED_GROUP_COMPARATOR);
+ }
+
+ if (mForAgent)
+ {
+ enableForAgent(true);
+ }
+}
+
+LLGroupList::~LLGroupList()
+{
+ if (mForAgent) gAgent.removeListener(this);
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
+}
+
+void LLGroupList::enableForAgent(bool show_icons)
+{
+ mForAgent = true;
+
+ mShowIcons = mForAgent && gSavedSettings.getBOOL("GroupListShowIcons") && show_icons;
+
+ // Listen for agent group changes.
+ gAgent.addListener(this, "new group");
// Set up context menu.
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -94,12 +153,6 @@ LLGroupList::LLGroupList(const Params& p)
mContextMenuHandle = context_menu->getHandle();
}
-LLGroupList::~LLGroupList()
-{
- gAgent.removeListener(this);
- if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
-}
-
// virtual
void LLGroupList::draw()
{
@@ -114,12 +167,15 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
- LLToggleableMenu* context_menu = mContextMenuHandle.get();
- if (context_menu && size() > 0)
- {
- context_menu->buildDrawLabels();
- context_menu->updateParent(LLMenuGL::sMenuContainer);
- LLMenuGL::showPopup(this, context_menu, x, y);
+ if (mForAgent)
+ {
+ LLToggleableMenu* context_menu = mContextMenuHandle.get();
+ if (context_menu && size() > 0)
+ {
+ context_menu->buildDrawLabels();
+ context_menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, context_menu, x, y);
+ }
}
return handled;
@@ -132,7 +188,7 @@ BOOL LLGroupList::handleDoubleClick(S32 x, S32 y, MASK mask)
// Handle double click only for the selected item in the list, skip clicks on empty space.
if (handled)
{
- if (mDoubleClickSignal)
+ if (mDoubleClickSignal && getItemsRect().pointInRect(x, y))
{
(*mDoubleClickSignal)(this, x, y, mask);
}
@@ -164,34 +220,49 @@ static bool findInsensitive(std::string haystack, const std::string& needle_uppe
void LLGroupList::refresh()
{
- const LLUUID& highlight_id = gAgent.getGroupID();
- S32 count = gAgent.mGroups.size();
- LLUUID id;
- bool have_filter = !mNameFilter.empty();
-
- clear();
-
- for(S32 i = 0; i < count; ++i)
- {
- id = gAgent.mGroups.at(i).mID;
- const LLGroupData& group_data = gAgent.mGroups.at(i);
- if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
- continue;
- addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM);
- }
-
- // Sort the list.
- sort();
-
- // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
- // but only if some real groups exists. EXT-4838
- if (!have_filter && count > 0)
- {
- std::string loc_none = LLTrans::getString("GroupsNone");
- addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
- }
-
- selectItemByUUID(highlight_id);
+ if (mForAgent)
+ {
+ const LLUUID& highlight_id = gAgent.getGroupID();
+ S32 count = gAgent.mGroups.size();
+ LLUUID id;
+ bool have_filter = !mNameFilter.empty();
+
+ clear();
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ id = gAgent.mGroups.at(i).mID;
+ const LLGroupData& group_data = gAgent.mGroups.at(i);
+ if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
+ continue;
+ addNewItem(id, group_data.mName, group_data.mInsigniaID, ADD_BOTTOM, group_data.mListInProfile);
+ }
+
+ // Sort the list.
+ sort();
+
+ // Add "none" to list at top if filter not set (what's the point of filtering "none"?).
+ // but only if some real groups exists. EXT-4838
+ if (!have_filter && count > 0 && mShowNone)
+ {
+ std::string loc_none = LLTrans::getString("GroupsNone");
+ addNewItem(LLUUID::null, loc_none, LLUUID::null, ADD_TOP);
+ }
+
+ selectItemByUUID(highlight_id);
+ }
+ else
+ {
+ clear();
+
+ for (group_map_t::iterator it = mGroups.begin(); it != mGroups.end(); ++it)
+ {
+ addNewItem(it->second, it->first, LLUUID::null, ADD_BOTTOM);
+ }
+
+ // Sort the list.
+ sort();
+ }
setDirty(false);
onCommit();
@@ -212,13 +283,19 @@ void LLGroupList::toggleIcons()
}
}
+void LLGroupList::setGroups(const std::map< std::string,LLUUID> group_list)
+{
+ mGroups = group_list;
+ setDirty(true);
+}
+
//////////////////////////////////////////////////////////////////////////
// PRIVATE Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos)
+void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos, bool visible_in_profile)
{
- LLGroupListItem* item = new LLGroupListItem();
+ LLGroupListItem* item = new LLGroupListItem(mForAgent, mShowIcons);
item->setGroupID(id);
item->setName(name, mNameFilter);
@@ -227,7 +304,10 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->getChildView("info_btn")->setVisible( false);
item->getChildView("profile_btn")->setVisible( false);
item->setGroupIconVisible(mShowIcons);
-
+ if (!mShowIcons)
+ {
+ item->setVisibleInProfile(visible_in_profile);
+ }
addItem(item, id, pos);
// setCommentVisible(false);
@@ -243,6 +323,29 @@ bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD&
return true;
}
+ if (event->desc() == "value_changed")
+ {
+ LLSD data = event->getValue();
+ if (data.has("group_id") && data.has("visible"))
+ {
+ LLUUID group_id = data["group_id"].asUUID();
+ bool visible = data["visible"].asBoolean();
+
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for (std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
+ {
+ LLGroupListItem* item = dynamic_cast<LLGroupListItem*>(*it);
+ if (item && item->getGroupID() == group_id)
+ {
+ item->setVisibleInProfile(visible);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
return false;
}
@@ -294,21 +397,25 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
/* LLGroupListItem implementation */
/************************************************************************/
-LLGroupListItem::LLGroupListItem()
+LLGroupListItem::LLGroupListItem(bool for_agent, bool show_icons)
: LLPanel(),
mGroupIcon(NULL),
mGroupNameBox(NULL),
mInfoBtn(NULL),
-mGroupID(LLUUID::null)
+mProfileBtn(NULL),
+mVisibilityHideBtn(NULL),
+mVisibilityShowBtn(NULL),
+mGroupID(LLUUID::null),
+mForAgent(for_agent)
{
- buildFromFile( "panel_group_list_item.xml");
-
- // Remember group icon width including its padding from the name text box,
- // so that we can hide and show the icon again later.
- if (!sIconWidth)
- {
- sIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
- }
+ if (show_icons)
+ {
+ buildFromFile( "panel_group_list_item.xml");
+ }
+ else
+ {
+ buildFromFile( "panel_group_list_item_short.xml");
+ }
}
LLGroupListItem::~LLGroupListItem()
@@ -325,7 +432,25 @@ BOOL LLGroupListItem::postBuild()
mInfoBtn = getChild<LLButton>("info_btn");
mInfoBtn->setClickedCallback(boost::bind(&LLGroupListItem::onInfoBtnClick, this));
- childSetAction("profile_btn", boost::bind(&LLGroupListItem::onProfileBtnClick, this));
+ mProfileBtn = getChild<LLButton>("profile_btn");
+ mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
+
+ mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn");
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(false); });
+ }
+ mVisibilityShowBtn = findChild<LLButton>("visibility_show_btn");
+ if (mVisibilityShowBtn)
+ {
+ mVisibilityShowBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onVisibilityBtnClick(true); });
+ }
+
+ // Remember group icon width including its padding from the name text box,
+ // so that we can hide and show the icon again later.
+ // Also note that panel_group_list_item and panel_group_list_item_short
+ // have icons of different sizes so we need to figure it per file.
+ mIconWidth = mGroupNameBox->getRect().mLeft - mGroupIcon->getRect().mLeft;
return TRUE;
}
@@ -344,7 +469,16 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
if (mGroupID.notNull()) // don't show the info button for the "none" group
{
mInfoBtn->setVisible(true);
- getChildView("profile_btn")->setVisible( true);
+ mProfileBtn->setVisible(true);
+ if (mForAgent && mVisibilityHideBtn)
+ {
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
+ mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ }
+ }
}
LLPanel::onMouseEnter(x, y, mask);
@@ -354,7 +488,12 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
getChildView("hovered_icon")->setVisible( false);
mInfoBtn->setVisible(false);
- getChildView("profile_btn")->setVisible( false);
+ mProfileBtn->setVisible(false);
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setVisible(false);
+ mVisibilityShowBtn->setVisible(false);
+ }
LLPanel::onMouseLeave(x, y, mask);
}
@@ -372,7 +511,17 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
mID = group_id;
mGroupID = group_id;
- setActive(group_id == gAgent.getGroupID());
+
+ if (mForAgent)
+ {
+ // Active group should be bold.
+ setBold(group_id == gAgent.getGroupID());
+ }
+ else
+ {
+ // Groups shared with the agent should be bold
+ setBold(gAgent.isInGroup(group_id, true));
+ }
LLGroupMgr::getInstance()->addObserver(this);
}
@@ -393,24 +542,28 @@ void LLGroupListItem::setGroupIconVisible(bool visible)
// Move the group name horizontally by icon size + its distance from the group name.
LLRect name_rect = mGroupNameBox->getRect();
- name_rect.mLeft += visible ? sIconWidth : -sIconWidth;
+ name_rect.mLeft += visible ? mIconWidth : -mIconWidth;
mGroupNameBox->setRect(name_rect);
}
+void LLGroupListItem::setVisibleInProfile(bool visible)
+{
+ mGroupNameBox->setColor(LLUIColorTable::instance().getColor((visible ? "GroupVisibleInProfile" : "GroupHiddenInProfile"), LLColor4::red).get());
+}
+
//////////////////////////////////////////////////////////////////////////
// Private Section
//////////////////////////////////////////////////////////////////////////
-void LLGroupListItem::setActive(bool active)
+void LLGroupListItem::setBold(bool bold)
{
// *BUG: setName() overrides the style params.
- // Active group should be bold.
LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
// *NOTE dzaporozhan
// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font
// is predefined as bold (SansSerifSmallBold, for example)
- new_desc.setStyle(active ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ new_desc.setStyle(bold ? LLFontGL::BOLD : LLFontGL::NORMAL);
LLFontGL* new_font = LLFontGL::getFont(new_desc);
mGroupNameStyle.font = new_font;
@@ -430,11 +583,25 @@ void LLGroupListItem::onProfileBtnClick()
LLGroupActions::show(mGroupID);
}
+void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
+{
+ LLGroupData agent_gdatap;
+ if (gAgent.getGroupData(mGroupID, agent_gdatap))
+ {
+ gAgent.setUserGroupFlags(mGroupID, agent_gdatap.mAcceptNotices, new_visibility);
+ setVisibleInProfile(new_visibility);
+ mVisibilityHideBtn->setVisible(new_visibility);
+ mVisibilityShowBtn->setVisible(!new_visibility);
+ }
+}
+
void LLGroupListItem::changed(LLGroupChange gc)
{
LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mID);
- if(group_data)
- setGroupIconID(group_data->mInsigniaID);
+ if ((gc == GC_ALL || gc == GC_PROPERTIES) && group_data)
+ {
+ setGroupIconID(group_data->mInsigniaID);
+ }
}
//EOF
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 171b77fb00..5cbabb712f 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -50,12 +50,15 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
public:
struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
{
- Params(){};
+ Optional<bool> for_agent;
+ Params();
};
LLGroupList(const Params& p);
virtual ~LLGroupList();
+ void enableForAgent(bool show_icons);
+
virtual void draw(); // from LLView
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); // from LLView
/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); // from LLView
@@ -63,13 +66,16 @@ public:
void setNameFilter(const std::string& filter);
void toggleIcons();
bool getIconsVisible() const { return mShowIcons; }
+ void setIconsVisible(bool show_icons) { mShowIcons = show_icons; }
+ void setShowNone(bool show_none) { mShowNone = show_none; }
+ void setGroups(const std::map< std::string,LLUUID> group_list);
LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
private:
void setDirty(bool val = true) { mDirty = val; }
void refresh();
- void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM);
+ void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, EAddPosition pos = ADD_BOTTOM, bool visible_in_profile = true);
bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
bool onContextMenuItemClick(const LLSD& userdata);
@@ -80,6 +86,11 @@ private:
bool mShowIcons;
bool mDirty;
std::string mNameFilter;
+
+ bool mForAgent;
+ bool mShowNone;
+ typedef std::map< std::string,LLUUID> group_map_t;
+ group_map_t mGroups;
};
class LLButton;
@@ -90,7 +101,7 @@ class LLGroupListItem : public LLPanel
, public LLGroupMgrObserver
{
public:
- LLGroupListItem();
+ LLGroupListItem(bool for_agent, bool show_icons);
~LLGroupListItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
@@ -106,19 +117,26 @@ public:
void setGroupIconVisible(bool visible);
virtual void changed(LLGroupChange gc);
+
+ void setVisibleInProfile(bool visible);
private:
- void setActive(bool active);
+ void setBold(bool bold);
void onInfoBtnClick();
void onProfileBtnClick();
+ void onVisibilityBtnClick(bool new_visibility);
LLTextBox* mGroupNameBox;
LLUUID mGroupID;
LLGroupIconCtrl* mGroupIcon;
- LLButton* mInfoBtn;
+ LLButton* mInfoBtn;
+ LLButton* mProfileBtn;
+ LLButton* mVisibilityHideBtn;
+ LLButton* mVisibilityShowBtn;
std::string mGroupName;
+ bool mForAgent;
LLStyle::Params mGroupNameStyle;
- static S32 sIconWidth; // icon width + padding
+ S32 mIconWidth;
};
#endif // LL_LLGROUPLIST_H
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 7f65153879..a9e5e55451 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -53,6 +53,7 @@
#include "llviewerregion.h"
#include <boost/regex.hpp>
#include "llcorehttputil.h"
+#include "lluiusage.h"
#if LL_MSVC
@@ -1859,6 +1860,9 @@ void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id)
//static
void LLGroupMgr::sendGroupMemberJoin(const LLUUID& group_id)
{
+
+ LLUIUsage::instance().logCommand("Group.Join");
+
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_JoinGroupRequest);
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 7be35ac260..5952edfc44 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -330,7 +330,7 @@ void LLHUDText::updateVisibility()
if (!mSourceObject)
{
- LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL;
+ // Beacons
mVisible = TRUE;
if (mOnHUDAttachment)
{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b7e0a6a794..4d6ebf9cbb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -69,7 +69,7 @@
#include "message.h"
#include "llviewerregion.h"
#include "llcorehttputil.h"
-
+#include "lluiusage.h"
const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -532,7 +532,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
mSessionInitialized(false),
mCallBackEnabled(true),
mTextIMPossible(true),
- mOtherParticipantIsAvatar(true),
mStartCallOnInitialize(false),
mStartedAsIMCall(voice),
mIsDNDsend(false),
@@ -544,13 +543,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType)
{
mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
- mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
-
- // check if it was AVALINE call
- if (!mOtherParticipantIsAvatar)
- {
- mSessionType = AVALINE_SESSION;
- }
}
else
{
@@ -651,9 +643,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
switch(mSessionType)
{
- case AVALINE_SESSION:
- // no text notifications
- break;
case P2P_SESSION:
LLAvatarNameCache::get(mOtherParticipantID, &av_name);
other_avatar_name = av_name.getUserName();
@@ -781,6 +770,23 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
message["index"] = (LLSD::Integer)mMsgs.size();
message["is_history"] = is_history;
+ LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL;
+ if (from_id == gAgent.getID())
+ {
+ if (mType == IM_SESSION_GROUP_START)
+ {
+ LLUIUsage::instance().logCommand("Chat.SendGroup");
+ }
+ else if (mType == IM_NOTHING_SPECIAL)
+ {
+ LLUIUsage::instance().logCommand("Chat.SendIM");
+ }
+ else
+ {
+ LLUIUsage::instance().logCommand("Chat.SendOther");
+ }
+ }
+
mMsgs.push_front(message);
if (mSpeakers && from_id.notNull())
@@ -913,11 +919,6 @@ bool LLIMModel::LLIMSession::isGroupChat()
return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID, TRUE));
}
-bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
-{
- return !mOtherParticipantIsAvatar;
-}
-
LLUUID LLIMModel::LLIMSession::generateOutgoingAdHocHash() const
{
LLUUID hash = LLUUID::null;
@@ -1795,7 +1796,6 @@ LLIMMgr::onConfirmForceCloseError(
LLCallDialogManager::LLCallDialogManager():
mPreviousSessionlName(""),
-mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION),
mCurrentSessionlName(""),
mSession(NULL),
mOldState(LLVoiceChannel::STATE_READY)
@@ -1826,12 +1826,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
return;
}
-
- if (mSession)
- {
- // store previous session type to process Avaline calls in dialogs
- mPreviousSessionType = mSession->mSessionType;
- }
mSession = session;
@@ -1857,7 +1851,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1893,7 +1886,6 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
mCallDialogPayload["session_name"] = mSession->mName;
mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID;
mCallDialogPayload["old_channel_name"] = mPreviousSessionlName;
- mCallDialogPayload["old_session_type"] = mPreviousSessionType;
mCallDialogPayload["state"] = new_state;
mCallDialogPayload["disconnected_channel_name"] = mSession->mName;
mCallDialogPayload["session_type"] = mSession->mSessionType;
@@ -1910,8 +1902,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
break;
case LLVoiceChannel::STATE_HUNG_UP:
- // this state is coming before session is changed, so, put it into payload map
- mCallDialogPayload["old_session_type"] = mSession->mSessionType;
+ // this state is coming before session is changed
break;
case LLVoiceChannel::STATE_CONNECTED :
@@ -2031,7 +2022,6 @@ void LLCallDialog::onOpen(const LLSD& key)
void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
{
- // *NOTE: 12/28/2009: check avaline calls: LLVoiceClient::isParticipantAvatar returns false for them
bool participant_is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
bool is_group = participant_is_avatar && gAgent.isInGroup(session_id, TRUE);
@@ -2052,8 +2042,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
}
else
{
- avatar_icon->setValue("Avaline_Icon");
- avatar_icon->setToolTip(std::string(""));
+ LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL;
+ group_icon->setValue(session_id);
}
}
@@ -2097,13 +2087,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
// tell the user which voice channel they are leaving
if (!mPayload["old_channel_name"].asString().empty())
{
- bool was_avaline_call = LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["old_session_type"].asInteger();
-
std::string old_caller_name = mPayload["old_channel_name"].asString();
- if (was_avaline_call)
- {
- old_caller_name = LLTextUtil::formatPhoneNumber(old_caller_name);
- }
getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name);
show_oldchannel = true;
@@ -2116,10 +2100,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)
if (!mPayload["disconnected_channel_name"].asString().empty())
{
std::string channel_name = mPayload["disconnected_channel_name"].asString();
- if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger())
- {
- channel_name = LLTextUtil::formatPhoneNumber(channel_name);
- }
getChild<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name);
// skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice,
@@ -2135,16 +2115,11 @@ void LLOutgoingCallDialog::show(const LLSD& key)
std::string callee_name = mPayload["session_name"].asString();
LLUUID session_id = mPayload["session_id"].asUUID();
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (callee_name == "anonymous")
+ if (callee_name == "anonymous") // obsolete? Likely was part of avaline support
{
callee_name = getString("anonymous");
}
- else if (!is_avatar)
- {
- callee_name = LLTextUtil::formatPhoneNumber(callee_name);
- }
LLSD callee_id = mPayload["other_user_id"];
// Beautification: Since you know who you called, just show display name
@@ -2344,18 +2319,11 @@ BOOL LLIncomingCallDialog::postBuild()
call_type = getString(notify_box_type);
}
- // check to see if this is an Avaline call
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- if (caller_name == "anonymous")
+ if (caller_name == "anonymous") // obsolete? Likely was part of avaline support
{
caller_name = getString("anonymous");
setCallerName(caller_name, caller_name, call_type);
}
- else if (!is_avatar)
- {
- caller_name = LLTextUtil::formatPhoneNumber(caller_name);
- setCallerName(caller_name, caller_name, call_type);
- }
else
{
// Get the full name information
@@ -2375,7 +2343,7 @@ BOOL LLIncomingCallDialog::postBuild()
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
- // starting notification's timer for P2P and AVALINE invitations
+ // starting notification's timer for P2P invitations
mLifetimeTimer.start();
}
else
@@ -2384,7 +2352,7 @@ BOOL LLIncomingCallDialog::postBuild()
}
//it's not possible to connect to existing Ad-Hoc/Group chat through incoming ad-hoc call
- //and no IM for avaline
+ bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
setCanDrag(FALSE);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 79c831ebb6..fdf9806e2e 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -72,7 +72,6 @@ public:
P2P_SESSION,
GROUP_SESSION,
ADHOC_SESSION,
- AVALINE_SESSION,
NONE_SESSION,
} SType;
@@ -92,12 +91,10 @@ public:
bool isAdHoc();
bool isP2P();
bool isGroupChat();
- bool isOtherParticipantAvaline();
bool isP2PSessionType() const { return mSessionType == P2P_SESSION;}
bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;}
bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
- bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
LLUUID generateOutgoingAdHocHash() const;
@@ -136,7 +133,6 @@ public:
bool mCallBackEnabled;
bool mTextIMPossible;
- bool mOtherParticipantIsAvatar;
bool mStartCallOnInitialize;
//if IM session is created for a voice call
@@ -516,7 +512,6 @@ private:
protected:
std::string mPreviousSessionlName;
- LLIMModel::LLIMSession::SType mPreviousSessionType;
std::string mCurrentSessionlName;
LLIMModel::LLIMSession* mSession;
LLVoiceChannel::EState mOldState;
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index 479e8f9abf..f382b5985f 100644
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
@@ -147,3 +147,19 @@ bool LLInspect::childHasVisiblePopupMenu()
}
return false;
}
+
+void LLInspect::repositionInspector(const LLSD& data)
+{
+ // Position the inspector relative to the mouse cursor
+ // Similar to how tooltips are positioned
+ // See LLToolTipMgr::createToolTip
+ if (data.has("pos"))
+ {
+ LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
+ }
+ else
+ {
+ LLUI::getInstance()->positionViewNearMouse(this);
+ }
+ applyRectControl();
+}
diff --git a/indra/newview/llinspect.h b/indra/newview/llinspect.h
index 1f6aafc7bd..6909aa3f16 100644
--- a/indra/newview/llinspect.h
+++ b/indra/newview/llinspect.h
@@ -49,6 +49,8 @@ public:
/// Inspectors close themselves when they lose focus
/*virtual*/ void onFocusLost();
+
+ void repositionInspector(const LLSD& data);
protected:
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 10814ac076..b11c440015 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -45,7 +45,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "lltextbox.h"
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
class LLFetchAvatarData;
@@ -202,17 +201,7 @@ void LLInspectAvatar::onOpen(const LLSD& data)
// Extract appropriate avatar id
mAvatarID = data["avatar_id"];
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// Generate link to avatar profile.
LLTextBase* avatar_profile_link = getChild<LLTextBase>("avatar_profile_link");
@@ -348,7 +337,7 @@ void LLInspectAvatar::onClickMuteVolume()
LLMuteList* mute_list = LLMuteList::getInstance();
bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
- LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT);
+ LLMute mute(mAvatarID, mAvatarName.getUserName(), LLMute::AGENT);
if (!is_muted)
{
mute_list->add(mute, LLMute::flagVoiceChat);
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index fa8a53c546..0a30ab9217 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -38,7 +38,6 @@
#include "llfloater.h"
#include "llfloaterreg.h"
#include "llresmgr.h" // getMonetaryString()
-#include "lltooltip.h" // positionViewNearMouse()
#include "lltrans.h"
#include "lluictrl.h"
#include "llgroupiconctrl.h"
@@ -124,17 +123,7 @@ void LLInspectGroup::onOpen(const LLSD& data)
setGroupID(data["group_id"]);
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
// can't call from constructor as widgets are not built yet
requestUpdate();
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index cb7031971b..5329f10612 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -50,7 +50,6 @@
#include "lltextbox.h" // for description truncation
#include "lltoggleablemenu.h"
#include "lltrans.h"
-#include "llui.h" // positionViewNearMouse()
#include "lluictrl.h"
class LLViewerObject;
@@ -198,17 +197,8 @@ void LLInspectObject::onOpen(const LLSD& data)
{
mObjectFace = data["object_face"];
}
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+
+ LLInspect::repositionInspector(data);
// Promote hovered object to a complete selection, which will also force
// a request for selected object data off the network
diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp
index 272c8acbd5..77320510a6 100644
--- a/indra/newview/llinspectremoteobject.cpp
+++ b/indra/newview/llinspectremoteobject.cpp
@@ -111,17 +111,7 @@ void LLInspectRemoteObject::onOpen(const LLSD& data)
// update the inspector with the current object state
update();
- // Position the inspector relative to the mouse cursor
- // Similar to how tooltips are positioned
- // See LLToolTipMgr::createToolTip
- if (data.has("pos"))
- {
- LLUI::getInstance()->positionViewNearMouse(this, data["pos"]["x"].asInteger(), data["pos"]["y"].asInteger());
- }
- else
- {
- LLUI::getInstance()->positionViewNearMouse(this);
- }
+ LLInspect::repositionInspector(data);
}
void LLInspectRemoteObject::onClickMap()
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index d0034eff13..68801b0895 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -110,7 +110,7 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
panel_rect = panel->getRect();
reshape(panel_rect.getWidth(), panel_rect.getHeight());
- LLUI::getInstance()->positionViewNearMouse(this);
+ LLInspect::repositionInspector(notification_id);
}
// virtual
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a0de3a2af1..a0bc1035bf 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -792,6 +792,19 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy"));
}
+ if (isAgentInventory())
+ {
+ items.push_back(std::string("New folder from selected"));
+ items.push_back(std::string("Subfolder Separator"));
+ std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs();
+ uuid_vec_t ids;
+ std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+ if (!is_only_items_selected(ids) && !is_only_cats_selected(ids))
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
+ }
+
if (obj->getIsLinkType())
{
items.push_back(std::string("Find Original"));
@@ -1102,7 +1115,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags,
LLInventoryModel::cat_array_t categories;
LLInventoryModel::item_array_t items;
gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE);
- if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount"))
+ LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4);
+ LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20);
+ if (categories.size() >= max_count
+ || depth > (max_depth + 1))
{
disabled_items.push_back(std::string("New Folder"));
}
@@ -3798,7 +3814,20 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (item && can_move_to_landmarks(item))
{
- dropToFavorites(item);
+ if (LLClipboard::instance().isCutMode())
+ {
+ LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
+ llassert(viitem);
+ if (viitem)
+ {
+ //changeItemParent() implicity calls dirtyFilter
+ changeItemParent(model, viitem, parent_id, FALSE);
+ }
+ }
+ else
+ {
+ dropToFavorites(item);
+ }
}
}
else if (LLClipboard::instance().isCutMode())
@@ -4266,7 +4295,16 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
items.push_back(std::string("Conference Chat Folder"));
items.push_back(std::string("IM All Contacts In Folder"));
}
+
+ if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren())
+ {
+ items.push_back(std::string("Ungroup folder items"));
+ }
}
+ else
+ {
+ disabled_items.push_back(std::string("New folder from selected"));
+ }
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d239b23e83..27edc8148e 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1868,6 +1868,86 @@ void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
}
}
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryItem* inv_item = gInventory.getItem(*it);
+ if (inv_item)
+ {
+ change_item_parent(*it, new_cat_uuid);
+ }
+ else
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (inv_cat && !LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
+ gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false);
+ }
+ }
+ }
+
+ LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+ if (!floater_inventory)
+ {
+ LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
+ return;
+ }
+ LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+ if (sidepanel_inventory)
+ {
+ if (sidepanel_inventory->getActivePanel())
+ {
+ sidepanel_inventory->getActivePanel()->setSelection(new_cat_uuid, TAKE_FOCUS_YES);
+ LLFolderViewItem* fv_folder = sidepanel_inventory->getActivePanel()->getItemByID(new_cat_uuid);
+ if (fv_folder)
+ {
+ fv_folder->setOpen(TRUE);
+ }
+ }
+ }
+}
+
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*it);
+ if (!inv_cat)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool is_only_items_selected(const uuid_vec_t& selected_uuids)
+{
+ for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it)
+ {
+ LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
+ if (!inv_item)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name)
+{
+ LLInventoryObject* first_item = gInventory.getObject(*selected_uuids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+
+ inventory_func_type func = boost::bind(&move_items_to_folder, _1, selected_uuids);
+ gInventory.createNewCategory(first_item->getParentUUID(), LLFolderType::FT_NONE, folder_name, func);
+
+}
+
///----------------------------------------------------------------------------
/// LLInventoryCollectFunctor implementations
///----------------------------------------------------------------------------
@@ -2522,6 +2602,81 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
{
(new LLDirPickerThread(boost::bind(&LLInventoryAction::saveMultipleTextures, _1, selected_items, model), std::string()))->getFile();
}
+ else if ("new_folder_from_selected" == action)
+ {
+
+ LLInventoryObject* first_item = gInventory.getObject(*ids.begin());
+ if (!first_item)
+ {
+ return;
+ }
+ const LLUUID& parent_uuid = first_item->getParentUUID();
+ for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
+ {
+ LLInventoryObject *item = gInventory.getObject(*it);
+ if (!item || item->getParentUUID() != parent_uuid)
+ {
+ LLNotificationsUtil::add("SameFolderRequired");
+ return;
+ }
+ }
+
+ LLSD args;
+ args["DESC"] = LLTrans::getString("New Folder");
+
+ LLNotificationsUtil::add("CreateSubfolder", args, LLSD(),
+ [ids](const LLSD& notification, const LLSD& response)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (opt == 0)
+ {
+ std::string settings_name = response["message"].asString();
+
+ LLInventoryObject::correctInventoryName(settings_name);
+ if (settings_name.empty())
+ {
+ settings_name = LLTrans::getString("New Folder");
+ }
+ move_items_to_new_subfolder(ids, settings_name);
+ }
+ });
+ }
+ else if ("ungroup_folder_items" == action)
+ {
+ if (selected_uuid_set.size() == 1)
+ {
+ LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
+ if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
+ {
+ return;
+ }
+ const LLUUID &new_cat_uuid = inv_cat->getParentUUID();
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cat_array, item_array);
+ LLInventoryModel::cat_array_t cats = *cat_array;
+ LLInventoryModel::item_array_t items = *item_array;
+
+ for (LLInventoryModel::cat_array_t::const_iterator cat_iter = cats.begin(); cat_iter != cats.end(); ++cat_iter)
+ {
+ LLViewerInventoryCategory* cat = *cat_iter;
+ if (cat)
+ {
+ gInventory.changeCategoryParent(cat, new_cat_uuid, false);
+ }
+ }
+ for (LLInventoryModel::item_array_t::const_iterator item_iter = items.begin(); item_iter != items.end(); ++item_iter)
+ {
+ LLViewerInventoryItem* item = *item_iter;
+ if(item)
+ {
+ gInventory.changeItemParent(item, new_cat_uuid, false);
+ }
+ }
+ gInventory.removeCategory(inv_cat->getUUID());
+ gInventory.notifyObservers();
+ }
+ }
else
{
std::set<LLFolderViewItem*>::iterator set_iter;
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 8915bfa1e0..ba9f157e47 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -93,6 +93,10 @@ LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
+void move_items_to_new_subfolder(const uuid_vec_t& selected_uuids, const std::string& folder_name);
+void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected_uuids);
+bool is_only_cats_selected(const uuid_vec_t& selected_uuids);
+bool is_only_items_selected(const uuid_vec_t& selected_uuids);
/** Miscellaneous global functions
** **
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 12bb609df8..de6a850b57 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -298,31 +298,41 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem
applyXUILayout(icon_params, this);
mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
- if (mIconCtrl)
- {
- addChild(mIconCtrl);
- }
- else
+ if (!mIconCtrl)
{
LLIconCtrl::Params icon_params;
icon_params.name = "item_icon";
mIconCtrl = LLUICtrlFactory::create<LLIconCtrl>(icon_params);
}
+ if (mIconCtrl)
+ {
+ addChild(mIconCtrl);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create mIconCtrl" << LL_ENDL;
+ }
+
LLTextBox::Params text_params(params.item_name);
applyXUILayout(text_params, this);
mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
- if (mTitleCtrl)
+ if (!mTitleCtrl)
{
- addChild(mTitleCtrl);
- }
- else
- {
- LLTextBox::Params text_aprams;
+ LLTextBox::Params text_params;
text_params.name = "item_title";
mTitleCtrl = LLUICtrlFactory::create<LLTextBox>(text_params);
}
+
+ if (mTitleCtrl)
+ {
+ addChild(mTitleCtrl);
+ }
+ else
+ {
+ LL_ERRS() << "Failed to create mTitleCtrl" << LL_ENDL;
+ }
}
class WidgetVisibilityChanger
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 37500176ea..fab7ae8f1a 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -135,15 +135,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
///----------------------------------------------------------------------------
/// Class LLInventoryValidationInfo
///----------------------------------------------------------------------------
-LLInventoryValidationInfo::LLInventoryValidationInfo():
- mFatalErrorCount(0),
- mWarningCount(0),
- mLoopCount(0),
- mOrphanedCount(0),
- mInitialized(false),
- mFatalNoRootFolder(false),
- mFatalNoLibraryRootFolder(false),
- mFatalQADebugMode(false)
+LLInventoryValidationInfo::LLInventoryValidationInfo()
{
}
@@ -165,7 +157,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v)
void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
{
sd["fatal_error_count"] = mFatalErrorCount;
- sd["warning_count"] = mWarningCount;
sd["loop_count"] = mLoopCount;
sd["orphaned_count"] = mOrphanedCount;
sd["initialized"] = mInitialized;
@@ -173,6 +164,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const
sd["fatal_no_root_folder"] = mFatalNoRootFolder;
sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder;
sd["fatal_qa_debug_mode"] = mFatalQADebugMode;
+
+ sd["warning_count"] = mWarningCount;
+ if (mWarningCount>0)
+ {
+ sd["warnings"] = LLSD::emptyArray();
+ for (auto const& it : mWarnings)
+ {
+ S32 val =LLSD::Integer(it.second);
+ if (val>0)
+ {
+ sd["warnings"][it.first] = val;
+ }
+ }
+ }
if (mMissingRequiredSystemFolders.size()>0)
{
sd["missing_system_folders"] = LLSD::emptyArray();
@@ -344,13 +349,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL
return NULL;
}
-LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
+LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const
{
LLInventoryObject *object = getObject(object_id);
if (!object)
{
LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
std::set<LLUUID> object_ids{ object_id }; // loop protection
@@ -360,19 +365,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co
if (object_ids.find(parent_id) != object_ids.end())
{
LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL;
- return ANSCESTOR_LOOP;
+ return ANCESTOR_LOOP;
}
object_ids.insert(parent_id);
LLInventoryObject *parent_object = getObject(parent_id);
if (!parent_object)
{
LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL;
- return ANSCESTOR_MISSING;
+ return ANCESTOR_MISSING;
}
object = parent_object;
}
result = object->getUUID();
- return ANSCESTOR_OK;
+ return ANCESTOR_OK;
}
// Get the object by id. Returns NULL if not found.
@@ -541,9 +546,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E
LLViewerInventoryCategory* cat = getCategory(*it);
changeCategoryParent(cat, main_id, TRUE);
}
-
+
// Purge the emptied folder
- removeCategory(folder_id);
+ // Note that this might be a system folder, don't validate removability
+ LLViewerInventoryCategory* cat = getCategory(folder_id);
+ if (cat)
+ {
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id.notNull())
+ {
+ changeCategoryParent(cat, trash_id, TRUE);
+ }
+ }
remove_inventory_category(folder_id, NULL);
}
}
@@ -3132,7 +3146,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
gInventory.accountForUpdate(update);
}
- U32 changes = 0x0;
if (account)
{
mask |= LLInventoryObserver::CREATE;
@@ -3140,7 +3153,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
//as above, this loop never seems to loop more than once per call
for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it, mask);
+ gInventory.updateItem(*it, mask);
}
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
@@ -3899,9 +3912,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo;
S32 fatal_errs = 0;
- S32 warnings = 0;
- S32 loops = 0;
- S32 orphaned = 0;
+ S32 warning_count= 0;
+ S32 loop_count = 0;
+ S32 orphaned_count = 0;
if (getRootFolderID().isNull())
{
@@ -3922,7 +3935,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// ParentChild should be one larger because of the special entry for null uuid.
LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size()
<< " parent/child " << mParentChildCategoryTree.size() << LL_ENDL;
- warnings++;
+
+ validation_info->mWarnings["category_map_size"]++;
+ warning_count++;
}
S32 cat_lock = 0;
S32 item_lock = 0;
@@ -3941,32 +3956,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cat)
{
LL_WARNS("Inventory") << "null cat" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_cat"]++;
+ warning_count++;
continue;
}
LLUUID topmost_ancestor_id;
// Will leave as null uuid on failure
- EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
+ EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id);
switch (res)
{
- case ANSCESTOR_MISSING:
- orphaned++;
+ case ANCESTOR_MISSING:
+ orphaned_count++;
break;
- case ANSCESTOR_LOOP:
- loops++;
+ case ANCESTOR_LOOP:
+ loop_count++;
break;
- case ANSCESTOR_OK:
+ case ANCESTOR_OK:
break;
default:
LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["unknown_ancestor_status"]++;
+ warning_count++;
break;
}
if (cat_id != cat->getUUID())
{
LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["cat_id_index_mismatch"]++;
+ warning_count++;
}
if (cat->getParentUUID().isNull())
@@ -3976,7 +3994,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root ("
<< getRootFolderID() << ") or library root ("
<< getLibraryRootFolderID() << ")" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_parent"]++;
+ warning_count++;
}
}
cat_array_t* cats;
@@ -3985,7 +4004,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!cats || !items)
{
LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["direct_descendents"]++;
+ warning_count++;
continue;
}
if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN)
@@ -4003,7 +4023,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " cached " << cat->getDescendentCount()
<< " expected " << cats->size() << "+" << items->size()
<< "=" << cats->size() +items->size() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["invalid_descendent_count"]++;
+ warning_count++;
}
}
if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
@@ -4027,7 +4048,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (!item)
{
LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["null_item_at_index"]++;
+ warning_count++;
continue;
}
@@ -4038,7 +4060,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "wrong parent for " << item_id << " found "
<< item->getParentUUID() << " expected " << cat_id
<< LL_ENDL;
- warnings++;
+ validation_info->mWarnings["wrong_parent_for_item"]++;
+ warning_count++;
}
@@ -4048,7 +4071,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " found as child of "
<< cat_id << " but not in top level mItemMap" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_not_in_top_map"]++;
+ warning_count++;
}
else
{
@@ -4062,11 +4086,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// Topmost ancestor should be root or library.
LLUUID topmost_ancestor_id;
- EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
- if (found != ANSCESTOR_OK)
+ EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id);
+ if (found != ANCESTOR_OK)
{
LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_found"]++;
+ warning_count++;
}
else
{
@@ -4077,7 +4102,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
<< " got " << topmost_ancestor_id
<< " expected " << getRootFolderID()
<< " or " << getLibraryRootFolderID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["topmost_ancestor_not_recognized"]++;
+ warning_count++;
}
}
}
@@ -4093,7 +4119,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4111,7 +4137,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName()
<< "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
}
@@ -4120,7 +4146,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LLFolderType::EType folder_type = cat->getPreferredType();
bool cat_is_in_library = false;
LLUUID topmost_id;
- if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID())
+ if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID())
{
cat_is_in_library = true;
}
@@ -4153,14 +4179,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (item->getUUID() != item_id)
{
LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["item_id_mismatch"]++;
+ warning_count++;
}
const LLUUID& parent_id = item->getParentUUID();
if (parent_id.isNull())
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4171,7 +4198,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else
{
@@ -4188,7 +4215,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName()
<< "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
}
@@ -4206,18 +4233,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType()
<< " missing backlink info at target_id " << target_id
<< LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
// Links should have referents.
if (item->getActualType() == LLAssetType::AT_LINK && !target_item)
{
LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat)
{
LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL;
- orphaned++;
+ orphaned_count++;
}
if (target_item && target_item->getIsLinkType())
{
@@ -4289,13 +4316,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
if (is_automatic)
{
LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL;
- fatal_errs++;
validation_info->mMissingRequiredSystemFolders.insert(folder_type);
+ fatal_errs++;
}
else
{
// Can create, and will when needed.
- warnings++;
+ // (Not sure this is really a warning, but worth logging)
+ validation_info->mWarnings["missing_system_folder_can_create"]++;
+ warning_count++;
}
}
else if (count_under_root > 1)
@@ -4306,6 +4335,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
{
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
+ validation_info->mFatalSystemDuplicate++;
fatal_errs++;
}
else
@@ -4313,13 +4343,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// For automatic folders it's not a fatal issue and shouldn't
// break inventory or other functionality further
// Exception: FT_SETTINGS is not automatic, but only deserves a warning.
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++;
+ warning_count++;
}
}
if (count_elsewhere > 0)
{
LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL;
- warnings++;
+ validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++;
+ warning_count++;
}
}
}
@@ -4341,12 +4373,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
// FIXME need to fail login and tell user to retry, contact support if problem persists.
bool valid = (fatal_errs == 0);
- LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL;
+ LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL;
validation_info->mFatalErrorCount = fatal_errs;
- validation_info->mWarningCount = warnings;
- validation_info->mLoopCount = loops;
- validation_info->mOrphanedCount = orphaned;
+ validation_info->mWarningCount = warning_count;
+ validation_info->mLoopCount = loop_count;
+ validation_info->mOrphanedCount = orphaned_count;
return validation_info;
}
@@ -4551,12 +4583,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
}
// as above, this loop never seems to loop more than once per call
- U32 changes(0U);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
- changes |= gInventory.updateItem(*it);
+ gInventory.updateItem(*it);
}
- // *HUH: Have computed 'changes', nothing uses it.
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index eeec89bfb0..c4133ff9bb 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -65,15 +65,19 @@ public:
void toOstream(std::ostream& os) const;
void asLLSD(LLSD& sd) const;
+ bool mInitialized{false};
+ S32 mWarningCount{0};
+ std::map<std::string,U32> mWarnings;
+
+ S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves
+ S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders
+
+ S32 mFatalErrorCount{0};
+ bool mFatalNoRootFolder{false};
+ S32 mFatalSystemDuplicate{0};
+ bool mFatalNoLibraryRootFolder{false};
+ bool mFatalQADebugMode{false};
- S32 mFatalErrorCount;
- S32 mWarningCount;
- S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves
- S32 mOrphanedCount; // Missing or orphaned items, links and folders
- bool mInitialized;
- bool mFatalNoRootFolder;
- bool mFatalNoLibraryRootFolder;
- bool mFatalQADebugMode;
std::set<LLFolderType::EType> mMissingRequiredSystemFolders;
std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders;
};
@@ -286,13 +290,13 @@ public:
// Check if one object has a parent chain up to the category specified by UUID.
BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
- enum EAnscestorResult{
- ANSCESTOR_OK = 0,
- ANSCESTOR_MISSING = 1,
- ANSCESTOR_LOOP = 2,
+ enum EAncestorResult{
+ ANCESTOR_OK = 0,
+ ANCESTOR_MISSING = 1,
+ ANCESTOR_LOOP = 2,
};
// Follow parent chain to the top.
- EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
+ EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const;
//--------------------------------------------------------------------
// Find
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index 1364067949..ce4ec668f1 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -386,7 +386,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
return;
}
- const BOOL hide_clip_plane = TRUE;
LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
@@ -472,33 +471,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
render_fog_color = sky_fog_color;
- F32 fog_density = 0.f;
fog_distance = mFogRatio * distance;
if (camera_height > water_height)
{
LLColor4 fog(render_fog_color);
mGLFogCol = fog;
-
- if (hide_clip_plane)
- {
- // For now, set the density to extend to the cull distance.
- const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
- fog_density = f_log/fog_distance;
- }
- else
- {
- const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
- fog_density = (f_log)/fog_distance;
- }
}
else
{
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
F32 depth = water_height - camera_height;
-
- // get the water param manager variables
- float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f);
LLColor4 water_fog_color(pwater->getWaterFogColor());
@@ -512,9 +495,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// set the gl fog color
mGLFogCol = fogCol;
-
- // set the density based on what the shaders use
- fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
}
mFogColor = sky_fog_color;
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 5a17332fde..de8db69e19 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -919,6 +919,36 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr()
mBitmapList.clear();
}
+LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename)
+{
+ if (!checkTextureDimensions(filename))
+ {
+ return LLUUID::null;
+ }
+
+ LLLocalBitmap* unit = new LLLocalBitmap(filename);
+
+ if (unit->getValid())
+ {
+ mBitmapList.push_back(unit);
+ return unit->getTrackingID();
+ }
+ else
+ {
+ LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
+
+ delete unit;
+ unit = NULL;
+ }
+
+ return LLUUID::null;
+}
+
bool LLLocalBitmapMgr::addUnit()
{
bool add_successful = false;
@@ -931,32 +961,10 @@ bool LLLocalBitmapMgr::addUnit()
std::string filename = picker.getFirstFile();
while(!filename.empty())
{
- if(!checkTextureDimensions(filename))
- {
- filename = picker.getNextFile();
- continue;
- }
-
- LLLocalBitmap* unit = new LLLocalBitmap(filename);
-
- if (unit->getValid())
- {
- mBitmapList.push_back(unit);
- add_successful = true;
- }
- else
- {
- LL_WARNS() << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
- << "Filename: " << filename << LL_ENDL;
-
- LLSD notif_args;
- notif_args["FNAME"] = filename;
- LLNotificationsUtil::add("LocalBitmapsVerifyFail", notif_args);
-
- delete unit;
- unit = NULL;
- }
-
+ if (addUnit(filename).notNull())
+ {
+ add_successful = true;
+ }
filename = picker.getNextFile();
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index d5ee7efdc6..02b8834c16 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -116,13 +116,14 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr>
~LLLocalBitmapMgr();
public:
bool addUnit();
+ LLUUID addUnit(const std::string &filename);
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
LLUUID getWorldID(LLUUID tracking_id);
bool isLocal(LLUUID world_id);
std::string getFilename(LLUUID tracking_id);
-
+
void feedScrollList(LLScrollListCtrl* ctrl);
void doUpdates();
void setNeedsRebake();
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index 79dbe17982..af2a9f6afd 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -109,6 +109,8 @@ public:
LLLineEditor* getTextEntry() const { return mTextEntry; }
void handleLoginComplete();
+ bool isNavMeshDirty() { return mIsNavMeshDirty; }
+
private:
enum EParcelIcon
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 82ecfbd4dc..dd8c9b2dde 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -451,26 +451,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
LLSD args(llsd::map( "MESSAGE", LLTrans::getString(response["message_id"]) ));
LLSD payload;
- LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) {
- bool continue_clicked = response["continue"].asBoolean();
- std::string token = response["token"].asString();
- LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL;
-
- // strip out whitespace - SL-17034/BUG-231938
- token = boost::regex_replace(token, boost::regex("\\s"), "");
-
- if (continue_clicked && !token.empty())
- {
- LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL;
-
- // Set the request data to true and retry login.
- mRequestData["params"]["token"] = token;
- reconnect();
- } else {
- LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL;
- attemptComplete();
- }
- });
+ LLNotificationsUtil::add("PromptMFAToken", args, payload,
+ boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2));
}
else if( reason_response == "key"
|| reason_response == "presence"
@@ -547,23 +529,59 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event)
bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
{
- if(accepted)
- {
- LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted" << LL_ENDL;
+ if(accepted)
+ {
+ LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted " << LL_ENDL;
- // Set the request data to true and retry login.
- mRequestData["params"][key] = true;
- reconnect();
- }
- else
- {
- LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL;
+ // Set the request data to true and retry login.
+ mRequestData["params"][key] = true;
- attemptComplete();
- }
+ if (!mRequestData["params"]["token"].asString().empty())
+ {
+ // SL-18511 this TOS failure happened while we are in the middle of an MFA challenge/response.
+ // the previously entered token is very likely expired, so prompt again
+ LLSD args(llsd::map( "MESSAGE", LLTrans::getString("LoginFailedAuthenticationMFARequired") ));
+ LLSD payload;
+ LLNotificationsUtil::add("PromptMFAToken", args, payload,
+ boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2));
+ }
+ else
+ {
+ reconnect();
+ }
+ }
+ else
+ {
+ LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL;
+
+ attemptComplete();
+ }
+
+ LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME);
+ return true;
+}
- LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME);
- return true;
+bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & response)
+{
+ bool continue_clicked = response["continue"].asBoolean();
+ std::string token = response["token"].asString();
+ LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL;
+
+ // strip out whitespace - SL-17034/BUG-231938
+ token = boost::regex_replace(token, boost::regex("\\s"), "");
+
+ if (continue_clicked && !token.empty())
+ {
+ LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL;
+
+ // Set the request data to true and retry login.
+ mRequestData["params"]["token"] = token;
+ reconnect();
+ } else {
+ LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL;
+ attemptComplete();
+ }
+ return true;
}
std::string construct_start_string()
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index b759b43474..ee3ef0e4b1 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -84,6 +84,7 @@ private:
void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response);
bool handleTOSResponse(bool v, const std::string& key);
+ bool handleMFAChallenge(LLSD const & notif, LLSD const & response);
void attemptComplete() { mAttemptComplete = true; } // In the future an event?
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 044c76ce2c..dd4ae4d201 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -758,7 +758,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type&
if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
// If already initialized, just confirm the status so the callback gets called
- setSLMStatus(mMarketPlaceStatus);
+ if (mMarketPlaceFailureReason.empty())
+ {
+ setSLMStatus(mMarketPlaceStatus);
+ }
+ else
+ {
+ setSLMConnectionFailure(mMarketPlaceFailureReason);
+ }
}
else
{
@@ -799,28 +806,27 @@ void LLMarketplaceData::getMerchantStatusCoro()
if (httpCode == HTTP_NOT_FOUND)
{
log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT);
}
else if (httpCode == HTTP_SERVICE_UNAVAILABLE)
{
log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated"));
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
+ LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT);
}
- else if (httpCode == HTTP_INTERNAL_ERROR)
+ else
{
- // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938
LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode
<< ", reason : " << status.toString()
<< ", code : " << result["error_code"].asString()
<< ", description : " << result["error_description"].asString() << LL_ENDL;
- LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
- }
- else
- {
- std::string err_code = result["error_code"].asString();
- //std::string err_description = result["error_description"].asString();
- log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]);
- setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+ std::string reason = status.toString();
+ if (reason.empty())
+ {
+ reason = result["error_code"].asString();
+ }
+ // Since user might not even have a marketplace, there is no reason to report the error
+ // to the user, instead write it down into listings' floater
+ LLMarketplaceData::instance().setSLMConnectionFailure(reason);
}
return;
}
@@ -1298,6 +1304,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route)
void LLMarketplaceData::setSLMStatus(U32 status)
{
mMarketPlaceStatus = status;
+ mMarketPlaceFailureReason.clear();
+ if (mStatusUpdatedSignal)
+ {
+ (*mStatusUpdatedSignal)();
+ }
+}
+
+void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason)
+{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+ mMarketPlaceFailureReason = reason;
if (mStatusUpdatedSignal)
{
(*mStatusUpdatedSignal)();
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index fee9225f77..088507d850 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -198,7 +198,9 @@ public:
typedef boost::signals2::signal<void ()> status_updated_signal_t;
void initializeSLM(const status_updated_signal_t::slot_type& cb);
U32 getSLMStatus() const { return mMarketPlaceStatus; }
+ std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; }
void setSLMStatus(U32 status);
+ void setSLMConnectionFailure(const std::string& reason);
void getSLMListings();
bool isEmpty() { return (mMarketplaceItems.size() == 0); }
void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb);
@@ -272,6 +274,7 @@ private:
// Handling Marketplace connection and inventory connection
U32 mMarketPlaceStatus;
+ std::string mMarketPlaceFailureReason;
status_updated_signal_t* mStatusUpdatedSignal;
LLInventoryObserver* mInventoryObserver;
bool mDirtyCount; // If true, stock count value need to be updated at the next check
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index bc45eb6d3a..9d0f62a30d 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -154,8 +154,7 @@ void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred)
if (matchPred(*it))
{
(*it)->markDead();
- // *TDOO: When C++11 is in change the following line to: it = c.erase(it);
- c.erase(it++);
+ it = c.erase(it);
}
else
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d28e929b48..a15a61429b 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -383,6 +383,9 @@ U32 LLMeshRepository::sLODPending = 0;
U32 LLMeshRepository::sCacheBytesRead = 0;
U32 LLMeshRepository::sCacheBytesWritten = 0;
+U32 LLMeshRepository::sCacheBytesHeaders = 0;
+U32 LLMeshRepository::sCacheBytesSkins = 0;
+U32 LLMeshRepository::sCacheBytesDecomps = 0;
U32 LLMeshRepository::sCacheReads = 0;
U32 LLMeshRepository::sCacheWrites = 0;
U32 LLMeshRepository::sMaxLockHoldoffs = 0;
@@ -1877,6 +1880,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
LLMutexLock lock(mHeaderMutex);
mMeshHeaderSize[mesh_id] = header_size;
mMeshHeader[mesh_id] = header;
+ LLMeshRepository::sCacheBytesHeaders += header_size;
}
@@ -2054,17 +2058,6 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
if (volume->unpackVolumeFaces(stream, data_size))
{
- //load volume faces into decomposition buffer
- S32 vertex_count = 0;
- S32 index_count = 0;
-
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- vertex_count += face.mNumVertices;
- index_count += face.mNumIndices;
- }
-
d->mPhysicsShapeMesh.clear();
std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions;
@@ -3019,27 +3012,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
return -1;
}
-void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header)
-{
- mThread->mMeshHeader[data.mUUID] = header;
-
- // we cache the mesh for default parameters
- LLVolumeParams volume_params;
- volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE);
- volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH);
-
- for (U32 i = 0; i < 4; i++)
- {
- if (data.mModel[i].notNull())
- {
- LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i));
- volume->copyVolumeFaces(data.mModel[i]);
- volume->setMeshAssetLoaded(TRUE);
- }
- }
-
-}
-
// Handle failed or successful requests for mesh assets.
//
// Support for 200 responses was added for several reasons. One,
@@ -3957,6 +3929,8 @@ void LLMeshRepository::notifyLoadedMeshes()
void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
{
mSkinMap[info.mMeshID] = info;
+ // Alternative: We can get skin size from header
+ sCacheBytesSkins += info.sizeBytes();
skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
if (iter != mLoadingSkins.end())
@@ -3980,10 +3954,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom
{ //just insert decomp into map
mDecompositionMap[decomp->mMeshID] = decomp;
mLoadingDecompositions.erase(decomp->mMeshID);
+ sCacheBytesDecomps += decomp->sizeBytes();
}
else
{ //merge decomp with existing entry
+ sCacheBytesDecomps -= iter->second->sizeBytes();
iter->second->merge(decomp);
+ sCacheBytesDecomps += iter->second->sizeBytes();
+
mLoadingDecompositions.erase(decomp->mMeshID);
delete decomp;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 1989350303..f61da3e571 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -554,6 +554,9 @@ public:
static U32 sLODProcessing;
static U32 sCacheBytesRead;
static U32 sCacheBytesWritten;
+ static U32 sCacheBytesHeaders;
+ static U32 sCacheBytesSkins;
+ static U32 sCacheBytesDecomps;
static U32 sCacheReads;
static U32 sCacheWrites;
static U32 sMaxLockHoldoffs; // Maximum sequential locking failures
@@ -643,8 +646,6 @@ public:
std::queue<LLUUID> mPendingPhysicsShapeRequests;
U32 mMeshThreadCount;
-
- void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header);
LLMeshRepoThread* mThread;
std::vector<LLMeshUploadThread*> mUploads;
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 859d987fc3..642df7f931 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -86,6 +86,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f);
static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f);
static const F32 PREVIEW_DEG_POINT_SIZE(8.f);
static const F32 PREVIEW_ZOOM_LIMIT(10.f);
+static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
@@ -432,6 +433,20 @@ void LLModelPreview::rebuildUploadData()
LLFloaterModelPreview::addStringToLog(out, false);
}
}
+ if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS))
+ {
+ // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition.
+ // That's ok, but might not what they wanted. Use default_physics_shape if found.
+ std::ostringstream out;
+ out << "No physics model specified for " << instance.mLabel;
+ if (mDefaultPhysicsShapeP)
+ {
+ out << " - using: " << DEFAULT_PHYSICS_MESH_NAME;
+ lod_model = mDefaultPhysicsShapeP;
+ }
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default.
+ }
if (lod_model)
{
@@ -816,8 +831,10 @@ void LLModelPreview::clearIncompatible(S32 lod)
// at this point we don't care about sub-models,
// different amount of sub-models means face count mismatch, not incompatibility
U32 lod_size = countRootModels(mModel[lod]);
+ bool replaced_base_model = (lod == LLModel::LOD_HIGH);
for (U32 i = 0; i <= LLModel::LOD_HIGH; i++)
- { //clear out any entries that aren't compatible with this model
+ {
+ // Clear out any entries that aren't compatible with this model
if (i != lod)
{
if (countRootModels(mModel[i]) != lod_size)
@@ -831,9 +848,47 @@ void LLModelPreview::clearIncompatible(S32 lod)
mBaseModel = mModel[lod];
mBaseScene = mScene[lod];
mVertexBuffer[5].clear();
+ replaced_base_model = true;
+ }
+ }
+ }
+ }
+
+ if (replaced_base_model && !mGenLOD)
+ {
+ // In case base was replaced, we might need to restart generation
+
+ // Check if already started
+ bool subscribe_for_generation = mLodsQuery.empty();
+
+ // Remove previously scheduled work
+ mLodsQuery.clear();
+
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (!fmp) return;
+
+ // Schedule new work
+ for (S32 i = LLModel::LOD_HIGH; i >= 0; --i)
+ {
+ if (mModel[i].empty())
+ {
+ // Base model was replaced, regenerate this lod if applicable
+ LLComboBox* lod_combo = mFMP->findChild<LLComboBox>("lod_source_" + lod_name[i]);
+ if (!lod_combo) return;
+
+ S32 lod_mode = lod_combo->getCurrentIndex();
+ if (lod_mode != LOD_FROM_FILE)
+ {
+ mLodsQuery.push_back(i);
}
}
}
+
+ // Subscribe if we have pending work and not subscribed yet
+ if (!mLodsQuery.empty() && subscribe_for_generation)
+ {
+ doOnIdleRepeating(lodQueryCallback);
+ }
}
}
@@ -994,6 +1049,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
}
else
{
+ if (loaded_lod == LLModel::LOD_PHYSICS)
+ { // Explicitly loading physics. See if there is a default mesh.
+ LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own.
+ mDefaultPhysicsShapeP = nullptr;
+ FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform);
+ mWarnOfUnmatchedPhyicsMeshes = true;
+ }
BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
if (!legacyMatching)
{
@@ -1064,7 +1126,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
}
-
mModel[loaded_lod][idx]->mLabel = name;
}
}
@@ -1221,8 +1282,9 @@ void LLModelPreview::restoreNormals()
// Runs per object, but likely it is a better way to run per model+submodels
// returns a ratio of base model indices to resulting indices
// returns -1 in case of failure
-F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, bool sloppy)
+F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode)
{
+ // I. Weld faces together
// Figure out buffer size
S32 size_indices = 0;
S32 size_vertices = 0;
@@ -1257,20 +1319,21 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
- // vertices
+ // Vertices
S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a);
LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes);
- // normals
+ // Normals
LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes);
- // tex coords
+ // Tex coords
copy_bytes = face.mNumVertices * sizeof(LLVector2);
memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes);
combined_positions_shift += face.mNumVertices;
- // indices, sadly can't do dumb memcpy for indices, need to adjust each value
+ // Indices
+ // Sadly can't do dumb memcpy for indices, need to adjust each value
for (S32 i = 0; i < face.mNumIndices; ++i)
{
U16 idx = face.mIndices[i];
@@ -1281,10 +1344,42 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
indices_idx_shift += face.mNumVertices;
}
- // Now that we have buffers, optimize
+ // II. Generate a shadow buffer if nessesary.
+ // Welds together vertices if possible
+
+ U32* shadow_indices = NULL;
+ // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32
+ // won't do anything new, model was remaped on a per face basis.
+ // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+ // since 'simplifySloppy' ignores all topology, including normals and uvs.
+ // Note: simplifySloppy can affect UVs significantly.
+ if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS)
+ {
+ // strip normals, reflections should restore relatively correctly
+ shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32));
+ LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, combined_tex_coords, size_vertices);
+ }
+ if (simplification_mode == MESH_OPTIMIZER_NO_UVS)
+ {
+ // strip uvs, can heavily affect textures
+ shadow_indices = (U32*)ll_aligned_malloc_32(size_indices * sizeof(U32));
+ LLMeshOptimizer::generateShadowIndexBufferU32(shadow_indices, combined_indices, size_indices, combined_positions, NULL, NULL, size_vertices);
+ }
+
+ U32* source_indices = NULL;
+ if (shadow_indices)
+ {
+ source_indices = shadow_indices;
+ }
+ else
+ {
+ source_indices = combined_indices;
+ }
+
+ // III. Simplify
S32 target_indices = 0;
F32 result_error = 0; // how far from original the model is, 1 == 100%
- S32 new_indices = 0;
+ S32 size_new_indices = 0;
if (indices_decimator > 0)
{
@@ -1294,38 +1389,43 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
target_indices = 3;
}
- new_indices = LLMeshOptimizer::simplifyU32(
+
+ size_new_indices = LLMeshOptimizer::simplifyU32(
output_indices,
- combined_indices,
+ source_indices,
size_indices,
combined_positions,
size_vertices,
LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX],
target_indices,
error_threshold,
- sloppy,
+ simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY,
&result_error);
-
if (result_error < 0)
{
LL_WARNS() << "Negative result error from meshoptimizer for model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices << LL_ENDL;
}
- if (new_indices < 3)
+ // free unused buffers
+ ll_aligned_free_32(combined_indices);
+ ll_aligned_free_32(shadow_indices);
+ combined_indices = NULL;
+ shadow_indices = NULL;
+
+ if (size_new_indices < 3)
{
// Model should have at least one visible triangle
ll_aligned_free<64>(combined_positions);
ll_aligned_free_32(output_indices);
- ll_aligned_free_32(combined_indices);
return -1;
}
- // repack back into individual faces
+ // IV. Repack back into individual faces
LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
LLVector4a* buffer_normals = buffer_positions + size_vertices;
@@ -1356,7 +1456,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
}
// Copy relevant indices and vertices
- for (S32 i = 0; i < new_indices; ++i)
+ for (S32 i = 0; i < size_new_indices; ++i)
{
U32 idx = output_indices[i];
@@ -1379,19 +1479,19 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
LL_WARNS() << "Over triangle limit. Failed to optimize in 'per object' mode, falling back to per face variant for"
<< " model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices
<< " error treshold: " << error_threshold
<< LL_ENDL;
// U16 vertices overflow shouldn't happen, but just in case
- new_indices = 0;
+ size_new_indices = 0;
valid_faces = 0;
for (U32 face_idx = 0; face_idx < base_model->getNumVolumeFaces(); ++face_idx)
{
- genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, false);
+ genMeshOptimizerPerFace(base_model, target_model, face_idx, indices_decimator, error_threshold, simplification_mode);
const LLVolumeFace &face = target_model->getVolumeFace(face_idx);
- new_indices += face.mNumIndices;
+ size_new_indices += face.mNumIndices;
if (face.mNumIndices >= 3)
{
valid_faces++;
@@ -1399,7 +1499,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
}
if (valid_faces)
{
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
else
{
@@ -1469,18 +1569,17 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
ll_aligned_free<64>(buffer_positions);
ll_aligned_free_32(output_indices);
ll_aligned_free_16(buffer_indices);
- ll_aligned_free_32(combined_indices);
- if (new_indices < 3 || valid_faces == 0)
+ if (size_new_indices < 3 || valid_faces == 0)
{
// Model should have at least one visible triangle
return -1;
}
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
-F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, bool sloppy)
+F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_decimator, F32 error_threshold, eSimplificationMode simplification_mode)
{
const LLVolumeFace &face = base_model->getVolumeFace(face_idx);
S32 size_indices = face.mNumIndices;
@@ -1488,14 +1587,40 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
{
return -1;
}
- // todo: do not allocate per each face, add one large buffer somewhere
- // faces have limited amount of indices
+
S32 size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
- U16* output = (U16*)ll_aligned_malloc_16(size);
+ U16* output_indices = (U16*)ll_aligned_malloc_16(size);
+
+ U16* shadow_indices = NULL;
+ // if MESH_OPTIMIZER_FULL, just leave as is, since generateShadowIndexBufferU32
+ // won't do anything new, model was remaped on a per face basis.
+ // Similar for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+ // since 'simplifySloppy' ignores all topology, including normals and uvs.
+ if (simplification_mode == MESH_OPTIMIZER_NO_NORMALS)
+ {
+ U16* shadow_indices = (U16*)ll_aligned_malloc_16(size);
+ LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, face.mTexCoords, face.mNumVertices);
+ }
+ if (simplification_mode == MESH_OPTIMIZER_NO_UVS)
+ {
+ U16* shadow_indices = (U16*)ll_aligned_malloc_16(size);
+ LLMeshOptimizer::generateShadowIndexBufferU16(shadow_indices, face.mIndices, size_indices, face.mPositions, NULL, NULL, face.mNumVertices);
+ }
+ // Don't run ShadowIndexBuffer for MESH_OPTIMIZER_NO_TOPOLOGY, it's pointless
+
+ U16* source_indices = NULL;
+ if (shadow_indices)
+ {
+ source_indices = shadow_indices;
+ }
+ else
+ {
+ source_indices = face.mIndices;
+ }
S32 target_indices = 0;
F32 result_error = 0; // how far from original the model is, 1 == 100%
- S32 new_indices = 0;
+ S32 size_new_indices = 0;
if (indices_decimator > 0)
{
@@ -1505,25 +1630,25 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
{
target_indices = 3;
}
- new_indices = LLMeshOptimizer::simplify(
- output,
- face.mIndices,
+
+ size_new_indices = LLMeshOptimizer::simplify(
+ output_indices,
+ source_indices,
size_indices,
face.mPositions,
face.mNumVertices,
LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX],
target_indices,
error_threshold,
- sloppy,
+ simplification_mode == MESH_OPTIMIZER_NO_TOPOLOGY,
&result_error);
-
if (result_error < 0)
{
LL_WARNS() << "Negative result error from meshoptimizer for face " << face_idx
<< " of model " << target_model->mLabel
<< " target Indices: " << target_indices
- << " new Indices: " << new_indices
+ << " new Indices: " << size_new_indices
<< " original count: " << size_indices
<< " error treshold: " << error_threshold
<< LL_ENDL;
@@ -1534,10 +1659,9 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
// Copy old values
new_face = face;
-
- if (new_indices < 3)
+ if (size_new_indices < 3)
{
- if (!sloppy)
+ if (simplification_mode != MESH_OPTIMIZER_NO_TOPOLOGY)
{
// meshopt_optimizeSloppy() can optimize triangles away even if target_indices is > 2,
// but optimize() isn't supposed to
@@ -1561,23 +1685,24 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target
else
{
// Assign new values
- new_face.resizeIndices(new_indices); // will wipe out mIndices, so new_face can't substitute output
- S32 idx_size = (new_indices * sizeof(U16) + 0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output, idx_size);
+ new_face.resizeIndices(size_new_indices); // will wipe out mIndices, so new_face can't substitute output
+ S32 idx_size = (size_new_indices * sizeof(U16) + 0xF) & ~0xF;
+ LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)output_indices, idx_size);
- // clear unused values
+ // Clear unused values
new_face.optimize();
}
- ll_aligned_free_16(output);
+ ll_aligned_free_16(output_indices);
+ ll_aligned_free_16(shadow_indices);
- if (new_indices < 3)
+ if (size_new_indices < 3)
{
// At least one triangle is needed
return -1;
}
- return (F32)size_indices / (F32)new_indices;
+ return (F32)size_indices / (F32)size_new_indices;
}
void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 decimation, bool enforce_tri_limit)
@@ -1711,16 +1836,19 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Ideally this should run not per model,
// but combine all submodels with origin model as well
- if (model_meshopt_mode == MESH_OPTIMIZER_COMBINE)
+ if (model_meshopt_mode == MESH_OPTIMIZER_PRECISE)
{
- // Run meshoptimizer for each model/object, up to 8 faces in one model.
-
- // Ideally this should run not per model,
- // but combine all submodels with origin model as well
- F32 res = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
- if (res < 0)
+ // Run meshoptimizer for each face
+ for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
- target_model->copyVolumeFaces(base);
+ F32 res = genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
+ if (res < 0)
+ {
+ // Mesh optimizer failed and returned an invalid model
+ const LLVolumeFace &face = base->getVolumeFace(face_idx);
+ LLVolumeFace &new_face = target_model->getVolumeFace(face_idx);
+ new_face = face;
+ }
}
}
@@ -1729,19 +1857,29 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Run meshoptimizer for each face
for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
{
- if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true) < 0)
+ if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY) < 0)
{
// Sloppy failed and returned an invalid model
- genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);
+ genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
}
}
}
if (model_meshopt_mode == MESH_OPTIMIZER_AUTO)
{
- // Switches between 'combine' method and 'sloppy' based on combine's result.
- F32 allowed_ratio_drift = 2.f;
- F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+ // Remove progressively more data if we can't reach the target.
+ F32 allowed_ratio_drift = 1.8f;
+ F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
+
+ if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
+ {
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_NORMALS);
+ }
+
+ if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
+ {
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_UVS);
+ }
if (precise_ratio < 0 || (precise_ratio * allowed_ratio_drift < indices_decimator))
{
@@ -1749,10 +1887,11 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// Sloppy variant can fail entirely and has issues with precision,
// so code needs to do multiple attempts with different decimators.
// Todo: this is a bit of a mess, needs to be refined and improved
+
F32 last_working_decimator = 0.f;
F32 last_working_ratio = F32_MAX;
- F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+ F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
if (sloppy_ratio > 0)
{
@@ -1775,13 +1914,13 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
// side due to overal lack of precision, and we don't need an ideal result, which
// likely does not exist, just a better one, so a partial correction is enough.
F32 sloppy_decimator = indices_decimator * (indices_decimator / sloppy_ratio + 1) / 2;
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
}
if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio)
{
// Compensation didn't work, return back to previous decimator
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
}
if (sloppy_ratio < 0)
@@ -1814,7 +1953,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
&& sloppy_decimator > precise_ratio
&& sloppy_decimator > 1)// precise_ratio isn't supposed to be below 1, but check just in case
{
- sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+ sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
sloppy_decimator = sloppy_decimator / sloppy_decimation_step;
}
}
@@ -1834,7 +1973,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
else
{
// Fallback to normal method
- precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+ precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL);
}
LL_INFOS() << "Model " << target_model->getName()
@@ -2562,8 +2701,6 @@ void LLModelPreview::clearBuffers()
void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
- U32 tri_count = 0;
- U32 vertex_count = 0;
U32 mesh_count = 0;
@@ -2596,7 +2733,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
continue;
}
- LLModel* base_mdl = *base_iter;
base_iter++;
S32 num_faces = mdl->getNumVolumeFaces();
@@ -2671,7 +2807,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
//find closest weight to vf.mVertices[i].mPosition
LLVector3 pos(vf.mPositions[i].getF32ptr());
- const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
+ const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos);
llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this
LLVector4 w(0, 0, 0, 0);
@@ -2699,10 +2835,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
mVertexBuffer[lod][mdl].push_back(vb);
- vertex_count += num_vertices;
- tri_count += num_indices / 3;
++mesh_count;
-
}
}
}
@@ -2798,6 +2931,20 @@ void LLModelPreview::loadedCallback(
{
pPreview->lookupLODModelFiles(lod);
}
+
+ const LLVOAvatar* avatarp = pPreview->getPreviewAvatar();
+ if (avatarp) { // set up ground plane for possible rendering
+ const LLVector3 root_pos = avatarp->mRoot->getPosition();
+ const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents();
+ const LLVector4a min = ext[0], max = ext[1];
+ const F32 center = (max[2] - min[2]) * 0.5f;
+ const F32 ground = root_pos[2] - center;
+ auto plane = pPreview->mGroundPlane;
+ plane[0] = {min[0], min[1], ground};
+ plane[1] = {max[0], min[1], ground};
+ plane[2] = {max[0], max[1], ground};
+ plane[3] = {min[0], max[1], ground};
+ }
}
}
@@ -3005,6 +3152,9 @@ BOOL LLModelPreview::render()
// (note: all these UI updates need to be somewhere that is not render)
fmp->childSetValue("upload_skin", true);
mFirstSkinUpdate = false;
+ upload_skin = true;
+ skin_weight = true;
+ mViewOption["show_skin_weight"] = true;
}
fmp->enableViewOption("show_skin_weight");
@@ -3609,6 +3759,7 @@ BOOL LLModelPreview::render()
{
getPreviewAvatar()->renderBones();
}
+ renderGroundPlane(mPelvisZOffset);
if (shader)
{
shader->bind();
@@ -3630,6 +3781,28 @@ BOOL LLModelPreview::render()
return TRUE;
}
+void LLModelPreview::renderGroundPlane(float z_offset)
+{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render
+
+ gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f );
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+ gGL.vertex3fv(mGroundPlane[1].mV);
+
+ gGL.vertex3fv(mGroundPlane[1].mV);
+ gGL.vertex3fv(mGroundPlane[2].mV);
+
+ gGL.vertex3fv(mGroundPlane[2].mV);
+ gGL.vertex3fv(mGroundPlane[3].mV);
+
+ gGL.vertex3fv(mGroundPlane[3].mV);
+ gGL.vertex3fv(mGroundPlane[0].mV);
+
+ gGL.end();
+}
+
+
//-----------------------------------------------------------------------------
// refresh()
//-----------------------------------------------------------------------------
@@ -3745,7 +3918,7 @@ bool LLModelPreview::lodQueryCallback()
}
// return false to continue cycle
- return false;
+ return preview->mLodsQuery.empty();
}
}
// nothing to process
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 9e32215e6a..df7320768c 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -125,7 +125,7 @@ public:
{
LOD_FROM_FILE = 0,
MESH_OPTIMIZER_AUTO, // automatically selects method based on model or face
- MESH_OPTIMIZER_COMBINE, // combines faces into a single model, simplifies, then splits back into faces
+ MESH_OPTIMIZER_PRECISE, // combines faces into a single model, simplifies, then splits back into faces
MESH_OPTIMIZER_SLOPPY, // uses sloppy method, works per face
USE_LOD_ABOVE,
} eLoDMode;
@@ -224,14 +224,39 @@ private:
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
+ LLVector3 mGroundPlane[4];
+ void renderGroundPlane(float z_offset = 0.0f);
+ /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh.
+ /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when
+ /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()).
+ ///
+ /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When
+ /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when
+ /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot.
+ /// When there are multiple meshes in each file, they are matched by name or order, and some meshes
+ /// are broken up by limitations into multiple objects, and thus there can be mismatches.)
+ bool mWarnOfUnmatchedPhyicsMeshes{false};
+ /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified.
+ /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME.
+ /// It is reset when such a name is not found, and when resetting the modelpreview.
+ /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true.
+ LLModel* mDefaultPhysicsShapeP{};
+
+ typedef enum
+ {
+ MESH_OPTIMIZER_FULL,
+ MESH_OPTIMIZER_NO_NORMALS,
+ MESH_OPTIMIZER_NO_UVS,
+ MESH_OPTIMIZER_NO_TOPOLOGY,
+ } eSimplificationMode;
// Merges faces into single mesh, simplifies using mesh optimizer,
// then splits back into faces.
// Returns reached simplification ratio. -1 in case of a failure.
- F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ F32 genMeshOptimizerPerModel(LLModel *base_model, LLModel *target_model, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode);
// Simplifies specified face using mesh optimizer.
// Returns reached simplification ratio. -1 in case of a failure.
- F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, bool sloppy);
+ F32 genMeshOptimizerPerFace(LLModel *base_model, LLModel *target_model, U32 face_idx, F32 indices_ratio, F32 error_threshold, eSimplificationMode simplification_mode);
protected:
friend class LLModelLoader;
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 4a8ef53a8b..bf00d77dea 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -352,7 +352,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
void LLMuteList::updateAdd(const LLMute& mute)
{
- // External mutes (e.g. Avaline callers) are local only, don't send them to the server.
+ // External mutes are local only, don't send them to the server.
if (mute.mType == LLMute::EXTERNAL)
{
return;
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 5215126789..8058faa5c7 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -271,6 +271,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
return handled;
}
+// virtual
+BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
+ LLFloater* floater = gFloaterView->getParentFloater(this);
+ if (floater && floater->isFrontmost() && hit_item)
+ {
+ if(hit_item->isGroup())
+ {
+ ContextMenuType prev_menu = getContextMenuType();
+ setContextMenu(MENU_GROUP);
+ BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+ setContextMenu(prev_menu);
+ return handled;
+ }
+ }
+ return LLScrollListCtrl::handleRightMouseDown(x, y, mask);
+}
+
// public
void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos,
BOOL enabled)
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ef0be135e6..5dd5da5892 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -170,6 +170,7 @@ public:
/*virtual*/ void updateColumns(bool force_update);
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
private:
void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 19dbbeb60e..f5ee1171d9 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -451,9 +451,9 @@ void LLNavigationBar::onLocationSelection()
if(value.has("AssetUUID"))
{
-
gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString()));
- mSaveToLocationHistory = true;
+ // user teleported by manually inputting inventory landmark's name
+ mSaveToLocationHistory = false;
return;
}
else
@@ -713,7 +713,7 @@ void LLNavigationBar::resizeLayoutPanel()
}
void LLNavigationBar::invokeSearch(std::string search_text)
{
- LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text)));
+ LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text)));
}
void LLNavigationBar::clearHistoryCache()
@@ -733,3 +733,8 @@ int LLNavigationBar::getDefFavBarHeight()
{
return mDefaultFpRect.getHeight();
}
+
+bool LLNavigationBar::isRebakeNavMeshAvailable()
+{
+ return mCmbLocation->isNavMeshDirty();
+}
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 646911a62c..11c671294a 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -102,6 +102,8 @@ public:
int getDefNavBarHeight();
int getDefFavBarHeight();
+
+ bool isRebakeNavMeshAvailable();
private:
// the distance between navigation panel and favorites panel in pixels
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1240ce7c0f..b34be80b07 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -37,6 +37,7 @@
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrender.h"
+#include "llresmgr.h"
#include "llui.h"
#include "lltooltip.h"
@@ -47,11 +48,16 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterland.h"
#include "llfloaterworldmap.h"
+#include "llparcel.h"
#include "lltracker.h"
#include "llsurface.h"
+#include "llurlmatch.h"
+#include "llurlregistry.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
@@ -64,7 +70,10 @@
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 LLNetMap::MAP_SCALE_MIN = 32;
-const F32 LLNetMap::MAP_SCALE_MID = 1024;
+const F32 LLNetMap::MAP_SCALE_FAR = 32;
+const F32 LLNetMap::MAP_SCALE_MEDIUM = 128;
+const F32 LLNetMap::MAP_SCALE_CLOSE = 256;
+const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
@@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
- mScale( MAP_SCALE_MID ),
- mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
+ mScale( MAP_SCALE_MEDIUM ),
+ mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
- mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
+ mPopupWorldPos(0.f, 0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
@@ -97,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p)
mPopupMenu(NULL)
{
mScale = gSavedSettings.getF32("MiniMapScale");
+ if (gAgent.isFirstLogin())
+ {
+ // *HACK: On first run, set this to false for new users, otherwise the
+ // default is true to maintain consistent experience for existing
+ // users.
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
mPixelsPerMeter = mScale / REGION_WIDTH_METERS;
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
}
@@ -107,13 +123,22 @@ LLNetMap::~LLNetMap()
BOOL LLNetMap::postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
- registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- return TRUE;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar;
+
+ enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2));
+ commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2));
+ commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+ commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2));
+ enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2));
+ commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
+ commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenu->setItemEnabled("Re-center map", false);
+
+ return true;
}
void LLNetMap::setScale( F32 scale )
@@ -158,18 +183,32 @@ void LLNetMap::draw()
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
- static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+ static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));
if (mObjectImagep.isNull())
{
createObjectImage();
}
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (auto_center)
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ bool auto_centering = auto_center && !mPanning;
+ mCentering = mCentering && !mPanning;
+
+ if (auto_centering || mCentering)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));
}
+ bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f;
+ if (centered)
+ {
+ mCurPan.mV[0] = 0.0f;
+ mCurPan.mV[1] = 0.0f;
+ mCentering = false;
+ }
+
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ updateAboutLandPopupButton();
// Prepare a scissor region
F32 rotation = 0;
@@ -216,7 +255,8 @@ void LLNetMap::draw()
}
// figure out where agent is
- S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const F32 scale_pixels_per_meter = mScale / region_width;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -225,8 +265,8 @@ void LLNetMap::draw()
// Find x and y position relative to camera's center.
LLVector3 origin_agent = regionp->getOriginAgent();
LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
- F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
- F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+ F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;
// background region rectangle
F32 bottom = relative_y;
@@ -249,6 +289,7 @@ void LLNetMap::draw()
}
+
// Draw using texture.
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
gGL.begin(LLRender::QUADS);
@@ -310,8 +351,8 @@ void LLNetMap::draw()
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
map_center_agent -= camera_position;
- map_center_agent.mV[VX] *= mScale/region_width;
- map_center_agent.mV[VY] *= mScale/region_width;
+ map_center_agent.mV[VX] *= scale_pixels_per_meter;
+ map_center_agent.mV[VY] *= scale_pixels_per_meter;
gGL.getTexUnit(0)->bind(mObjectImagep);
F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -327,6 +368,13 @@ void LLNetMap::draw()
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
gGL.end();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV);
+ }
gGL.popMatrix();
@@ -451,41 +499,34 @@ void LLNetMap::draw()
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
-
- F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
- F32 half_width_pixels = half_width_meters * meters_to_pixels;
- F32 ctr_x = (F32)center_sw_left;
- F32 ctr_y = (F32)center_sw_bottom;
-
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if( rotate_map )
- {
- gGL.color4fv((map_frustum_color()).mV);
-
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( ctr_x, ctr_y );
- gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
- gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
- gGL.end();
- }
- else
- {
- gGL.color4fv((map_frustum_rotating_color()).mV);
-
- // If we don't rotate the map, we have to rotate the frustum.
- gGL.pushMatrix();
- gGL.translatef( ctr_x, ctr_y, 0 );
- gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( 0, 0 );
- gGL.vertex2f( -half_width_pixels, far_clip_pixels );
- gGL.vertex2f( half_width_pixels, far_clip_pixels );
- gGL.end();
- gGL.popMatrix();
- }
+ F32 ctr_x = (F32)center_sw_left;
+ F32 ctr_y = (F32)center_sw_bottom;
+
+ const F32 steps_per_circle = 40.0f;
+ const F32 steps_per_radian = steps_per_circle / F_TWO_PI;
+ const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f));
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if( rotate_map )
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
+ else
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ // If we don't rotate the map, we have to rotate the frustum.
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
}
gGL.popMatrix();
@@ -552,6 +593,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
}
}
+bool LLNetMap::isMouseOnPopupMenu()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return false;
+ }
+
+ S32 popup_x;
+ S32 popup_y;
+ LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
+ // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
+ constexpr S32 tolerance = 10;
+ // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space.
+ // Assume the size of the popup menu is much larger than the provided tolerance.
+ // In practice, this is a [tolerance]px margin around the popup menu.
+ for (S32 sign_x = -1; sign_x <= 1; sign_x += 2)
+ {
+ for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
+ {
+ if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLNetMap::updateAboutLandPopupButton()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return;
+ }
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
+ if (!region)
+ {
+ mPopupMenu->setItemEnabled("About Land", false);
+ }
+ else
+ {
+ // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover
+ // parcel can be used to check if location-sensitive tooltip options are available.
+ if (isMouseOnPopupMenu())
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ bool valid_parcel = false;
+ if (hover_parcel)
+ {
+ valid_parcel = hover_parcel->getOwnerID().notNull();
+ }
+ mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ }
+ }
+}
+
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]);
@@ -579,66 +679,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
- F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
+ // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
+ F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
- setScale(new_scale);
+ setScale(new_scale);
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (!auto_center)
- {
- // Adjust pan to center the zoom on the mouse pointer
- LLVector2 zoom_offset;
- zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
- zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
- mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
- }
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ if (!auto_center)
+ {
+ // Adjust pan to center the zoom on the mouse pointer
+ LLVector2 zoom_offset;
+ zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
+ zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
+ mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
+ }
- return TRUE;
+ return true;
}
-BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (gDisconnected)
- {
- return FALSE;
- }
+ if (gDisconnected)
+ {
+ return false;
+ }
- // If the cursor is near an avatar on the minimap, a mini-inspector will be
- // shown for the avatar, instead of the normal map tooltip.
- if (handleToolTipAgent(mClosestAgentToCursor))
- {
- return TRUE;
- }
+ // If the cursor is near an avatar on the minimap, a mini-inspector will be
+ // shown for the avatar, instead of the normal map tooltip.
+ if (handleToolTipAgent(mClosestAgentToCursor))
+ {
+ return true;
+ }
- LLRect sticky_rect;
- std::string region_name;
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
- if(region)
- {
- // set sticky_rect
- S32 SLOP = 4;
- localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
- sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
- sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
-
- region_name = region->getName();
- if (!region_name.empty())
- {
- region_name += "\n";
- }
- }
+ // The popup menu uses the hover parcel when it is open and the mouse is on
+ // top of it, with some additional tolerance. Returning early here prevents
+ // fighting over that hover parcel when getting tooltip info in the
+ // tolerance region.
+ if (isMouseOnPopupMenu())
+ {
+ return false;
+ }
- LLStringUtil::format_map_t args;
- args["[REGION]"] = region_name;
- std::string msg = mToolTipMsg;
- LLStringUtil::format(msg, args);
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(msg)
- .sticky_rect(sticky_rect));
-
- return TRUE;
+ LLRect sticky_rect;
+ S32 SLOP = 4;
+ localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
+ sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
+ sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
+
+ std::string parcel_name_msg;
+ std::string parcel_sale_price_msg;
+ std::string parcel_sale_area_msg;
+ std::string parcel_owner_msg;
+ std::string region_name_msg;
+
+ LLVector3d posGlobal = viewPosToGlobal(x, y);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal);
+ if (region)
+ {
+ std::string region_name = region->getName();
+ if (!region_name.empty())
+ {
+ region_name_msg = mRegionNameMsg;
+ LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}});
+ }
+
+ // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is
+ // ambiguous.
+ if (gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ if (hover_parcel)
+ {
+ std::string parcel_name = hover_parcel->getName();
+ if (!parcel_name.empty())
+ {
+ parcel_name_msg = mParcelNameMsg;
+ LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}});
+ }
+
+ const LLUUID parcel_owner = hover_parcel->getOwnerID();
+ std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString();
+ static LLUrlMatch parcel_owner_name_url_match;
+ LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match);
+ if (!parcel_owner_name_url_match.empty())
+ {
+ parcel_owner_msg = mParcelOwnerMsg;
+ std::string parcel_owner_name = parcel_owner_name_url_match.getLabel();
+ LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}});
+ }
+
+ if (hover_parcel->getForSale())
+ {
+ const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID();
+ const LLUUID agent_id = gAgent.getID();
+ bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id;
+ if (show_for_sale)
+ {
+ S32 price = hover_parcel->getSalePrice();
+ S32 area = hover_parcel->getArea();
+ F32 cost_per_sqm = 0.0f;
+ if (area > 0)
+ {
+ cost_per_sqm = F32(price) / area;
+ }
+ std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price);
+ std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm);
+ parcel_sale_price_msg = mParcelSalePriceMsg;
+ LLStringUtil::format(parcel_sale_price_msg,
+ {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}});
+ std::string formatted_area = llformat("%d", area);
+ parcel_sale_area_msg = mParcelSaleAreaMsg;
+ LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}});
+ }
+ }
+ }
+ }
+ }
+
+ std::string tool_tip_hint_msg;
+ if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+ {
+ tool_tip_hint_msg = mAltToolTipHintMsg;
+ }
+ else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
+ {
+ tool_tip_hint_msg = mToolTipHintMsg;
+ }
+
+ LLStringUtil::format_map_t args;
+ args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n';
+ args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n';
+ args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n';
+ args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n';
+ args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n';
+ args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n';
+
+ std::string msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+ if (msg.back() == '\n')
+ {
+ msg.resize(msg.size() - 1);
+ }
+ LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect));
+
+ return true;
}
BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id)
@@ -811,59 +997,58 @@ void LLNetMap::createObjectImage()
mUpdateNow = true;
}
-BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (!(mask & MASK_SHIFT)) return FALSE;
-
- // Start panning
- gFocusMgr.setMouseCapture(this);
+ // Start panning
+ gFocusMgr.setMouseCapture(this);
- mStartPan = mCurPan;
- mMouseDown.mX = x;
- mMouseDown.mY = y;
- return TRUE;
+ mStartPan = mCurPan;
+ mMouseDown.mX = x;
+ mMouseDown.mY = y;
+ return true;
}
-BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
- handleClick(x,y,mask);
+ if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3)
+ {
+ handleClick(x, y, mask);
+ }
- if (hasMouseCapture())
- {
- if (mPanning)
- {
- // restore mouse cursor
- S32 local_x, local_y;
- local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
- local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
- LLRect clip_rect = getRect();
- clip_rect.stretch(-8);
- clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
- LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
-
- // finish the pan
- mPanning = false;
-
- mMouseDown.set(0, 0);
-
- // auto centre
- mTargetPan.setZero();
- }
- gViewerWindow->showCursor();
- gFocusMgr.setMouseCapture(NULL);
- return TRUE;
- }
- return FALSE;
+ if (hasMouseCapture())
+ {
+ if (mPanning)
+ {
+ // restore mouse cursor
+ S32 local_x, local_y;
+ local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
+ local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
+ LLRect clip_rect = getRect();
+ clip_rect.stretch(-8);
+ clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
+ LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
+
+ // finish the pan
+ mPanning = false;
+
+ mMouseDown.set(0, 0);
+ }
+ gViewerWindow->showCursor();
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+
+ return false;
}
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (mPopupMenu)
{
+ mPopupWorldPos = viewPosToGlobal(x, y);
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
return TRUE;
@@ -911,6 +1096,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+F32 LLNetMap::getScaleForName(std::string scale_name)
+{
+ if (scale_name == "very close")
+ {
+ return LLNetMap::MAP_SCALE_VERY_CLOSE;
+ }
+ else if (scale_name == "close")
+ {
+ return LLNetMap::MAP_SCALE_CLOSE;
+ }
+ else if (scale_name == "medium")
+ {
+ return LLNetMap::MAP_SCALE_MEDIUM;
+ }
+ else if (scale_name == "far")
+ {
+ return LLNetMap::MAP_SCALE_FAR;
+ }
+ return 0.0f;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -928,7 +1134,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (!mPanning)
{
- // just started panning, so hide cursor
+ // Just started panning. Hide cursor.
mPanning = true;
gViewerWindow->hideCursor();
}
@@ -938,61 +1144,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
// Set pan to value at start of drag + offset
mCurPan += delta;
- mTargetPan = mCurPan;
gViewerWindow->moveCursorToCenter();
}
-
- // Doesn't really matter, cursor should be hidden
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- if (mask & MASK_SHIFT)
- {
- // If shift is held, change the cursor to hint that the map can be dragged
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- gViewerWindow->setCursor( UI_CURSOR_CROSS );
- }
}
+ if (mask & MASK_SHIFT)
+ {
+ // If shift is held, change the cursor to hint that the map can be
+ // dragged. However, holding shift is not required to drag the map.
+ gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
+ }
+ else
+ {
+ gViewerWindow->setCursor( UI_CURSOR_CROSS );
+ }
+
return TRUE;
}
-void LLNetMap::handleZoom(const LLSD& userdata)
+bool LLNetMap::isZoomChecked(const LLSD &userdata)
{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- setScale(scale);
- }
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ return scale == mScale;
+}
+
+void LLNetMap::setZoom(const LLSD &userdata)
+{
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
}
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
if (mPopupMenu)
{
- mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ mPopupMenu->setItemEnabled ("Stop tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
+
+void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; }
+
+bool LLNetMap::isMapOrientationChecked(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate");
+ if (command_name == "north_at_top")
+ {
+ return !rotate_map;
+ }
+
+ if (command_name == "camera_at_top")
+ {
+ return rotate_map;
+ }
+
+ return false;
+}
+
+void LLNetMap::setMapOrientation(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "north_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
+ else if (command_name == "camera_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", true);
+ }
+}
+
+void LLNetMap::popupShowAboutLand(const LLSD &userdata)
+{
+ // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection.
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos);
+ gMenuHolder->setParcelSelection(selection);
+
+ LLFloaterReg::showInstance("about_land", LLSD(), false);
+}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 1f7e7d68c6..fe1aca65a9 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -62,9 +62,12 @@ protected:
public:
virtual ~LLNetMap();
- static const F32 MAP_SCALE_MIN;
- static const F32 MAP_SCALE_MID;
- static const F32 MAP_SCALE_MAX;
+ static const F32 MAP_SCALE_MIN;
+ static const F32 MAP_SCALE_FAR;
+ static const F32 MAP_SCALE_MEDIUM;
+ static const F32 MAP_SCALE_CLOSE;
+ static const F32 MAP_SCALE_VERY_CLOSE;
+ static const F32 MAP_SCALE_MAX;
/*virtual*/ void draw();
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -79,8 +82,17 @@ public:
/*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- void setScale( F32 scale );
- void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setScale(F32 scale);
+
+ void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; }
+ void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; }
+ void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; }
+ void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; }
+ void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; }
+ void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; }
+ void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; }
+
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
@@ -94,11 +106,14 @@ private:
void drawTracking( const LLVector3d& pos_global,
const LLColor4& color,
BOOL draw_arrow = TRUE);
+ bool isMouseOnPopupMenu();
+ void updateAboutLandPopupButton();
BOOL handleToolTipAgent(const LLUUID& avatar_id);
static void showAvatarInspector(const LLUUID& avatar_id);
void createObjectImage();
+ F32 getScaleForName(std::string scale_name);
static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);
private:
@@ -112,11 +127,12 @@ private:
F32 mObjectMapPixels; // Width of object map in pixels
F32 mDotRadius; // Size of avatar markers
- bool mPanning; // map is being dragged
- LLVector2 mTargetPan;
- LLVector2 mCurPan;
- LLVector2 mStartPan; // pan offset at start of drag
- LLCoordGL mMouseDown; // pointer position at start of drag
+ bool mPanning; // map is being dragged
+ bool mCentering; // map is being re-centered around the agent
+ LLVector2 mCurPan;
+ LLVector2 mStartPan; // pan offset at start of drag
+ LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened
+ LLCoordGL mMouseDown; // pointer position at start of drag
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
@@ -125,14 +141,26 @@ private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- std::string mToolTipMsg;
+ std::string mToolTipMsg;
+ std::string mParcelNameMsg;
+ std::string mParcelSalePriceMsg;
+ std::string mParcelSaleAreaMsg;
+ std::string mParcelOwnerMsg;
+ std::string mRegionNameMsg;
+ std::string mToolTipHintMsg;
+ std::string mAltToolTipHintMsg;
public:
void setSelected(uuid_vec_t uuids) { gmSelected=uuids; };
private:
- void handleZoom(const LLSD& userdata);
- void handleStopTracking (const LLSD& userdata);
+ bool isZoomChecked(const LLSD& userdata);
+ void setZoom(const LLSD& userdata);
+ void handleStopTracking(const LLSD& userdata);
+ void activateCenterMap(const LLSD& userdata);
+ bool isMapOrientationChecked(const LLSD& userdata);
+ void setMapOrientation(const LLSD& userdata);
+ void popupShowAboutLand(const LLSD& userdata);
LLMenuGL* mPopupMenu;
uuid_vec_t gmSelected;
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 4febb72c6c..f419e2e06d 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1374,6 +1374,7 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id)
texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLOutfitGallery::onTexturePickerCommit, this, _1, _2));
texture_floaterp->setOnUpdateImageStatsCallback(boost::bind(&LLOutfitGallery::onTexturePickerUpdateImageStats, this, _1));
texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
texture_floaterp->setCanApply(false, true);
}
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 37ed4bc74c..ff33efe4aa 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.cpp
* @brief LLPanelAvatar and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, 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$
*/
@@ -28,173 +28,127 @@
#include "llpanelavatar.h"
#include "llagent.h"
-#include "llavataractions.h"
-#include "llcallingcard.h"
-#include "llcombobox.h"
-#include "lldateutil.h" // ageFromDate()
-#include "llimview.h"
-#include "llmenubutton.h"
-#include "llnotificationsutil.h"
-#include "llslurl.h"
-#include "lltexteditor.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
+#include "llloadingindicator.h"
#include "lltooldraganddrop.h"
-#include "llscrollcontainer.h"
-#include "llavatariconctrl.h"
-#include "llfloaterreg.h"
-#include "llnotificationsutil.h"
-#include "llviewermenu.h" // is_agent_mappable
-#include "llvoiceclient.h"
-#include "lltextbox.h"
-#include "lltrans.h"
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLDropTarget
-//
-// This handy class is a simple way to drop something on another
-// view. It handles drop events, always setting itself to the size of
-// its parent.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLDropTarget : public LLView
-{
-public:
- struct Params : public LLInitParam::Block<Params, LLView::Params>
- {
- Optional<LLUUID> agent_id;
- Params()
- : agent_id("agent_id")
- {
- changeDefault(mouse_opaque, false);
- changeDefault(follows.flags, FOLLOWS_ALL);
- }
- };
-
- LLDropTarget(const Params&);
- ~LLDropTarget();
-
- void doDrop(EDragAndDropType cargo_type, void* cargo_data);
-
- //
- // LLView functionality
- virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg);
- void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
-protected:
- LLUUID mAgentID;
-};
-
-LLDropTarget::LLDropTarget(const LLDropTarget::Params& p)
-: LLView(p),
- mAgentID(p.agent_id)
-{}
-LLDropTarget::~LLDropTarget()
+//////////////////////////////////////////////////////////////////////////
+// LLProfileDropTarget
+
+LLProfileDropTarget::LLProfileDropTarget(const LLProfileDropTarget::Params& p)
+: LLView(p),
+ mAgentID(p.agent_id)
{}
-void LLDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
+void LLProfileDropTarget::doDrop(EDragAndDropType cargo_type, void* cargo_data)
{
- LL_INFOS() << "LLDropTarget::doDrop()" << LL_ENDL;
+ LL_INFOS() << "LLProfileDropTarget::doDrop()" << LL_ENDL;
}
-BOOL LLDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
- EDragAndDropType cargo_type,
- void* cargo_data,
- EAcceptance* accept,
- std::string& tooltip_msg)
+BOOL LLProfileDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
{
- if(getParent())
- {
- LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
- cargo_type, cargo_data, accept);
+ if (getParent())
+ {
+ LLToolDragAndDrop::handleGiveDragAndDrop(mAgentID, LLUUID::null, drop,
+ cargo_type, cargo_data, accept);
- return TRUE;
- }
+ return TRUE;
+ }
- return FALSE;
+ return FALSE;
}
-static LLDefaultChildRegistry::Register<LLDropTarget> r("drop_target");
+static LLDefaultChildRegistry::Register<LLProfileDropTarget> r("profile_drop_target");
//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileTab
LLPanelProfileTab::LLPanelProfileTab()
: LLPanel()
, mAvatarId(LLUUID::null)
+, mLoadingState(PROFILE_INIT)
+, mSelfProfile(false)
{
}
LLPanelProfileTab::~LLPanelProfileTab()
{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
}
-void LLPanelProfileTab::setAvatarId(const LLUUID& id)
+void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id)
{
- if(id.notNull())
- {
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId,this);
- }
- mAvatarId = id;
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(),this);
- }
+ if (avatar_id.notNull())
+ {
+ mAvatarId = avatar_id;
+ mSelfProfile = (getAvatarId() == gAgentID);
+ }
}
void LLPanelProfileTab::onOpen(const LLSD& key)
{
- // Don't reset panel if we are opening it for same avatar.
- if(getAvatarId() != key.asUUID())
- {
- resetControls();
- resetData();
-
- scrollToTop();
- }
-
- // Update data even if we are viewing same avatar profile as some data might been changed.
- setAvatarId(key.asUUID());
- updateData();
- updateButtons();
+ // Update data even if we are viewing same avatar profile as some data might been changed.
+ setAvatarId(key.asUUID());
+
+ setApplyProgress(true);
+}
+
+void LLPanelProfileTab::setLoaded()
+{
+ setApplyProgress(false);
+
+ mLoadingState = PROFILE_LOADED;
+}
+
+void LLPanelProfileTab::setApplyProgress(bool started)
+{
+ LLLoadingIndicator* indicator = findChild<LLLoadingIndicator>("progress_indicator");
+
+ if (indicator)
+ {
+ indicator->setVisible(started);
+
+ if (started)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ }
+
+ LLView* panel = findChild<LLView>("indicator_stack");
+ if (panel)
+ {
+ panel->setVisible(started);
+ }
}
-void LLPanelProfileTab::scrollToTop()
+LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
+ : LLPanelProfileTab()
{
- LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
- if (scrollContainer)
- scrollContainer->goToTop();
}
-void LLPanelProfileTab::onMapButtonClick()
+LLPanelProfilePropertiesProcessorTab::~LLPanelProfilePropertiesProcessorTab()
{
- LLAvatarActions::showOnMap(getAvatarId());
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
}
-void LLPanelProfileTab::updateButtons()
+void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
{
- bool is_buddy_online = LLAvatarTracker::instance().isBuddyOnline(getAvatarId());
-
- if(LLAvatarActions::isFriend(getAvatarId()))
- {
- getChildView("teleport")->setEnabled(is_buddy_online);
- }
- else
- {
- getChildView("teleport")->setEnabled(true);
- }
-
- bool enable_map_btn = (is_buddy_online &&
- is_agent_mappable(getAvatarId()))
- || gAgent.isGodlike();
- getChildView("show_on_map_btn")->setEnabled(enable_map_btn);
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
+ }
}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index e33a850cfa..f182660c8e 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelavatar.h
- * @brief LLPanelAvatar and related class definitions
+ * @brief Legacy profile panel base class
*
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
+ * 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$
*/
@@ -29,80 +29,141 @@
#include "llpanel.h"
#include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
-#include "llvoiceclient.h"
#include "llavatarnamecache.h"
class LLComboBox;
class LLLineEditor;
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLProfileDropTarget
+//
+// This handy class is a simple way to drop something on another
+// view. It handles drop events, always setting itself to the size of
+// its parent.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLProfileDropTarget : public LLView
+{
+public:
+ struct Params : public LLInitParam::Block<Params, LLView::Params>
+ {
+ Optional<LLUUID> agent_id;
+ Params()
+ : agent_id("agent_id")
+ {
+ changeDefault(mouse_opaque, false);
+ changeDefault(follows.flags, FOLLOWS_ALL);
+ }
+ };
+
+ LLProfileDropTarget(const Params&);
+ ~LLProfileDropTarget() {}
+
+ void doDrop(EDragAndDropType cargo_type, void* cargo_data);
+
+ //
+ // LLView functionality
+ virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg);
+
+ void setAgentID(const LLUUID &agent_id) { mAgentID = agent_id; }
+
+protected:
+ LLUUID mAgentID;
+};
+
+
/**
* Base class for any Profile View.
*/
class LLPanelProfileTab
- : public LLPanel
- , public LLAvatarPropertiesObserver
+ : public LLPanel
{
public:
- /**
- * Sets avatar ID, sets panel as observer of avatar related info replies from server.
- */
- virtual void setAvatarId(const LLUUID& id);
-
- /**
- * Returns avatar ID.
- */
- virtual const LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sends update data request to server.
- */
- virtual void updateData() = 0;
-
- /**
- * Clears panel data if viewing avatar info for first time and sends update data request.
- */
- virtual void onOpen(const LLSD& key);
-
- /**
- * Profile tabs should close any opened panels here.
- *
- * Called from LLPanelProfile::onOpen() before opening new profile.
- * See LLPanelPicks::onClosePanel for example. LLPanelPicks closes picture info panel
- * before new profile is displayed, otherwise new profile will
- * be hidden behind picture info panel.
- */
- virtual void onClosePanel() {}
-
- /**
- * Resets controls visibility, state, etc.
- */
- virtual void resetControls(){};
-
- /**
- * Clears all data received from server.
- */
- virtual void resetData(){};
-
- /*virtual*/ ~LLPanelProfileTab();
+ /**
+ * Sets avatar ID, sets panel as observer of avatar related info replies from server.
+ */
+ virtual void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Returns avatar ID.
+ */
+ virtual const LLUUID& getAvatarId() { return mAvatarId; }
+
+ /**
+ * Sends update data request to server.
+ */
+ virtual void updateData() {};
+
+ /**
+ * Clears panel data if viewing avatar info for first time and sends update data request.
+ */
+ virtual void onOpen(const LLSD& key);
+
+ /**
+ * Clears all data received from server.
+ */
+ virtual void resetData(){};
+
+ /*virtual*/ ~LLPanelProfileTab();
protected:
- LLPanelProfileTab();
+ LLPanelProfileTab();
+
+ enum ELoadingState
+ {
+ PROFILE_INIT,
+ PROFILE_LOADING,
+ PROFILE_LOADED,
+ };
+
+
+ // mLoading: false: Initial state, can request
+ // true: Data requested, skip duplicate requests (happens due to LLUI's habit of repeated callbacks)
+ // mLoaded: false: Initial state, show loading indicator
+ // true: Data recieved, which comes in a single message, hide indicator
+ ELoadingState getLoadingState() { return mLoadingState; }
+ virtual void setLoaded();
+ void setApplyProgress(bool started);
+
+ const bool getSelfProfile() const { return mSelfProfile; }
- /**
- * Scrolls panel to top when viewing avatar info for first time.
- */
- void scrollToTop();
+public:
+ void setIsLoading() { mLoadingState = PROFILE_LOADING; }
+ void resetLoading() { mLoadingState = PROFILE_INIT; }
- virtual void onMapButtonClick();
+ bool getStarted() { return mLoadingState != PROFILE_INIT; }
+ bool getIsLoaded() { return mLoadingState == PROFILE_LOADED; }
- virtual void updateButtons();
+ virtual bool hasUnsavedChanges() { return false; }
+ virtual void commitUnsavedChanges() {}
private:
- LLUUID mAvatarId;
+ LLUUID mAvatarId;
+ ELoadingState mLoadingState;
+ bool mSelfProfile;
+};
+
+class LLPanelProfilePropertiesProcessorTab
+ : public LLPanelProfileTab
+ , public LLAvatarPropertiesObserver
+{
+public:
+ LLPanelProfilePropertiesProcessorTab();
+ ~LLPanelProfilePropertiesProcessorTab();
+
+ /*virtual*/ void setAvatarId(const LLUUID& avatar_id);
+
+ /**
+ * Processes data received from server via LLAvatarPropertiesObserver.
+ */
+ virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
};
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 3322e8a3df..3a4fc613b7 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -232,7 +232,7 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
{
if (names.empty() || ids.empty()) return;
- LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT);
+ LLMute mute(ids[0], names[0].getUserName(), LLMute::AGENT);
LLMuteList::getInstance()->add(mute);
showPanelAndSelect(mute.mID);
}
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index c0342eef4e..183000ceac 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.cpp
- * @brief LLPanelClassified class implementation
+ * @brief LLPanelClassifiedInfo class implementation
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -34,33 +34,21 @@
#include "lldispatcher.h"
#include "llfloaterreg.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
#include "llparcel.h"
#include "llagent.h"
#include "llclassifiedflags.h"
-#include "llcommandhandler.h" // for classified HTML detail page click tracking
#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llcombobox.h"
#include "lltexturectrl.h"
-#include "lltexteditor.h"
-#include "llviewerparcelmgr.h"
#include "llfloaterworldmap.h"
#include "llviewergenericmessage.h" // send_generic_message
#include "llviewerregion.h"
-#include "llviewertexture.h"
-#include "lltrans.h"
#include "llscrollcontainer.h"
-#include "llstatusbar.h"
-#include "llviewertexture.h"
#include "llcorehttputil.h"
-const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
-
//static
LLPanelClassifiedInfo::panel_list_t LLPanelClassifiedInfo::sAllPanels;
+static LLPanelInjector<LLPanelClassifiedInfo> t_panel_panel_classified_info("panel_classified_info");
// "classifiedclickthrough"
// strings[0] = classified_id
@@ -118,17 +106,8 @@ LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
sAllPanels.remove(this);
}
-// static
-LLPanelClassifiedInfo* LLPanelClassifiedInfo::create()
-{
- LLPanelClassifiedInfo* panel = new LLPanelClassifiedInfo();
- panel->buildFromFile("panel_classified_info.xml");
- return panel;
-}
-
BOOL LLPanelClassifiedInfo::postBuild()
{
- childSetAction("back_btn", boost::bind(&LLPanelClassifiedInfo::onExit, this));
childSetAction("show_on_map_btn", boost::bind(&LLPanelClassifiedInfo::onMapClick, this));
childSetAction("teleport_btn", boost::bind(&LLPanelClassifiedInfo::onTeleportClick, this));
@@ -144,16 +123,6 @@ BOOL LLPanelClassifiedInfo::postBuild()
return TRUE;
}
-void LLPanelClassifiedInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedInfo::setEditClassifiedCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
void LLPanelClassifiedInfo::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
{
LLPanel::reshape(width, height, called_from_parent);
@@ -286,6 +255,8 @@ void LLPanelClassifiedInfo::processProperties(void* data, EAvatarProcessorType t
getChild<LLUICtrl>("creation_date")->setValue(date_str);
setInfoLoaded(true);
+
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
}
}
}
@@ -590,588 +561,4 @@ void LLPanelClassifiedInfo::onTeleportClick()
}
}
-void LLPanelClassifiedInfo::onExit()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
- gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-static const S32 CB_ITEM_MATURE = 0;
-static const S32 CB_ITEM_PG = 1;
-
-LLPanelClassifiedEdit::LLPanelClassifiedEdit()
- : LLPanelClassifiedInfo()
- , mIsNew(false)
- , mIsNewWithErrors(false)
- , mCanClose(false)
- , mPublishFloater(NULL)
-{
-}
-
-LLPanelClassifiedEdit::~LLPanelClassifiedEdit()
-{
-}
-
-//static
-LLPanelClassifiedEdit* LLPanelClassifiedEdit::create()
-{
- LLPanelClassifiedEdit* panel = new LLPanelClassifiedEdit();
- panel->buildFromFile("panel_edit_classified.xml");
- return panel;
-}
-
-BOOL LLPanelClassifiedEdit::postBuild()
-{
- LLPanelClassifiedInfo::postBuild();
-
- LLUICtrl* edit_icon = getChild<LLUICtrl>("edit_icon");
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon));
- edit_icon->setVisible(false);
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("classified_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("classified_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- LLComboBox* combobox = getChild<LLComboBox>( "category");
- LLClassifiedInfo::cat_map::iterator iter;
- for (iter = LLClassifiedInfo::sCategories.begin();
- iter != LLClassifiedInfo::sCategories.end();
- iter++)
- {
- combobox->add(LLTrans::getString(iter->second));
- }
-
- combobox->setCommitCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this));
-
- childSetCommitCallback("content_type", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("price_for_listing", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
- childSetCommitCallback("auto_renew", boost::bind(&LLPanelClassifiedEdit::onChange, this), NULL);
-
- childSetAction("save_changes_btn", boost::bind(&LLPanelClassifiedEdit::onSaveClick, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelClassifiedEdit::onSetLocationClick, this));
-
- mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onTextureSelected, this));
-
- return TRUE;
-}
-
-void LLPanelClassifiedEdit::fillIn(const LLSD& key)
-{
- setAvatarId(gAgent.getID());
-
- if(key.isUndefined())
- {
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID snapshot_id = LLUUID::null;
- std::string desc;
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-
- if(parcel)
- {
- desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- getChild<LLUICtrl>("classified_name")->setValue(makeClassifiedName());
- getChild<LLUICtrl>("classified_desc")->setValue(desc);
- setSnapshotId(snapshot_id);
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
- // server will set valid parcel id
- setParcelId(LLUUID::null);
- }
- else
- {
- setClassifiedId(key["classified_id"]);
- setClassifiedName(key["name"]);
- setDescription(key["desc"]);
- setSnapshotId(key["snapshot_id"]);
- setCategory((U32)key["category"].asInteger());
- setContentType((U32)key["content_type"].asInteger());
- setClassifiedLocation(key["location_text"]);
- getChild<LLUICtrl>("auto_renew")->setValue(key["auto_renew"]);
- getChild<LLUICtrl>("price_for_listing")->setValue(key["price_for_listing"].asInteger());
- }
-}
-
-void LLPanelClassifiedEdit::onOpen(const LLSD& key)
-{
- mIsNew = key.isUndefined();
-
- scrollToTop();
-
- // classified is not created yet
- bool is_new = isNew() || isNewWithErrors();
-
- if(is_new)
- {
- resetData();
- resetControls();
-
- fillIn(key);
-
- if(isNew())
- {
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- }
- }
- else
- {
- LLPanelClassifiedInfo::onOpen(key);
- }
-
- std::string save_btn_label = is_new ? getString("publish_label") : getString("save_label");
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", save_btn_label);
-
- enableVerbs(is_new);
- enableEditing(is_new);
- showEditing(!is_new);
- resetDirty();
- setInfoLoaded(false);
-}
-
-void LLPanelClassifiedEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO == type)
- {
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if(c_info && getClassifiedId() == c_info->classified_id)
- {
- // see LLPanelClassifiedEdit::sendUpdate() for notes
- mIsNewWithErrors = false;
- // for just created classified - panel will probably be closed when we get here.
- if(!getVisible())
- {
- return;
- }
-
- enableEditing(true);
-
- 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));
- // *HACK see LLPanelClassifiedEdit::sendUpdate()
- setCategory(c_info->category - 1);
-
- bool mature = is_cf_mature(c_info->flags);
- bool auto_renew = is_cf_auto_renew(c_info->flags);
-
- setContentType(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
- getChild<LLUICtrl>("auto_renew")->setValue(auto_renew);
- getChild<LLUICtrl>("price_for_listing")->setValue(c_info->price_for_listing);
- getChildView("price_for_listing")->setEnabled(isNew());
-
- resetDirty();
- setInfoLoaded(true);
- enableVerbs(false);
-
- // for just created classified - in case user opened edit panel before processProperties() callback
- getChild<LLUICtrl>("save_changes_btn")->setLabelArg("[LABEL]", getString("save_label"));
- }
- }
-}
-
-BOOL LLPanelClassifiedEdit::isDirty() const
-{
- if(mIsNew)
- {
- return TRUE;
- }
-
- BOOL dirty = false;
-
- dirty |= LLPanelClassifiedInfo::isDirty();
- dirty |= getChild<LLUICtrl>("classified_snapshot")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_name")->isDirty();
- dirty |= getChild<LLUICtrl>("classified_desc")->isDirty();
- dirty |= getChild<LLUICtrl>("category")->isDirty();
- dirty |= getChild<LLUICtrl>("content_type")->isDirty();
- dirty |= getChild<LLUICtrl>("auto_renew")->isDirty();
- dirty |= getChild<LLUICtrl>("price_for_listing")->isDirty();
-
- return dirty;
-}
-
-void LLPanelClassifiedEdit::resetDirty()
-{
- LLPanelClassifiedInfo::resetDirty();
- getChild<LLUICtrl>("classified_snapshot")->resetDirty();
- getChild<LLUICtrl>("classified_name")->resetDirty();
-
- LLTextEditor* desc = getChild<LLTextEditor>("classified_desc");
- // call blockUndo() to really reset dirty(and make isDirty work as intended)
- desc->blockUndo();
- desc->resetDirty();
-
- getChild<LLUICtrl>("category")->resetDirty();
- getChild<LLUICtrl>("content_type")->resetDirty();
- getChild<LLUICtrl>("auto_renew")->resetDirty();
- getChild<LLUICtrl>("price_for_listing")->resetDirty();
-}
-
-void LLPanelClassifiedEdit::setSaveCallback(const commit_signal_t::slot_type& cb)
-{
- mSaveButtonClickedSignal.connect(cb);
-}
-
-void LLPanelClassifiedEdit::setCancelCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelClassifiedEdit::resetControls()
-{
- LLPanelClassifiedInfo::resetControls();
-
- getChild<LLComboBox>("category")->setCurrentByIndex(0);
- getChild<LLComboBox>("content_type")->setCurrentByIndex(0);
- getChild<LLUICtrl>("auto_renew")->setValue(false);
- getChild<LLUICtrl>("price_for_listing")->setValue(MINIMUM_PRICE_FOR_LISTING);
- getChildView("price_for_listing")->setEnabled(TRUE);
-}
-
-bool LLPanelClassifiedEdit::canClose()
-{
- return mCanClose;
-}
-
-void LLPanelClassifiedEdit::draw()
-{
- LLPanel::draw();
-
- // Need to re-stretch on every draw because LLTextureCtrl::onSelectCallback
- // does not trigger callbacks when user navigates through images.
- stretchSnapshot();
-}
-
-void LLPanelClassifiedEdit::stretchSnapshot()
-{
- LLPanelClassifiedInfo::stretchSnapshot();
-
- getChild<LLUICtrl>("edit_icon")->setShape(mSnapshotCtrl->getRect());
-}
-
-U32 LLPanelClassifiedEdit::getContentType()
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- return ct_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setContentType(U32 content_type)
-{
- LLComboBox* ct_cb = getChild<LLComboBox>("content_type");
- ct_cb->setCurrentByIndex(content_type);
- ct_cb->resetDirty();
-}
-
-bool LLPanelClassifiedEdit::getAutoRenew()
-{
- return getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-}
-
-void LLPanelClassifiedEdit::sendUpdate()
-{
- LLAvatarClassifiedInfo c_data;
-
- if(getClassifiedId().isNull())
- {
- setClassifiedId(LLUUID::generateNewID());
- }
-
- c_data.agent_id = gAgent.getID();
- c_data.classified_id = getClassifiedId();
- // *HACK
- // Categories on server start with 1 while combo-box index starts with 0
- c_data.category = getCategory() + 1;
- c_data.name = getClassifiedName();
- c_data.description = getDescription();
- c_data.parcel_id = getParcelId();
- c_data.snapshot_id = getSnapshotId();
- c_data.pos_global = getPosGlobal();
- c_data.flags = getFlags();
- c_data.price_for_listing = getPriceForListing();
-
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
-
- if(isNew())
- {
- // Lets assume there will be some error.
- // Successful sendClassifiedInfoUpdate will trigger processProperties and
- // let us know there was no error.
- mIsNewWithErrors = true;
- }
-}
-
-U32 LLPanelClassifiedEdit::getCategory()
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- return cat_cb->getCurrentIndex();
-}
-
-void LLPanelClassifiedEdit::setCategory(U32 category)
-{
- LLComboBox* cat_cb = getChild<LLComboBox>("category");
- cat_cb->setCurrentByIndex(category);
- cat_cb->resetDirty();
-}
-
-U8 LLPanelClassifiedEdit::getFlags()
-{
- bool auto_renew = getChild<LLUICtrl>("auto_renew")->getValue().asBoolean();
-
- LLComboBox* content_cb = getChild<LLComboBox>("content_type");
- bool mature = content_cb->getCurrentIndex() == CB_ITEM_MATURE;
-
- return pack_classified_flags_request(auto_renew, false, mature, false);
-}
-
-void LLPanelClassifiedEdit::enableVerbs(bool enable)
-{
- getChildView("save_changes_btn")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::enableEditing(bool enable)
-{
- getChildView("classified_snapshot")->setEnabled(enable);
- getChildView("classified_name")->setEnabled(enable);
- getChildView("classified_desc")->setEnabled(enable);
- getChildView("set_to_curr_location_btn")->setEnabled(enable);
- getChildView("category")->setEnabled(enable);
- getChildView("content_type")->setEnabled(enable);
- getChildView("price_for_listing")->setEnabled(enable);
- getChildView("auto_renew")->setEnabled(enable);
-}
-
-void LLPanelClassifiedEdit::showEditing(bool show)
-{
- getChildView("price_for_listing_label")->setVisible( show);
- getChildView("price_for_listing")->setVisible( show);
-}
-
-std::string LLPanelClassifiedEdit::makeClassifiedName()
-{
- std::string name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- name = parcel->getName();
- }
-
- if(!name.empty())
- {
- return name;
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- name = region->getName();
- }
-
- return name;
-}
-
-S32 LLPanelClassifiedEdit::getPriceForListing()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPanelClassifiedEdit::setPriceForListing(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-void LLPanelClassifiedEdit::onSetLocationClick()
-{
- setPosGlobal(gAgent.getPositionGlobal());
- setParcelId(LLUUID::null);
-
- std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- region_name = region->getName();
- }
-
- setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
-
- // mark classified as dirty
- setValue(LLSD());
-
- onChange();
-}
-
-void LLPanelClassifiedEdit::onChange()
-{
- enableVerbs(isDirty());
-}
-
-void LLPanelClassifiedEdit::onSaveClick()
-{
- mCanClose = false;
-
- if(!isValidName())
- {
- notifyInvalidName();
- return;
- }
- if(isNew() || isNewWithErrors())
- {
- if(gStatusBar->getBalance() < getPriceForListing())
- {
- LLNotificationsUtil::add("ClassifiedInsufficientFunds");
- return;
- }
-
- mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- if(!mPublishFloater)
- {
- mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
- "publish_classified", LLSD());
-
- mPublishFloater->setPublishClickedCallback(boost::bind
- (&LLPanelClassifiedEdit::onPublishFloaterPublishClicked, this));
- }
-
- // set spinner value before it has focus or value wont be set
- mPublishFloater->setPrice(getPriceForListing());
- mPublishFloater->openFloater(mPublishFloater->getKey());
- mPublishFloater->center();
- }
- else
- {
- doSave();
- }
-}
-
-void LLPanelClassifiedEdit::doSave()
-{
- mCanClose = true;
- sendUpdate();
- resetDirty();
-
- mSaveButtonClickedSignal(this, LLSD());
-}
-
-void LLPanelClassifiedEdit::onPublishFloaterPublishClicked()
-{
- setPriceForListing(mPublishFloater->getPrice());
-
- doSave();
-}
-
-std::string LLPanelClassifiedEdit::getLocationNotice()
-{
- static std::string location_notice = getString("location_notice");
- return location_notice;
-}
-
-bool LLPanelClassifiedEdit::isValidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- return false;
- }
- if (!isalnum(name[0]))
- {
- return false;
- }
-
- return true;
-}
-
-void LLPanelClassifiedEdit::notifyInvalidName()
-{
- std::string name = getClassifiedName();
- if (name.empty())
- {
- LLNotificationsUtil::add("BlankClassifiedName");
- }
- else if (!isalnum(name[0]))
- {
- LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
- }
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- ctrl->setVisible(TRUE);
-}
-
-void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- ctrl->setVisible(FALSE);
-}
-
-void LLPanelClassifiedEdit::onTextureSelected()
-{
- setSnapshotId(mSnapshotCtrl->getValue().asUUID());
- onChange();
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
- : LLFloater(key)
-{
-}
-
-LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
-{
-}
-
-BOOL LLPublishClassifiedFloater::postBuild()
-{
- LLFloater::postBuild();
-
- childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
- childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
-
- return TRUE;
-}
-
-void LLPublishClassifiedFloater::setPrice(S32 price)
-{
- getChild<LLUICtrl>("price_for_listing")->setValue(price);
-}
-
-S32 LLPublishClassifiedFloater::getPrice()
-{
- return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
-}
-
-void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("publish_btn")->setClickedCallback(cb);
-}
-
-void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
//EOF
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index b292782615..471becd0f7 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -1,10 +1,10 @@
/**
* @file llpanelclassified.h
- * @brief LLPanelClassified class definition
+ * @brief LLPanelClassifiedInfo class definition
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2021, 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
@@ -35,39 +35,16 @@
#include "llfloater.h"
#include "llpanel.h"
#include "llrect.h"
-#include "lluuid.h"
-#include "v3dmath.h"
-#include "llcoros.h"
-#include "lleventcoro.h"
class LLScrollContainer;
class LLTextureCtrl;
-class LLUICtrl;
-
-class LLPublishClassifiedFloater : public LLFloater
-{
-public:
- LLPublishClassifiedFloater(const LLSD& key);
- virtual ~LLPublishClassifiedFloater();
-
- /*virtual*/ BOOL postBuild();
-
- void setPrice(S32 price);
- S32 getPrice();
-
- void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
- void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
-
-private:
-};
class LLPanelClassifiedInfo : public LLPanel, public LLAvatarPropertiesObserver
{
LOG_CLASS(LLPanelClassifiedInfo);
public:
- static LLPanelClassifiedInfo* create();
-
+ LLPanelClassifiedInfo();
virtual ~LLPanelClassifiedInfo();
/*virtual*/ void onOpen(const LLSD& key);
@@ -135,18 +112,12 @@ public:
const LLVector3d& global_pos,
const std::string& sim_name);
- void setExitCallback(const commit_callback_t& cb);
-
- void setEditClassifiedCallback(const commit_callback_t& cb);
-
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ void draw();
protected:
- LLPanelClassifiedInfo();
-
virtual void resetData();
virtual void resetControls();
@@ -165,7 +136,6 @@ protected:
void onMapClick();
void onTeleportClick();
- void onExit();
bool mSnapshotStreched;
LLRect mSnapshotRect;
@@ -202,100 +172,4 @@ private:
static panel_list_t sAllPanels;
};
-class LLPanelClassifiedEdit : public LLPanelClassifiedInfo
-{
- LOG_CLASS(LLPanelClassifiedEdit);
-public:
-
- static LLPanelClassifiedEdit* create();
-
- virtual ~LLPanelClassifiedEdit();
-
- /*virtual*/ BOOL postBuild();
-
- void fillIn(const LLSD& key);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void resetDirty();
-
- void setSaveCallback(const commit_signal_t::slot_type& cb);
-
- void setCancelCallback(const commit_signal_t::slot_type& cb);
-
- /*virtual*/ void resetControls();
-
- bool isNew() { return mIsNew; }
-
- bool isNewWithErrors() { return mIsNewWithErrors; }
-
- bool canClose();
-
- void draw();
-
- void stretchSnapshot();
-
- U32 getCategory();
-
- void setCategory(U32 category);
-
- U32 getContentType();
-
- void setContentType(U32 content_type);
-
- bool getAutoRenew();
-
- S32 getPriceForListing();
-
-protected:
-
- LLPanelClassifiedEdit();
-
- void sendUpdate();
-
- void enableVerbs(bool enable);
-
- void enableEditing(bool enable);
-
- void showEditing(bool show);
-
- std::string makeClassifiedName();
-
- void setPriceForListing(S32 price);
-
- U8 getFlags();
-
- std::string getLocationNotice();
-
- bool isValidName();
-
- void notifyInvalidName();
-
- void onSetLocationClick();
- void onChange();
- void onSaveClick();
-
- void doSave();
-
- void onPublishFloaterPublishClicked();
-
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
- void onTextureSelected();
-
-private:
- bool mIsNew;
- bool mIsNewWithErrors;
- bool mCanClose;
-
- LLPublishClassifiedFloater* mPublishFloater;
-
- commit_signal_t mSaveButtonClickedSignal;
-};
-
#endif // LL_LLPANELCLASSIFIED_H
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index be11a4a9f3..ea10aa75ae 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1308,7 +1308,9 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
{
- gMorphView->updateCamera();
+ // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE
+ gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating());
+ gMorphView->updateCamera();
}
}
diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h
index 9d5afd1a6a..11111f2a2e 100644
--- a/indra/newview/llpanelexperiences.h
+++ b/indra/newview/llpanelexperiences.h
@@ -29,7 +29,6 @@
#include "llaccordionctrltab.h"
#include "llflatlistview.h"
-#include "llpanelavatar.h"
class LLExperienceItem;
class LLPanelProfile;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 71657239a6..178aba11a3 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -38,6 +38,7 @@
#include "llfontgl.h"
// project includes
+#include "llagent.h"
#include "llagentdata.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
@@ -45,10 +46,18 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "llface.h"
+#include "llinventoryfunctions.h"
+#include "llinventorymodel.h" // gInventory
+#include "llinventorymodelbackgroundfetch.h"
+#include "llfloatermediasettings.h"
+#include "llfloaterreg.h"
#include "lllineeditor.h"
#include "llmaterialmgr.h"
+#include "llmediactrl.h"
#include "llmediaentry.h"
+#include "llmenubutton.h"
#include "llnotificationsutil.h"
+#include "llpanelcontents.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -57,6 +66,8 @@
#include "lltexturectrl.h"
#include "lltextureentry.h"
#include "lltooldraganddrop.h"
+#include "lltoolface.h"
+#include "lltoolmgr.h"
#include "lltrans.h"
#include "llui.h"
#include "llviewercontrol.h"
@@ -92,10 +103,9 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
+ LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
(radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
@@ -154,6 +164,8 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this);
childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this);
childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this);
+ childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
+ childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
@@ -165,7 +177,6 @@ BOOL LLPanelFace::postBuild()
LLColorSwatchCtrl* mShinyColorSwatch;
LLComboBox* mComboTexGen;
- LLComboBox* mComboMatMedia;
LLCheckBoxCtrl *mCheckFullbright;
@@ -298,7 +309,12 @@ BOOL LLPanelFace::postBuild()
{
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
-
+
+ mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn");
+ mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn");
+
+ mTitleMedia = getChild<LLMediaCtrl>("title_media");
+ mTitleMediaText = getChild<LLTextBox>("media_info");
clearCtrls();
@@ -307,17 +323,33 @@ BOOL LLPanelFace::postBuild()
LLPanelFace::LLPanelFace()
: LLPanel(),
- mIsAlpha(false)
+ mIsAlpha(false),
+ mComboMatMedia(NULL),
+ mTitleMedia(NULL),
+ mTitleMediaText(NULL),
+ mNeedMediaTitle(true)
{
- USE_TEXTURE = LLTrans::getString("use_texture");
+ USE_TEXTURE = LLTrans::getString("use_texture");
+ mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2));
}
-
LLPanelFace::~LLPanelFace()
{
- // Children all cleaned up by default view destructor.
+ unloadMedia();
}
+void LLPanelFace::draw()
+{
+ updateCopyTexButton();
+
+ // grab media name/title and update the UI widget
+ // Todo: move it, it's preferable not to update
+ // labels inside draw
+ updateMediaTitle();
+
+ LLPanel::draw();
+}
void LLPanelFace::sendTexture()
{
@@ -806,21 +838,20 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
- getChildView("button align")->setEnabled(editable);
+ childSetEnabled("button align", editable);
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
{
- combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
+ mComboMatMedia->setEnabled(editable);
}
else
{
LL_WARNS() << "failed getChild for 'combobox matmedia'" << LL_ENDL;
}
- getChildView("combobox matmedia")->setEnabled(editable);
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
@@ -829,7 +860,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
-
}
else
{
@@ -858,22 +888,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
getChildView("color label")->setEnabled(editable);
}
- LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
LLColor4 color = LLColor4::white;
bool identical_color = false;
- if(mColorSwatch)
+ if(color_swatch)
{
LLSelectedTE::getColor(color, identical_color);
- LLColor4 prev_color = mColorSwatch->get();
+ LLColor4 prev_color = color_swatch->get();
- mColorSwatch->setOriginal(color);
- mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable);
+ color_swatch->setOriginal(color);
+ color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
- mColorSwatch->setValid(editable);
- mColorSwatch->setEnabled( editable );
- mColorSwatch->setCanApplyImmediately( editable );
+ color_swatch->setValid(editable);
+ color_swatch->setEnabled( editable );
+ color_swatch->setCanApplyImmediately( editable );
}
// Color transparency
@@ -1356,7 +1386,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL identical_repeats = true;
F32 repeats = 1.0f;
- U32 material_type = (combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
+ U32 material_type = (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
switch (material_type)
@@ -1508,6 +1538,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
}
}
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (selected_count == 1);
+ mMenuClipboardColor->setEnabled(editable && single_volume);
// Set variable values for numeric expressions
LLCalc* calcp = LLCalc::getInstance();
@@ -1568,12 +1601,772 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
+void LLPanelFace::updateCopyTexButton()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()
+ && !objectp->isPermanentEnforced() && !objectp->isInventoryPending()
+ && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1));
+ std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options");
+ mMenuClipboardTexture->setToolTip(tooltip);
+
+}
+
void LLPanelFace::refresh()
{
LL_DEBUGS("Materials") << LL_ENDL;
getState();
}
+void LLPanelFace::refreshMedia()
+{
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject* first_object = selected_objects->getFirstObject();
+
+ if (!(first_object
+ && first_object->getPCode() == LL_PCODE_VOLUME
+ && first_object->permModify()
+ ))
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ mTitleMediaText->clear();
+ clearMediaSettings();
+ return;
+ }
+
+ std::string url = first_object->getRegion()->getCapability("ObjectMedia");
+ bool has_media_capability = (!url.empty());
+
+ if (!has_media_capability)
+ {
+ getChildView("add_media")->setEnabled(FALSE);
+ LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL;
+ clearMediaSettings();
+ return;
+ }
+
+ BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode()
+ && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced())
+ || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced();
+ bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable());
+
+ // Check modify permissions and whether any selected objects are in
+ // the process of being fetched. If they are, then we're not editable
+ if (editable)
+ {
+ LLObjectSelection::iterator iter = selected_objects->begin();
+ LLObjectSelection::iterator end = selected_objects->end();
+ for (; iter != end; ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject());
+ if (NULL != object)
+ {
+ if (!object->permModify())
+ {
+ LL_INFOS("LLFloaterToolsMedia")
+ << "Selection not editable due to lack of modify permissions on object id "
+ << object->getID() << LL_ENDL;
+
+ editable = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Media settings
+ bool bool_has_media = false;
+ struct media_functor : public LLSelectedTEGetFunctor<bool>
+ {
+ bool get(LLViewerObject* object, S32 face)
+ {
+ LLTextureEntry *te = object->getTE(face);
+ if (te)
+ {
+ return te->hasMedia();
+ }
+ return false;
+ }
+ } func;
+
+
+ // check if all faces have media(or, all dont have media)
+ LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media);
+
+ const LLMediaEntry default_media_data;
+
+ struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry>
+ {
+ functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ LLMediaEntry get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return *(object->getTE(face)->getMediaData());
+ return mMediaEntry;
+ };
+
+ const LLMediaEntry& mMediaEntry;
+
+ } func_media_data(default_media_data);
+
+ LLMediaEntry media_data_get;
+ LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get));
+
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ std::string media_title = "";
+ // update UI depending on whether "object" (prim or face) has media
+ // and whether or not you are allowed to edit it.
+
+ getChildView("add_media")->setEnabled(editable);
+ // IF all the faces have media (or all dont have media)
+ if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo)
+ {
+ // TODO: get media title and set it.
+ mTitleMediaText->clear();
+ // if identical is set, all faces are same (whether all empty or has the same media)
+ if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia))
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ // else all faces might be empty.
+ }
+ else // there' re Different Medias' been set on on the faces.
+ {
+ media_title = multi_media_info_str;
+ }
+
+ getChildView("delete_media")->setEnabled(bool_has_media && editable);
+ // TODO: display a list of all media on the face - use 'identical' flag
+ }
+ else // not all face has media but at least one does.
+ {
+ // seleted faces have not identical value
+ LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data);
+
+ if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia)
+ {
+ media_title = multi_media_info_str;
+ }
+ else
+ {
+ // Media data is valid
+ if (media_data_get != default_media_data)
+ {
+ // initial media title is the media URL (until we get the name)
+ media_title = media_data_get.getHomeURL();
+ }
+ }
+
+ getChildView("delete_media")->setEnabled(TRUE);
+ }
+
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
+ if (materials_media == MATMEDIA_MEDIA)
+ {
+ // currently displaying media info, navigateTo and update title
+ navigateToTitleMedia(media_title);
+ }
+ else
+ {
+ // Media can be heavy, don't keep it around
+ // MAC specific: MAC doesn't support setVolume(0) so if not
+ // unloaded, it might keep playing audio until user closes editor
+ unloadMedia();
+ mNeedMediaTitle = false;
+ }
+
+ mTitleMediaText->setText(media_title);
+
+ // load values for media settings
+ updateMediaSettings();
+
+ LLFloaterMediaSettings::initValues(mMediaSettings, editable);
+}
+
+void LLPanelFace::unloadMedia()
+{
+ // destroy media source used to grab media title
+ if (mTitleMedia)
+ mTitleMedia->unloadMediaSource();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+void LLPanelFace::navigateToTitleMedia( const std::string url )
+{
+ std::string multi_media_info_str = LLTrans::getString("Multiple Media");
+ if (url.empty() || multi_media_info_str == url)
+ {
+ // nothing to show
+ mNeedMediaTitle = false;
+ }
+ else if (mTitleMedia)
+ {
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ // check if url changed or if we need a new media source
+ if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL)
+ {
+ mTitleMedia->navigateTo( url );
+
+ LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID());
+ if (impl)
+ {
+ // if it's a page with a movie, we don't want to hear it
+ impl->setVolume(0);
+ };
+ }
+
+ // flag that we need to update the title (even if no request were made)
+ mNeedMediaTitle = true;
+ }
+}
+
+bool LLPanelFace::selectedMediaEditable()
+{
+ U32 owner_mask_on;
+ U32 owner_mask_off;
+ U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER,
+ &owner_mask_on, &owner_mask_off);
+ U32 group_mask_on;
+ U32 group_mask_off;
+ U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP,
+ &group_mask_on, &group_mask_off);
+ U32 everyone_mask_on;
+ U32 everyone_mask_off;
+ S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE,
+ &everyone_mask_on, &everyone_mask_off);
+
+ bool selected_Media_editable = false;
+
+ // if perms we got back are valid
+ if (valid_owner_perms &&
+ valid_group_perms &&
+ valid_everyone_perms)
+ {
+
+ if ((owner_mask_on & PERM_MODIFY) ||
+ (group_mask_on & PERM_MODIFY) ||
+ (everyone_mask_on & PERM_MODIFY))
+ {
+ selected_Media_editable = true;
+ }
+ else
+ // user is NOT allowed to press the RESET button
+ {
+ selected_Media_editable = false;
+ };
+ };
+
+ return selected_Media_editable;
+}
+
+void LLPanelFace::clearMediaSettings()
+{
+ LLFloaterMediaSettings::clearValues(false);
+}
+
+void LLPanelFace::updateMediaSettings()
+{
+ bool identical(false);
+ std::string base_key("");
+ std::string value_str("");
+ int value_int = 0;
+ bool value_bool = false;
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ // TODO: (CP) refactor this using something clever or boost or both !!
+
+ const LLMediaEntry default_media_data;
+
+ // controls
+ U8 value_u8 = default_media_data.getControls();
+ struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
+ {
+ functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {}
+
+ U8 get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getControls();
+ return mMediaEntry.getControls();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_controls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_controls, value_u8);
+ base_key = std::string(LLMediaEntry::CONTROLS_KEY);
+ mMediaSettings[base_key] = value_u8;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // First click (formerly left click)
+ value_bool = default_media_data.getFirstClickInteract();
+ struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getFirstClickInteract();
+ return mMediaEntry.getFirstClickInteract();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_first_click(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool);
+ base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Home URL
+ value_str = default_media_data.getHomeURL();
+ struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHomeURL();
+ return mMediaEntry.getHomeURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_home_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_home_url, value_str);
+ base_key = std::string(LLMediaEntry::HOME_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Current URL
+ value_str = default_media_data.getCurrentURL();
+ struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
+ {
+ functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::string get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getCurrentURL();
+ return mMediaEntry.getCurrentURL();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_current_url(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_current_url, value_str);
+ base_key = std::string(LLMediaEntry::CURRENT_URL_KEY);
+ mMediaSettings[base_key] = value_str;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto zoom
+ value_bool = default_media_data.getAutoZoom();
+ struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
+ {
+
+ functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoZoom();
+ return mMediaEntry.getAutoZoom();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_zoom(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto play
+ //value_bool = default_media_data.getAutoPlay();
+ // set default to auto play TRUE -- angela EXT-5172
+ value_bool = true;
+ struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoPlay();
+ //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_play(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+
+ // Auto scale
+ // set default to auto scale TRUE -- angela EXT-5172
+ //value_bool = default_media_data.getAutoScale();
+ value_bool = true;
+ struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoScale();
+ // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172
+ return true;
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_scale(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Auto loop
+ value_bool = default_media_data.getAutoLoop();
+ struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAutoLoop();
+ return mMediaEntry.getAutoLoop();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_auto_loop(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool);
+ base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // width pixels (if not auto scaled)
+ value_int = default_media_data.getWidthPixels();
+ struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWidthPixels();
+ return mMediaEntry.getWidthPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_width_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int);
+ base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // height pixels (if not auto scaled)
+ value_int = default_media_data.getHeightPixels();
+ struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
+ {
+ functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ int get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getHeightPixels();
+ return mMediaEntry.getHeightPixels();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_height_pixels(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int);
+ base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY);
+ mMediaSettings[base_key] = value_int;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Enable Alt image
+ value_bool = default_media_data.getAltImageEnable();
+ struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getAltImageEnable();
+ return mMediaEntry.getAltImageEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_enable_alt_image(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool);
+ base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - owner control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_owner_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_interact(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - group control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_group_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone interact
+ value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_interact(default_media_data);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // Perms - anyone control
+ value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
+ return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE);
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_perms_anyone_control(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool);
+ base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist enable
+ value_bool = default_media_data.getWhiteListEnable();
+ struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
+ {
+ functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ bool get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteListEnable();
+ return mMediaEntry.getWhiteListEnable();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_enable(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool);
+ base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY);
+ mMediaSettings[base_key] = value_bool;
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+
+ // security - whitelist URLs
+ std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
+ struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
+ {
+ functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {}
+
+ std::vector<std::string> get(LLViewerObject* object, S32 face)
+ {
+ if (object)
+ if (object->getTE(face))
+ if (object->getTE(face)->getMediaData())
+ return object->getTE(face)->getMediaData()->getWhiteList();
+ return mMediaEntry.getWhiteList();
+ };
+
+ const LLMediaEntry &mMediaEntry;
+
+ } func_whitelist_urls(default_media_data);
+ identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str);
+ base_key = std::string(LLMediaEntry::WHITELIST_KEY);
+ mMediaSettings[base_key].clear();
+ std::vector< std::string >::iterator iter = value_vector_str.begin();
+ while (iter != value_vector_str.end())
+ {
+ std::string white_list_url = *iter;
+ mMediaSettings[base_key].append(white_list_url);
+ ++iter;
+ };
+
+ mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical;
+}
+
+void LLPanelFace::updateMediaTitle()
+{
+ // only get the media name if we need it
+ if (!mNeedMediaTitle)
+ return;
+
+ // get plugin impl
+ LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin();
+ if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI())
+ {
+ // get the media name (asynchronous - must call repeatedly)
+ std::string media_title = media_plugin->getMediaName();
+
+ // only replace the title if what we get contains something
+ if (!media_title.empty())
+ {
+ // update the UI widget
+ if (mTitleMediaText)
+ {
+ mTitleMediaText->setText(media_title);
+
+ // stop looking for a title when we get one
+ mNeedMediaTitle = false;
+ };
+ };
+ };
+}
+
//
// Static functions
//
@@ -1632,30 +2425,29 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
self->updateShinyControls(false,true);
self->updateBumpyControls(false,true);
self->updateUI();
+ self->refreshMedia();
}
-// static
void LLPanelFace::updateVisibility()
{
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
- if (!radio_mat_type || !combo_matmedia || !combo_shininess || !combo_bumpiness)
+ if (!radio_mat_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
}
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled()));
- bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
getChildView("radio_material_type")->setVisible(!show_media);
// Media controls
- getChildView("media_info")->setVisible(show_media);
+ mTitleMediaText->setVisible(show_media);
getChildView("add_media")->setVisible(show_media);
getChildView("delete_media")->setVisible(show_media);
getChildView("button align")->setVisible(show_media);
@@ -1787,12 +2579,11 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
}
- LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled();
+ bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
+ bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
getChildView("label glossiness")->setVisible(show_shinyctrls);
@@ -1866,11 +2657,10 @@ void LLPanelFace::updateAlphaControls()
U32 alpha_value = comboAlphaMode->getCurrentIndex();
bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking
- LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia");
U32 mat_media = MATMEDIA_MATERIAL;
- if (combobox_matmedia)
+ if (mComboMatMedia)
{
- mat_media = combobox_matmedia->getCurrentIndex();
+ mat_media = mComboMatMedia->getCurrentIndex();
}
U32 mat_type = MATTYPE_DIFFUSE;
@@ -2027,6 +2817,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data)
sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE);
}
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to edit existing media settings on a prim or prim face
+// TODO: test if there is media on the item and only allow editing if present
+void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLFloaterReg::showInstance("media_settings");
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to delete media from a prim or prim face
+void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata)
+{
+ LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// called when a user wants to add media to a prim or prim face
+void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata)
+{
+ // check if multiple faces are selected
+ if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ self->refreshMedia();
+ LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm);
+ }
+ else
+ {
+ onClickBtnEditMedia(ctrl, userdata);
+ }
+}
+
+// static
+bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD());
+ if (LLFloaterReg::instanceVisible("media_settings"))
+ {
+ LLFloaterReg::hideInstance("media_settings");
+ }
+ break;
+
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
+// static
+bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ switch (option)
+ {
+ case 0: // "Yes"
+ LLFloaterReg::showInstance("media_settings");
+ break;
+ case 1: // "No"
+ default:
+ break;
+ }
+ return false;
+}
+
//static
void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU)
{
@@ -2404,10 +3265,9 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLPanelFace* self = (LLPanelFace*) userdata;
LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
- LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia");
LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
- U32 materials_media = combo_matmedia->getCurrentIndex();
+ U32 materials_media = self->mComboMatMedia->getCurrentIndex();
U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
@@ -2538,15 +3398,811 @@ void LLPanelFace::onAlignTexture(void* userdata)
self->alignTestureLayer();
}
+enum EPasteMode
+{
+ PASTE_COLOR,
+ PASTE_TEXTURE
+};
+
+struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor
+{
+ LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) :
+ mPanelFace(panel), mMode(mode) {}
+
+ virtual bool apply(LLViewerObject* objectp, S32 te)
+ {
+ switch (mMode)
+ {
+ case PASTE_COLOR:
+ mPanelFace->onPasteColor(objectp, te);
+ break;
+ case PASTE_TEXTURE:
+ mPanelFace->onPasteTexture(objectp, te);
+ break;
+ }
+ return true;
+ }
+private:
+ LLPanelFace *mPanelFace;
+ EPasteMode mMode;
+};
+
+struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
+{
+ LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ object->sendTEUpdate();
+ if (mUpdateMedia)
+ {
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
+ if (vo && vo->hasMedia())
+ {
+ vo->sendMediaDataUpdate();
+ }
+ }
+ return true;
+ }
+private:
+ bool mUpdateMedia;
+};
+
+struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor
+{
+ virtual bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && objectp->getTE(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ const LLMediaEntry *media_data = tep->getMediaData();
+ if (media_data)
+ {
+ if (media_data->getCurrentURL().empty() && media_data->getAutoPlay())
+ {
+ viewer_media_t media_impl =
+ LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID());
+ if (media_impl)
+ {
+ media_impl->navigateHome();
+ }
+ }
+ }
+ }
+ return true;
+ }
+};
+
+void LLPanelFace::onCopyColor()
+{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ return;
+ }
+
+ if (mClipboardParams.has("color"))
+ {
+ mClipboardParams["color"].clear();
+ }
+ else
+ {
+ mClipboardParams["color"] = LLSD::emptyArray();
+ }
+
+ std::map<LLUUID, LLUUID> asset_item_map;
+
+ // a way to resolve situations where source and target have different amount of faces
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ mClipboardParams["color_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ LLSD te_data;
+
+ // asLLSD() includes media
+ te_data["te"] = tep->asLLSD(); // Note: includes a lot more than just color/alpha/glow
+
+ mClipboardParams["color"].append(te_data);
+ }
+ }
+ }
+}
+
+void LLPanelFace::onPasteColor()
+{
+ if (!mClipboardParams.has("color"))
+ {
+ return;
+ }
+
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ // not supposed to happen
+ LL_WARNS() << "Failed to paste color due to missing or wrong selection" << LL_ENDL;
+ return;
+ }
+
+ bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ LLSD &clipboard = mClipboardParams["color"]; // array
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ S32 compare_tes = num_tes;
+
+ if (face_selection_mode)
+ {
+ compare_tes = 0;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ compare_tes++;
+ }
+ }
+ }
+
+ // we can copy if single face was copied in edit face mode or if face count matches
+ if (!((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean())
+ && compare_tes != clipboard.size())
+ {
+ LLSD notif_args;
+ if (face_selection_mode)
+ {
+ static std::string reason = getString("paste_error_face_selection_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ else
+ {
+ static std::string reason = getString("paste_error_object_face_count_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
-// TODO: I don't know who put these in or what these are for???
-void LLPanelFace::setMediaURL(const std::string& url)
+ LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR);
+ selected_objects->applyToTEs(&paste_func);
+
+ LLPanelFaceUpdateFunctor sendfunc(false);
+ selected_objects->applyToObjects(&sendfunc);
+}
+
+void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te)
{
+ LLSD te_data;
+ LLSD &clipboard = mClipboardParams["color"]; // array
+ if ((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean())
+ {
+ te_data = *(clipboard.beginArray());
+ }
+ else if (clipboard[te])
+ {
+ te_data = clipboard[te];
+ }
+ else
+ {
+ return;
+ }
+
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ if (te_data.has("te"))
+ {
+ // Color / Alpha
+ if (te_data["te"].has("colors"))
+ {
+ LLColor4 color = tep->getColor();
+
+ LLColor4 clip_color;
+ clip_color.setValue(te_data["te"]["colors"]);
+
+ // Color
+ color.mV[VRED] = clip_color.mV[VRED];
+ color.mV[VGREEN] = clip_color.mV[VGREEN];
+ color.mV[VBLUE] = clip_color.mV[VBLUE];
+
+ // Alpha
+ color.mV[VALPHA] = clip_color.mV[VALPHA];
+
+ objectp->setTEColor(te, color);
+ }
+
+ // Color/fullbright
+ if (te_data["te"].has("fullbright"))
+ {
+ objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger());
+ }
+
+ // Glow
+ if (te_data["te"].has("glow"))
+ {
+ objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal());
+ }
+ }
+ }
}
-void LLPanelFace::setMediaType(const std::string& mime_type)
+
+void LLPanelFace::onCopyTexture()
{
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ return;
+ }
+
+ if (mClipboardParams.has("texture"))
+ {
+ mClipboardParams["texture"].clear();
+ }
+ else
+ {
+ mClipboardParams["texture"] = LLSD::emptyArray();
+ }
+
+ std::map<LLUUID, LLUUID> asset_item_map;
+
+ // a way to resolve situations where source and target have different amount of faces
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ mClipboardParams["texture_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ LLSD te_data;
+
+ // asLLSD() includes media
+ te_data["te"] = tep->asLLSD();
+ te_data["te"]["shiny"] = tep->getShiny();
+ te_data["te"]["bumpmap"] = tep->getBumpmap();
+ te_data["te"]["bumpshiny"] = tep->getBumpShiny();
+ te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright();
+
+ if (te_data["te"].has("imageid"))
+ {
+ LLUUID item_id;
+ LLUUID id = te_data["te"]["imageid"].asUUID();
+ bool from_library = get_is_predefined_texture(id);
+ bool full_perm = from_library;
+
+ if (!full_perm
+ && objectp->permCopy()
+ && objectp->permTransfer()
+ && objectp->permModify())
+ {
+ // If agent created this object and nothing is limiting permissions, mark as full perm
+ // If agent was granted permission to edit objects owned and created by somebody else, mark full perm
+ // This check is not perfect since we can't figure out whom textures belong to so this ended up restrictive
+ std::string creator_app_link;
+ LLUUID creator_id;
+ LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link);
+ full_perm = objectp->mOwnerID == creator_id;
+ }
+
+ if (id.notNull() && !full_perm)
+ {
+ std::map<LLUUID, LLUUID>::iterator iter = asset_item_map.find(id);
+ if (iter != asset_item_map.end())
+ {
+ item_id = iter->second;
+ }
+ else
+ {
+ // What this does is simply searches inventory for item with same asset id,
+ // as result it is Hightly unreliable, leaves little control to user, borderline hack
+ // but there are little options to preserve permissions - multiple inventory
+ // items might reference same asset and inventory search is expensive.
+ bool no_transfer = false;
+ if (objectp->getInventoryItemByAsset(id))
+ {
+ no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm();
+ }
+ item_id = get_copy_free_item_by_asset_id(id, no_transfer);
+ // record value to avoid repeating inventory search when possible
+ asset_item_map[id] = item_id;
+ }
+ }
+
+ if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID()))
+ {
+ full_perm = true;
+ from_library = true;
+ }
+
+ {
+ te_data["te"]["itemfullperm"] = full_perm;
+ te_data["te"]["fromlibrary"] = from_library;
+
+ // If full permission object, texture is free to copy,
+ // but otherwise we need to check inventory and extract permissions
+ //
+ // Normally we care only about restrictions for current user and objects
+ // don't inherit any 'next owner' permissions from texture, so there is
+ // no need to record item id if full_perm==true
+ if (!full_perm && !from_library && item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ te_data["te"]["imageitemid"] = item_id;
+ te_data["te"]["itemfullperm"] = itemp->getIsFullPerm();
+ if (!itemp->isFinished())
+ {
+ // needed for dropTextureAllFaces
+ LLInventoryModelBackgroundFetch::instance().start(item_id, false);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ LLMaterialPtr material_ptr = tep->getMaterialParams();
+ if (!material_ptr.isNull())
+ {
+ LLSD mat_data;
+
+ mat_data["NormMap"] = material_ptr->getNormalID();
+ mat_data["SpecMap"] = material_ptr->getSpecularID();
+
+ mat_data["NormRepX"] = material_ptr->getNormalRepeatX();
+ mat_data["NormRepY"] = material_ptr->getNormalRepeatY();
+ mat_data["NormOffX"] = material_ptr->getNormalOffsetX();
+ mat_data["NormOffY"] = material_ptr->getNormalOffsetY();
+ mat_data["NormRot"] = material_ptr->getNormalRotation();
+
+ mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX();
+ mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY();
+ mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX();
+ mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY();
+ mat_data["SpecRot"] = material_ptr->getSpecularRotation();
+
+ mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue();
+ mat_data["SpecExp"] = material_ptr->getSpecularLightExponent();
+ mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity();
+ mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff();
+ mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode();
+
+ // Replace no-copy textures, destination texture will get used instead if available
+ if (mat_data.has("NormMap"))
+ {
+ LLUUID id = mat_data["NormMap"].asUUID();
+ if (id.notNull() && !get_can_copy_texture(id))
+ {
+ mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["NormMapNoCopy"] = true;
+ }
+
+ }
+ if (mat_data.has("SpecMap"))
+ {
+ LLUUID id = mat_data["SpecMap"].asUUID();
+ if (id.notNull() && !get_can_copy_texture(id))
+ {
+ mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["SpecMapNoCopy"] = true;
+ }
+
+ }
+
+ te_data["material"] = mat_data;
+ }
+
+ mClipboardParams["texture"].append(te_data);
+ }
+ }
+ }
}
+void LLPanelFace::onPasteTexture()
+{
+ if (!mClipboardParams.has("texture"))
+ {
+ return;
+ }
+
+ LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ if (!objectp || !node
+ || objectp->getPCode() != LL_PCODE_VOLUME
+ || !objectp->permModify()
+ || objectp->isPermanentEnforced()
+ || selected_count > 1)
+ {
+ // not supposed to happen
+ LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL;
+ return;
+ }
+
+ bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
+ LLSD &clipboard = mClipboardParams["texture"]; // array
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ S32 compare_tes = num_tes;
+
+ if (face_selection_mode)
+ {
+ compare_tes = 0;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ compare_tes++;
+ }
+ }
+ }
+
+ // we can copy if single face was copied in edit face mode or if face count matches
+ if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ && compare_tes != clipboard.size())
+ {
+ LLSD notif_args;
+ if (face_selection_mode)
+ {
+ static std::string reason = getString("paste_error_face_selection_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ else
+ {
+ static std::string reason = getString("paste_error_object_face_count_mismatch");
+ notif_args["REASON"] = reason;
+ }
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+
+ bool full_perm_object = true;
+ LLSD::array_const_iterator iter = clipboard.beginArray();
+ LLSD::array_const_iterator end = clipboard.endArray();
+ for (; iter != end; ++iter)
+ {
+ const LLSD& te_data = *iter;
+ if (te_data.has("te") && te_data["te"].has("imageid"))
+ {
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
+ full_perm_object &= full_perm;
+ if (!full_perm)
+ {
+ if (te_data["te"].has("imageitemid"))
+ {
+ LLUUID item_id = te_data["te"]["imageitemid"].asUUID();
+ if (item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (!itemp)
+ {
+ // image might be in object's inventory, but it can be not up to date
+ LLSD notif_args;
+ static std::string reason = getString("paste_error_inventory_not_found");
+ notif_args["REASON"] = reason;
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+ }
+ }
+ else
+ {
+ // Item was not found on 'copy' stage
+ // Since this happened at copy, might be better to either show this
+ // at copy stage or to drop clipboard here
+ LLSD notif_args;
+ static std::string reason = getString("paste_error_inventory_not_found");
+ notif_args["REASON"] = reason;
+ LLNotificationsUtil::add("FacePasteFailed", notif_args);
+ return;
+ }
+ }
+ }
+ }
+
+ if (!full_perm_object)
+ {
+ LLNotificationsUtil::add("FacePasteTexturePermissions");
+ }
+
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+
+ LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE);
+ selected_objects->applyToTEs(&paste_func);
+
+ LLPanelFaceUpdateFunctor sendfunc(true);
+ selected_objects->applyToObjects(&sendfunc);
+
+ LLPanelFaceNavigateHomeFunctor navigate_home_func;
+ selected_objects->applyToTEs(&navigate_home_func);
+}
+
+void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
+{
+ LLSD te_data;
+ LLSD &clipboard = mClipboardParams["texture"]; // array
+ if ((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean())
+ {
+ te_data = *(clipboard.beginArray());
+ }
+ else if (clipboard[te])
+ {
+ te_data = clipboard[te];
+ }
+ else
+ {
+ return;
+ }
+
+ LLTextureEntry* tep = objectp->getTE(te);
+ if (tep)
+ {
+ if (te_data.has("te"))
+ {
+ // Texture
+ bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean();
+ bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean();
+ if (te_data["te"].has("imageid"))
+ {
+ const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id
+ LLViewerInventoryItem* itemp_res = NULL;
+
+ if (te_data["te"].has("imageitemid"))
+ {
+ LLUUID item_id = te_data["te"]["imageitemid"].asUUID();
+ if (item_id.notNull())
+ {
+ LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
+ if (itemp && itemp->isFinished())
+ {
+ // dropTextureAllFaces will fail if incomplete
+ itemp_res = itemp;
+ }
+ else
+ {
+ // Theoretically shouldn't happend, but if it does happen, we
+ // might need to add a notification to user that paste will fail
+ // since inventory isn't fully loaded
+ LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL;
+ }
+ }
+ }
+ // for case when item got removed from inventory after we pressed 'copy'
+ // or texture got pasted into previous object
+ if (!itemp_res && !full_perm)
+ {
+ // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable.
+ LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL;
+ // Todo: fix this, we are often searching same texture multiple times (equal to number of faces)
+ // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(imageid);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ // Extremely unreliable and perfomance unfriendly.
+ // But we need this to check permissions and it is how texture control finds items
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp && itemp->isFinished())
+ {
+ // dropTextureAllFaces will fail if incomplete
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ itemp_res = itemp;
+ break; // first match
+ }
+ }
+ }
+ }
+
+ if (itemp_res)
+ {
+ if (te == -1) // all faces
+ {
+ LLToolDragAndDrop::dropTextureAllFaces(objectp,
+ itemp_res,
+ from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null);
+ }
+ else // one face
+ {
+ LLToolDragAndDrop::dropTextureOneFace(objectp,
+ te,
+ itemp_res,
+ from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null,
+ 0);
+ }
+ }
+ // not an inventory item or no complete items
+ else if (full_perm)
+ {
+ // Either library, local or existed as fullperm when user made a copy
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ objectp->setTEImage(U8(te), image);
+ }
+ }
+
+ if (te_data["te"].has("bumpmap"))
+ {
+ objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger());
+ }
+ if (te_data["te"].has("bumpshiny"))
+ {
+ objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger());
+ }
+ if (te_data["te"].has("bumpfullbright"))
+ {
+ objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger());
+ }
+
+ // Texture map
+ if (te_data["te"].has("scales") && te_data["te"].has("scalet"))
+ {
+ objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal());
+ }
+ if (te_data["te"].has("offsets") && te_data["te"].has("offsett"))
+ {
+ objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal());
+ }
+ if (te_data["te"].has("imagerot"))
+ {
+ objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal());
+ }
+
+ // Media
+ if (te_data["te"].has("media_flags"))
+ {
+ U8 media_flags = te_data["te"]["media_flags"].asInteger();
+ objectp->setTEMediaFlags(te, media_flags);
+ LLVOVolume *vo = dynamic_cast<LLVOVolume*>(objectp);
+ if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY))
+ {
+ vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/);
+ }
+ }
+ else
+ {
+ // Keep media flags on destination unchanged
+ }
+ }
+
+ if (te_data.has("material"))
+ {
+ LLUUID object_id = objectp->getID();
+
+ LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+
+ // Normal
+ // Replace placeholders with target's
+ if (te_data["material"].has("NormMapNoCopy"))
+ {
+ LLMaterialPtr material = tep->getMaterialParams();
+ if (material.notNull())
+ {
+ LLUUID id = material->getNormalID();
+ if (id.notNull())
+ {
+ te_data["material"]["NormMap"] = id;
+ }
+ }
+ }
+ LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id);
+ LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id);
+
+ // Specular
+ // Replace placeholders with target's
+ if (te_data["material"].has("SpecMapNoCopy"))
+ {
+ LLMaterialPtr material = tep->getMaterialParams();
+ if (material.notNull())
+ {
+ LLUUID id = material->getSpecularID();
+ if (id.notNull())
+ {
+ te_data["material"]["SpecMap"] = id;
+ }
+ }
+ }
+ LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id);
+ LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id);
+ LLColor4 spec_color(te_data["material"]["SpecColor"]);
+ LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te);
+ LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id);
+ LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id);
+ if (te_data.has("te") && te_data["te"].has("shiny"))
+ {
+ objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger());
+ }
+ }
+ }
+}
+
+void LLPanelFace::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "color_paste")
+ {
+ onPasteColor();
+ }
+ else if (command == "texture_paste")
+ {
+ onPasteTexture();
+ }
+ // copy
+ else if (command == "color_copy")
+ {
+ onCopyColor();
+ }
+ else if (command == "texture_copy")
+ {
+ onCopyTexture();
+ }
+}
+
+bool LLPanelFace::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "color_paste")
+ {
+ return mClipboardParams.has("color");
+ }
+ else if (command == "texture_paste")
+ {
+ return mClipboardParams.has("texture");
+ }
+ return false;
+}
+
+
// static
void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
{
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 2d57d89a44..44bc442bbb 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -47,6 +47,8 @@ class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLMaterialID;
+class LLMediaCtrl;
+class LLMenuButton;
// Represents an edit for use in replicating the op across one or more materials in the selection set.
//
@@ -97,8 +99,10 @@ public:
virtual ~LLPanelFace();
void refresh();
- void setMediaURL(const std::string& url);
- void setMediaType(const std::string& mime_type);
+ void refreshMedia();
+ void unloadMedia();
+
+ /*virtual*/ void draw();
LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
{
@@ -114,6 +118,12 @@ public:
LLRender::eTexIndex getTextureChannelToEdit();
protected:
+ void navigateToTitleMedia(const std::string url);
+ bool selectedMediaEditable();
+ void clearMediaSettings();
+ void updateMediaSettings();
+ void updateMediaTitle();
+
void getState();
void sendTexture(); // applies and sends texture
@@ -128,6 +138,8 @@ protected:
void sendMedia();
void alignTestureLayer();
+ void updateCopyTexButton();
+
// this function is to return TRUE if the drag should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
@@ -150,6 +162,9 @@ protected:
void onCloseTexturePicker(const LLSD& data);
+ static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
+ static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
+
// Make UI reflect state of currently selected material (refresh)
// and UI mode (e.g. editing normal map v diffuse map)
//
@@ -194,6 +209,9 @@ protected:
static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
+ static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
static void onCommitBump( LLUICtrl* ctrl, void* userdata);
static void onCommitTexGen( LLUICtrl* ctrl, void* userdata);
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
@@ -205,6 +223,18 @@ protected:
static void onClickAutoFix(void*);
static void onAlignTexture(void*);
+public: // needs to be accessible to selection manager
+ void onCopyColor(); // records all selected faces
+ void onPasteColor(); // to specific face
+ void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face
+ void onCopyTexture();
+ void onPasteTexture();
+ void onPasteTexture(LLViewerObject* objectp, S32 te);
+
+protected:
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
+
static F32 valueGlow(LLViewerObject* object, S32 face);
@@ -234,6 +264,10 @@ private:
F32 getCurrentShinyOffsetU();
F32 getCurrentShinyOffsetV();
+ LLComboBox *mComboMatMedia;
+ LLMediaCtrl *mTitleMedia;
+ LLTextBox *mTitleMediaText;
+
// Update visibility of controls to match current UI mode
// (e.g. materials vs media editing)
//
@@ -241,10 +275,6 @@ private:
//
void updateVisibility();
- // Make material(s) reflect current state of UI (apply edit)
- //
- void updateMaterial();
-
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@@ -400,7 +430,10 @@ private:
* If agent selects texture which is not allowed to be applied for the currently selected object,
* all controls of the floater texture picker which allow to apply the texture will be disabled.
*/
- void onTextureSelectionChanged(LLInventoryItem* itemp);
+ void onTextureSelectionChanged(LLInventoryItem* itemp);
+
+ LLMenuButton* mMenuClipboardColor;
+ LLMenuButton* mMenuClipboardTexture;
bool mIsAlpha;
@@ -415,7 +448,12 @@ private:
* up-arrow on a spinner, and avoids running afoul of its throttle.
*/
bool mUpdateInFlight;
- bool mUpdatePending;
+ bool mUpdatePending;
+
+ LLSD mClipboardParams;
+
+ LLSD mMediaSettings;
+ bool mNeedMediaTitle;
public:
#if defined(DEF_GET_MAT_STATE)
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index 389baa86cd..07a8641a92 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,6 +1,6 @@
/**
- * @file llpanelavatar.cpp
- * @brief LLPanelAvatar and related class implementations
+ * @file llpanelimcontrolpanel.cpp
+ * @brief LLPanelIMControlPanel and related class implementations
*
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
* Second Life Viewer Source Code
diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp
index e7bdc51b4a..9e3fc54477 100644
--- a/indra/newview/llpanellandaudio.cpp
+++ b/indra/newview/llpanellandaudio.cpp
@@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild()
mCheckAVSoundGroup = getChild<LLCheckBoxCtrl>("group av sound check");
childSetCommitCallback("group av sound check", onCommitAny, this);
+ mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("obscure_moap");
+ childSetCommitCallback("obscure_moap", onCommitAny, this);
+
return TRUE;
}
@@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh()
mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on
mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off
+
+ mCheckObscureMOAP->set(parcel->getObscureMOAP());
+ mCheckObscureMOAP->setEnabled(can_change_media);
}
}
// static
@@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
group_av_sound = self->mCheckAVSoundGroup->get();
}
+ bool obscure_moap = self->mCheckObscureMOAP->get();
+
// Remove leading/trailing whitespace (common when copying/pasting)
LLStringUtil::trim(music_url);
@@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata)
parcel->setMusicURL(music_url);
parcel->setAllowAnyAVSounds(any_av_sound);
parcel->setAllowGroupAVSounds(group_av_sound);
+ parcel->setObscureMOAP(obscure_moap);
// Send current parcel data upstream to server
LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h
index 7e4fce80e4..b54fe62179 100644
--- a/indra/newview/llpanellandaudio.h
+++ b/indra/newview/llpanellandaudio.h
@@ -53,6 +53,7 @@ private:
LLLineEditor* mMusicURLEdit;
LLCheckBoxCtrl* mCheckAVSoundAny;
LLCheckBoxCtrl* mCheckAVSoundGroup;
+ LLCheckBoxCtrl* mCheckObscureMOAP;
LLSafeHandle<LLParcelSelection>& mParcel;
};
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ce17da3076..c3334605ae 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -29,6 +29,7 @@
#include "llpanellandmarks.h"
#include "llbutton.h"
+#include "llfloaterprofile.h"
#include "llfloaterreg.h"
#include "llnotificationsutil.h"
#include "llsdutil.h"
@@ -1003,17 +1004,6 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
return can_be_modified;
}
-void LLLandmarksPanel::onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params)
-{
- pick_panel->setVisible(FALSE);
- owner->removeChild(pick_panel);
- //we need remove observer to avoid processParcelInfo in the future.
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(params["parcel_id"].asUUID(), this);
-
- delete pick_panel;
- pick_panel = NULL;
-}
-
bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data , EAcceptance* accept)
{
*accept = ACCEPT_NO;
@@ -1080,49 +1070,21 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
LLInventoryItem* inv_item,
const LLParcelData& parcel_data)
{
- LLPanelPickEdit* panel_pick = LLPanelPickEdit::create();
LLVector3d landmark_global_pos;
landmark->getGlobalPos(landmark_global_pos);
- // let's toggle pick panel into panel places
- LLPanel* panel_places = NULL;
- LLFloaterSidePanelContainer* floaterp = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("places");
- if (floaterp)
- {
- panel_places = floaterp->findChild<LLPanel>("main_panel");
- }
-
- if (!panel_places)
- {
- llassert(NULL != panel_places);
- return;
- }
- panel_places->addChild(panel_pick);
- LLRect paren_rect(panel_places->getRect());
- panel_pick->reshape(paren_rect.getWidth(),paren_rect.getHeight(), TRUE);
- panel_pick->setRect(paren_rect);
- panel_pick->onOpen(LLSD());
-
LLPickData data;
data.pos_global = landmark_global_pos;
data.name = inv_item->getName();
data.desc = inv_item->getDescription();
data.snapshot_id = parcel_data.snapshot_id;
data.parcel_id = parcel_data.parcel_id;
- panel_pick->setPickData(&data);
-
- LLSD params;
- params["parcel_id"] = parcel_data.parcel_id;
- /* set exit callback to get back onto panel places
- in callback we will make cleaning up( delete pick_panel instance,
- remove landmark panel from observer list
- */
- panel_pick->setExitCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setSaveCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
- panel_pick->setCancelCallback(boost::bind(&LLLandmarksPanel::onPickPanelExit,this,
- panel_pick, panel_places,params));
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index d7408269b5..16f3a5dc24 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -34,7 +34,6 @@
#include "llinventorymodel.h"
#include "lllandmarklist.h"
#include "llpanelplacestab.h"
-#include "llpanelpick.h"
#include "llremoteparcelrequest.h"
class LLAccordionCtrlTab;
@@ -136,7 +135,6 @@ private:
* For now it checks cut/rename/delete/paste actions.
*/
bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
- void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
/**
* Landmark actions callbacks. Fire when a landmark is loaded from the list.
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
deleted file mode 100644
index 55e4ffff5e..0000000000
--- a/indra/newview/llpanelme.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file llpanelme.cpp
- * @brief Side tray "Me" (My Profile) panel
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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 "llpanelme.h"
-
-// Viewer includes
-#include "llpanelprofile.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "llfirstuse.h"
-#include "llfloaterreg.h"
-#include "llhints.h"
-#include "llviewercontrol.h"
-
-// Linden libraries
-#include "llavatarnamecache.h" // IDEVO
-#include "lliconctrl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h" // IDEVO
-#include "lltabcontainer.h"
-#include "lltexturectrl.h"
-
-static LLPanelInjector<LLPanelMe> t_panel_me_profile("panel_me");
-
-LLPanelMe::LLPanelMe(void)
- : LLPanelProfile()
-{
- setAvatarId(gAgent.getID());
-}
-
-BOOL LLPanelMe::postBuild()
-{
- LLPanelProfile::postBuild();
-
- return TRUE;
-}
-
-void LLPanelMe::onOpen(const LLSD& key)
-{
- LLPanelProfile::onOpen(key);
-}
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 9730f0f16d..e1818cc68b 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild()
childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this);
- // interrogates controls and updates widgets as required
- updateMediaPreview();
-
return true;
}
@@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
-
- // interrogates controls and updates widgets as required
- self->updateMediaPreview();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 64f1fc9b90..0bfc1297d3 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -46,6 +46,7 @@
#include "llcombobox.h"
#include "llfocusmgr.h"
#include "llmanipscale.h"
+#include "llmenubutton.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -117,8 +118,9 @@ BOOL LLPanelObject::postBuild()
// Phantom checkbox
mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl");
childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this);
-
+
// Position
+ mMenuClipboardPos = getChild<LLMenuButton>("clipboard_pos_btn");
mLabelPosition = getChild<LLTextBox>("label position");
mCtrlPosX = getChild<LLSpinCtrl>("Pos X");
childSetCommitCallback("Pos X",onCommitPosition,this);
@@ -128,6 +130,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Pos Z",onCommitPosition,this);
// Scale
+ mMenuClipboardSize = getChild<LLMenuButton>("clipboard_size_btn");
mLabelSize = getChild<LLTextBox>("label size");
mCtrlScaleX = getChild<LLSpinCtrl>("Scale X");
childSetCommitCallback("Scale X",onCommitScale,this);
@@ -141,6 +144,7 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Scale Z",onCommitScale,this);
// Rotation
+ mMenuClipboardRot = getChild<LLMenuButton>("clipboard_rot_btn");
mLabelRotation = getChild<LLTextBox>("label rotation");
mCtrlRotX = getChild<LLSpinCtrl>("Rot X");
childSetCommitCallback("Rot X",onCommitRotation,this);
@@ -155,6 +159,8 @@ BOOL LLPanelObject::postBuild()
mComboBaseType = getChild<LLComboBox>("comboBaseType");
childSetCommitCallback("comboBaseType",onCommitParametric,this);
+ mMenuClipboardParams = getChild<LLMenuButton>("clipboard_obj_params_btn");
+
// Cut
mLabelCut = getChild<LLTextBox>("text cut");
mSpinCutBegin = getChild<LLSpinCtrl>("cut begin");
@@ -285,8 +291,13 @@ LLPanelObject::LLPanelObject()
mSelectedType(MI_BOX),
mSculptTextureRevert(LLUUID::null),
mSculptTypeRevert(0),
+ mHasClipboardPos(false),
+ mHasClipboardSize(false),
+ mHasClipboardRot(false),
mSizeChanged(FALSE)
{
+ mCommitCallbackRegistrar.add("PanelObject.menuDoToSelected", boost::bind(&LLPanelObject::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelObject.menuEnable", boost::bind(&LLPanelObject::menuEnableItem, this, _2));
}
@@ -373,7 +384,7 @@ void LLPanelObject::getState( )
calcp->clearVar(LLCalc::Z_POS);
}
-
+ mMenuClipboardPos->setEnabled(enable_move);
mLabelPosition->setEnabled( enable_move );
mCtrlPosX->setEnabled(enable_move);
mCtrlPosY->setEnabled(enable_move);
@@ -399,6 +410,7 @@ void LLPanelObject::getState( )
calcp->setVar(LLCalc::Z_SCALE, 0.f);
}
+ mMenuClipboardSize->setEnabled(enable_scale);
mLabelSize->setEnabled( enable_scale );
mCtrlScaleX->setEnabled( enable_scale );
mCtrlScaleY->setEnabled( enable_scale );
@@ -430,6 +442,7 @@ void LLPanelObject::getState( )
calcp->clearVar(LLCalc::Z_ROT);
}
+ mMenuClipboardRot->setEnabled(enable_rotate);
mLabelRotation->setEnabled( enable_rotate );
mCtrlRotX->setEnabled( enable_rotate );
mCtrlRotY->setEnabled( enable_rotate );
@@ -607,7 +620,7 @@ void LLPanelObject::getState( )
}
else
{
- LL_INFOS() << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL;
selected_item = MI_BOX;
}
@@ -933,6 +946,7 @@ void LLPanelObject::getState( )
// Update field enablement
mComboBaseType ->setEnabled( enabled );
+ mMenuClipboardParams->setEnabled(enabled);
mLabelCut ->setEnabled( enabled );
mSpinCutBegin ->setEnabled( enabled );
@@ -1093,7 +1107,8 @@ void LLPanelObject::getState( )
}
mComboBaseType->setEnabled(!isMesh);
-
+ mMenuClipboardParams->setEnabled(!isMesh);
+
if (mCtrlSculptType)
{
if (sculpt_stitching == LL_SCULPT_TYPE_NONE)
@@ -1157,11 +1172,11 @@ void LLPanelObject::sendIsPhysical()
LLSelectMgr::getInstance()->selectionUpdatePhysics(value);
mIsPhysical = value;
- LL_INFOS() << "update physics sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update physics not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update physics not changed" << LL_ENDL;
}
}
@@ -1173,11 +1188,11 @@ void LLPanelObject::sendIsTemporary()
LLSelectMgr::getInstance()->selectionUpdateTemporary(value);
mIsTemporary = value;
- LL_INFOS() << "update temporary sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update temporary not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update temporary not changed" << LL_ENDL;
}
}
@@ -1190,11 +1205,11 @@ void LLPanelObject::sendIsPhantom()
LLSelectMgr::getInstance()->selectionUpdatePhantom(value);
mIsPhantom = value;
- LL_INFOS() << "update phantom sent" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom sent" << LL_ENDL;
}
else
{
- LL_INFOS() << "update phantom not changed" << LL_ENDL;
+ LL_INFOS("FloaterTools") << "update phantom not changed" << LL_ENDL;
}
}
@@ -1304,7 +1319,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
break;
default:
- LL_WARNS() << "Unknown base type " << selected_type
+ LL_WARNS("FloaterTools") << "Unknown base type " << selected_type
<< " in getVolumeParams()" << LL_ENDL;
// assume a box
selected_type = MI_BOX;
@@ -1644,13 +1659,15 @@ void LLPanelObject::sendPosition(BOOL btn_down)
LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
LLViewerRegion* regionp = mObject->getRegion();
- // Clamp the Z height
- const F32 height = newpos.mV[VZ];
- const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
- const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+ if (!regionp) return;
if (!mObject->isAttachment())
{
+ // Clamp the Z height
+ const F32 height = newpos.mV[VZ];
+ const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
+ const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
+
if ( height < min_height)
{
newpos.mV[VZ] = min_height;
@@ -2011,3 +2028,283 @@ void LLPanelObject::onCommitSculptType(LLUICtrl *ctrl, void* userdata)
self->sendSculpt();
}
+
+void LLPanelObject::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "psr_paste")
+ {
+ onPastePos();
+ onPasteSize();
+ onPasteRot();
+ }
+ else if (command == "pos_paste")
+ {
+ onPastePos();
+ }
+ else if (command == "size_paste")
+ {
+ onPasteSize();
+ }
+ else if (command == "rot_paste")
+ {
+ onPasteRot();
+ }
+ else if (command == "params_paste")
+ {
+ onPasteParams();
+ }
+ // copy
+ else if (command == "psr_copy")
+ {
+ onCopyPos();
+ onCopySize();
+ onCopyRot();
+ }
+ else if (command == "pos_copy")
+ {
+ onCopyPos();
+ }
+ else if (command == "size_copy")
+ {
+ onCopySize();
+ }
+ else if (command == "rot_copy")
+ {
+ onCopyRot();
+ }
+ else if (command == "params_copy")
+ {
+ onCopyParams();
+ }
+}
+
+bool LLPanelObject::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "psr_paste")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ return enable_move && enable_modify && mHasClipboardPos && mHasClipboardSize && mHasClipboardRot;
+ }
+ else if (command == "pos_paste")
+ {
+ // assumes that menu won't be active if there is no move permission
+ return mHasClipboardPos;
+ }
+ else if (command == "size_paste")
+ {
+ return mHasClipboardSize;
+ }
+ else if (command == "rot_paste")
+ {
+ return mHasClipboardRot;
+ }
+ else if (command == "params_paste")
+ {
+ return mClipboardParams.isMap() && !mClipboardParams.emptyMap();
+ }
+ // copy options
+ else if (command == "psr_copy")
+ {
+ S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
+ BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME))
+ && (selected_count == 1);
+
+ if (!single_volume)
+ {
+ return false;
+ }
+
+ bool enable_move;
+ bool enable_modify;
+
+ LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify);
+
+ // since we forbid seeing values we also should forbid copying them
+ return enable_move && enable_modify;
+ }
+ return false;
+}
+
+void LLPanelObject::onCopyPos()
+{
+ mClipboardPos = LLVector3(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardPos = true;
+}
+
+void LLPanelObject::onCopySize()
+{
+ mClipboardSize = LLVector3(mCtrlScaleX->get(), mCtrlScaleY->get(), mCtrlScaleZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardSize = true;
+}
+
+void LLPanelObject::onCopyRot()
+{
+ mClipboardRot = LLVector3(mCtrlRotX->get(), mCtrlRotY->get(), mCtrlRotZ->get());
+
+ std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]);
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec));
+
+ mHasClipboardRot = true;
+}
+
+void LLPanelObject::onPastePos()
+{
+ if (!mHasClipboardPos) return;
+ if (mObject.isNull()) return;
+
+ LLViewerRegion* regionp = mObject->getRegion();
+ if (!regionp) return;
+
+
+ // Clamp pos on non-attachments, just keep the prims within the region
+ if (!mObject->isAttachment())
+ {
+ F32 max_width = regionp->getWidth(); // meters
+ mClipboardPos.mV[VX] = llclamp(mClipboardPos.mV[VX], 0.f, max_width);
+ mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width);
+ //height will get properly clamped by sendPosition
+ }
+
+ mCtrlPosX->set( mClipboardPos.mV[VX] );
+ mCtrlPosY->set( mClipboardPos.mV[VY] );
+ mCtrlPosZ->set( mClipboardPos.mV[VZ] );
+
+ sendPosition(FALSE);
+}
+
+void LLPanelObject::onPasteSize()
+{
+ if (!mHasClipboardSize) return;
+
+ mClipboardSize.mV[VX] = llclamp(mClipboardSize.mV[VX], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VY] = llclamp(mClipboardSize.mV[VY], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+ mClipboardSize.mV[VZ] = llclamp(mClipboardSize.mV[VZ], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE);
+
+ mCtrlScaleX->set(mClipboardSize.mV[VX]);
+ mCtrlScaleY->set(mClipboardSize.mV[VY]);
+ mCtrlScaleZ->set(mClipboardSize.mV[VZ]);
+
+ sendScale(FALSE);
+}
+
+void LLPanelObject::onPasteRot()
+{
+ if (!mHasClipboardRot) return;
+
+ mCtrlRotX->set(mClipboardRot.mV[VX]);
+ mCtrlRotY->set(mClipboardRot.mV[VY]);
+ mCtrlRotZ->set(mClipboardRot.mV[VZ]);
+
+ sendRotation(FALSE);
+}
+
+void LLPanelObject::onCopyParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || objectp->isMesh())
+ {
+ return;
+ }
+
+ mClipboardParams.clear();
+
+ // Parametrics
+ LLVolumeParams params;
+ getVolumeParams(params);
+ mClipboardParams["volume_params"] = params.asLLSD();
+
+ // Sculpted Prim
+ if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+
+ LLUUID texture_id = sculpt_params->getSculptTexture();
+ if (get_can_copy_texture(texture_id))
+ {
+ LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
+ mClipboardParams["sculpt"]["id"] = texture_id;
+ }
+ else
+ {
+ mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE);
+ }
+
+ mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
+ }
+}
+
+void LLPanelObject::onPasteParams()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ // Sculpted Prim
+ if (mClipboardParams.has("sculpt"))
+ {
+ LLSculptParams sculpt_params;
+ LLUUID sculpt_id = mClipboardParams["sculpt"]["id"].asUUID();
+ U8 sculpt_type = (U8)mClipboardParams["sculpt"]["type"].asInteger();
+ sculpt_params.setSculptTexture(sculpt_id, sculpt_type);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+ }
+ else
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ if (sculpt_params)
+ {
+ objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
+ }
+ }
+
+ // volume params
+ // make sure updateVolume() won't affect flexible
+ if (mClipboardParams.has("volume_params"))
+ {
+ LLVolumeParams params;
+ params.fromLLSD(mClipboardParams["volume_params"]);
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->isFlexible())
+ {
+ if (params.getPathParams().getCurveType() == LL_PCODE_PATH_LINE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE);
+ }
+ }
+ else if (params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
+ {
+ params.getPathParams().setCurveType(LL_PCODE_PATH_LINE);
+ }
+
+ objectp->updateVolume(params);
+ }
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 8829f493fa..515dd27c0a 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -37,6 +37,7 @@ class LLCheckBoxCtrl;
class LLTextBox;
class LLUICtrl;
class LLButton;
+class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
@@ -66,6 +67,14 @@ public:
static void onCommitPhantom( LLUICtrl* ctrl, void* userdata);
static void onCommitPhysics( LLUICtrl* ctrl, void* userdata);
+ void onCopyPos();
+ void onPastePos();
+ void onCopySize();
+ void onPasteSize();
+ void onCopyRot();
+ void onPasteRot();
+ void onCopyParams();
+ void onPasteParams();
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
@@ -75,6 +84,9 @@ public:
BOOL onDropSculpt(LLInventoryItem* item);
static void onCommitSculptType( LLUICtrl *ctrl, void* userdata);
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
+
protected:
void getState();
@@ -92,6 +104,7 @@ protected:
protected:
// Per-object options
LLComboBox* mComboBaseType;
+ LLMenuButton* mMenuClipboardParams;
LLTextBox* mLabelCut;
LLSpinCtrl* mSpinCutBegin;
@@ -131,17 +144,20 @@ protected:
LLTextBox* mLabelRevolutions;
LLSpinCtrl* mSpinRevolutions;
+ LLMenuButton* mMenuClipboardPos;
LLTextBox* mLabelPosition;
LLSpinCtrl* mCtrlPosX;
LLSpinCtrl* mCtrlPosY;
LLSpinCtrl* mCtrlPosZ;
+ LLMenuButton* mMenuClipboardSize;
LLTextBox* mLabelSize;
LLSpinCtrl* mCtrlScaleX;
LLSpinCtrl* mCtrlScaleY;
LLSpinCtrl* mCtrlScaleZ;
BOOL mSizeChanged;
+ LLMenuButton* mMenuClipboardRot;
LLTextBox* mLabelRotation;
LLSpinCtrl* mCtrlRotX;
LLSpinCtrl* mCtrlRotY;
@@ -157,7 +173,7 @@ protected:
LLComboBox *mCtrlSculptType;
LLCheckBoxCtrl *mCtrlSculptMirror;
LLCheckBoxCtrl *mCtrlSculptInvert;
-
+
LLVector3 mCurEulerDegrees; // to avoid sending rotation when not changed
BOOL mIsPhysical; // to avoid sending "physical" when not changed
BOOL mIsTemporary; // to avoid sending "temporary" when not changed
@@ -167,6 +183,15 @@ protected:
LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel
U8 mSculptTypeRevert; // so we can revert the sculpt type on cancel
+ LLVector3 mClipboardPos;
+ LLVector3 mClipboardSize;
+ LLVector3 mClipboardRot;
+ LLSD mClipboardParams;
+
+ bool mHasClipboardPos;
+ bool mHasClipboardSize;
+ bool mHasClipboardRot;
+
LLPointer<LLViewerObject> mObject;
LLPointer<LLViewerObject> mRootObject;
};
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 0d987df6ca..cfaa9456be 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -618,7 +618,18 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
if (cat)
{
- mDisplayName.assign(cat->getName());
+ std::string name = cat->getName();
+ if (mChildren.size() > 0)
+ {
+ // Add item count
+ // Normally we would be using getLabelSuffix for this
+ // but object's inventory just uses displaynames
+ LLStringUtil::format_map_t args;
+ args["[ITEMS_COUNT]"] = llformat("%d", mChildren.size());
+
+ name.append(" " + LLTrans::getString("InventoryItemsCount", args));
+ }
+ mDisplayName.assign(name);
}
return mDisplayName;
@@ -1522,6 +1533,8 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
{
createViewsForCategory(&contents, inventory_root, new_folder);
}
+ // Refresh for label to add item count
+ new_folder->refresh();
}
}
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
deleted file mode 100644
index 40326cfb39..0000000000
--- a/indra/newview/llpanelpick.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/**
- * @file llpanelpick.cpp
- * @brief LLPanelPick class implementation
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelpick.h"
-
-#include "message.h"
-
-#include "llparcel.h"
-
-#include "llbutton.h"
-#include "llfloaterreg.h"
-#include "lliconctrl.h"
-#include "lllineeditor.h"
-#include "llpanel.h"
-#include "llscrollcontainer.h"
-#include "lltexteditor.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloaterworldmap.h"
-#include "lltexturectrl.h"
-#include "lluiconstants.h"
-#include "llviewerparcelmgr.h"
-#include "llviewerregion.h"
-#include "llworldmap.h"
-
-
-#define XML_PANEL_EDIT_PICK "panel_edit_pick.xml"
-#define XML_PANEL_PICK_INFO "panel_pick_info.xml"
-
-#define XML_NAME "pick_name"
-#define XML_DESC "pick_desc"
-#define XML_SNAPSHOT "pick_snapshot"
-#define XML_LOCATION "pick_location"
-
-#define XML_BTN_ON_TXTR "edit_icon"
-#define XML_BTN_SAVE "save_changes_btn"
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickInfo* LLPanelPickInfo::create()
-{
- LLPanelPickInfo* panel = new LLPanelPickInfo();
- panel->buildFromFile(XML_PANEL_PICK_INFO);
- return panel;
-}
-
-LLPanelPickInfo::LLPanelPickInfo()
- : LLPanel()
- , LLAvatarPropertiesObserver()
- , LLRemoteParcelInfoObserver()
- , mAvatarId(LLUUID::null)
- , mSnapshotCtrl(NULL)
- , mPickId(LLUUID::null)
- , mParcelId(LLUUID::null)
- , mRequestedId(LLUUID::null)
- , mScrollingPanelMinHeight(0)
- , mScrollingPanelWidth(0)
- , mScrollingPanel(NULL)
- , mScrollContainer(NULL)
-{
-}
-
-LLPanelPickInfo::~LLPanelPickInfo()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::onOpen(const LLSD& key)
-{
- LLUUID avatar_id = key["avatar_id"];
- if(avatar_id.isNull())
- {
- return;
- }
-
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(
- getAvatarId(), this);
- }
-
- setAvatarId(avatar_id);
-
- resetData();
- resetControls();
-
- setPickId(key["pick_id"]);
- setPickName(key["pick_name"]);
- setPickDesc(key["pick_desc"]);
- setSnapshotId(key["snapshot_id"]);
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(
- getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(
- getAvatarId(), getPickId());
-}
-
-BOOL LLPanelPickInfo::postBuild()
-{
- mSnapshotCtrl = getChild<LLTextureCtrl>(XML_SNAPSHOT);
-
- childSetAction("teleport_btn", boost::bind(&LLPanelPickInfo::onClickTeleport, this));
- childSetAction("show_on_map_btn", boost::bind(&LLPanelPickInfo::onClickMap, this));
- childSetAction("back_btn", boost::bind(&LLPanelPickInfo::onClickBack, this));
-
- mScrollingPanel = getChild<LLPanel>("scroll_content_panel");
- mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
-
- mScrollingPanelMinHeight = mScrollContainer->getScrolledViewRect().getHeight();
- mScrollingPanelWidth = mScrollingPanel->getRect().getWidth();
-
- LLTextEditor* text_desc = getChild<LLTextEditor>(XML_DESC);
- text_desc->setContentTrusted(false);
-
- return TRUE;
-}
-
-void LLPanelPickInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
-
- if (!mScrollContainer || !mScrollingPanel)
- return;
-
- static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
- S32 scroll_height = mScrollContainer->getRect().getHeight();
- if (mScrollingPanelMinHeight >= scroll_height)
- {
- mScrollingPanel->reshape(mScrollingPanelWidth, mScrollingPanelMinHeight);
- }
- else
- {
- mScrollingPanel->reshape(mScrollingPanelWidth + scrollbar_size, scroll_height);
- }
-}
-
-void LLPanelPickInfo::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICK_INFO != type)
- {
- return;
- }
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if(!pick_info
- || pick_info->creator_id != getAvatarId()
- || pick_info->pick_id != getPickId())
- {
- return;
- }
-
- mParcelId = pick_info->parcel_id;
- setSnapshotId(pick_info->snapshot_id);
- setPickName(pick_info->name);
- setPickDesc(pick_info->desc);
- setPosGlobal(pick_info->pos_global);
-
- // Send remote parcel info request to get parcel name and sim (region) name.
- sendParcelInfoRequest();
-
- // *NOTE dzaporozhan
- // We want to keep listening to APT_PICK_INFO because user may
- // edit the Pick and we have to update Pick info panel.
- // revomeObserver is called from onClickBack
-}
-
-void LLPanelPickInfo::sendParcelInfoRequest()
-{
- if (mParcelId != mRequestedId)
- {
- LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
- LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
-
- mRequestedId = mParcelId;
- }
-}
-
-void LLPanelPickInfo::setExitCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("back_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickInfo::processParcelInfo(const LLParcelData& parcel_data)
-{
- setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name,
- parcel_data.sim_name, getPosGlobal()));
-
- // We have received parcel info for the requested ID so clear it now.
- mRequestedId.setNull();
-
- if (mParcelId.notNull())
- {
- LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
- }
-}
-
-void LLPanelPickInfo::setEditPickCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("edit_btn")->setClickedCallback(cb);
-}
-
-// PROTECTED AREA
-
-void LLPanelPickInfo::resetControls()
-{
- if(getAvatarId() == gAgent.getID())
- {
- getChildView("edit_btn")->setEnabled(TRUE);
- getChildView("edit_btn")->setVisible( TRUE);
- }
- else
- {
- getChildView("edit_btn")->setEnabled(FALSE);
- getChildView("edit_btn")->setVisible( FALSE);
- }
-}
-
-void LLPanelPickInfo::resetData()
-{
- setPickName(LLStringUtil::null);
- setPickDesc(LLStringUtil::null);
- setPickLocation(LLStringUtil::null);
- setPickId(LLUUID::null);
- setSnapshotId(LLUUID::null);
- mPosGlobal.clearVec();
- mParcelId.setNull();
- mRequestedId.setNull();
-}
-
-// static
-std::string LLPanelPickInfo::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
-{
- std::string location_text;
- location_text.append(owner_name);
- if (!original_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(original_name);
-
- }
- if (!sim_name.empty())
- {
- if (!location_text.empty()) location_text.append(", ");
- location_text.append(sim_name);
- }
-
- if (!location_text.empty()) location_text.append(" ");
-
- if (!pos_global.isNull())
- {
- S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
- S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
- S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
- location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
- }
- return location_text;
-}
-
-void LLPanelPickInfo::setSnapshotId(const LLUUID& id)
-{
- mSnapshotCtrl->setImageAssetID(id);
- mSnapshotCtrl->setValid(TRUE);
-}
-
-void LLPanelPickInfo::setPickName(const std::string& name)
-{
- getChild<LLUICtrl>(XML_NAME)->setValue(name);
-}
-
-void LLPanelPickInfo::setPickDesc(const std::string& desc)
-{
- getChild<LLUICtrl>(XML_DESC)->setValue(desc);
-}
-
-void LLPanelPickInfo::setPickLocation(const std::string& location)
-{
- getChild<LLUICtrl>(XML_LOCATION)->setValue(location);
-}
-
-void LLPanelPickInfo::onClickMap()
-{
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-void LLPanelPickInfo::onClickTeleport()
-{
- if (!getPosGlobal().isExactlyZero())
- {
- gAgent.teleportViaLocation(getPosGlobal());
- LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
- }
-}
-
-void LLPanelPickInfo::onClickBack()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-//static
-LLPanelPickEdit* LLPanelPickEdit::create()
-{
- LLPanelPickEdit* panel = new LLPanelPickEdit();
- panel->buildFromFile(XML_PANEL_EDIT_PICK);
- return panel;
-}
-
-LLPanelPickEdit::LLPanelPickEdit()
- : LLPanelPickInfo()
- , mLocationChanged(false)
- , mNeedData(true)
- , mNewPick(false)
-{
-}
-
-LLPanelPickEdit::~LLPanelPickEdit()
-{
-}
-
-void LLPanelPickEdit::onOpen(const LLSD& key)
-{
- LLUUID pick_id = key["pick_id"];
- mNeedData = true;
-
- // creating new Pick
- if(pick_id.isNull())
- {
- mNewPick = true;
-
- setAvatarId(gAgent.getID());
-
- resetData();
- resetControls();
-
- setPosGlobal(gAgent.getPositionGlobal());
-
- LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
- std::string pick_name, pick_desc, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if(parcel)
- {
- parcel_id = parcel->getID();
- pick_name = parcel->getName();
- pick_desc = parcel->getDesc();
- snapshot_id = parcel->getSnapshotID();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setParcelID(parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_name.empty() ? region_name : pick_name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_desc);
- setSnapshotId(snapshot_id);
- setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
-
- enableSaveButton(true);
- }
- // editing existing pick
- else
- {
- mNewPick = false;
- LLPanelPickInfo::onOpen(key);
-
- enableSaveButton(false);
- }
-
- resetDirty();
-}
-
-void LLPanelPickEdit::setPickData(const LLPickData* pick_data)
-{
- if(!pick_data)
- {
- return;
- }
-
- mNeedData = false;
-
- setParcelID(pick_data->parcel_id);
- getChild<LLUICtrl>("pick_name")->setValue(pick_data->name);
- getChild<LLUICtrl>("pick_desc")->setValue(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- setPosGlobal(pick_data->pos_global);
- setPickLocation(createLocationText(LLStringUtil::null, pick_data->name,
- pick_data->sim_name, pick_data->pos_global));
-}
-
-BOOL LLPanelPickEdit::postBuild()
-{
- LLPanelPickInfo::postBuild();
-
- mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelPickEdit::onSnapshotChanged, this));
-
- LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
- line_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1), NULL);
-
- LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
- text_edit->setKeystrokeCallback(boost::bind(&LLPanelPickEdit::onPickChanged, this, _1));
-
- childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPickEdit::onClickSave, this));
- childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPickEdit::onClickSetLocation, this));
-
- initTexturePickerMouseEvents();
-
- return TRUE;
-}
-
-void LLPanelPickEdit::setSaveCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("save_changes_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::setCancelCallback(const commit_callback_t& cb)
-{
- getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
-}
-
-void LLPanelPickEdit::resetDirty()
-{
- LLPanelPickInfo::resetDirty();
-
- getChild<LLLineEditor>("pick_name")->resetDirty();
- getChild<LLTextEditor>("pick_desc")->resetDirty();
- mSnapshotCtrl->resetDirty();
- mLocationChanged = false;
-}
-
-BOOL LLPanelPickEdit::isDirty() const
-{
- if( mNewPick
- || LLPanelPickInfo::isDirty()
- || mLocationChanged
- || mSnapshotCtrl->isDirty()
- || getChild<LLLineEditor>("pick_name")->isDirty()
- || getChild<LLTextEditor>("pick_desc")->isDirty())
- {
- return TRUE;
- }
- return FALSE;
-}
-
-// PROTECTED AREA
-
-void LLPanelPickEdit::sendUpdate()
-{
- LLPickData pick_data;
-
- // If we don't have a pick id yet, we'll need to generate one,
- // otherwise we'll keep overwriting pick_id 00000 in the database.
- if (getPickId().isNull())
- {
- getPickId().generate();
- }
-
- pick_data.agent_id = gAgent.getID();
- pick_data.session_id = gAgent.getSessionID();
- pick_data.pick_id = getPickId();
- pick_data.creator_id = gAgent.getID();;
-
- //legacy var need to be deleted
- pick_data.top_pick = FALSE;
- pick_data.parcel_id = mParcelId;
- pick_data.name = getChild<LLUICtrl>(XML_NAME)->getValue().asString();
- pick_data.desc = getChild<LLUICtrl>(XML_DESC)->getValue().asString();
- pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
- pick_data.pos_global = getPosGlobal();
- pick_data.sort_order = 0;
- pick_data.enabled = TRUE;
-
- LLAvatarPropertiesProcessor::instance().sendPickInfoUpdate(&pick_data);
-
- if(mNewPick)
- {
- // Assume a successful create pick operation, make new number of picks
- // available immediately. Actual number of picks will be requested in
- // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
- LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
- }
-}
-
-void LLPanelPickEdit::onSnapshotChanged()
-{
- enableSaveButton(true);
-}
-
-void LLPanelPickEdit::onPickChanged(LLUICtrl* ctrl)
-{
- enableSaveButton(isDirty());
-}
-
-void LLPanelPickEdit::resetData()
-{
- LLPanelPickInfo::resetData();
- mLocationChanged = false;
-}
-
-void LLPanelPickEdit::enableSaveButton(bool enable)
-{
- getChildView(XML_BTN_SAVE)->setEnabled(enable);
-}
-
-void LLPanelPickEdit::onClickSetLocation()
-{
- // Save location for later use.
- setPosGlobal(gAgent.getPositionGlobal());
-
- std::string parcel_name, region_name;
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- mParcelId = parcel->getID();
- parcel_name = parcel->getName();
- }
-
- LLViewerRegion* region = gAgent.getRegion();
- if(region)
- {
- region_name = region->getName();
- }
-
- setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
-
- mLocationChanged = true;
- enableSaveButton(TRUE);
-}
-
-void LLPanelPickEdit::onClickSave()
-{
- sendUpdate();
-
- mLocationChanged = false;
-
- LLSD params;
- params["action"] = "save_new_pick";
- notifyParent(params);
-}
-
-std::string LLPanelPickEdit::getLocationNotice()
-{
- static std::string notice = getString("location_notice");
- return notice;
-}
-
-void LLPanelPickEdit::processProperties(void* data, EAvatarProcessorType type)
-{
- if(mNeedData)
- {
- LLPanelPickInfo::processProperties(data, type);
- }
-}
-
-// PRIVATE AREA
-
-void LLPanelPickEdit::initTexturePickerMouseEvents()
-{
- text_icon = getChild<LLIconCtrl>(XML_BTN_ON_TXTR);
- mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseEnter, this, _1));
- mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelPickEdit::onTexturePickerMouseLeave, this, _1));
-
- text_icon->setVisible(FALSE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseEnter(LLUICtrl* ctrl)
-{
- text_icon->setVisible(TRUE);
-}
-
-void LLPanelPickEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl)
-{
- text_icon->setVisible(FALSE);
-}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
deleted file mode 100644
index 7a8bd66fcf..0000000000
--- a/indra/newview/llpanelpick.h
+++ /dev/null
@@ -1,264 +0,0 @@
-/**
- * @file llpanelpick.h
- * @brief LLPanelPick class definition
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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$
- */
-
-// Display of a "Top Pick" used both for the global top picks in the
-// Find directory, and also for each individual user's picks in their
-// profile.
-
-#ifndef LL_LLPANELPICK_H
-#define LL_LLPANELPICK_H
-
-#include "llpanel.h"
-#include "llremoteparcelrequest.h"
-#include "llavatarpropertiesprocessor.h"
-
-class LLIconCtrl;
-class LLTextureCtrl;
-class LLScrollContainer;
-class LLMessageSystem;
-class LLAvatarPropertiesObserver;
-
-/**
- * Panel for displaying Pick Information - snapshot, name, description, etc.
- */
-class LLPanelPickInfo : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteParcelInfoObserver
-{
- LOG_CLASS(LLPanelPickInfo);
-public:
-
- // Creates new panel
- static LLPanelPickInfo* create();
-
- virtual ~LLPanelPickInfo();
-
- /**
- * Initializes panel properties
- *
- * By default Pick will be created for current Agent location.
- * Use setPickData to change Pick properties.
- */
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /**
- * Sends remote parcel info request to resolve parcel name from its ID.
- */
- void sendParcelInfoRequest();
-
- /**
- * Sets "Back" button click callback
- */
- virtual void setExitCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Edit" button click callback
- */
- virtual void setEditPickCallback(const commit_callback_t& cb);
-
- //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
- /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
- /*virtual*/ void setParcelID(const LLUUID& parcel_id) { mParcelId = parcel_id; }
- /*virtual*/ void setErrorStatus(S32 status, const std::string& reason) {};
-
-protected:
-
- LLPanelPickInfo();
-
- /**
- * Resets Pick information
- */
- virtual void resetData();
-
- /**
- * Resets UI controls (visibility, values)
- */
- virtual void resetControls();
-
- /**
- * "Location text" is actually the owner name, the original
- * name that owner gave the parcel, and the location.
- */
- static std::string createLocationText(
- const std::string& owner_name,
- const std::string& original_name,
- const std::string& sim_name,
- const LLVector3d& pos_global);
-
- virtual void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
- virtual LLUUID& getAvatarId() { return mAvatarId; }
-
- /**
- * Sets snapshot id.
- *
- * Will mark snapshot control as valid if id is not null.
- * Will mark snapshot control as invalid if id is null. If null id is a valid value,
- * you have to manually mark snapshot is valid.
- */
- virtual void setSnapshotId(const LLUUID& id);
-
- virtual void setPickId(const LLUUID& id) { mPickId = id; }
- virtual LLUUID& getPickId() { return mPickId; }
-
- virtual void setPickName(const std::string& name);
-
- virtual void setPickDesc(const std::string& desc);
-
- virtual void setPickLocation(const std::string& location);
-
- virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
- virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
-
- /**
- * Callback for "Map" button, opens Map
- */
- void onClickMap();
-
- /**
- * Callback for "Teleport" button, teleports user to Pick location.
- */
- void onClickTeleport();
-
- void onClickBack();
-
-protected:
-
- S32 mScrollingPanelMinHeight;
- S32 mScrollingPanelWidth;
- LLScrollContainer* mScrollContainer;
- LLPanel* mScrollingPanel;
- LLTextureCtrl* mSnapshotCtrl;
-
- LLUUID mAvatarId;
- LLVector3d mPosGlobal;
- LLUUID mParcelId;
- LLUUID mPickId;
- LLUUID mRequestedId;
-};
-
-/**
- * Panel for creating/editing Pick.
- */
-class LLPanelPickEdit : public LLPanelPickInfo
-{
- LOG_CLASS(LLPanelPickEdit);
-public:
-
- /**
- * Creates new panel
- */
- static LLPanelPickEdit* create();
-
- /*virtual*/ ~LLPanelPickEdit();
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- virtual void setPickData(const LLPickData* pick_data);
-
- /*virtual*/ BOOL postBuild();
-
- /**
- * Sets "Save" button click callback
- */
- virtual void setSaveCallback(const commit_callback_t& cb);
-
- /**
- * Sets "Cancel" button click callback
- */
- virtual void setCancelCallback(const commit_callback_t& cb);
-
- /**
- * Resets panel and all cantrols to unedited state
- */
- /*virtual*/ void resetDirty();
-
- /**
- * Returns true if any of Pick properties was changed by user.
- */
- /*virtual*/ BOOL isDirty() const;
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
-protected:
-
- LLPanelPickEdit();
-
- /**
- * Sends Pick properties to server.
- */
- void sendUpdate();
-
- /**
- * Called when snapshot image changes.
- */
- void onSnapshotChanged();
-
- /**
- * Callback for Pick snapshot, name and description changed event.
- */
- void onPickChanged(LLUICtrl* ctrl);
-
- /*virtual*/ void resetData();
-
- /**
- * Enables/disables "Save" button
- */
- void enableSaveButton(bool enable);
-
- /**
- * Callback for "Set Location" button click
- */
- void onClickSetLocation();
-
- /**
- * Callback for "Save" button click
- */
- void onClickSave();
-
- std::string getLocationNotice();
-
-protected:
-
- bool mLocationChanged;
- bool mNeedData;
- bool mNewPick;
-
-private:
-
- void initTexturePickerMouseEvents();
- void onTexturePickerMouseEnter(LLUICtrl* ctrl);
- void onTexturePickerMouseLeave(LLUICtrl* ctrl);
-
-private:
-
- LLIconCtrl* text_icon;
-};
-
-#endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
deleted file mode 100644
index 8294977f99..0000000000
--- a/indra/newview/llpanelpicks.cpp
+++ /dev/null
@@ -1,1484 +0,0 @@
-/**
- * @file llpanelpicks.cpp
- * @brief LLPanelPicks and related class implementations
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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 "llpanelpicks.h"
-
-#include "llagent.h"
-#include "llagentpicksinfo.h"
-#include "llcommandhandler.h"
-#include "lldispatcher.h"
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfloaterworldmap.h"
-#include "llnotificationsutil.h"
-#include "llstartup.h"
-#include "lltexturectrl.h"
-#include "lltoggleablemenu.h"
-#include "lltrans.h"
-#include "llviewergenericmessage.h" // send_generic_message
-#include "llmenugl.h"
-#include "llviewermenu.h"
-#include "llregistry.h"
-
-#include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llpanelavatar.h"
-#include "llpanelprofile.h"
-#include "llpanelpick.h"
-#include "llpanelclassified.h"
-
-static const std::string XML_BTN_NEW = "new_btn";
-static const std::string XML_BTN_DELETE = "trash_btn";
-static const std::string XML_BTN_INFO = "info_btn";
-static const std::string XML_BTN_TELEPORT = "teleport_btn";
-static const std::string XML_BTN_SHOW_ON_MAP = "show_on_map_btn";
-
-static const std::string PICK_ID("pick_id");
-static const std::string PICK_CREATOR_ID("pick_creator_id");
-static const std::string PICK_NAME("pick_name");
-
-static const std::string CLASSIFIED_ID("classified_id");
-static const std::string CLASSIFIED_NAME("classified_name");
-
-
-static LLPanelInjector<LLPanelPicks> t_panel_picks("panel_picks");
-
-
-class LLPickHandler : public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
-
- std::set<LLUUID> mPickIds;
-
- // requires trusted browser to trigger
- LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
-
- bool handle(const LLSD& params, const LLSD& query_map,
- LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
- {
- LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createPick();
- return true;
- }
-
- // then handle the general app/pick/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the pick_id
- LLUUID pick_id;
- if (!pick_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // edit the pick in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "edit")
- {
- mPickIds.insert(pick_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(gAgent.getID(),pick_id);
- return true;
- }
- else
- {
- LL_WARNS() << "unknown verb " << verb << LL_ENDL;
- return false;
- }
- }
-
- void createPick()
- {
- // open the new pick panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewPick();
- }
- }
-
- void editPick(LLPickData* pick_info)
- {
- LLSD params;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_pick";
- params["pick_id"] = pick_info->pick_id;
- params["avatar_id"] = pick_info->creator_id;
- params["snapshot_id"] = pick_info->snapshot_id;
- params["pick_name"] = pick_info->name;
- params["pick_desc"] = pick_info->desc;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- // is this the pick that we asked for?
- LLPickData* pick_info = static_cast<LLPickData*>(data);
- if (!pick_info || mPickIds.find(pick_info->pick_id) == mPickIds.end())
- {
- return;
- }
-
- // open the edit side tray for this pick
- if (pick_info->creator_id == gAgent.getID())
- {
- editPick(pick_info);
- }
- else
- {
- LL_WARNS() << "Can't edit a pick you did not create" << LL_ENDL;
- }
-
- // remove our observer now that we're done
- mPickIds.erase(pick_info->pick_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-};
-
-LLPickHandler gPickHandler;
-
-class LLClassifiedHandler :
- public LLCommandHandler,
- public LLAvatarPropertiesObserver
-{
-public:
- // throttle calls from untrusted browsers
- LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
-
- std::set<LLUUID> mClassifiedIds;
-
- std::string mRequestVerb;
-
- bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
- {
- if (LLStartUp::getStartupState() < STATE_STARTED)
- {
- return true;
- }
-
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
- {
- LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
- // handle app/classified/create urls first
- if (params.size() == 1 && params[0].asString() == "create")
- {
- createClassified();
- return true;
- }
-
- // then handle the general app/classified/{UUID}/{CMD} urls
- if (params.size() < 2)
- {
- return false;
- }
-
- // get the ID for the classified
- LLUUID classified_id;
- if (!classified_id.set(params[0], FALSE))
- {
- return false;
- }
-
- // show the classified in the side tray.
- // need to ask the server for more info first though...
- const std::string verb = params[1].asString();
- if (verb == "about")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
- else if (verb == "edit")
- {
- mRequestVerb = verb;
- mClassifiedIds.insert(classified_id);
- LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
- return true;
- }
-
- return false;
- }
-
- void createClassified()
- {
- // open the new classified panel on the Picks floater
- LLFloater* picks_floater = LLFloaterReg::showInstance("picks");
-
- LLPanelPicks* picks = picks_floater->findChild<LLPanelPicks>("panel_picks");
- if (picks)
- {
- picks->createNewClassified();
- }
- }
-
- void openClassified(LLAvatarClassifiedInfo* c_info)
- {
- if (mRequestVerb == "about")
- {
- // open the classified info panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = c_info->creator_id;
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "classified_details";
- params["classified_id"] = c_info->classified_id;
- params["classified_creator_id"] = c_info->creator_id;
- params["classified_snapshot_id"] = c_info->snapshot_id;
- params["classified_name"] = c_info->name;
- params["classified_desc"] = c_info->description;
- params["from_search"] = true;
- LLFloaterSidePanelContainer::showPanel("picks", params);
- }
- else if (mRequestVerb == "edit")
- {
- if (c_info->creator_id == gAgent.getID())
- {
- LL_WARNS() << "edit in progress" << LL_ENDL;
- // open the new classified panel on the Me > Picks sidetray
- LLSD params;
- params["id"] = gAgent.getID();
- params["open_tab_name"] = "panel_picks";
- params["show_tab_panel"] = "edit_classified";
- params["classified_id"] = c_info->classified_id;
- LLFloaterSidePanelContainer::showPanel("my_profile", params);
- }
- else
- {
- LL_WARNS() << "Can't edit a classified you did not create" << LL_ENDL;
- }
- }
- }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type)
- {
- if (APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- // is this the classified that we asked for?
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
- {
- return;
- }
-
- // open the detail side tray for this classified
- openClassified(c_info);
-
- // remove our observer now that we're done
- mClassifiedIds.erase(c_info->classified_id);
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
- }
-
-};
-LLClassifiedHandler gClassifiedHandler;
-
-//////////////////////////////////////////////////////////////////////////
-
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPanelPicks::LLPanelPicks()
-: LLPanelProfileTab(),
- mPopupMenu(NULL),
- mProfilePanel(NULL),
- mPickPanel(NULL),
- mPicksList(NULL),
- mClassifiedsList(NULL),
- mPanelPickInfo(NULL),
- mPanelPickEdit(NULL),
- mPlusMenu(NULL),
- mPicksAccTab(NULL),
- mClassifiedsAccTab(NULL),
- mPanelClassifiedInfo(NULL),
- mNoClassifieds(false),
- mNoPicks(false)
-{
-}
-
-LLPanelPicks::~LLPanelPicks()
-{
- if(getAvatarId().notNull())
- {
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(),this);
- }
-}
-
-void* LLPanelPicks::create(void* data /* = NULL */)
-{
- return new LLPanelPicks();
-}
-
-void LLPanelPicks::updateData()
-{
- // Send Picks request only when we need to, not on every onOpen(during tab switch).
- if(isDirty())
- {
- mNoPicks = false;
- mNoClassifieds = false;
-
- mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
- mNoItemsLabel->setVisible(TRUE);
-
- mPicksList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
-
- mClassifiedsList->clear();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(getAvatarId());
- }
-}
-
-void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_PICKS == type)
- {
- LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
- if(avatar_picks && getAvatarId() == avatar_picks->target_id)
- {
- LLAvatarName av_name;
- LLAvatarNameCache::get(getAvatarId(), &av_name);
- getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName());
-
- // Save selection, to be able to edit same item after saving changes. See EXT-3023.
- LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
-
- mPicksList->clear();
-
- LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
- for(; avatar_picks->picks_list.end() != it; ++it)
- {
- LLUUID pick_id = it->first;
- std::string pick_name = it->second;
-
- LLPickItem* picture = LLPickItem::create();
- picture->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- picture->setPickName(pick_name);
- picture->setPickId(pick_id);
- picture->setCreatorId(getAvatarId());
-
- LLAvatarPropertiesProcessor::instance().addObserver(getAvatarId(), picture);
- picture->update();
-
- LLSD pick_value = LLSD();
- pick_value.insert(PICK_ID, pick_id);
- pick_value.insert(PICK_NAME, pick_name);
- pick_value.insert(PICK_CREATOR_ID, getAvatarId());
-
- mPicksList->addItem(picture, pick_value);
-
- // Restore selection by item id.
- if ( pick_id == selected_id )
- mPicksList->selectItemByValue(pick_value);
-
- picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickPickItem, this, _1));
- picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_picks", mPicksList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoPicks = !mPicksList->size();
- }
- else if((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
- {
- LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
- if(c_info && getAvatarId() == c_info->target_id)
- {
- // do not clear classified list in case we will receive two or more data packets.
- // list has been cleared in updateData(). (fix for EXT-6436)
-
- LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
- for(; c_info->classifieds_list.end() != it; ++it)
- {
- LLAvatarClassifieds::classified_data c_data = *it;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), c_data.classified_id);
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
- c_item->setClassifiedName(c_data.name);
-
- LLSD pick_value = LLSD();
- pick_value.insert(CLASSIFIED_ID, c_data.classified_id);
- pick_value.insert(CLASSIFIED_NAME, c_data.name);
-
- if (!findClassifiedById(c_data.classified_id))
- {
- mClassifiedsList->addItem(c_item, pick_value);
- }
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- }
-
- showAccordion("tab_classifieds", mClassifiedsList->size());
-
- resetDirty();
- updateButtons();
- }
-
- mNoClassifieds = !mClassifiedsList->size();
- }
-
- updateNoItemsLabel();
-}
-
-LLPickItem* LLPanelPicks::getSelectedPickItem()
-{
- LLPanel* selected_item = mPicksList->getSelectedItem();
- if (!selected_item) return NULL;
-
- return dynamic_cast<LLPickItem*>(selected_item);
-}
-
-LLClassifiedItem* LLPanelPicks::getSelectedClassifiedItem()
-{
- LLPanel* selected_item = mClassifiedsList->getSelectedItem();
- if (!selected_item)
- {
- return NULL;
- }
- return dynamic_cast<LLClassifiedItem*>(selected_item);
-}
-
-BOOL LLPanelPicks::postBuild()
-{
- mPicksList = getChild<LLFlatListView>("picks_list");
- mClassifiedsList = getChild<LLFlatListView>("classifieds_list");
-
- mPicksList->setCommitOnSelectionChange(true);
- mClassifiedsList->setCommitOnSelectionChange(true);
-
- mPicksList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mPicksList));
- mClassifiedsList->setCommitCallback(boost::bind(&LLPanelPicks::onListCommit, this, mClassifiedsList));
-
- mPicksList->setNoItemsCommentText(getString("no_picks"));
- mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
-
- mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
-
- childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
- childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
- childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
- childSetAction(XML_BTN_SHOW_ON_MAP, boost::bind(&LLPanelPicks::onClickMap, this));
- childSetAction(XML_BTN_INFO, boost::bind(&LLPanelPicks::onClickInfo, this));
-
- mPicksAccTab = getChild<LLAccordionCtrlTab>("tab_picks");
- mPicksAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mPicksAccTab));
- mPicksAccTab->setDisplayChildren(true);
-
- mClassifiedsAccTab = getChild<LLAccordionCtrlTab>("tab_classifieds");
- mClassifiedsAccTab->setDropDownStateChangedCallback(boost::bind(&LLPanelPicks::onAccordionStateChanged, this, mClassifiedsAccTab));
- mClassifiedsAccTab->setDisplayChildren(false);
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
- registar.add("Pick.Info", boost::bind(&LLPanelPicks::onClickInfo, this));
- registar.add("Pick.Edit", boost::bind(&LLPanelPicks::onClickMenuEdit, this));
- registar.add("Pick.Teleport", boost::bind(&LLPanelPicks::onClickTeleport, this));
- registar.add("Pick.Map", boost::bind(&LLPanelPicks::onClickMap, this));
- registar.add("Pick.Delete", boost::bind(&LLPanelPicks::onClickDelete, this));
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registar;
- enable_registar.add("Pick.Enable", boost::bind(&LLPanelPicks::onEnableMenuItem, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_picks.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar plus_registar;
- plus_registar.add("Picks.Plus.Action", boost::bind(&LLPanelPicks::onPlusMenuItemClicked, this, _2));
- mEnableCallbackRegistrar.add("Picks.Plus.Enable", boost::bind(&LLPanelPicks::isActionEnabled, this, _2));
- mPlusMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_picks_plus.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-
- return TRUE;
-}
-
-void LLPanelPicks::onPlusMenuItemClicked(const LLSD& param)
-{
- std::string value = param.asString();
-
- if("new_pick" == value)
- {
- createNewPick();
- }
- else if("new_classified" == value)
- {
- createNewClassified();
- }
-}
-
-bool LLPanelPicks::isActionEnabled(const LLSD& userdata) const
-{
- std::string command_name = userdata.asString();
-
- if (command_name == "new_pick" && LLAgentPicksInfo::getInstance()->isPickLimitReached())
- {
- return false;
- }
-
- return true;
-}
-
-bool LLPanelPicks::isClassifiedPublished(LLClassifiedItem* c_item)
-{
- if(c_item)
- {
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(panel)
- {
- return !panel->isNewWithErrors();
- }
-
- // we've got this classified from server - it's published
- return true;
- }
- return false;
-}
-
-void LLPanelPicks::onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab)
-{
- if(!mPicksAccTab->getDisplayChildren())
- {
- mPicksList->resetSelection(true);
- }
- if(!mClassifiedsAccTab->getDisplayChildren())
- {
- mClassifiedsList->resetSelection(true);
- }
-
- updateButtons();
-}
-
-void LLPanelPicks::onOpen(const LLSD& key)
-{
- const LLUUID id(key.asUUID());
- BOOL self = (gAgent.getID() == id);
-
- // only agent can edit her picks
- getChildView("edit_panel")->setEnabled(self);
- getChildView("edit_panel")->setVisible( self);
-
- // Disable buttons when viewing profile for first time
- if(getAvatarId() != id)
- {
- getChildView(XML_BTN_INFO)->setEnabled(FALSE);
- getChildView(XML_BTN_TELEPORT)->setEnabled(FALSE);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(FALSE);
- }
-
- // and see a special title - set as invisible by default in xml file
- if (self)
- {
- getChildView("pick_title")->setVisible( !self);
- getChildView("pick_title_agent")->setVisible( self);
-
- mPopupMenu->setItemVisible("pick_delete", TRUE);
- mPopupMenu->setItemVisible("pick_edit", TRUE);
- mPopupMenu->setItemVisible("pick_separator", TRUE);
- }
-
- if(getAvatarId() != id)
- {
- showAccordion("tab_picks", false);
- showAccordion("tab_classifieds", false);
-
- mPicksList->goToTop();
- // Set dummy value to make panel dirty and make it reload picks
- setValue(LLSD());
- }
-
- LLPanelProfileTab::onOpen(key);
-}
-
-void LLPanelPicks::onClosePanel()
-{
- if (mPanelClassifiedInfo)
- {
- onPanelClassifiedClose(mPanelClassifiedInfo);
- }
- if (mPanelPickInfo)
- {
- onPanelPickClose(mPanelPickInfo);
- }
-}
-
-void LLPanelPicks::onListCommit(const LLFlatListView* f_list)
-{
- // Make sure only one of the lists has selection.
- if(f_list == mPicksList)
- {
- mClassifiedsList->resetSelection(true);
- }
- else if(f_list == mClassifiedsList)
- {
- mPicksList->resetSelection(true);
- }
- else
- {
- LL_WARNS() << "Unknown list" << LL_ENDL;
- }
-
- updateButtons();
-}
-
-//static
-void LLPanelPicks::onClickDelete()
-{
- LLSD value = mPicksList->getSelectedValue();
- if (value.isDefined())
- {
- LLSD args;
- args["PICK"] = value[PICK_NAME];
- LLNotificationsUtil::add("DeleteAvatarPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeletePick, this, _1, _2));
- return;
- }
-
- value = mClassifiedsList->getSelectedValue();
- if(value.isDefined())
- {
- LLSD args;
- args["NAME"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackDeleteClassified, this, _1, _2));
- return;
- }
-}
-
-bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD pick_value = mPicksList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
- mPicksList->removeItemByValue(pick_value);
-
- mNoPicks = !mPicksList->size();
- if (mNoPicks)
- {
- showAccordion("tab_picks", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLSD value = mClassifiedsList->getSelectedValue();
-
- if (0 == option)
- {
- LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
- mClassifiedsList->removeItemByValue(value);
-
- mNoClassifieds = !mClassifiedsList->size();
- if (mNoClassifieds)
- {
- showAccordion("tab_classifieds", false);
- }
- updateNoItemsLabel();
- }
- updateButtons();
- return false;
-}
-
-bool LLPanelPicks::callbackTeleport( const LLSD& notification, const LLSD& response )
-{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
- if (0 == option)
- {
- onClickTeleport();
- }
- return false;
-}
-
-//static
-void LLPanelPicks::onClickTeleport()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if(pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- pos = c_item->getPosGlobal();
- LLPanelClassifiedInfo::sendClickMessage("teleport", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- }
-
- if (!pos.isExactlyZero())
- {
- gAgent.teleportViaLocation(pos);
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- }
-}
-
-//static
-void LLPanelPicks::onClickMap()
-{
- LLPickItem* pick_item = getSelectedPickItem();
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
-
- LLVector3d pos;
- if (pick_item)
- pos = pick_item->getPosGlobal();
- else if(c_item)
- {
- LLPanelClassifiedInfo::sendClickMessage("map", false,
- c_item->getClassifiedId(), LLUUID::null, pos, LLStringUtil::null);
- pos = c_item->getPosGlobal();
- }
-
- LLFloaterWorldMap::getInstance()->trackLocation(pos);
- LLFloaterReg::showInstance("world_map", "center");
-}
-
-
-void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
-{
- updateButtons();
-
- if (mPopupMenu)
- {
- mPopupMenu->buildDrawLabels();
- mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- ((LLContextMenu*)mPopupMenu)->show(x, y);
- LLMenuGL::showPopup(item, mPopupMenu, x, y);
- }
-}
-
-void LLPanelPicks::onDoubleClickPickItem(LLUICtrl* item)
-{
- LLSD pick_value = mPicksList->getSelectedValue();
- if (pick_value.isUndefined()) return;
-
- LLSD args;
- args["PICK"] = pick_value[PICK_NAME];
- LLNotificationsUtil::add("TeleportToPick", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::onDoubleClickClassifiedItem(LLUICtrl* item)
-{
- LLSD value = mClassifiedsList->getSelectedValue();
- if (value.isUndefined()) return;
-
- LLSD args;
- args["CLASSIFIED"] = value[CLASSIFIED_NAME];
- LLNotificationsUtil::add("TeleportToClassified", args, LLSD(), boost::bind(&LLPanelPicks::callbackTeleport, this, _1, _2));
-}
-
-void LLPanelPicks::updateButtons()
-{
- bool has_selected = mPicksList->numSelected() > 0 || mClassifiedsList->numSelected() > 0;
-
- if (getAvatarId() == gAgentID)
- {
- getChildView(XML_BTN_DELETE)->setEnabled(has_selected);
- }
-
- getChildView(XML_BTN_INFO)->setEnabled(has_selected);
- getChildView(XML_BTN_TELEPORT)->setEnabled(has_selected);
- getChildView(XML_BTN_SHOW_ON_MAP)->setEnabled(has_selected);
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item)
- {
- getChildView(XML_BTN_INFO)->setEnabled(isClassifiedPublished(c_item));
- }
-}
-
-void LLPanelPicks::updateNoItemsLabel()
-{
- bool no_data = mNoPicks && mNoClassifieds;
- mNoItemsLabel->setVisible(no_data);
- if (no_data)
- {
- if (getAvatarId() == gAgentID)
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
- }
- else
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
- }
- }
-}
-
-void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
-{
- mProfilePanel = profile_panel;
-}
-
-
-void LLPanelPicks::buildPickPanel()
-{
-// if (mPickPanel == NULL)
-// {
-// mPickPanel = new LLPanelPick();
-// mPickPanel->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, NULL));
-// }
-}
-
-void LLPanelPicks::onClickPlusBtn()
-{
- LLRect rect(getChildView(XML_BTN_NEW)->getRect());
-
- mPlusMenu->updateParent(LLMenuGL::sMenuContainer);
- mPlusMenu->setButtonRect(rect, this);
- LLMenuGL::showPopup(this, mPlusMenu, rect.mLeft, rect.mTop);
-}
-
-void LLPanelPicks::createNewPick()
-{
- createPickEditPanel();
-
- getProfilePanel()->openPanel(mPanelPickEdit, LLSD());
-}
-
-void LLPanelPicks::createNewClassified()
-{
- LLPanelClassifiedEdit* panel = NULL;
- createClassifiedEditPanel(&panel);
-
- getProfilePanel()->openPanel(panel, LLSD());
-}
-
-void LLPanelPicks::onClickInfo()
-{
- if(mPicksList->numSelected() > 0)
- {
- openPickInfo();
- }
- else if(mClassifiedsList->numSelected() > 0)
- {
- openClassifiedInfo();
- }
-}
-
-void LLPanelPicks::openPickInfo()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = (LLPickItem*)mPicksList->getSelectedItem();
-
- createPickInfoPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickInfo, params);
-}
-
-void LLPanelPicks::openClassifiedInfo()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLClassifiedItem* c_item = getSelectedClassifiedItem();
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["classified_snapshot_id"] = c_item->getSnapshotId();
- params["classified_name"] = c_item->getClassifiedName();
- params["classified_desc"] = c_item->getDescription();
- params["from_search"] = false;
-
- openClassifiedInfo(params);
-}
-
-void LLPanelPicks::openClassifiedInfo(const LLSD &params)
-{
- createClassifiedInfoPanel();
- getProfilePanel()->openPanel(mPanelClassifiedInfo, params);
-}
-
-void LLPanelPicks::openClassifiedEdit(const LLSD& params)
-{
- LLUUID classified_id = params["classified_id"].asUUID();;
- LL_INFOS() << "opening classified " << classified_id << " for edit" << LL_ENDL;
- editClassified(classified_id);
-}
-
-void LLPanelPicks::showAccordion(const std::string& name, bool show)
-{
- LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(name);
- tab->setVisible(show);
- LLAccordionCtrl* acc = getChild<LLAccordionCtrl>("accordion");
- acc->arrange();
-}
-
-void LLPanelPicks::onPanelPickClose(LLPanel* panel)
-{
- getProfilePanel()->closePanel(panel);
-}
-
-void LLPanelPicks::onPanelPickSave(LLPanel* panel)
-{
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedSave(LLPanelClassifiedEdit* panel)
-{
- if(!panel->canClose())
- {
- return;
- }
-
- if(panel->isNew())
- {
- mEditClassifiedPanels[panel->getClassifiedId()] = panel;
-
- LLClassifiedItem* c_item = new LLClassifiedItem(getAvatarId(), panel->getClassifiedId());
- c_item->fillIn(panel);
-
- LLSD c_value;
- c_value.insert(CLASSIFIED_ID, c_item->getClassifiedId());
- c_value.insert(CLASSIFIED_NAME, c_item->getClassifiedName());
- mClassifiedsList->addItem(c_item, c_value, ADD_TOP);
-
- c_item->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickClassifiedItem, this, _1));
- c_item->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
- c_item->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
- c_item->childSetAction("info_chevron", boost::bind(&LLPanelPicks::onClickInfo, this));
-
- // order does matter, showAccordion will invoke arrange for accordions.
- mClassifiedsAccTab->changeOpenClose(false);
- showAccordion("tab_classifieds", true);
- }
- else if(panel->isNewWithErrors())
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (c_item)
- {
- c_item->fillIn(panel);
- }
- }
- else
- {
- onPanelClassifiedClose(panel);
- return;
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::onPanelClassifiedClose(LLPanelClassifiedInfo* panel)
-{
- if(panel->getInfoLoaded() && !panel->isDirty())
- {
- std::vector<LLSD> values;
- mClassifiedsList->getValues(values);
- for(size_t n = 0; n < values.size(); ++n)
- {
- LLUUID c_id = values[n][CLASSIFIED_ID].asUUID();
- if(panel->getClassifiedId() == c_id)
- {
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(
- mClassifiedsList->getItemByValue(values[n]));
- llassert(c_item);
- if (c_item)
- {
- c_item->setClassifiedName(panel->getClassifiedName());
- c_item->setDescription(panel->getDescription());
- c_item->setSnapshotId(panel->getSnapshotId());
- }
- }
- }
- }
-
- onPanelPickClose(panel);
- updateButtons();
-}
-
-void LLPanelPicks::createPickInfoPanel()
-{
- if(!mPanelPickInfo)
- {
- mPanelPickInfo = LLPanelPickInfo::create();
- mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
- mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
- mPanelPickInfo->setVisible(FALSE);
- }
-}
-
-void LLPanelPicks::createClassifiedInfoPanel()
-{
- mPanelClassifiedInfo = LLPanelClassifiedInfo::create();
- mPanelClassifiedInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, mPanelClassifiedInfo));
- mPanelClassifiedInfo->setEditClassifiedCallback(boost::bind(&LLPanelPicks::onPanelClassifiedEdit, this));
- mPanelClassifiedInfo->setVisible(FALSE);
-}
-
-void LLPanelPicks::createClassifiedEditPanel(LLPanelClassifiedEdit** panel)
-{
- if(panel)
- {
- LLPanelClassifiedEdit* new_panel = LLPanelClassifiedEdit::create();
- new_panel->setExitCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setSaveCallback(boost::bind(&LLPanelPicks::onPanelClassifiedSave, this, new_panel));
- new_panel->setCancelCallback(boost::bind(&LLPanelPicks::onPanelClassifiedClose, this, new_panel));
- new_panel->setVisible(FALSE);
- *panel = new_panel;
- }
-}
-
-void LLPanelPicks::createPickEditPanel()
-{
- mPanelPickEdit = LLPanelPickEdit::create();
- mPanelPickEdit->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setSaveCallback(boost::bind(&LLPanelPicks::onPanelPickSave, this, mPanelPickEdit));
- mPanelPickEdit->setCancelCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickEdit));
- mPanelPickEdit->setVisible(FALSE);
-}
-
-// void LLPanelPicks::openPickEditPanel(LLPickItem* pick)
-// {
-// if(!pick)
-// {
-// return;
-// }
-// }
-
-// void LLPanelPicks::openPickInfoPanel(LLPickItem* pick)
-// {
-// if(!mPanelPickInfo)
-// {
-// mPanelPickInfo = LLPanelPickInfo::create();
-// mPanelPickInfo->setExitCallback(boost::bind(&LLPanelPicks::onPanelPickClose, this, mPanelPickInfo));
-// mPanelPickInfo->setEditPickCallback(boost::bind(&LLPanelPicks::onPanelPickEdit, this));
-// mPanelPickInfo->setVisible(FALSE);
-// }
-//
-// LLSD params;
-// params["pick_id"] = pick->getPickId();
-// params["avatar_id"] = pick->getCreatorId();
-// params["snapshot_id"] = pick->getSnapshotId();
-// params["pick_name"] = pick->getPickName();
-// params["pick_desc"] = pick->getPickDesc();
-//
-// getProfilePanel()->openPanel(mPanelPickInfo, params);
-// }
-
-void LLPanelPicks::openPickEdit(const LLSD& params)
-{
- createPickEditPanel();
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelPickEdit()
-{
- LLSD selected_value = mPicksList->getSelectedValue();
- if (selected_value.isUndefined()) return;
-
- LLPickItem* pick = dynamic_cast<LLPickItem*>(mPicksList->getSelectedItem());
-
- createPickEditPanel();
-
- LLSD params;
- params["pick_id"] = pick->getPickId();
- params["avatar_id"] = pick->getCreatorId();
- params["snapshot_id"] = pick->getSnapshotId();
- params["pick_name"] = pick->getPickName();
- params["pick_desc"] = pick->getPickDesc();
-
- getProfilePanel()->openPanel(mPanelPickEdit, params);
-}
-
-void LLPanelPicks::onPanelClassifiedEdit()
-{
- LLSD selected_value = mClassifiedsList->getSelectedValue();
- if (selected_value.isUndefined())
- {
- return;
- }
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- llassert(c_item);
- if (!c_item)
- {
- return;
- }
- editClassified(c_item->getClassifiedId());
-}
-
-LLClassifiedItem *LLPanelPicks::findClassifiedById(const LLUUID& classified_id)
-{
- // HACK - find item by classified id. Should be a better way.
- std::vector<LLPanel*> items;
- mClassifiedsList->getItems(items);
- LLClassifiedItem* c_item = NULL;
- for(std::vector<LLPanel*>::iterator it = items.begin(); it != items.end(); ++it)
- {
- LLClassifiedItem *test_item = dynamic_cast<LLClassifiedItem*>(*it);
- if (test_item && test_item->getClassifiedId() == classified_id)
- {
- c_item = test_item;
- break;
- }
- }
- return c_item;
-}
-
-void LLPanelPicks::editClassified(const LLUUID& classified_id)
-{
- LLClassifiedItem* c_item = findClassifiedById(classified_id);
- if (!c_item)
- {
- LL_WARNS() << "item not found for classified_id " << classified_id << LL_ENDL;
- return;
- }
-
- LLSD params;
- params["classified_id"] = c_item->getClassifiedId();
- params["classified_creator_id"] = c_item->getAvatarId();
- params["snapshot_id"] = c_item->getSnapshotId();
- params["name"] = c_item->getClassifiedName();
- params["desc"] = c_item->getDescription();
- params["category"] = (S32)c_item->getCategory();
- params["content_type"] = (S32)c_item->getContentType();
- params["auto_renew"] = c_item->getAutoRenew();
- params["price_for_listing"] = c_item->getPriceForListing();
- params["location_text"] = c_item->getLocationText();
-
- LLPanelClassifiedEdit* panel = mEditClassifiedPanels[c_item->getClassifiedId()];
- if(!panel)
- {
- createClassifiedEditPanel(&panel);
- mEditClassifiedPanels[c_item->getClassifiedId()] = panel;
- }
- getProfilePanel()->openPanel(panel, params);
- panel->setPosGlobal(c_item->getPosGlobal());
-}
-
-void LLPanelPicks::onClickMenuEdit()
-{
- if(getSelectedPickItem())
- {
- onPanelPickEdit();
- }
- else if(getSelectedClassifiedItem())
- {
- onPanelClassifiedEdit();
- }
-}
-
-bool LLPanelPicks::onEnableMenuItem(const LLSD& user_data)
-{
- std::string param = user_data.asString();
-
- LLClassifiedItem* c_item = dynamic_cast<LLClassifiedItem*>(mClassifiedsList->getSelectedItem());
- if(c_item && "info" == param)
- {
- // dont show Info panel if classified was not created
- return isClassifiedPublished(c_item);
- }
-
- return true;
-}
-
-inline LLPanelProfile* LLPanelPicks::getProfilePanel()
-{
- llassert_always(NULL != mProfilePanel);
- return mProfilePanel;
-}
-
-//-----------------------------------------------------------------------------
-// LLPanelPicks
-//-----------------------------------------------------------------------------
-LLPickItem::LLPickItem()
-: LLPanel()
-, mPickID(LLUUID::null)
-, mCreatorID(LLUUID::null)
-, mParcelID(LLUUID::null)
-, mSnapshotID(LLUUID::null)
-, mNeedData(true)
-{
- buildFromFile("panel_pick_list_item.xml");
-}
-
-LLPickItem::~LLPickItem()
-{
- if (mCreatorID.notNull())
- {
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
- }
-
-}
-
-LLPickItem* LLPickItem::create()
-{
- return new LLPickItem();
-}
-
-void LLPickItem::init(LLPickData* pick_data)
-{
- setPickDesc(pick_data->desc);
- setSnapshotId(pick_data->snapshot_id);
- mPosGlobal = pick_data->pos_global;
- mSimName = pick_data->sim_name;
- mPickDescription = pick_data->desc;
- mUserName = pick_data->user_name;
- mOriginalName = pick_data->original_name;
-
- LLTextureCtrl* picture = getChild<LLTextureCtrl>("picture");
- picture->setImageAssetID(pick_data->snapshot_id);
-}
-
-void LLPickItem::setPickName(const std::string& name)
-{
- mPickName = name;
- getChild<LLUICtrl>("picture_name")->setValue(name);
-
-}
-
-const std::string& LLPickItem::getPickName()
-{
- return mPickName;
-}
-
-const LLUUID& LLPickItem::getCreatorId()
-{
- return mCreatorID;
-}
-
-const LLUUID& LLPickItem::getSnapshotId()
-{
- return mSnapshotID;
-}
-
-void LLPickItem::setPickDesc(const std::string& descr)
-{
- getChild<LLUICtrl>("picture_descr")->setValue(descr);
-}
-
-void LLPickItem::setPickId(const LLUUID& id)
-{
- mPickID = id;
-}
-
-const LLUUID& LLPickItem::getPickId()
-{
- return mPickID;
-}
-
-const LLVector3d& LLPickItem::getPosGlobal()
-{
- return mPosGlobal;
-}
-
-const std::string LLPickItem::getDescription()
-{
- return getChild<LLUICtrl>("picture_descr")->getValue().asString();
-}
-
-void LLPickItem::update()
-{
- setNeedData(true);
- LLAvatarPropertiesProcessor::instance().sendPickInfoRequest(mCreatorID, mPickID);
-}
-
-void LLPickItem::processProperties(void *data, EAvatarProcessorType type)
-{
- if (APT_PICK_INFO != type)
- {
- return;
- }
-
- LLPickData* pick_data = static_cast<LLPickData *>(data);
- if (!pick_data || mPickID != pick_data->pick_id)
- {
- return;
- }
-
- init(pick_data);
- setNeedData(false);
- LLAvatarPropertiesProcessor::instance().removeObserver(mCreatorID, this);
-}
-
-void set_child_visible(LLView* parent, const std::string& child_name, bool visible)
-{
- parent->getChildView(child_name)->setVisible(visible);
-}
-
-BOOL LLPickItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLPickItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLClassifiedItem::LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id)
- : LLPanel()
- , mAvatarId(avatar_id)
- , mClassifiedId(classified_id)
-{
- buildFromFile("panel_classifieds_list_item.xml");
-
- LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
- LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
-}
-
-LLClassifiedItem::~LLClassifiedItem()
-{
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-void LLClassifiedItem::processProperties(void* data, EAvatarProcessorType type)
-{
- if(APT_CLASSIFIED_INFO != type)
- {
- return;
- }
-
- LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
- if( !c_info || c_info->classified_id != getClassifiedId() )
- {
- return;
- }
-
- setClassifiedName(c_info->name);
- setDescription(c_info->description);
- setSnapshotId(c_info->snapshot_id);
- setPosGlobal(c_info->pos_global);
-
- LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
-}
-
-BOOL LLClassifiedItem::postBuild()
-{
- setMouseEnterCallback(boost::bind(&set_child_visible, this, "hovered_icon", true));
- setMouseLeaveCallback(boost::bind(&set_child_visible, this, "hovered_icon", false));
- return TRUE;
-}
-
-void LLClassifiedItem::setValue(const LLSD& value)
-{
- if (!value.isMap()) return;;
- if (!value.has("selected")) return;
- getChildView("selected_icon")->setVisible( value["selected"]);
-}
-
-void LLClassifiedItem::fillIn(LLPanelClassifiedEdit* panel)
-{
- if(!panel)
- {
- return;
- }
-
- setClassifiedName(panel->getClassifiedName());
- setDescription(panel->getDescription());
- setSnapshotId(panel->getSnapshotId());
- setCategory(panel->getCategory());
- setContentType(panel->getContentType());
- setAutoRenew(panel->getAutoRenew());
- setPriceForListing(panel->getPriceForListing());
- setPosGlobal(panel->getPosGlobal());
- setLocationText(panel->getClassifiedLocation());
-}
-
-void LLClassifiedItem::setClassifiedName(const std::string& name)
-{
- getChild<LLUICtrl>("name")->setValue(name);
-}
-
-void LLClassifiedItem::setDescription(const std::string& desc)
-{
- getChild<LLUICtrl>("description")->setValue(desc);
-}
-
-void LLClassifiedItem::setSnapshotId(const LLUUID& snapshot_id)
-{
- getChild<LLUICtrl>("picture")->setValue(snapshot_id);
-}
-
-LLUUID LLClassifiedItem::getSnapshotId()
-{
- return getChild<LLUICtrl>("picture")->getValue();
-}
-
-//EOF
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
deleted file mode 100644
index fd7688b99d..0000000000
--- a/indra/newview/llpanelpicks.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * @file llpanelpicks.h
- * @brief LLPanelPicks and related class definitions
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, 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_LLPANELPICKS_H
-#define LL_LLPANELPICKS_H
-
-#include "llpanel.h"
-#include "v3dmath.h"
-#include "lluuid.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llpanelavatar.h"
-#include "llregistry.h"
-
-class LLAccordionCtrlTab;
-class LLPanelProfile;
-class LLMessageSystem;
-class LLVector3d;
-class LLPanelProfileTab;
-class LLAgent;
-class LLMenuGL;
-class LLPickItem;
-class LLClassifiedItem;
-class LLFlatListView;
-class LLPanelPickInfo;
-class LLPanelPickEdit;
-class LLToggleableMenu;
-class LLPanelClassifiedInfo;
-class LLPanelClassifiedEdit;
-
-// *TODO
-// Panel Picks has been consolidated with Classifieds (EXT-2095), give LLPanelPicks
-// and corresponding files (cpp, h, xml) a new name. (new name is TBD at the moment)
-
-class LLPanelPicks
- : public LLPanelProfileTab
-{
-public:
- LLPanelPicks();
- ~LLPanelPicks();
-
- static void* create(void* data);
-
- /*virtual*/ BOOL postBuild(void);
-
- /*virtual*/ void onOpen(const LLSD& key);
-
- /*virtual*/ void onClosePanel();
-
- void processProperties(void* data, EAvatarProcessorType type);
-
- void updateData();
-
- // returns the selected pick item
- LLPickItem* getSelectedPickItem();
- LLClassifiedItem* getSelectedClassifiedItem();
- LLClassifiedItem* findClassifiedById(const LLUUID& classified_id);
-
- //*NOTE top down approch when panel toggling is done only by
- // parent panels failed to work (picks related code was in my profile panel)
- void setProfilePanel(LLPanelProfile* profile_panel);
-
- void createNewPick();
- void createNewClassified();
-
-protected:
- /*virtual*/void updateButtons();
- void updateNoItemsLabel();
-
-private:
- void onClickDelete();
- void onClickTeleport();
- void onClickMap();
-
- void onPlusMenuItemClicked(const LLSD& param);
- bool isActionEnabled(const LLSD& userdata) const;
-
- bool isClassifiedPublished(LLClassifiedItem* c_item);
-
- void onListCommit(const LLFlatListView* f_list);
- void onAccordionStateChanged(const LLAccordionCtrlTab* acc_tab);
-
- //------------------------------------------------
- // Callbacks which require panel toggling
- //------------------------------------------------
- void onClickPlusBtn();
- void onClickInfo();
- void onPanelPickClose(LLPanel* panel);
- void onPanelPickSave(LLPanel* panel);
- void onPanelClassifiedSave(LLPanelClassifiedEdit* panel);
- void onPanelClassifiedClose(LLPanelClassifiedInfo* panel);
- void openPickEdit(const LLSD& params);
- void onPanelPickEdit();
- void onPanelClassifiedEdit();
- void editClassified(const LLUUID& classified_id);
- void onClickMenuEdit();
-
- bool onEnableMenuItem(const LLSD& user_data);
-
- void openPickInfo();
- void openClassifiedInfo();
- void openClassifiedInfo(const LLSD& params);
- void openClassifiedEdit(const LLSD& params);
- friend class LLPanelProfile;
-
- void showAccordion(const std::string& name, bool show);
-
- void buildPickPanel();
-
- bool callbackDeletePick(const LLSD& notification, const LLSD& response);
- bool callbackDeleteClassified(const LLSD& notification, const LLSD& response);
- bool callbackTeleport(const LLSD& notification, const LLSD& response);
-
-
- virtual void onDoubleClickPickItem(LLUICtrl* item);
- virtual void onDoubleClickClassifiedItem(LLUICtrl* item);
- virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
-
- LLPanelProfile* getProfilePanel();
-
- void createPickInfoPanel();
- void createPickEditPanel();
- void createClassifiedInfoPanel();
- void createClassifiedEditPanel(LLPanelClassifiedEdit** panel);
-
- LLMenuGL* mPopupMenu;
- LLPanelProfile* mProfilePanel;
- LLPanelPickInfo* mPickPanel;
- LLFlatListView* mPicksList;
- LLFlatListView* mClassifiedsList;
- LLPanelPickInfo* mPanelPickInfo;
- LLPanelClassifiedInfo* mPanelClassifiedInfo;
- LLPanelPickEdit* mPanelPickEdit;
- LLToggleableMenu* mPlusMenu;
- LLUICtrl* mNoItemsLabel;
-
- // <classified_id, edit_panel>
- typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t;
-
- // This map is needed for newly created classifieds. The purpose of panel is to
- // sit in this map and listen to LLPanelClassifiedEdit::processProperties callback.
- panel_classified_edit_map_t mEditClassifiedPanels;
-
- LLAccordionCtrlTab* mPicksAccTab;
- LLAccordionCtrlTab* mClassifiedsAccTab;
-
- //true if picks list is empty after processing picks
- bool mNoPicks;
- //true if classifieds list is empty after processing classifieds
- bool mNoClassifieds;
-};
-
-class LLPickItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLPickItem();
-
- static LLPickItem* create();
-
- void init(LLPickData* pick_data);
-
- void setPickName(const std::string& name);
-
- void setPickDesc(const std::string& descr);
-
- void setPickId(const LLUUID& id);
-
- void setCreatorId(const LLUUID& id) {mCreatorID = id;};
-
- void setSnapshotId(const LLUUID& id) {mSnapshotID = id;};
-
- void setNeedData(bool need){mNeedData = need;};
-
- const LLUUID& getPickId();
-
- const std::string& getPickName();
-
- const LLUUID& getCreatorId();
-
- const LLUUID& getSnapshotId();
-
- const LLVector3d& getPosGlobal();
-
- const std::string getDescription();
-
- const std::string& getSimName() { return mSimName; }
-
- const std::string& getUserName() { return mUserName; }
-
- const std::string& getOriginalName() { return mOriginalName; }
-
- const std::string& getPickDesc() { return mPickDescription; }
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- void update();
-
- ~LLPickItem();
-
- /*virtual*/ BOOL postBuild();
-
- /** setting on/off background icon to indicate selected state */
- /*virtual*/ void setValue(const LLSD& value);
-
-protected:
-
- LLUUID mPickID;
- LLUUID mCreatorID;
- LLUUID mParcelID;
- LLUUID mSnapshotID;
- LLVector3d mPosGlobal;
- bool mNeedData;
-
- std::string mPickName;
- std::string mUserName;
- std::string mOriginalName;
- std::string mPickDescription;
- std::string mSimName;
-};
-
-class LLClassifiedItem : public LLPanel, public LLAvatarPropertiesObserver
-{
-public:
-
- LLClassifiedItem(const LLUUID& avatar_id, const LLUUID& classified_id);
-
- virtual ~LLClassifiedItem();
-
- /*virtual*/ void processProperties(void* data, EAvatarProcessorType type);
-
- /*virtual*/ BOOL postBuild();
-
- /*virtual*/ void setValue(const LLSD& value);
-
- void fillIn(LLPanelClassifiedEdit* panel);
-
- LLUUID getAvatarId() {return mAvatarId;}
-
- void setAvatarId(const LLUUID& avatar_id) {mAvatarId = avatar_id;}
-
- LLUUID getClassifiedId() {return mClassifiedId;}
-
- void setClassifiedId(const LLUUID& classified_id) {mClassifiedId = classified_id;}
-
- void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
-
- const LLVector3d getPosGlobal() { return mPosGlobal; }
-
- void setLocationText(const std::string location) { mLocationText = location; }
-
- std::string getLocationText() { return mLocationText; }
-
- void setClassifiedName (const std::string& name);
-
- std::string getClassifiedName() { return getChild<LLUICtrl>("name")->getValue().asString(); }
-
- void setDescription(const std::string& desc);
-
- std::string getDescription() { return getChild<LLUICtrl>("description")->getValue().asString(); }
-
- void setSnapshotId(const LLUUID& snapshot_id);
-
- LLUUID getSnapshotId();
-
- void setCategory(U32 cat) { mCategory = cat; }
-
- U32 getCategory() { return mCategory; }
-
- void setContentType(U32 ct) { mContentType = ct; }
-
- U32 getContentType() { return mContentType; }
-
- void setAutoRenew(U32 renew) { mAutoRenew = renew; }
-
- bool getAutoRenew() { return mAutoRenew; }
-
- void setPriceForListing(S32 price) { mPriceForListing = price; }
-
- S32 getPriceForListing() { return mPriceForListing; }
-
-private:
- LLUUID mAvatarId;
- LLUUID mClassifiedId;
- LLVector3d mPosGlobal;
- std::string mLocationText;
- U32 mCategory;
- U32 mContentType;
- bool mAutoRenew;
- S32 mPriceForListing;
-};
-
-#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 9157df789f..fb5957ff8f 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -27,6 +27,8 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelplaceinfo.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
#include "llavatarname.h"
#include "llsdutil.h"
@@ -42,7 +44,6 @@
#include "llagent.h"
#include "llexpandabletextbox.h"
-#include "llpanelpick.h"
#include "llslurl.h"
#include "lltexturectrl.h"
#include "llviewerregion.h"
@@ -287,7 +288,7 @@ void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent)
}
}
-void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel)
+void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global)
{
LLPickData data;
data.pos_global = pos_global;
@@ -296,7 +297,12 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit*
data.desc = mDescEditor->getText();
data.snapshot_id = mSnapshotCtrl->getImageAssetID();
data.parcel_id = mParcelID;
- pick_panel->setPickData(&data);
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::showInstance("profile", LLSD().with("id", gAgentID)));
+ if (profile_floater)
+ {
+ profile_floater->createPick(data);
+ }
}
// static
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 8bf67cfe7d..533215016a 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -38,7 +38,6 @@ class LLAvatarName;
class LLExpandableTextBox;
class LLIconCtrl;
class LLInventoryItem;
-class LLPanelPickEdit;
class LLParcel;
class LLScrollContainer;
class LLTextBox;
@@ -94,7 +93,7 @@ public:
// Create a pick for the location specified
// by global_pos.
- void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel);
+ void createPick(const LLVector3d& pos_global);
protected:
static void onNameCache(LLTextBox* text, const std::string& full_name);
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 69f181e1b3..74ec576554 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -63,7 +63,6 @@
#include "lllayoutstack.h"
#include "llpanellandmarkinfo.h"
#include "llpanellandmarks.h"
-#include "llpanelpick.h"
#include "llpanelplaceprofile.h"
#include "llpanelteleporthistory.h"
#include "llremoteparcelrequest.h"
@@ -238,7 +237,6 @@ LLPanelPlaces::LLPanelPlaces()
mFilterEditor(NULL),
mPlaceProfile(NULL),
mLandmarkInfo(NULL),
- mPickPanel(NULL),
mItem(NULL),
mPlaceMenu(NULL),
mLandmarkMenu(NULL),
@@ -952,28 +950,11 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
}
else if (item == "pick")
{
- if (mPickPanel == NULL)
- {
- mPickPanel = LLPanelPickEdit::create();
- addChild(mPickPanel);
-
- mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setCancelCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- mPickPanel->setSaveCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
- }
-
- togglePickPanel(TRUE);
- mPickPanel->onOpen(LLSD());
-
LLPanelPlaceInfo* panel = getCurrentInfoPanel();
if (panel)
{
- panel->createPick(mPosGlobal, mPickPanel);
+ panel->createPick(mPosGlobal);
}
-
- LLRect rect = getRect();
- mPickPanel->reshape(rect.getWidth(), rect.getHeight());
- mPickPanel->setRect(rect);
}
else if (item == "add_to_favbar")
{
@@ -1050,17 +1031,6 @@ bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_t
return false;
}
-void LLPanelPlaces::togglePickPanel(BOOL visible)
-{
- if (mPickPanel)
- {
- mPickPanel->setVisible(visible);
- mPlaceProfile->setVisible(!visible);
- updateVerbs();
- }
-
-}
-
void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
{
if (!mPlaceProfile || !mLandmarkInfo)
@@ -1309,15 +1279,11 @@ void LLPanelPlaces::updateVerbs()
bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
- bool is_pick_panel_visible = false;
- if(mPickPanel)
- {
- is_pick_panel_visible = mPickPanel->isInVisibleChain();
- }
+
bool have_3d_pos = ! mPosGlobal.isExactlyZero();
- mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
- mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
+ mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
+ mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 3b87eb6cb9..e554099343 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -38,7 +38,6 @@ class LLLandmark;
class LLPanelLandmarkInfo;
class LLPanelPlaceProfile;
-class LLPanelPickEdit;
class LLPanelPlaceInfo;
class LLPanelPlacesTab;
class LLParcelSelection;
@@ -95,7 +94,6 @@ private:
void onOverflowButtonClicked();
void onOverflowMenuItemClicked(const LLSD& param);
bool onOverflowMenuItemEnable(const LLSD& param);
- void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
void onBackButtonClicked();
void onGearMenuClick();
void onSortingMenuClick();
@@ -103,9 +101,6 @@ private:
void onRemoveButtonClicked();
bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
-
- void toggleMediaPanel();
- void togglePickPanel(BOOL visible);
void togglePlaceInfoPanel(BOOL visible);
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
@@ -122,7 +117,6 @@ private:
LLPanelPlaceProfile* mPlaceProfile;
LLPanelLandmarkInfo* mLandmarkInfo;
- LLPanelPickEdit* mPickPanel;
LLToggleableMenu* mPlaceMenu;
LLToggleableMenu* mLandmarkMenu;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 5f13b223fb..f4eaa78f11 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.cpp
* @brief Profile panel implementation
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, 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$
*/
@@ -27,32 +27,433 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelprofile.h"
-#include "llagent.h"
+// Common
+#include "llavatarnamecache.h"
+#include "llsdutil.h"
+#include "llslurl.h"
+#include "lldateutil.h" //ageFromDate
+
+// UI
+#include "llavatariconctrl.h"
+#include "llclipboard.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lllineeditor.h"
+#include "llloadingindicator.h"
+#include "llmenubutton.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltoggleablemenu.h"
+#include "llgrouplist.h"
+#include "llurlaction.h"
+
+// Image
+#include "llimagej2c.h"
+
+// Newview
+#include "llagent.h" //gAgent
+#include "llagentpicksinfo.h"
#include "llavataractions.h"
-#include "llfloaterreg.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
#include "llcommandhandler.h"
-#include "llnotificationsutil.h"
-#include "llpanelpicks.h"
-#include "lltabcontainer.h"
-#include "llviewercontrol.h"
-#include "llviewernetwork.h"
+#include "llfloaterprofiletexture.h"
+#include "llfloaterreg.h"
+#include "llfloaterreporter.h"
+#include "llfilepicker.h"
+#include "llfirstuse.h"
+#include "llgroupactions.h"
+#include "lllogchat.h"
#include "llmutelist.h"
+#include "llnotificationsutil.h"
#include "llpanelblockedlist.h"
+#include "llpanelprofileclassifieds.h"
+#include "llpanelprofilepicks.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewermenu.h" //is_agent_mappable
+#include "llviewermenufile.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
#include "llweb.h"
-static const std::string PANEL_PICKS = "panel_picks";
-std::string getProfileURL(const std::string& agent_name)
+static LLPanelInjector<LLPanelProfileSecondLife> t_panel_profile_secondlife("panel_profile_secondlife");
+static LLPanelInjector<LLPanelProfileWeb> t_panel_web("panel_profile_web");
+static LLPanelInjector<LLPanelProfilePicks> t_panel_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfileFirstLife> t_panel_firstlife("panel_profile_firstlife");
+static LLPanelInjector<LLPanelProfileNotes> t_panel_notes("panel_profile_notes");
+static LLPanelInjector<LLPanelProfile> t_panel_profile("panel_profile");
+
+static const std::string PANEL_SECONDLIFE = "panel_profile_secondlife";
+static const std::string PANEL_WEB = "panel_profile_web";
+static const std::string PANEL_PICKS = "panel_profile_picks";
+static const std::string PANEL_CLASSIFIEDS = "panel_profile_classifieds";
+static const std::string PANEL_FIRSTLIFE = "panel_profile_firstlife";
+static const std::string PANEL_NOTES = "panel_profile_notes";
+static const std::string PANEL_PROFILE_VIEW = "panel_profile_view";
+
+static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile";
+static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage";
+
+
+//////////////////////////////////////////////////////////////////////////
+
+void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)
{
- std::string url = "[WEB_PROFILE_URL][AGENT_NAME]";
- LLSD subs;
- subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
- subs["AGENT_NAME"] = agent_name;
- url = LLWeb::expandURLSubstitutions(url, subs);
- LLStringUtil::toLower(url);
- return url;
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL;
+
+ if (!status
+ || !result.has("id")
+ || agent_id != result["id"].asUUID())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id));
+ if (!floater_profile)
+ {
+ // floater is dead, so panels are dead as well
+ return;
+ }
+
+ LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE);
+ LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel);
+ if (!panel_profile)
+ {
+ LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL;
+ return;
+ }
+
+
+ // Avatar Data
+
+ LLAvatarData *avatar_data = &panel_profile->mAvatarData;
+ std::string birth_date;
+
+ avatar_data->agent_id = agent_id;
+ avatar_data->avatar_id = agent_id;
+ avatar_data->image_id = result["sl_image_id"].asUUID();
+ avatar_data->fl_image_id = result["fl_image_id"].asUUID();
+ avatar_data->partner_id = result["partner_id"].asUUID();
+ avatar_data->about_text = result["sl_about_text"].asString();
+ avatar_data->fl_about_text = result["fl_about_text"].asString();
+ avatar_data->born_on = result["member_since"].asDate();
+ avatar_data->profile_url = getProfileURL(agent_id.asString());
+
+ avatar_data->flags = 0;
+
+ if (result["online"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ONLINE;
+ }
+ if (result["allow_publish"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_ALLOW_PUBLISH;
+ }
+ if (result["identified"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_IDENTIFIED;
+ }
+ if (result["transacted"].asBoolean())
+ {
+ avatar_data->flags |= AVATAR_TRANSACTED;
+ }
+
+ avatar_data->caption_index = 0;
+ if (result.has("charter_member")) // won't be present if "caption" is set
+ {
+ avatar_data->caption_index = result["charter_member"].asInteger();
+ }
+ else if (result.has("caption"))
+ {
+ avatar_data->caption_text = result["caption"].asString();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE);
+ LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel);
+ if (panel_sl)
+ {
+ panel_sl->processProfileProperties(avatar_data);
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE);
+ LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel);
+ if (panel_web)
+ {
+ panel_web->setLoaded();
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE);
+ LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel);
+ if (panel_first)
+ {
+ panel_first->processProperties(avatar_data);
+ }
+
+ // Picks
+
+ LLSD picks_array = result["picks"];
+ LLAvatarPicks avatar_picks;
+ avatar_picks.agent_id = agent_id; // Not in use?
+ avatar_picks.target_id = agent_id;
+
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE);
+ LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel);
+ if (panel_picks)
+ {
+ // Refresh pick limit before processing
+ LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks);
+ panel_picks->processProperties(&avatar_picks);
+ }
+
+ // Groups
+
+ LLSD groups_array = result["groups"];
+ LLAvatarGroups avatar_groups;
+ avatar_groups.agent_id = agent_id; // Not in use?
+ avatar_groups.avatar_id = agent_id; // target_id
+
+ for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
+ {
+ const LLSD& group_info = *it;
+ LLAvatarGroups::LLGroupData group_data;
+ group_data.group_powers = 0; // Not in use?
+ group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
+ group_data.group_id = group_info["id"].asUUID();
+ group_data.group_name = group_info["name"].asString();
+ group_data.group_insignia_id = group_info["image_id"].asUUID();
+
+ avatar_groups.group_list.push_back(group_data);
+ }
+
+ if (panel_sl)
+ {
+ panel_sl->processGroupProperties(&avatar_groups);
+ }
+
+ // Notes
+ LLAvatarNotes avatar_notes;
+
+ avatar_notes.agent_id = agent_id;
+ avatar_notes.target_id = agent_id;
+ avatar_notes.notes = result["notes"].asString();
+
+ panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE);
+ LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel);
+ if (panel_notes)
+ {
+ panel_notes->processProperties(&avatar_notes);
+ }
+}
+
+//TODO: changes take two minutes to propagate!
+// Add some storage that holds updated data for two minutes
+// for new instances to reuse the data
+// Profile data is only relevant to won avatar, but notes
+// are for everybody
+void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL;
+}
+
+LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("post_profile_image_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, first_data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+ if (!result.has("uploader"))
+ {
+ // todo: notification?
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, response contains no data." << LL_ENDL;
+ return LLUUID::null;
+ }
+ std::string uploader_cap = result["uploader"].asString();
+ if (uploader_cap.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to get uploader cap, cap invalid." << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ // Upload the image
+
+ LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
+ LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
+ S64 length;
+
+ {
+ llifstream instream(path_to_image.c_str(), std::iostream::binary | std::iostream::ate);
+ if (!instream.is_open())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to open file " << path_to_image << LL_ENDL;
+ return LLUUID::null;
+ }
+ length = instream.tellg();
+ }
+
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/jp2"); // optional
+ uploaderhttpHeaders->append(HTTP_OUT_HEADER_CONTENT_LENGTH, llformat("%d", length)); // required!
+ uploaderhttpOpts->setFollowRedirects(true);
+
+ result = httpAdapter->postFileAndSuspend(uploaderhttpRequest, uploader_cap, path_to_image, uploaderhttpOpts, uploaderhttpHeaders);
+
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ LL_WARNS("AvatarProperties") << result << LL_ENDL;
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << status.toString() << LL_ENDL;
+ return LLUUID::null;
+ }
+
+ if (result["state"].asString() != "complete")
+ {
+ if (result.has("message"))
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image, state " << result["state"] << " message: " << result["message"] << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload image " << result << LL_ENDL;
+ }
+ return LLUUID::null;
+ }
+
+ return result["new_asset"].asUUID();
}
+enum EProfileImageType
+{
+ PROFILE_IMAGE_SL,
+ PROFILE_IMAGE_FL,
+};
+
+void post_profile_image_coro(std::string cap_url, EProfileImageType type, std::string path_to_image, LLHandle<LLPanel> *handle)
+{
+ LLSD data;
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ data["profile-image-asset"] = "sl_image_id";
+ break;
+ case PROFILE_IMAGE_FL:
+ data["profile-image-asset"] = "fl_image_id";
+ break;
+ }
+
+ LLUUID result = post_profile_image(cap_url, data, path_to_image, handle);
+
+ // reset loading indicator
+ if (!handle->isDead())
+ {
+ switch (type)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(handle->get());
+ if (result.notNull())
+ {
+ panel->setProfileImageUploaded(result);
+ }
+ else
+ {
+ // failure, just stop progress indicator
+ panel->setProfileImageUploading(false);
+ }
+ break;
+ }
+ }
+ }
+
+ // Cleanup
+ LLFile::remove(path_to_image);
+ delete handle;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLProfileHandler
+
class LLProfileHandler : public LLCommandHandler
{
public:
@@ -73,6 +474,10 @@ public:
};
LLProfileHandler gProfileHandler;
+
+//////////////////////////////////////////////////////////////////////////
+// LLAgentHandler
+
class LLAgentHandler : public LLCommandHandler
{
public:
@@ -178,279 +583,2070 @@ public:
}
return true;
}
+
+ // reportAbuse is here due to convoluted avatar handling
+ // in LLScrollListCtrl and LLTextBase
+ if (verb == "reportAbuse" && web == NULL)
+ {
+ LLAvatarName av_name;
+ if (LLAvatarNameCache::get(avatar_id, &av_name))
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName());
+ }
+ else
+ {
+ LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable");
+ }
+ return true;
+ }
return false;
}
};
LLAgentHandler gAgentHandler;
-//-- LLPanelProfile::ChildStack begins ----------------------------------------
-LLPanelProfile::ChildStack::ChildStack()
-: mParent(NULL)
+///----------------------------------------------------------------------------
+/// LLFloaterProfilePermissions
+///----------------------------------------------------------------------------
+
+class LLFloaterProfilePermissions
+ : public LLFloater
+ , public LLFriendObserver
{
+public:
+ LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id);
+ ~LLFloaterProfilePermissions();
+ BOOL postBuild() override;
+ void onOpen(const LLSD& key) override;
+ void draw() override;
+ void changed(U32 mask) override; // LLFriendObserver
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+ bool hasUnsavedChanges() { return mHasUnsavedPermChanges; }
+
+ void onApplyRights();
+
+private:
+ void fillRightsData();
+ void rightsConfirmationCallback(const LLSD& notification, const LLSD& response);
+ void confirmModifyRights(bool grant);
+ void onCommitSeeOnlineRights();
+ void onCommitEditRights();
+ void onCancel();
+
+ LLTextBase* mDescription;
+ LLCheckBoxCtrl* mOnlineStatus;
+ LLCheckBoxCtrl* mMapRights;
+ LLCheckBoxCtrl* mEditObjectRights;
+ LLButton* mOkBtn;
+ LLButton* mCancelBtn;
+
+ LLUUID mAvatarID;
+ F32 mContextConeOpacity;
+ bool mHasUnsavedPermChanges;
+ LLHandle<LLView> mOwnerHandle;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+LLFloaterProfilePermissions::LLFloaterProfilePermissions(LLView * owner, const LLUUID &avatar_id)
+ : LLFloater(LLSD())
+ , mAvatarID(avatar_id)
+ , mContextConeOpacity(0.0f)
+ , mHasUnsavedPermChanges(false)
+ , mOwnerHandle(owner->getHandle())
+{
+ buildFromFile("floater_profile_permissions.xml");
}
-LLPanelProfile::ChildStack::~ChildStack()
+LLFloaterProfilePermissions::~LLFloaterProfilePermissions()
{
- while (mStack.size() != 0)
- {
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- if (viewp)
- {
- viewp->die();
- }
- }
- mStack.pop_back();
- }
+ mAvatarNameCacheConnection.disconnect();
+ if (mAvatarID.notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
+ }
}
-void LLPanelProfile::ChildStack::setParent(LLPanel* parent)
+BOOL LLFloaterProfilePermissions::postBuild()
{
- llassert_always(parent != NULL);
- mParent = parent;
+ mDescription = getChild<LLTextBase>("perm_description");
+ mOnlineStatus = getChild<LLCheckBoxCtrl>("online_check");
+ mMapRights = getChild<LLCheckBoxCtrl>("map_check");
+ mEditObjectRights = getChild<LLCheckBoxCtrl>("objects_check");
+ mOkBtn = getChild<LLButton>("perms_btn_ok");
+ mCancelBtn = getChild<LLButton>("perms_btn_cancel");
+
+ mOnlineStatus->setCommitCallback([this](LLUICtrl*, void*) { onCommitSeeOnlineRights(); }, nullptr);
+ mMapRights->setCommitCallback([this](LLUICtrl*, void*) { mHasUnsavedPermChanges = true; }, nullptr);
+ mEditObjectRights->setCommitCallback([this](LLUICtrl*, void*) { onCommitEditRights(); }, nullptr);
+ mOkBtn->setCommitCallback([this](LLUICtrl*, void*) { onApplyRights(); }, nullptr);
+ mCancelBtn->setCommitCallback([this](LLUICtrl*, void*) { onCancel(); }, nullptr);
+
+ return TRUE;
}
-/// Save current parent's child views and remove them from the child list.
-bool LLPanelProfile::ChildStack::push()
+void LLFloaterProfilePermissions::onOpen(const LLSD& key)
{
- view_list_t vlist = *mParent->getChildList();
+ if (LLAvatarActions::isFriend(mAvatarID))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
+ fillRightsData();
+ }
- for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->removeChild(viewp);
- }
+ mCancelBtn->setFocus(true);
- mStack.push_back(vlist);
- dump();
- return true;
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterProfilePermissions::onAvatarNameCache, this, _1, _2));
}
-/// Restore saved children (adding them back to the child list).
-bool LLPanelProfile::ChildStack::pop()
+void LLFloaterProfilePermissions::draw()
{
- if (mStack.size() == 0)
- {
- LL_WARNS() << "Empty stack" << LL_ENDL;
- llassert(mStack.size() == 0);
- return false;
- }
+ // drawFrustum
+ LLView *owner = mOwnerHandle.get();
+ static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+ drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+ LLFloater::draw();
+}
- view_list_t& top = mStack.back();
- for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
- {
- LLView* viewp = *it;
- mParent->addChild(viewp);
- }
+void LLFloaterProfilePermissions::changed(U32 mask)
+{
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
- mStack.pop_back();
- dump();
- return true;
+void LLFloaterProfilePermissions::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ LLStringUtil::format_map_t args;
+ args["[AGENT_NAME]"] = av_name.getDisplayName();
+ std::string descritpion = getString("description_string", args);
+ mDescription->setValue(descritpion);
}
-/// Temporarily add all saved children back.
-void LLPanelProfile::ChildStack::preParentReshape()
+void LLFloaterProfilePermissions::fillRightsData()
{
- mSavedStack = mStack;
- while(mStack.size() > 0)
- {
- pop();
- }
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+
+ BOOL see_online = LLRelationship::GRANT_ONLINE_STATUS & rights ? TRUE : FALSE;
+ mOnlineStatus->setValue(see_online);
+ mMapRights->setEnabled(see_online);
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ mEditObjectRights->setValue(LLRelationship::GRANT_MODIFY_OBJECTS & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
}
-/// Add the temporarily saved children back.
-void LLPanelProfile::ChildStack::postParentReshape()
+void LLFloaterProfilePermissions::rightsConfirmationCallback(const LLSD& notification,
+ const LLSD& response)
{
- mStack = mSavedStack;
- mSavedStack = stack_t();
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option != 0) // canceled
+ {
+ mEditObjectRights->setValue(mEditObjectRights->getValue().asBoolean() ? FALSE : TRUE);
+ }
+ else
+ {
+ mHasUnsavedPermChanges = true;
+ }
+}
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it)
- {
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- LLView* viewp = *list_it;
- LL_DEBUGS() << "removing " << viewp->getName() << LL_ENDL;
- mParent->removeChild(viewp);
- }
- }
+void LLFloaterProfilePermissions::confirmModifyRights(bool grant)
+{
+ LLSD args;
+ args["NAME"] = LLSLURL("agent", mAvatarID, "completename").getSLURLString();
+ LLNotificationsUtil::add(grant ? "GrantModifyRights" : "RevokeModifyRights", args, LLSD(),
+ boost::bind(&LLFloaterProfilePermissions::rightsConfirmationCallback, this, _1, _2));
}
-void LLPanelProfile::ChildStack::dump()
+void LLFloaterProfilePermissions::onCommitSeeOnlineRights()
{
- unsigned lvl = 0;
- LL_DEBUGS() << "child stack dump:" << LL_ENDL;
- for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl)
- {
- std::ostringstream dbg_line;
- dbg_line << "lvl #" << lvl << ":";
- const view_list_t& vlist = (*stack_it);
- for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
- {
- dbg_line << " " << (*list_it)->getName();
- }
- LL_DEBUGS() << dbg_line.str() << LL_ENDL;
- }
+ bool see_online = mOnlineStatus->getValue().asBoolean();
+ mMapRights->setEnabled(see_online);
+ if (see_online)
+ {
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ mMapRights->setValue(LLRelationship::GRANT_MAP_LOCATION & rights ? TRUE : FALSE);
+ }
+ else
+ {
+ closeFloater();
+ LL_INFOS("ProfilePermissions") << "Floater closing since agent is no longer a friend" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mMapRights->setValue(FALSE);
+ }
+ mHasUnsavedPermChanges = true;
}
-//-- LLPanelProfile::ChildStack ends ------------------------------------------
+void LLFloaterProfilePermissions::onCommitEditRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
-LLPanelProfile::LLPanelProfile()
- : LLPanel()
- , mAvatarId(LLUUID::null)
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Closing floater." << LL_ENDL;
+ closeFloater();
+ return;
+ }
+
+ bool allow_modify_objects = mEditObjectRights->getValue().asBoolean();
+
+ // if modify objects checkbox clicked
+ if (buddy_relationship->isRightGrantedTo(
+ LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects)
+ {
+ confirmModifyRights(allow_modify_objects);
+ }
+}
+
+void LLFloaterProfilePermissions::onApplyRights()
+{
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(mAvatarID);
+
+ if (!buddy_relationship)
+ {
+ LL_WARNS("ProfilePermissions") << "Trying to modify rights for non-friend avatar. Skipped." << LL_ENDL;
+ return;
+ }
+
+ S32 rights = 0;
+
+ if (mOnlineStatus->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ }
+ if (mMapRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MAP_LOCATION;
+ }
+ if (mEditObjectRights->getValue().asBoolean())
+ {
+ rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
+ }
+
+ LLAvatarPropertiesProcessor::getInstance()->sendFriendRights(mAvatarID, rights);
+
+ closeFloater();
+}
+
+void LLFloaterProfilePermissions::onCancel()
{
- mChildStack.setParent(this);
+ closeFloater();
}
-BOOL LLPanelProfile::postBuild()
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileSecondLife
+
+LLPanelProfileSecondLife::LLPanelProfileSecondLife()
+ : LLPanelProfileTab()
+ , mAvatarNameCacheConnection()
+ , mHasUnsavedDescriptionChanges(false)
+ , mWaitingForImageUpload(false)
+ , mAllowPublish(false)
+{
+}
+
+LLPanelProfileSecondLife::~LLPanelProfileSecondLife()
+{
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
+ }
+
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+BOOL LLPanelProfileSecondLife::postBuild()
+{
+ mGroupList = getChild<LLGroupList>("group_list");
+ mShowInSearchCombo = getChild<LLComboBox>("show_in_search");
+ mSecondLifePic = getChild<LLIconCtrl>("2nd_life_pic");
+ mSecondLifePicLayout = getChild<LLPanel>("image_panel");
+ mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit");
+ mAgentActionMenuButton = getChild<LLMenuButton>("agent_actions_menu");
+ mSaveDescriptionChanges = getChild<LLButton>("save_description_changes");
+ mDiscardDescriptionChanges = getChild<LLButton>("discard_description_changes");
+ mCanSeeOnlineIcon = getChild<LLIconCtrl>("can_see_online");
+ mCantSeeOnlineIcon = getChild<LLIconCtrl>("cant_see_online");
+ mCanSeeOnMapIcon = getChild<LLIconCtrl>("can_see_on_map");
+ mCantSeeOnMapIcon = getChild<LLIconCtrl>("cant_see_on_map");
+ mCanEditObjectsIcon = getChild<LLIconCtrl>("can_edit_objects");
+ mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects");
+
+ mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr);
+ mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); });
+ mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ mCanSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnlineIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); });
+ mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileSecondLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ LLUUID avatar_id = getAvatarId();
+
+ BOOL own_profile = getSelfProfile();
+
+ mGroupList->setShowNone(!own_profile);
+
+ childSetVisible("notes_panel", !own_profile);
+ childSetVisible("settings_panel", own_profile);
+ childSetVisible("about_buttons_panel", own_profile);
+
+ if (own_profile)
+ {
+ // Group list control cannot toggle ForAgent loading
+ // Less than ideal, but viewing own profile via search is edge case
+ mGroupList->enableForAgent(false);
+ }
+
+ // Init menu, menu needs to be created in scope of a registar to work correctly.
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commit;
+ commit.add("Profile.Commit", [this](LLUICtrl*, const LLSD& userdata) { onCommitMenu(userdata); });
+
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable;
+ enable.add("Profile.EnableItem", [this](LLUICtrl*, const LLSD& userdata) { return onEnableMenu(userdata); });
+ enable.add("Profile.CheckItem", [this](LLUICtrl*, const LLSD& userdata) { return onCheckMenu(userdata); });
+
+ if (own_profile)
+ {
+ mAgentActionMenuButton->setMenu("menu_profile_self.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+ else
+ {
+ // Todo: use PeopleContextMenu instead?
+ mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT);
+ }
+
+ mDescriptionEdit->setParseHTML(!own_profile);
+
+ if (!own_profile)
+ {
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(avatar_id) ? LLAvatarTracker::instance().isBuddyOnline(avatar_id) : TRUE);
+ updateOnlineStatus();
+ fillRightsData();
+ }
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+}
+
+void LLPanelProfileSecondLife::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ else
+ {
+ LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::refreshName()
+{
+ if (!mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
+ }
+}
+
+void LLPanelProfileSecondLife::resetData()
+{
+ resetLoading();
+
+ // Set default image and 1:1 dimensions for it
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ mSecondLifePicLayout->reshape(imageRect.getHeight(), imageRect.getHeight());
+
+ setDescriptionText(LLStringUtil::null);
+ mGroups.clear();
+ mGroupList->setGroups(mGroups);
+
+ bool own_profile = getSelfProfile();
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(!own_profile);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(!own_profile);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(!own_profile);
+
+ mCanSeeOnlineIcon->setEnabled(false);
+ mCantSeeOnlineIcon->setEnabled(false);
+ mCanSeeOnMapIcon->setEnabled(false);
+ mCantSeeOnMapIcon->setEnabled(false);
+ mCanEditObjectsIcon->setEnabled(false);
+ mCantEditObjectsIcon->setEnabled(false);
+
+ childSetVisible("partner_layout", FALSE);
+}
+
+void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
+{
+ LLUUID avatar_id = getAvatarId();
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile())
+ {
+ // Relies onto friend observer to get information about online status updates.
+ // Once SL-17506 gets implemented, condition might need to become:
+ // (gAgent.isGodlike() || isRightGrantedFrom || flags & AVATAR_ONLINE)
+ processOnlineStatus(relationship != NULL,
+ gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS),
+ (avatar_data->flags & AVATAR_ONLINE));
+ }
+
+ fillCommonData(avatar_data);
+
+ fillPartnerData(avatar_data);
+
+ fillAccountStatus(avatar_data);
+
+ setLoaded();
+}
+
+void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups)
+{
+
+ LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
+ const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
+
+ for (; it_end != it; ++it)
+ {
+ LLAvatarGroups::LLGroupData group_data = *it;
+ mGroups[group_data.group_name] = group_data.group_id;
+ }
+
+ mGroupList->setGroups(mGroups);
+}
+
+void LLPanelProfileSecondLife::openGroupProfile()
+{
+ LLUUID group_id = mGroupList->getSelectedUUID();
+ LLGroupActions::show(group_id);
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+ getChild<LLUICtrl>("display_name")->setValue(av_name.getDisplayName());
+ getChild<LLUICtrl>("user_name")->setValue(av_name.getAccountName());
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploading(bool loading)
+{
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+ mWaitingForImageUpload = loading;
+}
+
+void LLPanelProfileSecondLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mSecondLifePic->setValue(image_asset_id);
+ mImageId = image_asset_id;
+
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(image_asset_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+
+ setProfileImageUploading(false);
+}
+
+bool LLPanelProfileSecondLife::hasUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ return true;
+ }
+ }
+ // if floater
+ return mHasUnsavedDescriptionChanges;
+}
+
+void LLPanelProfileSecondLife::commitUnsavedChanges()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (floater)
+ {
+ LLFloaterProfilePermissions* perm = dynamic_cast<LLFloaterProfilePermissions*>(floater);
+ if (perm && perm->hasUnsavedChanges())
+ {
+ perm->onApplyRights();
+ }
+ }
+ if (mHasUnsavedDescriptionChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
+{
+ // Refresh avatar id in cache with new info to prevent re-requests
+ // and to make sure icons in text will be up to date
+ LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id);
+
+ fillAgeData(avatar_data->born_on);
+
+ setDescriptionText(avatar_data->about_text);
+
+ if (avatar_data->image_id.notNull())
+ {
+ mSecondLifePic->setValue(avatar_data->image_id);
+ mImageId = avatar_data->image_id;
+ }
+ else
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+ }
+
+ // Will be loaded as a LLViewerFetchedTexture::BOOST_UI due to mSecondLifePic
+ LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(avatar_data->image_id);
+ if (imagep->getFullHeight())
+ {
+ onImageLoaded(true, imagep);
+ }
+ else
+ {
+ imagep->setLoadedCallback(onImageLoaded,
+ MAX_DISCARD_LEVEL,
+ FALSE,
+ FALSE,
+ new LLHandle<LLPanel>(getHandle()),
+ NULL,
+ FALSE);
+ }
+
+ if (getSelfProfile())
+ {
+ mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH;
+ mShowInSearchCombo->setValue((BOOL)mAllowPublish);
+ }
+}
+
+void LLPanelProfileSecondLife::fillPartnerData(const LLAvatarData* avatar_data)
+{
+ LLTextBox* partner_text_ctrl = getChild<LLTextBox>("partner_link");
+ if (avatar_data->partner_id.notNull())
+ {
+ childSetVisible("partner_layout", TRUE);
+ LLStringUtil::format_map_t args;
+ args["[LINK]"] = LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString();
+ std::string partner_text = getString("partner_text", args);
+ partner_text_ctrl->setText(partner_text);
+ }
+ else
+ {
+ childSetVisible("partner_layout", FALSE);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data)
+{
+ LLStringUtil::format_map_t args;
+ args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(avatar_data);
+ args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(avatar_data);
+
+ std::string caption_text = getString("CaptionTextAcctInfo", args);
+ getChild<LLUICtrl>("account_info")->setValue(caption_text);
+}
+
+void LLPanelProfileSecondLife::fillRightsData()
+{
+ if (getSelfProfile())
+ {
+ return;
+ }
+
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ // If true - we are viewing friend's profile, enable check boxes and set values.
+ if (relation)
+ {
+ S32 rights = relation->getRightsGrantedTo();
+ bool can_see_online = LLRelationship::GRANT_ONLINE_STATUS & rights;
+ bool can_see_on_map = LLRelationship::GRANT_MAP_LOCATION & rights;
+ bool can_edit_objects = LLRelationship::GRANT_MODIFY_OBJECTS & rights;
+
+ mCanSeeOnlineIcon->setVisible(can_see_online);
+ mCantSeeOnlineIcon->setVisible(!can_see_online);
+ mCanSeeOnMapIcon->setVisible(can_see_on_map);
+ mCantSeeOnMapIcon->setVisible(!can_see_on_map);
+ mCanEditObjectsIcon->setVisible(can_edit_objects);
+ mCantEditObjectsIcon->setVisible(!can_edit_objects);
+
+ mCanSeeOnlineIcon->setEnabled(true);
+ mCantSeeOnlineIcon->setEnabled(true);
+ mCanSeeOnMapIcon->setEnabled(true);
+ mCantSeeOnMapIcon->setEnabled(true);
+ mCanEditObjectsIcon->setEnabled(true);
+ mCantEditObjectsIcon->setEnabled(true);
+ }
+ else
+ {
+ mCanSeeOnlineIcon->setVisible(false);
+ mCantSeeOnlineIcon->setVisible(false);
+ mCanSeeOnMapIcon->setVisible(false);
+ mCantSeeOnMapIcon->setVisible(false);
+ mCanEditObjectsIcon->setVisible(false);
+ mCantEditObjectsIcon->setVisible(false);
+ }
+}
+
+void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on)
+{
+ std::string name_and_date = getString("date_format");
+ LLSD args_name;
+ args_name["datetime"] = (S32)born_on.secondsSinceEpoch();
+ LLStringUtil::format(name_and_date, args_name);
+ getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date);
+
+ std::string register_date = getString("age_format");
+ LLSD args_age;
+ args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now());
+ LLStringUtil::format(register_date, args_age);
+ getChild<LLUICtrl>("user_age")->setValue(register_date);
+}
+
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep)
+{
+ LLRect imageRect = mSecondLifePicLayout->getRect();
+ if (!success || imagep->getFullWidth() == imagep->getFullHeight())
+ {
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth());
+ }
+ else
+ {
+ // assume 3:4, for sake of firestorm
+ mSecondLifePicLayout->reshape(imageRect.getWidth(), imageRect.getWidth() * 3 / 4);
+ }
+}
+
+//static
+void LLPanelProfileSecondLife::onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata)
+{
+ if (!userdata) return;
+
+ LLHandle<LLPanel>* handle = (LLHandle<LLPanel>*)userdata;
+
+ if (!handle->isDead())
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(handle->get());
+ if (panel)
+ {
+ panel->onImageLoaded(success, src_vi);
+ }
+ }
+
+ if (final || !success)
+ {
+ delete handle;
+ }
+}
+
+// virtual, called by LLAvatarTracker
+void LLPanelProfileSecondLife::changed(U32 mask)
+{
+ updateOnlineStatus();
+ if (mask != LLFriendObserver::ONLINE)
+ {
+ fillRightsData();
+ }
+}
+
+// virtual, called by LLVoiceClient
+void LLPanelProfileSecondLife::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+ if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+ {
+ return;
+ }
+
+ mVoiceStatus = LLAvatarActions::canCall() && (LLAvatarActions::isFriend(getAvatarId()) ? LLAvatarTracker::instance().isBuddyOnline(getAvatarId()) : TRUE);
+}
+
+void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ if (getAvatarId().notNull())
+ {
+ LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+ }
+
+ LLPanelProfileTab::setAvatarId(avatar_id);
+
+ if (LLAvatarActions::isFriend(getAvatarId()))
+ {
+ LLAvatarTracker::instance().addParticularFriendObserver(getAvatarId(), this);
+ }
+ }
+}
+
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
+void LLPanelProfileSecondLife::updateOnlineStatus()
+{
+ const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if (relationship != NULL)
+ {
+ // For friend let check if he allowed me to see his status
+ bool online = relationship->isOnline();
+ bool perm_granted = relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
+ processOnlineStatus(true, perm_granted, online);
+ }
+ else
+ {
+ childSetVisible("frind_layout", false);
+ childSetVisible("online_layout", false);
+ childSetVisible("offline_layout", false);
+ }
+}
+
+void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online)
+{
+ childSetVisible("frind_layout", is_friend);
+ childSetVisible("online_layout", online && show_online);
+ childSetVisible("offline_layout", !online && show_online);
+}
+
+void LLPanelProfileSecondLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mShowInSearchCombo->setEnabled(TRUE);
+ mDescriptionEdit->setEnabled(TRUE);
+ }
+}
+
+
+
+class LLProfileImagePicker : public LLFilePickerThread
+{
+public:
+ LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle);
+ ~LLProfileImagePicker();
+ void notify(const std::vector<std::string>& filenames) override;
+
+private:
+ LLHandle<LLPanel> *mHandle;
+ EProfileImageType mType;
+};
+
+LLProfileImagePicker::LLProfileImagePicker(EProfileImageType type, LLHandle<LLPanel> *handle)
+ : LLFilePickerThread(LLFilePicker::FFLOAD_IMAGE),
+ mHandle(handle),
+ mType(type)
+{
+}
+
+LLProfileImagePicker::~LLProfileImagePicker()
+{
+ delete mHandle;
+}
+
+void LLProfileImagePicker::notify(const std::vector<std::string>& filenames)
+{
+ if (mHandle->isDead())
+ {
+ return;
+ }
+ if (filenames.empty())
+ {
+ return;
+ }
+ std::string file_path = filenames[0];
+ if (file_path.empty())
+ {
+ return;
+ }
+
+ // generate a temp texture file for coroutine
+ std::string temp_file = gDirUtilp->getTempFilename();
+ U32 codec = LLImageBase::getCodecFromExtension(gDirUtilp->getExtension(file_path));
+ const S32 MAX_DIM = 256;
+ if (!LLViewerTextureList::createUploadFile(file_path, temp_file, codec, MAX_DIM))
+ {
+ //todo: image not supported notification
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", failed to open image" << LL_ENDL;
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ if (cap_url.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to upload profile image of type " << (S32)PROFILE_IMAGE_SL << ", no cap found" << LL_ENDL;
+ return;
+ }
+
+ switch (mType)
+ {
+ case PROFILE_IMAGE_SL:
+ {
+ LLPanelProfileSecondLife* panel = static_cast<LLPanelProfileSecondLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ case PROFILE_IMAGE_FL:
+ {
+ LLPanelProfileFirstLife* panel = static_cast<LLPanelProfileFirstLife*>(mHandle->get());
+ panel->setProfileImageUploading(true);
+ }
+ break;
+ }
+
+ LLCoros::instance().launch("postAgentUserImageCoro",
+ boost::bind(post_profile_image_coro, cap_url, mType, temp_file, mHandle));
+
+ mHandle = nullptr; // transferred to post_profile_image_coro
+}
+
+void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ // todo: consider moving this into LLAvatarActions::onCommit(name, id)
+ // and making all other flaoters, like people menu do the same
+ if (item_name == "im")
+ {
+ LLAvatarActions::startIM(agent_id);
+ }
+ else if (item_name == "offer_teleport")
+ {
+ LLAvatarActions::offerTeleport(agent_id);
+ }
+ else if (item_name == "request_teleport")
+ {
+ LLAvatarActions::teleportRequest(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ LLAvatarActions::startCall(agent_id);
+ }
+ else if (item_name == "chat_history")
+ {
+ LLAvatarActions::viewChatHistory(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ LLAvatarActions::requestFriendshipDialog(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ LLAvatarActions::removeFriendDialog(agent_id);
+ }
+ else if (item_name == "invite_to_group")
+ {
+ LLAvatarActions::inviteToGroup(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ LLAvatarActions::showOnMap(agent_id);
+ }
+ else if (item_name == "share")
+ {
+ LLAvatarActions::share(agent_id);
+ }
+ else if (item_name == "pay")
+ {
+ LLAvatarActions::pay(agent_id);
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ LLAvatarActions::toggleBlock(agent_id);
+ }
+ else if (item_name == "copy_user_id")
+ {
+ LLWString wstr = utf8str_to_wstring(getAvatarId().asString());
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "agent_permissions")
+ {
+ onShowAgentPermissionsDialog();
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get(getAvatarId(), &av_name))
+ {
+ // shouldn't happen, option is supposed to be invisible while name is fetching
+ LL_WARNS() << "Failed to get agent data" << LL_ENDL;
+ return;
+ }
+ LLWString wstr;
+ if (item_name == "copy_display_name")
+ {
+ wstr = utf8str_to_wstring(av_name.getDisplayName(true));
+ }
+ else if (item_name == "copy_username")
+ {
+ wstr = utf8str_to_wstring(av_name.getUserName());
+ }
+ LLClipboard::instance().copyToClipboard(wstr, 0, wstr.size());
+ }
+ else if (item_name == "edit_display_name")
+ {
+ LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCacheSetName, this, _1, _2));
+ LLFirstUse::setDisplayName(false);
+ }
+ else if (item_name == "edit_partner")
+ {
+ std::string url = "https://[GRID]/my/account/partners.php";
+ LLSD subs;
+ url = LLWeb::expandURLSubstitutions(url, subs);
+ LLUrlAction::openURL(url);
+ }
+ else if (item_name == "upload_photo")
+ {
+ (new LLProfileImagePicker(PROFILE_IMAGE_SL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+ else if (item_name == "change_photo")
+ {
+ onShowTexturePicker();
+ }
+ else if (item_name == "remove_photo")
+ {
+ onCommitProfileImage(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+ }
+}
+
+bool LLPanelProfileSecondLife::onEnableMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "offer_teleport" || item_name == "request_teleport")
+ {
+ return LLAvatarActions::canOfferTeleport(agent_id);
+ }
+ else if (item_name == "voice_call")
+ {
+ return mVoiceStatus;
+ }
+ else if (item_name == "chat_history")
+ {
+ return LLLogChat::isTranscriptExist(agent_id);
+ }
+ else if (item_name == "add_friend")
+ {
+ return !LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "remove_friend")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "can_show_on_map")
+ {
+ return (LLAvatarTracker::instance().isBuddyOnline(agent_id) && is_agent_mappable(agent_id))
+ || gAgent.isGodlike();
+ }
+ else if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::canBlock(agent_id);
+ }
+ else if (item_name == "agent_permissions")
+ {
+ return LLAvatarActions::isFriend(agent_id);
+ }
+ else if (item_name == "copy_display_name"
+ || item_name == "copy_username")
+ {
+ return !mAvatarNameCacheConnection.connected();
+ }
+ else if (item_name == "upload_photo"
+ || item_name == "change_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP);
+ return !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+ else if (item_name == "remove_photo")
+ {
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ return mImageId.notNull() && !cap_url.empty() && !mWaitingForImageUpload && getIsLoaded();
+ }
+
+ return false;
+}
+
+bool LLPanelProfileSecondLife::onCheckMenu(const LLSD& userdata)
+{
+ const std::string item_name = userdata.asString();
+ const LLUUID agent_id = getAvatarId();
+ if (item_name == "toggle_block_agent")
+ {
+ return LLAvatarActions::isBlocked(agent_id);
+ }
+ return false;
+}
+
+void LLPanelProfileSecondLife::onAvatarNameCacheSetName(const LLUUID& agent_id, const LLAvatarName& av_name)
{
- LLPanelPicks* panel_picks = findChild<LLPanelPicks>(PANEL_PICKS);
- panel_picks->setProfilePanel(this);
+ if (av_name.getDisplayName().empty())
+ {
+ // something is wrong, tell user to try again later
+ LLNotificationsUtil::add("SetDisplayNameFailedGeneric");
+ return;
+ }
- getTabContainer()[PANEL_PICKS] = panel_picks;
+ LL_INFOS("LegacyProfile") << "name-change now " << LLDate::now() << " next_update "
+ << LLDate(av_name.mNextUpdate) << LL_ENDL;
+ F64 now_secs = LLDate::now().secondsSinceEpoch();
- return TRUE;
+ if (now_secs < av_name.mNextUpdate)
+ {
+ // if the update time is more than a year in the future, it means updates have been blocked
+ // show a more general message
+ static const S32 YEAR = 60*60*24*365;
+ if (now_secs + YEAR < av_name.mNextUpdate)
+ {
+ LLNotificationsUtil::add("SetDisplayNameBlocked");
+ return;
+ }
+ }
+
+ LLFloaterReg::showInstance("display_name");
+}
+
+void LLPanelProfileSecondLife::setDescriptionText(const std::string &text)
+{
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+
+ mDescriptionText = text;
+ mDescriptionEdit->setValue(mDescriptionText);
}
-// virtual
-void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent)
+void LLPanelProfileSecondLife::onSetDescriptionDirty()
{
- // Temporarily add saved children back and reshape them.
- mChildStack.preParentReshape();
- LLPanel::reshape(width, height, called_from_parent);
- mChildStack.postParentReshape();
+ mSaveDescriptionChanges->setEnabled(TRUE);
+ mDiscardDescriptionChanges->setEnabled(TRUE);
+ mHasUnsavedDescriptionChanges = true;
+}
+
+void LLPanelProfileSecondLife::onShowInSearchCallback()
+{
+ S32 value = mShowInSearchCombo->getValue().asInteger();
+ if (mAllowPublish == (bool)value)
+ {
+ return;
+ }
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ mAllowPublish = value;
+ LLSD data;
+ data["allow_publish"] = mAllowPublish;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileSecondLife::onSaveDescriptionChanges()
+{
+ mDescriptionText = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveDescriptionChanges->setEnabled(FALSE);
+ mDiscardDescriptionChanges->setEnabled(FALSE);
+ mHasUnsavedDescriptionChanges = false;
+}
+
+void LLPanelProfileSecondLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mDescriptionText);
+}
+
+void LLPanelProfileSecondLife::onShowAgentPermissionsDialog()
+{
+ LLFloater *floater = mFloaterPermissionsHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfilePermissions * perms = new LLFloaterProfilePermissions(parent_floater, getAvatarId());
+ mFloaterPermissionsHandle = perms->getHandle();
+ perms->openFloater();
+ perms->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterPermissionsHandle);
+ }
+ }
+ else // already open
+ {
+ floater->setMinimized(FALSE);
+ floater->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onShowAgentProfileTexture()
+{
+ if (!getIsLoaded())
+ {
+ return;
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (!floater)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater);
+ mFloaterProfileTextureHandle = texture_view->getHandle();
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ texture_view->openFloater();
+ texture_view->setVisibleAndFrontmost(TRUE);
+
+ parent_floater->addDependentFloater(mFloaterProfileTextureHandle);
+ }
+ }
+ else // already open
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ texture_view->setMinimized(FALSE);
+ texture_view->setVisibleAndFrontmost(TRUE);
+ if (mImageId.notNull())
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ else
+ {
+ texture_view->resetAsset();
+ }
+ }
+}
+
+void LLPanelProfileSecondLife::onShowTexturePicker()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitProfileImage(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setBakeTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["sl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId == LLUUID::null)
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ }
+ else
+ {
+ mSecondLifePic->setValue(mImageId);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
+ if (mImageId == LLUUID::null)
+ {
+ texture_view->resetAsset();
+ }
+ else
+ {
+ texture_view->loadAsset(mImageId);
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfileWeb
+
+LLPanelProfileWeb::LLPanelProfileWeb()
+ : LLPanelProfileTab()
+ , mWebBrowser(NULL)
+ , mAvatarNameCacheConnection()
+{
+}
+
+LLPanelProfileWeb::~LLPanelProfileWeb()
+{
+ if (mAvatarNameCacheConnection.connected())
+ {
+ mAvatarNameCacheConnection.disconnect();
+ }
+}
+
+void LLPanelProfileWeb::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+
+ mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileWeb::onAvatarNameCache, this, _1, _2));
+}
+
+BOOL LLPanelProfileWeb::postBuild()
+{
+ mWebBrowser = getChild<LLMediaCtrl>("profile_html");
+ mWebBrowser->addObserver(this);
+ mWebBrowser->setHomePageUrl("about:blank");
+
+ return TRUE;
+}
+
+void LLPanelProfileWeb::resetData()
+{
+ mWebBrowser->navigateHome();
+}
+
+void LLPanelProfileWeb::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull() && !mURLWebProfile.empty())
+ {
+ setIsLoading();
+
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo(mURLWebProfile, HTTP_CONTENT_TEXT_HTML);
+ }
+}
+
+void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+{
+ mAvatarNameCacheConnection.disconnect();
+
+ std::string username = av_name.getAccountName();
+ if (username.empty())
+ {
+ username = LLCacheName::buildUsername(av_name.getDisplayName());
+ }
+ else
+ {
+ LLStringUtil::replaceChar(username, ' ', '.');
+ }
+
+ mURLWebProfile = getProfileURL(username, true);
+ if (mURLWebProfile.empty())
+ {
+ return;
+ }
+
+ //if the tab was opened before name was resolved, load the panel now
+ updateData();
+}
+
+void LLPanelProfileWeb::onCommitLoad(LLUICtrl* ctrl)
+{
+ if (!mURLHome.empty())
+ {
+ LLSD::String valstr = ctrl->getValue().asString();
+ if (valstr.empty())
+ {
+ mWebBrowser->setVisible(TRUE);
+ mPerformanceTimer.start();
+ mWebBrowser->navigateTo( mURLHome, HTTP_CONTENT_TEXT_HTML );
+ }
+ else if (valstr == "popout")
+ {
+ // open in viewer's browser, new window
+ LLWeb::loadURLInternal(mURLHome);
+ }
+ else if (valstr == "external")
+ {
+ // open in external browser
+ LLWeb::loadURLExternal(mURLHome);
+ }
+ }
+}
+
+void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ childSetValue("status_text", LLSD( self->getStatusText() ) );
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ if (mFirstNavigate)
+ {
+ mFirstNavigate = false;
+ }
+ else
+ {
+ mPerformanceTimer.start();
+ }
+ }
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LLStringUtil::format_map_t args;
+ args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32());
+ childSetValue("status_text", LLSD( getString("LoadTime", args)) );
+ }
+ break;
+
+ default:
+ // Having a default case makes the compiler happy.
+ break;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileFirstLife::LLPanelProfileFirstLife()
+ : LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+}
+
+LLPanelProfileFirstLife::~LLPanelProfileFirstLife()
+{
+}
+
+BOOL LLPanelProfileFirstLife::postBuild()
+{
+ mDescriptionEdit = getChild<LLTextEditor>("fl_description_edit");
+ mPicture = getChild<LLIconCtrl>("real_world_pic");
+
+ mUploadPhoto = getChild<LLButton>("fl_upload_image");
+ mChangePhoto = getChild<LLButton>("fl_change_image");
+ mRemovePhoto = getChild<LLButton>("fl_remove_image");
+ mSaveChanges = getChild<LLButton>("fl_save_changes");
+ mDiscardChanges = getChild<LLButton>("fl_discard_changes");
+
+ mUploadPhoto->setCommitCallback([this](LLUICtrl*, void*) { onUploadPhoto(); }, nullptr);
+ mChangePhoto->setCommitCallback([this](LLUICtrl*, void*) { onChangePhoto(); }, nullptr);
+ mRemovePhoto->setCommitCallback([this](LLUICtrl*, void*) { onRemovePhoto(); }, nullptr);
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr);
+ mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileFirstLife::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ if (!getSelfProfile())
+ {
+ // Otherwise as the only focusable element it will be selected
+ mDescriptionEdit->setTabStop(FALSE);
+ }
+
+ resetData();
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploading(bool loading)
+{
+ mUploadPhoto->setEnabled(!loading);
+ mChangePhoto->setEnabled(!loading);
+ mRemovePhoto->setEnabled(!loading && mImageId.notNull());
+
+ LLLoadingIndicator* indicator = getChild<LLLoadingIndicator>("image_upload_indicator");
+ indicator->setVisible(loading);
+ if (loading)
+ {
+ indicator->start();
+ }
+ else
+ {
+ indicator->stop();
+ }
+}
+
+void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_id)
+{
+ mPicture->setValue(image_asset_id);
+ mImageId = image_asset_id;
+ setProfileImageUploading(false);
+}
+
+void LLPanelProfileFirstLife::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveDescriptionChanges();
+ }
+}
+
+void LLPanelProfileFirstLife::onUploadPhoto()
+{
+ (new LLProfileImagePicker(PROFILE_IMAGE_FL, new LLHandle<LLPanel>(getHandle())))->getFile();
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onChangePhoto()
+{
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+
+ // Show the dialog
+ if (!floaterp)
+ {
+ LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+ if (parent_floater)
+ {
+ // because inventory construction is somewhat slow
+ getWindow()->setCursor(UI_CURSOR_WAIT);
+ LLFloaterTexturePicker* texture_floaterp = new LLFloaterTexturePicker(
+ this,
+ mImageId,
+ LLUUID::null,
+ mImageId,
+ FALSE,
+ FALSE,
+ "SELECT PHOTO",
+ PERM_NONE,
+ PERM_NONE,
+ PERM_NONE,
+ FALSE,
+ NULL);
+
+ mFloaterTexturePickerHandle = texture_floaterp->getHandle();
+
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLUUID id)
+ {
+ if (op == LLTextureCtrl::TEXTURE_SELECT)
+ {
+ LLUUID image_asset_id;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ if (id.notNull())
+ {
+ image_asset_id = id;
+ }
+ else
+ {
+ image_asset_id = floaterp->getAssetID();
+ }
+ }
+
+ onCommitPhoto(image_asset_id);
+ }
+ });
+ texture_floaterp->setLocalTextureEnabled(FALSE);
+ texture_floaterp->setCanApply(false, true);
+
+ parent_floater->addDependentFloater(mFloaterTexturePickerHandle);
+
+ texture_floaterp->openFloater();
+ texture_floaterp->setFocus(TRUE);
+ }
+ }
+ else
+ {
+ floaterp->setMinimized(FALSE);
+ floaterp->setVisibleAndFrontmost(TRUE);
+ }
+}
+
+void LLPanelProfileFirstLife::onRemovePhoto()
+{
+ onCommitPhoto(LLUUID::null);
+
+ LLFloater* floaterp = mFloaterTexturePickerHandle.get();
+ if (floaterp)
+ {
+ floaterp->closeFloater();
+ }
+}
+
+void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id)
+{
+ if (mImageId == id)
+ {
+ return;
+ }
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLSD params;
+ params["fl_image_id"] = id;
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params));
+
+ mImageId = id;
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+}
+
+void LLPanelProfileFirstLife::setDescriptionText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentDescription = text;
+ mDescriptionEdit->setValue(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::onSetDescriptionDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileFirstLife::onSaveDescriptionChanges()
+{
+ mCurrentDescription = mDescriptionEdit->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileFirstLife::onDiscardDescriptionChanges()
+{
+ setDescriptionText(mCurrentDescription);
+}
+
+void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data)
+{
+ setDescriptionText(avatar_data->fl_about_text);
+
+ mImageId = avatar_data->fl_image_id;
+
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
+ }
+ else
+ {
+ mPicture->setValue("Generic_Person_Large");
+ }
+
+ setLoaded();
+}
+
+void LLPanelProfileFirstLife::resetData()
+{
+ setDescriptionText(std::string());
+ mPicture->setValue("Generic_Person_Large");
+ mImageId = LLUUID::null;
+
+ mUploadPhoto->setVisible(getSelfProfile());
+ mChangePhoto->setVisible(getSelfProfile());
+ mRemovePhoto->setVisible(getSelfProfile());
+ mSaveChanges->setVisible(getSelfProfile());
+ mDiscardChanges->setVisible(getSelfProfile());
+}
+
+void LLPanelProfileFirstLife::setLoaded()
+{
+ LLPanelProfileTab::setLoaded();
+
+ if (getSelfProfile())
+ {
+ mDescriptionEdit->setEnabled(TRUE);
+ mPicture->setEnabled(TRUE);
+ mRemovePhoto->setEnabled(mImageId.notNull());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLPanelProfileNotes::LLPanelProfileNotes()
+: LLPanelProfileTab()
+ , mHasUnsavedChanges(false)
+{
+
+}
+
+LLPanelProfileNotes::~LLPanelProfileNotes()
+{
+}
+
+void LLPanelProfileNotes::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
+}
+
+void LLPanelProfileNotes::commitUnsavedChanges()
+{
+ if (mHasUnsavedChanges)
+ {
+ onSaveNotesChanges();
+ }
+}
+
+BOOL LLPanelProfileNotes::postBuild()
+{
+ mNotesEditor = getChild<LLTextEditor>("notes_edit");
+ mSaveChanges = getChild<LLButton>("notes_save_changes");
+ mDiscardChanges = getChild<LLButton>("notes_discard_changes");
+
+ mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveNotesChanges(); }, nullptr);
+ mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardNotesChanges(); }, nullptr);
+ mNotesEditor->setKeystrokeCallback([this](LLTextEditor* caller) { onSetNotesDirty(); });
+
+ return TRUE;
+}
+
+void LLPanelProfileNotes::onOpen(const LLSD& key)
+{
+ LLPanelProfileTab::onOpen(key);
+
+ resetData();
+}
+
+void LLPanelProfileNotes::setNotesText(const std::string &text)
+{
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+
+ mCurrentNotes = text;
+ mNotesEditor->setValue(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::onSetNotesDirty()
+{
+ mSaveChanges->setEnabled(TRUE);
+ mDiscardChanges->setEnabled(TRUE);
+ mHasUnsavedChanges = true;
+}
+
+void LLPanelProfileNotes::onSaveNotesChanges()
+{
+ mCurrentNotes = mNotesEditor->getValue().asString();
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes)));
+ }
+ else
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ }
+
+ mSaveChanges->setEnabled(FALSE);
+ mDiscardChanges->setEnabled(FALSE);
+ mHasUnsavedChanges = false;
+}
+
+void LLPanelProfileNotes::onDiscardNotesChanges()
+{
+ setNotesText(mCurrentNotes);
+}
+
+void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes)
+{
+ setNotesText(avatar_notes->notes);
+ mNotesEditor->setEnabled(TRUE);
+ setLoaded();
+}
+
+void LLPanelProfileNotes::resetData()
+{
+ resetLoading();
+ setNotesText(std::string());
+}
+
+void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.notNull())
+ {
+ LLPanelProfileTab::setAvatarId(avatar_id);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// LLPanelProfile
+
+LLPanelProfile::LLPanelProfile()
+ : LLPanelProfileTab()
+{
+}
+
+LLPanelProfile::~LLPanelProfile()
+{
+}
+
+BOOL LLPanelProfile::postBuild()
+{
+ return TRUE;
+}
+
+void LLPanelProfile::onTabChange()
+{
+ LLPanelProfileTab* active_panel = dynamic_cast<LLPanelProfileTab*>(mTabContainer->getCurrentPanel());
+ if (active_panel)
+ {
+ active_panel->updateData();
+ }
}
void LLPanelProfile::onOpen(const LLSD& key)
{
- getTabContainer()[PANEL_PICKS]->onOpen(getAvatarId());
+ LLUUID avatar_id = key["id"].asUUID();
- // support commands to open further pieces of UI
- if (key.has("show_tab_panel"))
- {
- std::string panel = key["show_tab_panel"].asString();
- if (panel == "create_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewClassified();
- }
- }
- else if (panel == "classified_details")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedInfo(params);
- }
- }
- else if (panel == "edit_classified")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openClassifiedEdit(params);
- }
- }
- else if (panel == "create_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- picks->createNewPick();
- }
- }
- else if (panel == "edit_pick")
- {
- LLPanelPicks* picks = dynamic_cast<LLPanelPicks *>(getTabContainer()[PANEL_PICKS]);
- if (picks)
- {
- LLSD params = key;
- params.erase("show_tab_panel");
- params.erase("open_tab_name");
- picks->openPickEdit(params);
- }
- }
- }
+ // Don't reload the same profile
+ if (getAvatarId() == avatar_id)
+ {
+ return;
+ }
+
+ LLPanelProfileTab::onOpen(avatar_id);
+
+ mTabContainer = getChild<LLTabContainer>("panel_profile_tabs");
+ mPanelSecondlife = findChild<LLPanelProfileSecondLife>(PANEL_SECONDLIFE);
+ mPanelWeb = findChild<LLPanelProfileWeb>(PANEL_WEB);
+ mPanelPicks = findChild<LLPanelProfilePicks>(PANEL_PICKS);
+ mPanelClassifieds = findChild<LLPanelProfileClassifieds>(PANEL_CLASSIFIEDS);
+ mPanelFirstlife = findChild<LLPanelProfileFirstLife>(PANEL_FIRSTLIFE);
+ mPanelNotes = findChild<LLPanelProfileNotes>(PANEL_NOTES);
+
+ mPanelSecondlife->onOpen(avatar_id);
+ mPanelWeb->onOpen(avatar_id);
+ mPanelPicks->onOpen(avatar_id);
+ mPanelClassifieds->onOpen(avatar_id);
+ mPanelFirstlife->onOpen(avatar_id);
+ mPanelNotes->onOpen(avatar_id);
+
+ // Always request the base profile info
+ resetLoading();
+ updateData();
+
+ // Some tabs only request data when opened
+ mTabContainer->setCommitCallback(boost::bind(&LLPanelProfile::onTabChange, this));
}
-void LLPanelProfile::onTabSelected(const LLSD& param)
+void LLPanelProfile::updateData()
{
- std::string tab_name = param.asString();
- if (NULL != getTabContainer()[tab_name])
- {
- getTabContainer()[tab_name]->onOpen(getAvatarId());
- }
+ LLUUID avatar_id = getAvatarId();
+ // Todo: getIsloading functionality needs to be expanded to
+ // include 'inited' or 'data_provided' state to not rerequest
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ mPanelSecondlife->setIsLoading();
+ mPanelPicks->setIsLoading();
+ mPanelFirstlife->setIsLoading();
+ mPanelNotes->setIsLoading();
+
+ std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
+ if (!cap_url.empty())
+ {
+ LLCoros::instance().launch("requestAgentUserInfoCoro",
+ boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
+ }
+ }
}
-void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
+void LLPanelProfile::refreshName()
{
- // Hide currently visible panel (STORM-690).
- mChildStack.push();
+ mPanelSecondlife->refreshName();
+}
- // Add the panel or bring it to front.
- if (panel->getParent() != this)
- {
- addChild(panel);
- }
- else
- {
- sendChildToFront(panel);
- }
+void LLPanelProfile::createPick(const LLPickData &data)
+{
+ mTabContainer->selectTabPanel(mPanelPicks);
+ mPanelPicks->createPick(data);
+}
- panel->setVisible(TRUE);
- panel->setFocus(TRUE); // prevent losing focus by the floater
- panel->onOpen(params);
+void LLPanelProfile::showPick(const LLUUID& pick_id)
+{
+ if (pick_id.notNull())
+ {
+ mPanelPicks->selectPick(pick_id);
+ }
+ mTabContainer->selectTabPanel(mPanelPicks);
+}
- LLRect new_rect = getRect();
- panel->reshape(new_rect.getWidth(), new_rect.getHeight());
- new_rect.setLeftTopAndSize(0, new_rect.getHeight(), new_rect.getWidth(), new_rect.getHeight());
- panel->setRect(new_rect);
+bool LLPanelProfile::isPickTabSelected()
+{
+ return (mTabContainer->getCurrentPanel() == mPanelPicks);
}
-void LLPanelProfile::closePanel(LLPanel* panel)
+bool LLPanelProfile::isNotesTabSelected()
{
- panel->setVisible(FALSE);
+ return (mTabContainer->getCurrentPanel() == mPanelNotes);
+}
- if (panel->getParent() == this)
- {
- removeChild(panel);
+bool LLPanelProfile::hasUnsavedChanges()
+{
+ return mPanelSecondlife->hasUnsavedChanges()
+ || mPanelPicks->hasUnsavedChanges()
+ || mPanelClassifieds->hasUnsavedChanges()
+ || mPanelFirstlife->hasUnsavedChanges()
+ || mPanelNotes->hasUnsavedChanges();
+}
- // Make the underlying panel visible.
- mChildStack.pop();
+bool LLPanelProfile::hasUnpublishedClassifieds()
+{
+ return mPanelClassifieds->hasNewClassifieds();
+}
- // Prevent losing focus by the floater
- const child_list_t* child_list = getChildList();
- if (child_list->size() > 0)
- {
- child_list->front()->setFocus(TRUE);
- }
- else
- {
- LL_WARNS() << "No underlying panel to focus." << LL_ENDL;
- }
- }
+void LLPanelProfile::commitUnsavedChanges()
+{
+ mPanelSecondlife->commitUnsavedChanges();
+ mPanelPicks->commitUnsavedChanges();
+ mPanelClassifieds->commitUnsavedChanges();
+ mPanelFirstlife->commitUnsavedChanges();
+ mPanelNotes->commitUnsavedChanges();
}
-S32 LLPanelProfile::notifyParent(const LLSD& info)
+void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit)
{
- std::string action = info["action"];
- // lets update Picks list after Pick was saved
- if("save_new_pick" == action)
- {
- onOpen(info);
- return 1;
- }
+ if (classified_id.notNull())
+ {
+ mPanelClassifieds->selectClassified(classified_id, edit);
+ }
+ mTabContainer->selectTabPanel(mPanelClassifieds);
+}
- return LLPanel::notifyParent(info);
+void LLPanelProfile::createClassified()
+{
+ mPanelClassifieds->createClassified();
+ mTabContainer->selectTabPanel(mPanelClassifieds);
}
+
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index d97f60ed22..d32bb943bd 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file llpanelprofile.h
* @brief Profile panel
*
-* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-*
+* Copyright (C) 2022, 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$
*/
@@ -27,76 +27,383 @@
#ifndef LL_LLPANELPROFILE_H
#define LL_LLPANELPROFILE_H
+#include "llavatarpropertiesprocessor.h"
+#include "llcallingcard.h"
+#include "llfloater.h"
#include "llpanel.h"
#include "llpanelavatar.h"
+#include "llmediactrl.h"
+#include "llvoiceclient.h"
+
+// class LLPanelProfileClassifieds;
+// class LLTabContainer;
+// class LLPanelProfileSecondLife;
+// class LLPanelProfileWeb;
+// class LLPanelProfilePicks;
+// class LLPanelProfileFirstLife;
+// class LLPanelProfileNotes;
+
+class LLAvatarName;
+class LLButton;
+class LLCheckBoxCtrl;
+class LLComboBox;
+class LLIconCtrl;
class LLTabContainer;
+class LLTextBox;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLGroupList;
+class LLTextBase;
+class LLMenuButton;
+class LLLineEditor;
+class LLTextEditor;
+class LLPanelProfileClassifieds;
+class LLPanelProfilePicks;
+class LLViewerFetchedTexture;
-std::string getProfileURL(const std::string& agent_name);
/**
-* Base class for Profile View and My Profile.
+* Panel for displaying Avatar's second life related info.
*/
-class LLPanelProfile : public LLPanel
+class LLPanelProfileSecondLife
+ : public LLPanelProfileTab
+ , public LLFriendObserver
+ , public LLVoiceClientStatusObserver
{
- LOG_CLASS(LLPanelProfile);
+public:
+ LLPanelProfileSecondLife();
+ /*virtual*/ ~LLPanelProfileSecondLife();
+
+ void onOpen(const LLSD& key) override;
+
+ /**
+ * LLFriendObserver trigger
+ */
+ void changed(U32 mask) override;
+
+ // Implements LLVoiceClientStatusObserver::onChange() to enable the call
+ // button when voice is available
+ void onChange(EStatusType status, const std::string &channelURI, bool proximal) override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ BOOL postBuild() override;
+
+ void resetData() override;
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+ void refreshName();
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ /**
+ * Process profile related data received from server.
+ */
+ void processProfileProperties(const LLAvatarData* avatar_data);
+
+ /**
+ * Processes group related data received from server.
+ */
+ void processGroupProperties(const LLAvatarGroups* avatar_groups);
+
+ /**
+ * Fills common for Avatar profile and My Profile fields.
+ */
+ void fillCommonData(const LLAvatarData* avatar_data);
+
+ /**
+ * Fills partner data.
+ */
+ void fillPartnerData(const LLAvatarData* avatar_data);
+ /**
+ * Fills account status.
+ */
+ void fillAccountStatus(const LLAvatarData* avatar_data);
+
+ /**
+ * Sets permissions specific icon
+ */
+ void fillRightsData();
+
+ /**
+ * Fills user name, display name, age.
+ */
+ void fillAgeData(const LLDate &born_on);
+
+ void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep);
+ static void onImageLoaded(BOOL success,
+ LLViewerFetchedTexture *src_vi,
+ LLImageRaw* src,
+ LLImageRaw* aux_src,
+ S32 discard_level,
+ BOOL final,
+ void* userdata);
+
+ /**
+ * Displays avatar's online status if possible.
+ *
+ * Requirements from EXT-3880:
+ * For friends:
+ * - Online when online and privacy settings allow to show
+ * - Offline when offline and privacy settings allow to show
+ * - Else: nothing
+ * For other avatars:
+ * - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+ * - Else: Offline
+ */
+ void updateOnlineStatus();
+ void processOnlineStatus(bool is_friend, bool show_online, bool online);
+
+private:
+ void setLoaded() override;
+ void onCommitMenu(const LLSD& userdata);
+ bool onEnableMenu(const LLSD& userdata);
+ bool onCheckMenu(const LLSD& userdata);
+ void onAvatarNameCacheSetName(const LLUUID& id, const LLAvatarName& av_name);
+
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onShowInSearchCallback();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+ void onShowAgentPermissionsDialog();
+ void onShowAgentProfileTexture();
+ void onShowTexturePicker();
+ void onCommitProfileImage(const LLUUID& id);
+
+private:
+ typedef std::map<std::string, LLUUID> group_map_t;
+ group_map_t mGroups;
+ void openGroupProfile();
+
+ LLGroupList* mGroupList;
+ LLComboBox* mShowInSearchCombo;
+ LLIconCtrl* mSecondLifePic;
+ LLPanel* mSecondLifePicLayout;
+ LLTextEditor* mDescriptionEdit;
+ LLMenuButton* mAgentActionMenuButton;
+ LLButton* mSaveDescriptionChanges;
+ LLButton* mDiscardDescriptionChanges;
+ LLIconCtrl* mCanSeeOnlineIcon;
+ LLIconCtrl* mCantSeeOnlineIcon;
+ LLIconCtrl* mCanSeeOnMapIcon;
+ LLIconCtrl* mCantSeeOnMapIcon;
+ LLIconCtrl* mCanEditObjectsIcon;
+ LLIconCtrl* mCantEditObjectsIcon;
+
+ LLHandle<LLFloater> mFloaterPermissionsHandle;
+ LLHandle<LLFloater> mFloaterProfileTextureHandle;
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ bool mHasUnsavedDescriptionChanges;
+ bool mVoiceStatus;
+ bool mWaitingForImageUpload;
+ bool mAllowPublish;
+ std::string mDescriptionText;
+ LLUUID mImageId;
+
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+
+/**
+* Panel for displaying Avatar's web profile and home page.
+*/
+class LLPanelProfileWeb
+ : public LLPanelProfileTab
+ , public LLViewerMediaObserver
+{
public:
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ void onOpen(const LLSD& key);
+ LLPanelProfileWeb();
+ /*virtual*/ ~LLPanelProfileWeb();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
- virtual void openPanel(LLPanel* panel, const LLSD& params);
+ void resetData() override;
- virtual void closePanel(LLPanel* panel);
+ /**
+ * Loads web profile.
+ */
+ void updateData() override;
- S32 notifyParent(const LLSD& info);
+ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override;
+
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
protected:
+ void onCommitLoad(LLUICtrl* ctrl);
- LLPanelProfile();
+private:
+ std::string mURLHome;
+ std::string mURLWebProfile;
+ LLMediaCtrl* mWebBrowser;
- virtual void onTabSelected(const LLSD& param);
+ LLFrameTimer mPerformanceTimer;
+ bool mFirstNavigate;
- const LLUUID& getAvatarId() { return mAvatarId; }
+ boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+/**
+* Panel for displaying Avatar's first life related info.
+*/
+class LLPanelProfileFirstLife
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileFirstLife();
+ /*virtual*/ ~LLPanelProfileFirstLife();
+
+ void onOpen(const LLSD& key) override;
+
+ BOOL postBuild() override;
+
+ void processProperties(const LLAvatarData* avatar_data);
+
+ void resetData() override;
+
+ void setProfileImageUploading(bool loading);
+ void setProfileImageUploaded(const LLUUID &image_asset_id);
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+protected:
+ void setLoaded() override;
+
+ void onUploadPhoto();
+ void onChangePhoto();
+ void onRemovePhoto();
+ void onCommitPhoto(const LLUUID& id);
+ void setDescriptionText(const std::string &text);
+ void onSetDescriptionDirty();
+ void onSaveDescriptionChanges();
+ void onDiscardDescriptionChanges();
+
+ LLTextEditor* mDescriptionEdit;
+ LLIconCtrl* mPicture;
+ LLButton* mUploadPhoto;
+ LLButton* mChangePhoto;
+ LLButton* mRemovePhoto;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ LLHandle<LLFloater> mFloaterTexturePickerHandle;
+
+ std::string mCurrentDescription;
+ LLUUID mImageId;
+ bool mHasUnsavedChanges;
+};
+
+/**
+ * Panel for displaying Avatar's notes and modifying friend's rights.
+ */
+class LLPanelProfileNotes
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfileNotes();
+ /*virtual*/ ~LLPanelProfileNotes();
- void setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; }
+ void setAvatarId(const LLUUID& avatar_id) override;
- typedef std::map<std::string, LLPanelProfileTab*> profile_tabs_t;
+ void onOpen(const LLSD& key) override;
- profile_tabs_t& getTabContainer() { return mTabContainer; }
+ BOOL postBuild() override;
+
+ void processProperties(LLAvatarNotes* avatar_notes);
+
+ void resetData() override;
+
+ void updateData() override;
+
+ bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
+ void commitUnsavedChanges() override;
+
+protected:
+ void setNotesText(const std::string &text);
+ void onSetNotesDirty();
+ void onSaveNotesChanges();
+ void onDiscardNotesChanges();
+
+ LLTextEditor* mNotesEditor;
+ LLButton* mSaveChanges;
+ LLButton* mDiscardChanges;
+
+ std::string mCurrentNotes;
+ bool mHasUnsavedChanges;
+};
+
+
+/**
+* Container panel for the profile tabs
+*/
+class LLPanelProfile
+ : public LLPanelProfileTab
+{
+public:
+ LLPanelProfile();
+ /*virtual*/ ~LLPanelProfile();
+
+ BOOL postBuild() override;
+
+ void updateData() override;
+ void refreshName();
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void showPick(const LLUUID& pick_id = LLUUID::null);
+ bool isPickTabSelected();
+ bool isNotesTabSelected();
+ bool hasUnsavedChanges() override;
+ bool hasUnpublishedClassifieds();
+ void commitUnsavedChanges() override;
+
+ void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
+ void createClassified();
+
+ LLAvatarData getAvatarData() { return mAvatarData; };
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
private:
+ void onTabChange();
+
+ LLPanelProfileSecondLife* mPanelSecondlife;
+ LLPanelProfileWeb* mPanelWeb;
+ LLPanelProfilePicks* mPanelPicks;
+ LLPanelProfileClassifieds* mPanelClassifieds;
+ LLPanelProfileFirstLife* mPanelFirstlife;
+ LLPanelProfileNotes* mPanelNotes;
+ LLTabContainer* mTabContainer;
- //-- ChildStack begins ----------------------------------------------------
- class ChildStack
- {
- LOG_CLASS(LLPanelProfile::ChildStack);
- public:
- ChildStack();
- ~ChildStack();
- void setParent(LLPanel* parent);
-
- bool push();
- bool pop();
- void preParentReshape();
- void postParentReshape();
-
- private:
- void dump();
-
- typedef LLView::child_list_t view_list_t;
- typedef std::list<view_list_t> stack_t;
-
- stack_t mStack;
- stack_t mSavedStack;
- LLPanel* mParent;
- };
- //-- ChildStack ends ------------------------------------------------------
-
- profile_tabs_t mTabContainer;
- ChildStack mChildStack;
- LLUUID mAvatarId;
+ // Todo: due to server taking minutes to update this needs a more long term storage
+ // to reuse recently saved values if user opens floater again
+ // Storage implementation depends onto how a cap will be implemented, if cap will be
+ // enought to fully update LLAvatarPropertiesProcessor, then this storage can be
+ // implemented there.
+ LLAvatarData mAvatarData;
};
#endif //LL_LLPANELPROFILE_H
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
new file mode 100644
index 0000000000..a3913ddc49
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -0,0 +1,1513 @@
+/**
+ * @file llpanelprofileclassifieds.cpp
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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 "llpanelprofileclassifieds.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedflags.h"
+#include "llcombobox.h"
+#include "llcommandhandler.h" // for classified HTML detail page click tracking
+#include "llcorehttputil.h"
+#include "lldispatcher.h"
+#include "llfloaterclassified.h"
+#include "llfloaterreg.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfloaterworldmap.h"
+#include "lliconctrl.h"
+#include "lllineeditor.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llparcel.h"
+#include "llregistry.h"
+#include "llscrollcontainer.h"
+#include "llstartup.h"
+#include "llstatusbar.h"
+#include "lltabcontainer.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+#include "llviewertexture.h"
+#include "llviewertexture.h"
+
+
+//*TODO: verify this limit
+const S32 MAX_AVATAR_CLASSIFIEDS = 100;
+
+const S32 MINIMUM_PRICE_FOR_LISTING = 50; // L$
+const S32 DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT = 530;
+
+//static
+LLPanelProfileClassified::panel_list_t LLPanelProfileClassified::sAllPanels;
+
+static LLPanelInjector<LLPanelProfileClassifieds> t_panel_profile_classifieds("panel_profile_classifieds");
+static LLPanelInjector<LLPanelProfileClassified> t_panel_profile_classified("panel_profile_classified");
+
+class LLClassifiedHandler : public LLCommandHandler, public LLAvatarPropertiesObserver
+{
+public:
+ // throttle calls from untrusted browsers
+ LLClassifiedHandler() : LLCommandHandler("classified", UNTRUSTED_THROTTLE) {}
+
+ std::set<LLUUID> mClassifiedIds;
+ std::string mRequestVerb;
+
+ bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
+ {
+ LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/classified/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createClassified();
+ return true;
+ }
+
+ // then handle the general app/classified/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the classified
+ LLUUID classified_id;
+ if (!classified_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // show the classified in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "about")
+ {
+ mRequestVerb = verb;
+ mClassifiedIds.insert(classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->addObserver(LLUUID(), this);
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(classified_id);
+ return true;
+ }
+ else if (verb == "edit")
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), classified_id, true);
+ return true;
+ }
+
+ return false;
+ }
+
+ void openClassified(LLAvatarClassifiedInfo* c_info)
+ {
+ if (mRequestVerb == "about")
+ {
+ if (c_info->creator_id == gAgent.getID())
+ {
+ LLAvatarActions::showClassified(gAgent.getID(), c_info->classified_id, false);
+ }
+ else
+ {
+ LLSD params;
+ params["id"] = c_info->creator_id;
+ params["classified_id"] = c_info->classified_id;
+ params["classified_creator_id"] = c_info->creator_id;
+ params["classified_snapshot_id"] = c_info->snapshot_id;
+ params["classified_name"] = c_info->name;
+ params["classified_desc"] = c_info->description;
+ params["from_search"] = true;
+
+ LLFloaterClassified* floaterp = LLFloaterReg::getTypedInstance<LLFloaterClassified>("classified", params);
+ if (floaterp)
+ {
+ floaterp->openFloater(params);
+ floaterp->setVisibleAndFrontmost();
+ }
+ }
+ }
+ }
+
+ void processProperties(void* data, EAvatarProcessorType type)
+ {
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ // is this the classified that we asked for?
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if (!c_info || mClassifiedIds.find(c_info->classified_id) == mClassifiedIds.end())
+ {
+ return;
+ }
+
+ // open the detail side tray for this classified
+ openClassified(c_info);
+
+ // remove our observer now that we're done
+ mClassifiedIds.erase(c_info->classified_id);
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(LLUUID(), this);
+ }
+};
+LLClassifiedHandler gClassifiedHandler;
+
+//////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassifieds
+//-----------------------------------------------------------------------------
+
+LLPanelProfileClassifieds::LLPanelProfileClassifieds()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mClassifiedToSelectOnLoad(LLUUID::null)
+ , mClassifiedEditOnLoad(false)
+ , mSheduledClassifiedCreation(false)
+{
+}
+
+LLPanelProfileClassifieds::~LLPanelProfileClassifieds()
+{
+}
+
+void LLPanelProfileClassifieds::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+
+}
+
+void LLPanelProfileClassifieds::selectClassified(const LLUUID& classified_id, bool edit)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel)
+ {
+ if (classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->selectTabPanel(classified_panel);
+ if (edit)
+ {
+ classified_panel->setEditMode(TRUE);
+ }
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mClassifiedToSelectOnLoad = classified_id;
+ mClassifiedEditOnLoad = edit;
+ }
+}
+
+void LLPanelProfileClassifieds::createClassified()
+{
+ if (getIsLoaded())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+ }
+ else
+ {
+ mSheduledClassifiedCreation = true;
+ }
+}
+
+BOOL LLPanelProfileClassifieds::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_classifieds");
+ mNoItemsLabel = getChild<LLUICtrl>("classifieds_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfileClassifieds::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassifieds::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(true).
+ label(classified_panel->getClassifiedName()));
+ updateButtons();
+}
+
+void LLPanelProfileClassifieds::onClickDelete()
+{
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getCurrentPanel());
+ if (classified_panel)
+ {
+ LLUUID classified_id = classified_panel->getClassifiedId();
+ LLSD args;
+ args["CLASSIFIED"] = classified_panel->getClassifiedName();
+ LLSD payload;
+ payload["classified_id"] = classified_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeleteClassified", args, payload,
+ boost::bind(&LLPanelProfileClassifieds::callbackDeleteClassified, this, _1, _2));
+ }
+}
+
+void LLPanelProfileClassifieds::callbackDeleteClassified(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID classified_id = notification["payload"]["classified_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->getClassifiedId() == classified_id)
+ {
+ mTabContainer->removeTabPanel(classified_panel);
+ }
+
+ if (classified_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedDelete(classified_id);
+ }
+
+ updateButtons();
+
+ BOOL no_data = !mTabContainer->getTabCount();
+ mNoItemsLabel->setVisible(no_data);
+ }
+}
+
+void LLPanelProfileClassifieds::processProperties(void* data, EAvatarProcessorType type)
+{
+ if ((APT_CLASSIFIEDS == type) || (APT_CLASSIFIED_INFO == type))
+ {
+ LLUUID avatar_id = getAvatarId();
+
+ LLAvatarClassifieds* c_info = static_cast<LLAvatarClassifieds*>(data);
+ if (c_info && getAvatarId() == c_info->target_id)
+ {
+ // do not clear classified list in case we will receive two or more data packets.
+ // list has been cleared in updateData(). (fix for EXT-6436)
+ LLUUID selected_id = mClassifiedToSelectOnLoad;
+ bool has_selection = false;
+
+ LLAvatarClassifieds::classifieds_list_t::const_iterator it = c_info->classifieds_list.begin();
+ for (; c_info->classifieds_list.end() != it; ++it)
+ {
+ LLAvatarClassifieds::classified_data c_data = *it;
+
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+
+ LLSD params;
+ params["classified_creator_id"] = avatar_id;
+ params["classified_id"] = c_data.classified_id;
+ params["classified_name"] = c_data.name;
+ params["from_search"] = (selected_id == c_data.classified_id); //SLURL handling and stats tracking
+ params["edit"] = (selected_id == c_data.classified_id) && mClassifiedEditOnLoad;
+ classified_panel->onOpen(params);
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(selected_id == c_data.classified_id).
+ label(c_data.name));
+
+ if (selected_id == c_data.classified_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ if (mSheduledClassifiedCreation)
+ {
+ LLPanelProfileClassified* classified_panel = LLPanelProfileClassified::create();
+ classified_panel->onOpen(LLSD());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(classified_panel).
+ select_tab(!has_selection).
+ label(classified_panel->getClassifiedName()));
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mClassifiedToSelectOnLoad = LLUUID::null;
+ mClassifiedEditOnLoad = false;
+ mSheduledClassifiedCreation = false;
+
+ // set even if not visible, user might delete own
+ // calassified and this string will need to be shown
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoClassifiedsText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarClassifiedsText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+ }
+ }
+}
+
+void LLPanelProfileClassifieds::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfileClassifieds::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewClassified());
+ mDeleteButton->setEnabled(canDeleteClassified());
+ }
+}
+
+void LLPanelProfileClassifieds::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarClassifiedsRequest(avatar_id);
+ }
+}
+
+bool LLPanelProfileClassifieds::hasNewClassifieds()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isNew())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty()) // includes 'new'
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLPanelProfileClassifieds::canAddNewClassified()
+{
+ return (mTabContainer->getTabCount() < MAX_AVATAR_CLASSIFIEDS);
+}
+
+bool LLPanelProfileClassifieds::canDeleteClassified()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+void LLPanelProfileClassifieds::commitUnsavedChanges()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfileClassified* classified_panel = dynamic_cast<LLPanelProfileClassified*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (classified_panel && classified_panel->isDirty() && !classified_panel->isNew())
+ {
+ classified_panel->doSave();
+ }
+ }
+ }
+}
+//-----------------------------------------------------------------------------
+// LLDispatchClassifiedClickThrough
+//-----------------------------------------------------------------------------
+
+// "classifiedclickthrough"
+// strings[0] = classified_id
+// strings[1] = teleport_clicks
+// strings[2] = map_clicks
+// strings[3] = profile_clicks
+class LLDispatchClassifiedClickThrough : public LLDispatchHandler
+{
+public:
+ virtual bool operator()(
+ const LLDispatcher* dispatcher,
+ const std::string& key,
+ const LLUUID& invoice,
+ const sparam_t& strings)
+ {
+ if (strings.size() != 4) return false;
+ LLUUID classified_id(strings[0]);
+ S32 teleport_clicks = atoi(strings[1].c_str());
+ S32 map_clicks = atoi(strings[2].c_str());
+ S32 profile_clicks = atoi(strings[3].c_str());
+
+ LLPanelProfileClassified::setClickThrough(
+ classified_id, teleport_clicks, map_clicks, profile_clicks, false);
+
+ return true;
+ }
+};
+static LLDispatchClassifiedClickThrough sClassifiedClickThrough;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfileClassified
+//-----------------------------------------------------------------------------
+
+static const S32 CB_ITEM_MATURE = 0;
+static const S32 CB_ITEM_PG = 1;
+
+LLPanelProfileClassified::LLPanelProfileClassified()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mInfoLoaded(false)
+ , mTeleportClicksOld(0)
+ , mMapClicksOld(0)
+ , mProfileClicksOld(0)
+ , mTeleportClicksNew(0)
+ , mMapClicksNew(0)
+ , mProfileClicksNew(0)
+ , mPriceForListing(0)
+ , mSnapshotCtrl(NULL)
+ , mPublishFloater(NULL)
+ , mIsNew(false)
+ , mIsNewWithErrors(false)
+ , mCanClose(false)
+ , mEditMode(false)
+ , mEditOnLoad(false)
+{
+ sAllPanels.push_back(this);
+}
+
+LLPanelProfileClassified::~LLPanelProfileClassified()
+{
+ sAllPanels.remove(this);
+ gGenericDispatcher.addHandler("classifiedclickthrough", NULL); // deregister our handler
+}
+
+//static
+LLPanelProfileClassified* LLPanelProfileClassified::create()
+{
+ LLPanelProfileClassified* panel = new LLPanelProfileClassified();
+ panel->buildFromFile("panel_profile_classified.xml");
+ return panel;
+}
+
+BOOL LLPanelProfileClassified::postBuild()
+{
+ mScrollContainer = getChild<LLScrollContainer>("profile_scroll");
+ mInfoPanel = getChild<LLView>("info_panel");
+ mInfoScroll = getChild<LLPanel>("info_scroll_content_panel");
+ mEditPanel = getChild<LLPanel>("edit_panel");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("classified_snapshot");
+ mEditIcon = getChild<LLUICtrl>("edit_icon");
+
+ //info
+ mClassifiedNameText = getChild<LLUICtrl>("classified_name");
+ mClassifiedDescText = getChild<LLTextEditor>("classified_desc");
+ mLocationText = getChild<LLUICtrl>("classified_location");
+ mCategoryText = getChild<LLUICtrl>("category");
+ mContentTypeText = getChild<LLUICtrl>("content_type");
+ mContentTypeM = getChild<LLIconCtrl>("content_type_moderate");
+ mContentTypeG = getChild<LLIconCtrl>("content_type_general");
+ mPriceText = getChild<LLUICtrl>("price_for_listing");
+ mAutoRenewText = getChild<LLUICtrl>("auto_renew");
+
+ mMapButton = getChild<LLButton>("show_on_map_btn");
+ mTeleportButton = getChild<LLButton>("teleport_btn");
+ mEditButton = getChild<LLButton>("edit_btn");
+
+ //edit
+ mClassifiedNameEdit = getChild<LLLineEditor>("classified_name_edit");
+ mClassifiedDescEdit = getChild<LLTextEditor>("classified_desc_edit");
+ mLocationEdit = getChild<LLUICtrl>("classified_location_edit");
+ mCategoryCombo = getChild<LLComboBox>("category_edit");
+ mContentTypeCombo = getChild<LLComboBox>("content_type_edit");
+ mAutoRenewEdit = getChild<LLUICtrl>("auto_renew_edit");
+
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mSetLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+ mCancelButton = getChild<LLButton>("cancel_btn");
+
+ mUtilityBtnCnt = getChild<LLPanel>("util_buttons_lp");
+ mPublishBtnsCnt = getChild<LLPanel>("publish_layout_panel");
+ mCancelBtnCnt = getChild<LLPanel>("cancel_btn_lp");
+ mSaveBtnCnt = getChild<LLPanel>("save_btn_lp");
+
+ mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelProfileClassified::onTextureSelected, this));
+ mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseEnter, this));
+ mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelProfileClassified::onTexturePickerMouseLeave, this));
+ mEditIcon->setVisible(false);
+
+ mMapButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onMapClick, this));
+ mTeleportButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onTeleportClick, this));
+ mEditButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onEditClick, this));
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSaveClick, this));
+ mSetLocationButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onSetLocationClick, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfileClassified::onCancelClick, this));
+
+ LLClassifiedInfo::cat_map::iterator iter;
+ for (iter = LLClassifiedInfo::sCategories.begin();
+ iter != LLClassifiedInfo::sCategories.end();
+ iter++)
+ {
+ mCategoryCombo->add(LLTrans::getString(iter->second));
+ }
+
+ mClassifiedNameEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this), NULL);
+ mClassifiedDescEdit->setKeystrokeCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mCategoryCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mContentTypeCombo->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+ mAutoRenewEdit->setCommitCallback(boost::bind(&LLPanelProfileClassified::onChange, this));
+
+ return TRUE;
+}
+
+void LLPanelProfileClassified::onOpen(const LLSD& key)
+{
+ mIsNew = key.isUndefined();
+
+ resetData();
+ resetControls();
+ scrollToTop();
+
+ // classified is not created yet
+ bool is_new = isNew() || isNewWithErrors();
+
+ if(is_new)
+ {
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(gAgent.getID());
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID snapshot_id = LLUUID::null;
+ std::string desc;
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedName(makeClassifiedName());
+ setDescription(desc);
+ setSnapshotId(snapshot_id);
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+ // server will set valid parcel id
+ setParcelId(LLUUID::null);
+
+ mSaveButton->setLabelArg("[LABEL]", getString("publish_label"));
+
+ setEditMode(TRUE);
+ enableSave(true);
+ enableEditing(true);
+ resetDirty();
+ setInfoLoaded(false);
+ }
+ else
+ {
+ LLUUID avatar_id = key["classified_creator_id"];
+ if(avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ setClassifiedId(key["classified_id"]);
+ setClassifiedName(key["classified_name"]);
+ setFromSearch(key["from_search"]);
+ mEditOnLoad = key["edit"];
+
+ LL_INFOS() << "Opening classified [" << getClassifiedName() << "] (" << getClassifiedId() << ")" << LL_ENDL;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+
+ gGenericDispatcher.addHandler("classifiedclickthrough", &sClassifiedClickThrough);
+
+ if (gAgent.getRegion())
+ {
+ // While we're at it let's get the stats from the new table if that
+ // capability exists.
+ std::string url = gAgent.getRegion()->getCapability("SearchStatRequest");
+ if (!url.empty())
+ {
+ LL_INFOS() << "Classified stat request via capability" << LL_ENDL;
+ LLSD body;
+ LLUUID classifiedId = getClassifiedId();
+ body["classified_id"] = classifiedId;
+ LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpPost(url, body,
+ boost::bind(&LLPanelProfileClassified::handleSearchStatResponse, classifiedId, _1));
+ }
+ }
+ // Update classified click stats.
+ // *TODO: Should we do this when opening not from search?
+ if (!fromSearch() )
+ {
+ sendClickMessage("profile");
+ }
+
+ setInfoLoaded(false);
+ }
+
+
+ bool is_self = getSelfProfile();
+ getChildView("auto_renew_layout_panel")->setVisible(is_self);
+ getChildView("clickthrough_layout_panel")->setVisible(is_self);
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_CLASSIFIED_INFO != type)
+ {
+ return;
+ }
+
+ LLAvatarClassifiedInfo* c_info = static_cast<LLAvatarClassifiedInfo*>(data);
+ if(c_info && getClassifiedId() == c_info->classified_id)
+ {
+ // see LLPanelProfileClassified::sendUpdate() for notes
+ if (mIsNewWithErrors)
+ {
+ // We just published it
+ setEditMode(FALSE);
+ }
+ mIsNewWithErrors = false;
+ mIsNew = false;
+
+ setClassifiedName(c_info->name);
+ setDescription(c_info->description);
+ setSnapshotId(c_info->snapshot_id);
+ setParcelId(c_info->parcel_id);
+ setPosGlobal(c_info->pos_global);
+ setSimName(c_info->sim_name);
+
+ setClassifiedLocation(createLocationText(c_info->parcel_name, c_info->sim_name, c_info->pos_global));
+
+ mCategoryText->setValue(LLClassifiedInfo::sCategories[c_info->category]);
+ // *HACK see LLPanelProfileClassified::sendUpdate()
+ setCategory(c_info->category - 1);
+
+ bool mature = is_cf_mature(c_info->flags);
+ setContentType(mature);
+
+ bool auto_renew = is_cf_auto_renew(c_info->flags);
+ std::string auto_renew_str = auto_renew ? getString("auto_renew_on") : getString("auto_renew_off");
+ mAutoRenewText->setValue(auto_renew_str);
+ mAutoRenewEdit->setValue(auto_renew);
+
+ static LLUIString price_str = getString("l$_price");
+ price_str.setArg("[PRICE]", llformat("%d", c_info->price_for_listing));
+ mPriceText->setValue(LLSD(price_str));
+
+ static std::string date_fmt = getString("date_fmt");
+ std::string date_str = date_fmt;
+ LLStringUtil::format(date_str, LLSD().with("datetime", (S32) c_info->creation_date));
+ getChild<LLUICtrl>("creation_date")->setValue(date_str);
+
+ resetDirty();
+ setInfoLoaded(true);
+ enableSave(false);
+ enableEditing(true);
+
+ // for just created classified - in case user opened edit panel before processProperties() callback
+ mSaveButton->setLabelArg("[LABEL]", getString("save_label"));
+
+ setLoaded();
+ updateButtons();
+
+ if (mEditOnLoad)
+ {
+ setEditMode(TRUE);
+ }
+ }
+
+}
+
+void LLPanelProfileClassified::setEditMode(BOOL edit_mode)
+{
+ mEditMode = edit_mode;
+
+ mInfoPanel->setVisible(!edit_mode);
+ mEditPanel->setVisible(edit_mode);
+
+ // snapshot control is common between info and edit,
+ // enable it only when in edit mode
+ mSnapshotCtrl->setEnabled(edit_mode);
+
+ scrollToTop();
+ updateButtons();
+ updateInfoRect();
+}
+
+void LLPanelProfileClassified::updateButtons()
+{
+ bool edit_mode = getEditMode();
+ mUtilityBtnCnt->setVisible(!edit_mode);
+
+ // cancel button should either delete unpublished
+ // classified or not be there at all
+ mCancelBtnCnt->setVisible(edit_mode && !mIsNew);
+ mPublishBtnsCnt->setVisible(edit_mode);
+ mSaveBtnCnt->setVisible(edit_mode);
+ mEditButton->setVisible(!edit_mode && getSelfProfile());
+}
+
+void LLPanelProfileClassified::updateInfoRect()
+{
+ if (getEditMode())
+ {
+ // info_scroll_content_panel contains both info and edit panel
+ // info panel can be very large and scroll bar will carry over.
+ // Resize info panel to prevent scroll carry over when in edit mode.
+ mInfoScroll->reshape(mInfoScroll->getRect().getWidth(), DEFAULT_EDIT_CLASSIFIED_SCROLL_HEIGHT, FALSE);
+ }
+ else
+ {
+ // Adjust text height to make description scrollable.
+ S32 new_height = mClassifiedDescText->getTextBoundingRect().getHeight();
+ LLRect visible_rect = mClassifiedDescText->getVisibleDocumentRect();
+ S32 delta_height = new_height - visible_rect.getHeight() + 5;
+
+ LLRect rect = mInfoScroll->getRect();
+ mInfoScroll->reshape(rect.getWidth(), rect.getHeight() + delta_height, FALSE);
+ }
+}
+
+void LLPanelProfileClassified::enableEditing(bool enable)
+{
+ mEditButton->setEnabled(enable);
+ mClassifiedNameEdit->setEnabled(enable);
+ mClassifiedDescEdit->setEnabled(enable);
+ mSetLocationButton->setEnabled(enable);
+ mCategoryCombo->setEnabled(enable);
+ mContentTypeCombo->setEnabled(enable);
+ mAutoRenewEdit->setEnabled(enable);
+}
+
+void LLPanelProfileClassified::resetControls()
+{
+ updateButtons();
+
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+}
+
+void LLPanelProfileClassified::onEditClick()
+{
+ setEditMode(TRUE);
+}
+
+void LLPanelProfileClassified::onCancelClick()
+{
+ if (isNew())
+ {
+ mClassifiedNameEdit->setValue(mClassifiedNameText->getValue());
+ mClassifiedDescEdit->setValue(mClassifiedDescText->getValue());
+ mLocationEdit->setValue(mLocationText->getValue());
+ mCategoryCombo->setCurrentByIndex(0);
+ mContentTypeCombo->setCurrentByIndex(0);
+ mAutoRenewEdit->setValue(false);
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+ }
+ else
+ {
+ // Reload data to undo changes to forms
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoRequest(getClassifiedId());
+ }
+
+ setInfoLoaded(false);
+
+ setEditMode(FALSE);
+}
+
+void LLPanelProfileClassified::onSaveClick()
+{
+ mCanClose = false;
+
+ if(!isValidName())
+ {
+ notifyInvalidName();
+ return;
+ }
+ if(isNew() || isNewWithErrors())
+ {
+ if(gStatusBar->getBalance() < getPriceForListing())
+ {
+ LLNotificationsUtil::add("ClassifiedInsufficientFunds");
+ return;
+ }
+
+ mPublishFloater = LLFloaterReg::findTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ if(!mPublishFloater)
+ {
+ mPublishFloater = LLFloaterReg::getTypedInstance<LLPublishClassifiedFloater>(
+ "publish_classified", LLSD());
+
+ mPublishFloater->setPublishClickedCallback(boost::bind
+ (&LLPanelProfileClassified::onPublishFloaterPublishClicked, this));
+ }
+
+ // set spinner value before it has focus or value wont be set
+ mPublishFloater->setPrice(getPriceForListing());
+ mPublishFloater->openFloater(mPublishFloater->getKey());
+ mPublishFloater->center();
+ }
+ else
+ {
+ doSave();
+ }
+}
+
+/*static*/
+void LLPanelProfileClassified::handleSearchStatResponse(LLUUID classifiedId, LLSD result)
+{
+ S32 teleport = result["teleport_clicks"].asInteger();
+ S32 map = result["map_clicks"].asInteger();
+ S32 profile = result["profile_clicks"].asInteger();
+ S32 search_teleport = result["search_teleport_clicks"].asInteger();
+ S32 search_map = result["search_map_clicks"].asInteger();
+ S32 search_profile = result["search_profile_clicks"].asInteger();
+
+ LLPanelProfileClassified::setClickThrough(classifiedId,
+ teleport + search_teleport,
+ map + search_map,
+ profile + search_profile,
+ true);
+}
+
+void LLPanelProfileClassified::resetData()
+{
+ setClassifiedName(LLStringUtil::null);
+ setDescription(LLStringUtil::null);
+ setClassifiedLocation(LLStringUtil::null);
+ setClassifiedId(LLUUID::null);
+ setSnapshotId(LLUUID::null);
+ setPosGlobal(LLVector3d::zero);
+ setParcelId(LLUUID::null);
+ setSimName(LLStringUtil::null);
+ setFromSearch(false);
+
+ // reset click stats
+ mTeleportClicksOld = 0;
+ mMapClicksOld = 0;
+ mProfileClicksOld = 0;
+ mTeleportClicksNew = 0;
+ mMapClicksNew = 0;
+ mProfileClicksNew = 0;
+
+ mPriceForListing = MINIMUM_PRICE_FOR_LISTING;
+
+ mCategoryText->setValue(LLStringUtil::null);
+ mContentTypeText->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("click_through_text")->setValue(LLStringUtil::null);
+ mEditButton->setValue(LLStringUtil::null);
+ getChild<LLUICtrl>("creation_date")->setValue(LLStringUtil::null);
+ mContentTypeM->setVisible(FALSE);
+ mContentTypeG->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::setClassifiedName(const std::string& name)
+{
+ mClassifiedNameText->setValue(name);
+ mClassifiedNameEdit->setValue(name);
+}
+
+std::string LLPanelProfileClassified::getClassifiedName()
+{
+ return mClassifiedNameEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setDescription(const std::string& desc)
+{
+ mClassifiedDescText->setValue(desc);
+ mClassifiedDescEdit->setValue(desc);
+
+ updateInfoRect();
+}
+
+std::string LLPanelProfileClassified::getDescription()
+{
+ return mClassifiedDescEdit->getValue().asString();
+}
+
+void LLPanelProfileClassified::setClassifiedLocation(const std::string& location)
+{
+ mLocationText->setValue(location);
+ mLocationEdit->setValue(location);
+}
+
+std::string LLPanelProfileClassified::getClassifiedLocation()
+{
+ return mLocationText->getValue().asString();
+}
+
+void LLPanelProfileClassified::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setValue(id);
+}
+
+LLUUID LLPanelProfileClassified::getSnapshotId()
+{
+ return mSnapshotCtrl->getValue().asUUID();
+}
+
+// static
+void LLPanelProfileClassified::setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table)
+{
+ LL_INFOS() << "Click-through data for classified " << classified_id << " arrived: ["
+ << teleport << ", " << map << ", " << profile << "] ("
+ << (from_new_table ? "new" : "old") << ")" << LL_ENDL;
+
+ for (panel_list_t::iterator iter = sAllPanels.begin(); iter != sAllPanels.end(); ++iter)
+ {
+ LLPanelProfileClassified* self = *iter;
+ if (self->getClassifiedId() != classified_id)
+ {
+ continue;
+ }
+
+ // *HACK: Skip LLPanelProfileClassified instances: they don't display clicks data.
+ // Those instances should not be in the list at all.
+ if (typeid(*self) != typeid(LLPanelProfileClassified))
+ {
+ continue;
+ }
+
+ LL_INFOS() << "Updating classified info panel" << LL_ENDL;
+
+ // We need to check to see if the data came from the new stat_table
+ // or the old classified table. We also need to cache the data from
+ // the two separate sources so as to display the aggregate totals.
+
+ if (from_new_table)
+ {
+ self->mTeleportClicksNew = teleport;
+ self->mMapClicksNew = map;
+ self->mProfileClicksNew = profile;
+ }
+ else
+ {
+ self->mTeleportClicksOld = teleport;
+ self->mMapClicksOld = map;
+ self->mProfileClicksOld = profile;
+ }
+
+ static LLUIString ct_str = self->getString("click_through_text_fmt");
+
+ ct_str.setArg("[TELEPORT]", llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld));
+ ct_str.setArg("[MAP]", llformat("%d", self->mMapClicksNew + self->mMapClicksOld));
+ ct_str.setArg("[PROFILE]", llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld));
+
+ self->getChild<LLUICtrl>("click_through_text")->setValue(ct_str.getString());
+ // *HACK: remove this when there is enough room for click stats in the info panel
+ self->getChildView("click_through_text")->setToolTip(ct_str.getString());
+
+ LL_INFOS() << "teleport: " << llformat("%d", self->mTeleportClicksNew + self->mTeleportClicksOld)
+ << ", map: " << llformat("%d", self->mMapClicksNew + self->mMapClicksOld)
+ << ", profile: " << llformat("%d", self->mProfileClicksNew + self->mProfileClicksOld)
+ << LL_ENDL;
+ }
+}
+
+// static
+std::string LLPanelProfileClassified::createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global)
+{
+ std::string location_text;
+
+ location_text.append(original_name);
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ location_text.append(", ");
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ location_text.append(" ");
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+
+ return location_text;
+}
+
+void LLPanelProfileClassified::scrollToTop()
+{
+ if (mScrollContainer)
+ {
+ mScrollContainer->goToTop();
+ }
+}
+
+//info
+// static
+// *TODO: move out of the panel
+void LLPanelProfileClassified::sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name)
+{
+ if (gAgent.getRegion())
+ {
+ // You're allowed to click on your own ads to reassure yourself
+ // that the system is working.
+ LLSD body;
+ body["type"] = type;
+ body["from_search"] = from_search;
+ body["classified_id"] = classified_id;
+ body["parcel_id"] = parcel_id;
+ body["dest_pos_global"] = global_pos.getValue();
+ body["region_name"] = sim_name;
+
+ std::string url = gAgent.getRegion()->getCapability("SearchStatTracking");
+ LL_INFOS() << "Sending click msg via capability (url=" << url << ")" << LL_ENDL;
+ LL_INFOS() << "body: [" << body << "]" << LL_ENDL;
+ LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
+ "SearchStatTracking Click report sent.", "SearchStatTracking Click report NOT sent.");
+ }
+}
+
+void LLPanelProfileClassified::sendClickMessage(const std::string& type)
+{
+ sendClickMessage(
+ type,
+ fromSearch(),
+ getClassifiedId(),
+ getParcelId(),
+ getPosGlobal(),
+ getSimName());
+}
+
+void LLPanelProfileClassified::onMapClick()
+{
+ sendClickMessage("map");
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfileClassified::onTeleportClick()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ sendClickMessage("teleport");
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+BOOL LLPanelProfileClassified::isDirty() const
+{
+ if(mIsNew)
+ {
+ return TRUE;
+ }
+
+ BOOL dirty = false;
+ dirty |= mSnapshotCtrl->isDirty();
+ dirty |= mClassifiedNameEdit->isDirty();
+ dirty |= mClassifiedDescEdit->isDirty();
+ dirty |= mCategoryCombo->isDirty();
+ dirty |= mContentTypeCombo->isDirty();
+ dirty |= mAutoRenewEdit->isDirty();
+
+ return dirty;
+}
+
+void LLPanelProfileClassified::resetDirty()
+{
+ mSnapshotCtrl->resetDirty();
+ mClassifiedNameEdit->resetDirty();
+
+ // call blockUndo() to really reset dirty(and make isDirty work as intended)
+ mClassifiedDescEdit->blockUndo();
+ mClassifiedDescEdit->resetDirty();
+
+ mCategoryCombo->resetDirty();
+ mContentTypeCombo->resetDirty();
+ mAutoRenewEdit->resetDirty();
+}
+
+bool LLPanelProfileClassified::canClose()
+{
+ return mCanClose;
+}
+
+U32 LLPanelProfileClassified::getContentType()
+{
+ return mContentTypeCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setContentType(bool mature)
+{
+ static std::string mature_str = getString("type_mature");
+ static std::string pg_str = getString("type_pg");
+ mContentTypeText->setValue(mature ? mature_str : pg_str);
+ mContentTypeM->setVisible(mature);
+ mContentTypeG->setVisible(!mature);
+ mContentTypeCombo->setCurrentByIndex(mature ? CB_ITEM_MATURE : CB_ITEM_PG);
+ mContentTypeCombo->resetDirty();
+}
+
+bool LLPanelProfileClassified::getAutoRenew()
+{
+ return mAutoRenewEdit->getValue().asBoolean();
+}
+
+void LLPanelProfileClassified::sendUpdate()
+{
+ LLAvatarClassifiedInfo c_data;
+
+ if(getClassifiedId().isNull())
+ {
+ setClassifiedId(LLUUID::generateNewID());
+ }
+
+ c_data.agent_id = gAgent.getID();
+ c_data.classified_id = getClassifiedId();
+ // *HACK
+ // Categories on server start with 1 while combo-box index starts with 0
+ c_data.category = getCategory() + 1;
+ c_data.name = getClassifiedName();
+ c_data.description = getDescription();
+ c_data.parcel_id = getParcelId();
+ c_data.snapshot_id = getSnapshotId();
+ c_data.pos_global = getPosGlobal();
+ c_data.flags = getFlags();
+ c_data.price_for_listing = getPriceForListing();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendClassifiedInfoUpdate(&c_data);
+
+ if(isNew())
+ {
+ // Lets assume there will be some error.
+ // Successful sendClassifiedInfoUpdate will trigger processProperties and
+ // let us know there was no error.
+ mIsNewWithErrors = true;
+ }
+}
+
+U32 LLPanelProfileClassified::getCategory()
+{
+ return mCategoryCombo->getCurrentIndex();
+}
+
+void LLPanelProfileClassified::setCategory(U32 category)
+{
+ mCategoryCombo->setCurrentByIndex(category);
+ mCategoryCombo->resetDirty();
+}
+
+U8 LLPanelProfileClassified::getFlags()
+{
+ bool auto_renew = mAutoRenewEdit->getValue().asBoolean();
+
+ bool mature = mContentTypeCombo->getCurrentIndex() == CB_ITEM_MATURE;
+
+ return pack_classified_flags_request(auto_renew, false, mature, false);
+}
+
+void LLPanelProfileClassified::enableSave(bool enable)
+{
+ mSaveButton->setEnabled(enable);
+}
+
+std::string LLPanelProfileClassified::makeClassifiedName()
+{
+ std::string name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if(parcel)
+ {
+ name = parcel->getName();
+ }
+
+ if(!name.empty())
+ {
+ return name;
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if(region)
+ {
+ name = region->getName();
+ }
+
+ return name;
+}
+
+void LLPanelProfileClassified::onSetLocationClick()
+{
+ setPosGlobal(gAgent.getPositionGlobal());
+ setParcelId(LLUUID::null);
+
+ std::string region_name = LLTrans::getString("ClassifiedUpdateAfterPublish");
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setClassifiedLocation(createLocationText(getLocationNotice(), region_name, getPosGlobal()));
+
+ // mark classified as dirty
+ setValue(LLSD());
+
+ onChange();
+}
+
+void LLPanelProfileClassified::onChange()
+{
+ enableSave(isDirty());
+}
+
+void LLPanelProfileClassified::doSave()
+{
+ //*TODO: Fix all of this
+
+ mCanClose = true;
+ sendUpdate();
+ updateTabLabel(getClassifiedName());
+ resetDirty();
+
+ if (!canClose())
+ {
+ return;
+ }
+
+ if (!isNew() && !isNewWithErrors())
+ {
+ setEditMode(FALSE);
+ return;
+ }
+
+ updateButtons();
+}
+
+void LLPanelProfileClassified::onPublishFloaterPublishClicked()
+{
+ setPriceForListing(mPublishFloater->getPrice());
+
+ doSave();
+}
+
+std::string LLPanelProfileClassified::getLocationNotice()
+{
+ static std::string location_notice = getString("location_notice");
+ return location_notice;
+}
+
+bool LLPanelProfileClassified::isValidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ return false;
+ }
+ if (!isalnum(name[0]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLPanelProfileClassified::notifyInvalidName()
+{
+ std::string name = getClassifiedName();
+ if (name.empty())
+ {
+ LLNotificationsUtil::add("BlankClassifiedName");
+ }
+ else if (!isalnum(name[0]))
+ {
+ LLNotificationsUtil::add("ClassifiedMustBeAlphanumeric");
+ }
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseEnter()
+{
+ mEditIcon->setVisible(TRUE);
+}
+
+void LLPanelProfileClassified::onTexturePickerMouseLeave()
+{
+ mEditIcon->setVisible(FALSE);
+}
+
+void LLPanelProfileClassified::onTextureSelected()
+{
+ setSnapshotId(mSnapshotCtrl->getValue().asUUID());
+ onChange();
+}
+
+void LLPanelProfileClassified::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPublishClassifiedFloater
+//-----------------------------------------------------------------------------
+
+LLPublishClassifiedFloater::LLPublishClassifiedFloater(const LLSD& key)
+ : LLFloater(key)
+{
+}
+
+LLPublishClassifiedFloater::~LLPublishClassifiedFloater()
+{
+}
+
+BOOL LLPublishClassifiedFloater::postBuild()
+{
+ LLFloater::postBuild();
+
+ childSetAction("publish_btn", boost::bind(&LLFloater::closeFloater, this, false));
+ childSetAction("cancel_btn", boost::bind(&LLFloater::closeFloater, this, false));
+
+ return TRUE;
+}
+
+void LLPublishClassifiedFloater::setPrice(S32 price)
+{
+ getChild<LLUICtrl>("price_for_listing")->setValue(price);
+}
+
+S32 LLPublishClassifiedFloater::getPrice()
+{
+ return getChild<LLUICtrl>("price_for_listing")->getValue().asInteger();
+}
+
+void LLPublishClassifiedFloater::setPublishClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("publish_btn")->setClickedCallback(cb);
+}
+
+void LLPublishClassifiedFloater::setCancelClickedCallback(const commit_signal_t::slot_type& cb)
+{
+ getChild<LLButton>("cancel_btn")->setClickedCallback(cb);
+}
diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h
new file mode 100644
index 0000000000..912819e86b
--- /dev/null
+++ b/indra/newview/llpanelprofileclassifieds.h
@@ -0,0 +1,340 @@
+/**
+ * @file llpanelprofileclassifieds.h
+ * @brief LLPanelProfileClassifieds and related class implementations
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_PANELPROFILECLASSIFIEDS_H
+#define LL_PANELPROFILECLASSIFIEDS_H
+
+#include "llavatarpropertiesprocessor.h"
+#include "llclassifiedinfo.h"
+#include "llfloater.h"
+#include "llpanel.h"
+#include "llpanelavatar.h"
+#include "llrect.h"
+#include "lluuid.h"
+#include "v3dmath.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+
+class LLCheckBoxCtrl;
+class LLLineEditor;
+class LLMediaCtrl;
+class LLScrollContainer;
+class LLTabContainer;
+class LLTextEditor;
+class LLTextureCtrl;
+class LLUICtrl;
+
+
+class LLPublishClassifiedFloater : public LLFloater
+{
+public:
+ LLPublishClassifiedFloater(const LLSD& key);
+ virtual ~LLPublishClassifiedFloater();
+
+ BOOL postBuild() override;
+
+ void setPrice(S32 price);
+ S32 getPrice();
+
+ void setPublishClickedCallback(const commit_signal_t::slot_type& cb);
+ void setCancelClickedCallback(const commit_signal_t::slot_type& cb);
+};
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfileClassifieds
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfileClassifieds();
+ /*virtual*/ ~LLPanelProfileClassifieds();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void selectClassified(const LLUUID& classified_id, bool edit);
+
+ void createClassified();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void resetData() override;
+
+ void updateButtons();
+
+ void updateData() override;
+
+ bool hasNewClassifieds();
+ bool hasUnsavedChanges() override;
+ // commits changes to existing classifieds, but does not publish new classified!
+ void commitUnsavedChanges() override;
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeleteClassified(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewClassified();
+ bool canDeleteClassified();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mClassifiedToSelectOnLoad;
+ bool mClassifiedEditOnLoad;
+ bool mSheduledClassifiedCreation;
+};
+
+
+class LLPanelProfileClassified
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+
+ static LLPanelProfileClassified* create();
+
+ LLPanelProfileClassified();
+
+ /*virtual*/ ~LLPanelProfileClassified();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+
+ void setSnapshotId(const LLUUID& id);
+
+ LLUUID getSnapshotId();
+
+ void setClassifiedId(const LLUUID& id) { mClassifiedId = id; }
+
+ LLUUID& getClassifiedId() { return mClassifiedId; }
+
+ void setClassifiedName(const std::string& name);
+
+ std::string getClassifiedName();
+
+ void setDescription(const std::string& desc);
+
+ std::string getDescription();
+
+ void setClassifiedLocation(const std::string& location);
+
+ std::string getClassifiedLocation();
+
+ void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+
+ LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ void setParcelId(const LLUUID& id) { mParcelId = id; }
+
+ LLUUID getParcelId() { return mParcelId; }
+
+ void setSimName(const std::string& sim_name) { mSimName = sim_name; }
+
+ std::string getSimName() { return mSimName; }
+
+ void setFromSearch(bool val) { mFromSearch = val; }
+
+ bool fromSearch() { return mFromSearch; }
+
+ bool getInfoLoaded() { return mInfoLoaded; }
+
+ void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; }
+
+ BOOL isDirty() const override;
+
+ void resetDirty() override;
+
+ bool isNew() { return mIsNew; }
+
+ bool isNewWithErrors() { return mIsNewWithErrors; }
+
+ bool canClose();
+
+ U32 getCategory();
+
+ void setCategory(U32 category);
+
+ U32 getContentType();
+
+ void setContentType(bool mature);
+
+ bool getAutoRenew();
+
+ S32 getPriceForListing() { return mPriceForListing; }
+
+ void setEditMode(BOOL edit_mode);
+ bool getEditMode() {return mEditMode;}
+
+ static void setClickThrough(
+ const LLUUID& classified_id,
+ S32 teleport,
+ S32 map,
+ S32 profile,
+ bool from_new_table);
+
+ static void sendClickMessage(
+ const std::string& type,
+ bool from_search,
+ const LLUUID& classified_id,
+ const LLUUID& parcel_id,
+ const LLVector3d& global_pos,
+ const std::string& sim_name);
+
+ void doSave();
+
+protected:
+
+ void resetData() override;
+
+ void resetControls();
+
+ void updateButtons();
+ void updateInfoRect();
+
+ static std::string createLocationText(
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ void sendClickMessage(const std::string& type);
+
+ void scrollToTop();
+
+ void onEditClick();
+ void onCancelClick();
+ void onSaveClick();
+ void onMapClick();
+ void onTeleportClick();
+
+ void sendUpdate();
+
+ void enableSave(bool enable);
+
+ void enableEditing(bool enable);
+
+ std::string makeClassifiedName();
+
+ void setPriceForListing(S32 price) { mPriceForListing = price; }
+
+ U8 getFlags();
+
+ std::string getLocationNotice();
+
+ bool isValidName();
+
+ void notifyInvalidName();
+
+ void onSetLocationClick();
+ void onChange();
+
+ void onPublishFloaterPublishClicked();
+
+ void onTexturePickerMouseEnter();
+ void onTexturePickerMouseLeave();
+
+ void onTextureSelected();
+
+ void updateTabLabel(const std::string& title);
+
+private:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLUICtrl* mEditIcon;
+ LLUICtrl* mClassifiedNameText;
+ LLTextEditor* mClassifiedDescText;
+ LLLineEditor* mClassifiedNameEdit;
+ LLTextEditor* mClassifiedDescEdit;
+ LLUICtrl* mLocationText;
+ LLUICtrl* mLocationEdit;
+ LLUICtrl* mCategoryText;
+ LLComboBox* mCategoryCombo;
+ LLUICtrl* mContentTypeText;
+ LLIconCtrl* mContentTypeM;
+ LLIconCtrl* mContentTypeG;
+ LLComboBox* mContentTypeCombo;
+ LLUICtrl* mPriceText;
+ LLUICtrl* mAutoRenewText;
+ LLUICtrl* mAutoRenewEdit;
+
+ LLButton* mMapButton;
+ LLButton* mTeleportButton;
+ LLButton* mEditButton;
+ LLButton* mSaveButton;
+ LLButton* mSetLocationButton;
+ LLButton* mCancelButton;
+
+ LLPanel* mUtilityBtnCnt;
+ LLPanel* mPublishBtnsCnt;
+ LLPanel* mSaveBtnCnt;
+ LLPanel* mCancelBtnCnt;
+
+ LLScrollContainer* mScrollContainer;
+ LLView* mInfoPanel;
+ LLPanel* mInfoScroll;
+ LLPanel* mEditPanel;
+
+
+ LLUUID mClassifiedId;
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ std::string mSimName;
+ bool mFromSearch;
+ bool mInfoLoaded;
+ bool mEditMode;
+
+ // Needed for stat tracking
+ S32 mTeleportClicksOld;
+ S32 mMapClicksOld;
+ S32 mProfileClicksOld;
+ S32 mTeleportClicksNew;
+ S32 mMapClicksNew;
+ S32 mProfileClicksNew;
+
+ S32 mPriceForListing;
+
+ static void handleSearchStatResponse(LLUUID classifiedId, LLSD result);
+
+ typedef std::list<LLPanelProfileClassified*> panel_list_t;
+ static panel_list_t sAllPanels;
+
+
+ bool mIsNew;
+ bool mIsNewWithErrors;
+ bool mCanClose;
+ bool mEditOnLoad;
+
+ LLPublishClassifiedFloater* mPublishFloater;
+};
+
+#endif // LL_PANELPROFILECLASSIFIEDS_H
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
new file mode 100644
index 0000000000..774119f169
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -0,0 +1,883 @@
+/**
+ * @file llpanelprofilepicks.cpp
+ * @brief LLPanelProfilePicks and related class implementations
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 "llpanelprofilepicks.h"
+
+#include "llagent.h"
+#include "llagentpicksinfo.h"
+#include "llavataractions.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llcommandhandler.h"
+#include "lldispatcher.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
+#include "lllineeditor.h"
+#include "llnotificationsutil.h"
+#include "llpanelavatar.h"
+#include "llpanelprofile.h"
+#include "llparcel.h"
+#include "llstartup.h"
+#include "lltabcontainer.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lltexturectrl.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewergenericmessage.h" // send_generic_message
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+static LLPanelInjector<LLPanelProfilePicks> t_panel_profile_picks("panel_profile_picks");
+static LLPanelInjector<LLPanelProfilePick> t_panel_profile_pick("panel_profile_pick");
+
+
+class LLPickHandler : public LLCommandHandler
+{
+public:
+
+ // requires trusted browser to trigger
+ LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
+
+ bool handle(const LLSD& params, const LLSD& query_map,
+ LLMediaCtrl* web)
+ {
+ if (LLStartUp::getStartupState() < STATE_STARTED)
+ {
+ return true;
+ }
+
+ if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
+ {
+ LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+ return true;
+ }
+
+ // handle app/pick/create urls first
+ if (params.size() == 1 && params[0].asString() == "create")
+ {
+ LLAvatarActions::createPick();
+ return true;
+ }
+
+ // then handle the general app/pick/{UUID}/{CMD} urls
+ if (params.size() < 2)
+ {
+ return false;
+ }
+
+ // get the ID for the pick_id
+ LLUUID pick_id;
+ if (!pick_id.set(params[0], FALSE))
+ {
+ return false;
+ }
+
+ // edit the pick in the side tray.
+ // need to ask the server for more info first though...
+ const std::string verb = params[1].asString();
+ if (verb == "edit")
+ {
+ LLAvatarActions::showPick(gAgent.getID(), pick_id);
+ return true;
+ }
+ else
+ {
+ LL_WARNS() << "unknown verb " << verb << LL_ENDL;
+ return false;
+ }
+ }
+};
+LLPickHandler gPickHandler;
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePicks
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePicks::LLPanelProfilePicks()
+ : LLPanelProfilePropertiesProcessorTab()
+ , mPickToSelectOnLoad(LLUUID::null)
+{
+}
+
+LLPanelProfilePicks::~LLPanelProfilePicks()
+{
+}
+
+void LLPanelProfilePicks::onOpen(const LLSD& key)
+{
+ LLPanelProfilePropertiesProcessorTab::onOpen(key);
+
+ resetData();
+
+ bool own_profile = getSelfProfile();
+ if (own_profile)
+ {
+ mNewButton->setVisible(TRUE);
+ mNewButton->setEnabled(FALSE);
+
+ mDeleteButton->setVisible(TRUE);
+ mDeleteButton->setEnabled(FALSE);
+ }
+
+ childSetVisible("buttons_header", own_profile);
+}
+
+void LLPanelProfilePicks::createPick(const LLPickData &data)
+{
+ if (getIsLoaded())
+ {
+ if (canAddNewPick())
+ {
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+ }
+ else
+ {
+ // This means that something doesn't properly check limits
+ // before creating a pick
+ LL_WARNS() << "failed to add pick" << LL_ENDL;
+ }
+ }
+ else
+ {
+ mSheduledPickCreation.push_back(data);
+ }
+}
+
+void LLPanelProfilePicks::selectPick(const LLUUID& pick_id)
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ if (pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->selectTabPanel(pick_panel);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ mPickToSelectOnLoad = pick_id;
+ }
+}
+
+BOOL LLPanelProfilePicks::postBuild()
+{
+ mTabContainer = getChild<LLTabContainer>("tab_picks");
+ mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
+ mNewButton = getChild<LLButton>("new_btn");
+ mDeleteButton = getChild<LLButton>("delete_btn");
+
+ mNewButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickNewBtn, this));
+ mDeleteButton->setCommitCallback(boost::bind(&LLPanelProfilePicks::onClickDelete, this));
+
+ return TRUE;
+}
+
+void LLPanelProfilePicks::onClickNewBtn()
+{
+ mNoItemsLabel->setVisible(FALSE);
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(true).
+ label(pick_panel->getPickName()));
+ updateButtons();
+}
+
+void LLPanelProfilePicks::onClickDelete()
+{
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (pick_panel)
+ {
+ LLUUID pick_id = pick_panel->getPickId();
+ LLSD args;
+ args["PICK"] = pick_panel->getPickName();
+ LLSD payload;
+ payload["pick_id"] = pick_id;
+ payload["tab_idx"] = mTabContainer->getCurrentPanelIndex();
+ LLNotificationsUtil::add("ProfileDeletePick", args, payload,
+ boost::bind(&LLPanelProfilePicks::callbackDeletePick, this, _1, _2));
+ }
+}
+
+void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+
+ if (0 == option)
+ {
+ LLUUID pick_id = notification["payload"]["pick_id"].asUUID();
+ S32 tab_idx = notification["payload"]["tab_idx"].asInteger();
+
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && pick_panel->getPickId() == pick_id)
+ {
+ mTabContainer->removeTabPanel(pick_panel);
+ }
+
+ if (pick_id.notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickDelete(pick_id);
+ }
+
+ updateButtons();
+ }
+}
+
+void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICKS == type)
+ {
+ LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
+ if (avatar_picks && getAvatarId() == avatar_picks->target_id)
+ {
+ processProperties(avatar_picks);
+ }
+ }
+}
+
+void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
+{
+ LLUUID selected_id = mPickToSelectOnLoad;
+ bool has_selection = false;
+ if (mPickToSelectOnLoad.isNull())
+ {
+ if (mTabContainer->getTabCount() > 0)
+ {
+ LLPanelProfilePick* active_pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getCurrentPanel());
+ if (active_pick_panel)
+ {
+ selected_id = active_pick_panel->getPickId();
+ }
+ }
+ }
+
+ mTabContainer->deleteAllTabs();
+
+ LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ for (; avatar_picks->picks_list.end() != it; ++it)
+ {
+ LLUUID pick_id = it->first;
+ std::string pick_name = it->second;
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+
+ pick_panel->setPickId(pick_id);
+ pick_panel->setPickName(pick_name);
+ pick_panel->setAvatarId(getAvatarId());
+
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(selected_id == pick_id).
+ label(pick_name));
+
+ if (selected_id == pick_id)
+ {
+ has_selection = true;
+ }
+ }
+
+ while (!mSheduledPickCreation.empty() && canAddNewPick())
+ {
+ const LLPickData data =
+ mSheduledPickCreation.back();
+
+ LLPanelProfilePick* pick_panel = LLPanelProfilePick::create();
+ pick_panel->setAvatarId(getAvatarId());
+ pick_panel->processProperties(&data);
+ mTabContainer->addTabPanel(
+ LLTabContainer::TabPanelParams().
+ panel(pick_panel).
+ select_tab(!has_selection).
+ label(pick_panel->getPickName()));
+
+ mSheduledPickCreation.pop_back();
+ has_selection = true;
+ }
+
+ // reset 'do on load' values
+ mPickToSelectOnLoad = LLUUID::null;
+ mSheduledPickCreation.clear();
+
+ if (getSelfProfile())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoPicksText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksText"));
+ }
+
+ bool has_data = mTabContainer->getTabCount() > 0;
+ mNoItemsLabel->setVisible(!has_data);
+ if (has_data && !has_selection)
+ {
+ mTabContainer->selectFirstTab();
+ }
+
+ setLoaded();
+ updateButtons();
+}
+
+void LLPanelProfilePicks::resetData()
+{
+ resetLoading();
+ mTabContainer->deleteAllTabs();
+}
+
+void LLPanelProfilePicks::updateButtons()
+{
+ if (getSelfProfile())
+ {
+ mNewButton->setEnabled(canAddNewPick());
+ mDeleteButton->setEnabled(canDeletePick());
+ }
+}
+
+void LLPanelProfilePicks::apply()
+{
+ if (getIsLoaded())
+ {
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+ }
+}
+
+void LLPanelProfilePicks::updateData()
+{
+ // Send picks request only once
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id);
+ }
+ if (!getIsLoaded())
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+ mNoItemsLabel->setVisible(TRUE);
+ }
+}
+
+bool LLPanelProfilePicks::hasUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel && (pick_panel->isDirty() || pick_panel->isDirty()))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLPanelProfilePicks::commitUnsavedChanges()
+{
+ for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+ {
+ LLPanelProfilePick* pick_panel = dynamic_cast<LLPanelProfilePick*>(mTabContainer->getPanelByIndex(tab_idx));
+ if (pick_panel)
+ {
+ pick_panel->apply();
+ }
+ }
+}
+
+bool LLPanelProfilePicks::canAddNewPick()
+{
+ return (!LLAgentPicksInfo::getInstance()->isPickLimitReached() &&
+ mTabContainer->getTabCount() < LLAgentPicksInfo::getInstance()->getMaxNumberOfPicks());
+}
+
+bool LLPanelProfilePicks::canDeletePick()
+{
+ return (mTabContainer->getTabCount() > 0);
+}
+
+
+//-----------------------------------------------------------------------------
+// LLPanelProfilePick
+//-----------------------------------------------------------------------------
+
+LLPanelProfilePick::LLPanelProfilePick()
+ : LLPanelProfilePropertiesProcessorTab()
+ , LLRemoteParcelInfoObserver()
+ , mSnapshotCtrl(NULL)
+ , mPickId(LLUUID::null)
+ , mParcelId(LLUUID::null)
+ , mRequestedId(LLUUID::null)
+ , mLocationChanged(false)
+ , mNewPick(false)
+ , mIsEditing(false)
+{
+}
+
+//static
+LLPanelProfilePick* LLPanelProfilePick::create()
+{
+ LLPanelProfilePick* panel = new LLPanelProfilePick();
+ panel->buildFromFile("panel_profile_pick.xml");
+ return panel;
+}
+
+LLPanelProfilePick::~LLPanelProfilePick()
+{
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
+{
+ if (avatar_id.isNull())
+ {
+ return;
+ }
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
+
+ // creating new Pick
+ if (getPickId().isNull() && getSelfProfile())
+ {
+ mNewPick = true;
+
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ LLUUID parcel_id = LLUUID::null, snapshot_id = LLUUID::null;
+ std::string pick_name, pick_desc, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ parcel_id = parcel->getID();
+ pick_name = parcel->getName();
+ pick_desc = parcel->getDesc();
+ snapshot_id = parcel->getSnapshotID();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setParcelID(parcel_id);
+ setPickName(pick_name.empty() ? region_name : pick_name);
+ setPickDesc(pick_desc);
+ setSnapshotId(snapshot_id);
+ setPickLocation(createLocationText(getLocationNotice(), pick_name, region_name, getPosGlobal()));
+
+ enableSaveButton(TRUE);
+ }
+ else
+ {
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+
+ enableSaveButton(FALSE);
+ }
+
+ resetDirty();
+
+ if (getSelfProfile())
+ {
+ mPickName->setEnabled(TRUE);
+ mPickDescription->setEnabled(TRUE);
+ mSetCurrentLocationButton->setVisible(TRUE);
+ }
+ else
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+}
+
+BOOL LLPanelProfilePick::postBuild()
+{
+ mPickName = getChild<LLLineEditor>("pick_name");
+ mPickDescription = getChild<LLTextEditor>("pick_desc");
+ mSaveButton = getChild<LLButton>("save_changes_btn");
+ mCreateButton = getChild<LLButton>("create_changes_btn");
+ mCancelButton = getChild<LLButton>("cancel_changes_btn");
+ mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn");
+
+ mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot");
+ mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this));
+
+ childSetAction("teleport_btn", boost::bind(&LLPanelProfilePick::onClickTeleport, this));
+ childSetAction("show_on_map_btn", boost::bind(&LLPanelProfilePick::onClickMap, this));
+
+ mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this));
+ mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this));
+ mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this));
+
+ mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL);
+ mPickName->setEnabled(FALSE);
+
+ mPickDescription->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1));
+ mPickDescription->setFocusReceivedCallback(boost::bind(&LLPanelProfilePick::onDescriptionFocusReceived, this));
+
+ getChild<LLUICtrl>("pick_location")->setEnabled(FALSE);
+
+ return TRUE;
+}
+
+void LLPanelProfilePick::onDescriptionFocusReceived()
+{
+ if (!mIsEditing && getSelfProfile())
+ {
+ mIsEditing = true;
+ mPickDescription->setParseHTML(false);
+ }
+}
+
+void LLPanelProfilePick::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PICK_INFO != type)
+ {
+ return;
+ }
+
+ LLPickData* pick_info = static_cast<LLPickData*>(data);
+ if (!pick_info
+ || pick_info->creator_id != getAvatarId()
+ || pick_info->pick_id != getPickId())
+ {
+ return;
+ }
+
+ processProperties(pick_info);
+}
+
+void LLPanelProfilePick::processProperties(const LLPickData* pick_info)
+{
+ mIsEditing = false;
+ mPickDescription->setParseHTML(true);
+ mParcelId = pick_info->parcel_id;
+ setSnapshotId(pick_info->snapshot_id);
+ if (!getSelfProfile())
+ {
+ mSnapshotCtrl->setEnabled(FALSE);
+ }
+ setPickName(pick_info->name);
+ setPickDesc(pick_info->desc);
+ setPosGlobal(pick_info->pos_global);
+
+ // Send remote parcel info request to get parcel name and sim (region) name.
+ sendParcelInfoRequest();
+
+ // *NOTE dzaporozhan
+ // We want to keep listening to APT_PICK_INFO because user may
+ // edit the Pick and we have to update Pick info panel.
+ // revomeObserver is called from onClickBack
+
+ setLoaded();
+}
+
+void LLPanelProfilePick::apply()
+{
+ if ((mNewPick || getIsLoaded()) && isDirty())
+ {
+ sendUpdate();
+ }
+}
+
+void LLPanelProfilePick::setSnapshotId(const LLUUID& id)
+{
+ mSnapshotCtrl->setImageAssetID(id);
+ mSnapshotCtrl->setValid(TRUE);
+}
+
+void LLPanelProfilePick::setPickName(const std::string& name)
+{
+ mPickName->setValue(name);
+}
+
+const std::string LLPanelProfilePick::getPickName()
+{
+ return mPickName->getValue().asString();
+}
+
+void LLPanelProfilePick::setPickDesc(const std::string& desc)
+{
+ mPickDescription->setValue(desc);
+}
+
+void LLPanelProfilePick::setPickLocation(const std::string& location)
+{
+ getChild<LLUICtrl>("pick_location")->setValue(location);
+}
+
+void LLPanelProfilePick::onClickMap()
+{
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ LLFloaterReg::showInstance("world_map", "center");
+}
+
+void LLPanelProfilePick::onClickTeleport()
+{
+ if (!getPosGlobal().isExactlyZero())
+ {
+ gAgent.teleportViaLocation(getPosGlobal());
+ LLFloaterWorldMap::getInstance()->trackLocation(getPosGlobal());
+ }
+}
+
+void LLPanelProfilePick::enableSaveButton(BOOL enable)
+{
+ childSetVisible("save_changes_lp", enable);
+
+ childSetVisible("save_btn_lp", enable && !mNewPick);
+ childSetVisible("create_btn_lp", enable && mNewPick);
+ childSetVisible("cancel_btn_lp", enable && !mNewPick);
+}
+
+void LLPanelProfilePick::onSnapshotChanged()
+{
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onPickChanged(LLUICtrl* ctrl)
+{
+ if (ctrl && ctrl == mPickName)
+ {
+ updateTabLabel(mPickName->getText());
+ }
+
+ enableSaveButton(isDirty());
+}
+
+void LLPanelProfilePick::resetDirty()
+{
+ LLPanel::resetDirty();
+
+ mPickName->resetDirty();
+ mPickDescription->resetDirty();
+ mSnapshotCtrl->resetDirty();
+ mLocationChanged = false;
+}
+
+BOOL LLPanelProfilePick::isDirty() const
+{
+ if (mNewPick
+ || LLPanel::isDirty()
+ || mLocationChanged
+ || mSnapshotCtrl->isDirty()
+ || mPickName->isDirty()
+ || mPickDescription->isDirty())
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void LLPanelProfilePick::onClickSetLocation()
+{
+ // Save location for later use.
+ setPosGlobal(gAgent.getPositionGlobal());
+
+ std::string parcel_name, region_name;
+
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mParcelId = parcel->getID();
+ parcel_name = parcel->getName();
+ }
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ region_name = region->getName();
+ }
+
+ setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal()));
+
+ mLocationChanged = true;
+ enableSaveButton(TRUE);
+}
+
+void LLPanelProfilePick::onClickSave()
+{
+ sendUpdate();
+
+ mLocationChanged = false;
+}
+
+void LLPanelProfilePick::onClickCancel()
+{
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoRequest(getAvatarId(), getPickId());
+ mLocationChanged = false;
+ enableSaveButton(FALSE);
+}
+
+std::string LLPanelProfilePick::getLocationNotice()
+{
+ static const std::string notice = getString("location_notice");
+ return notice;
+}
+
+void LLPanelProfilePick::sendParcelInfoRequest()
+{
+ if (mParcelId != mRequestedId)
+ {
+ if (mRequestedId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this);
+ }
+ LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
+ LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
+
+ mRequestedId = mParcelId;
+ }
+}
+
+void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data)
+{
+ setPickLocation(createLocationText(LLStringUtil::null, parcel_data.name, parcel_data.sim_name, getPosGlobal()));
+
+ // We have received parcel info for the requested ID so clear it now.
+ mRequestedId.setNull();
+
+ if (mParcelId.notNull())
+ {
+ LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mParcelId, this);
+ }
+}
+
+void LLPanelProfilePick::sendUpdate()
+{
+ LLPickData pick_data;
+
+ // If we don't have a pick id yet, we'll need to generate one,
+ // otherwise we'll keep overwriting pick_id 00000 in the database.
+ if (getPickId().isNull())
+ {
+ getPickId().generate();
+ }
+
+ pick_data.agent_id = gAgentID;
+ pick_data.session_id = gAgent.getSessionID();
+ pick_data.pick_id = getPickId();
+ pick_data.creator_id = gAgentID;;
+
+ //legacy var need to be deleted
+ pick_data.top_pick = FALSE;
+ pick_data.parcel_id = mParcelId;
+ pick_data.name = getPickName();
+ pick_data.desc = mPickDescription->getValue().asString();
+ pick_data.snapshot_id = mSnapshotCtrl->getImageAssetID();
+ pick_data.pos_global = getPosGlobal();
+ pick_data.sort_order = 0;
+ pick_data.enabled = TRUE;
+
+ LLAvatarPropertiesProcessor::getInstance()->sendPickInfoUpdate(&pick_data);
+
+ if(mNewPick)
+ {
+ // Assume a successful create pick operation, make new number of picks
+ // available immediately. Actual number of picks will be requested in
+ // LLAvatarPropertiesProcessor::sendPickInfoUpdate and updated upon server respond.
+ LLAgentPicksInfo::getInstance()->incrementNumberOfPicks();
+ }
+}
+
+// static
+std::string LLPanelProfilePick::createLocationText(const std::string& owner_name, const std::string& original_name, const std::string& sim_name, const LLVector3d& pos_global)
+{
+ std::string location_text(owner_name);
+ if (!original_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(original_name);
+
+ }
+
+ if (!sim_name.empty())
+ {
+ if (!location_text.empty())
+ {
+ location_text.append(", ");
+ }
+ location_text.append(sim_name);
+ }
+
+ if (!location_text.empty())
+ {
+ location_text.append(" ");
+ }
+
+ if (!pos_global.isNull())
+ {
+ S32 region_x = ll_round((F32)pos_global.mdV[VX]) % REGION_WIDTH_UNITS;
+ S32 region_y = ll_round((F32)pos_global.mdV[VY]) % REGION_WIDTH_UNITS;
+ S32 region_z = ll_round((F32)pos_global.mdV[VZ]);
+ location_text.append(llformat(" (%d, %d, %d)", region_x, region_y, region_z));
+ }
+ return location_text;
+}
+
+void LLPanelProfilePick::updateTabLabel(const std::string& title)
+{
+ setLabel(title);
+ LLTabContainer* parent = dynamic_cast<LLTabContainer*>(getParent());
+ if (parent)
+ {
+ parent->setCurrentTabName(title);
+ }
+}
+
diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h
new file mode 100644
index 0000000000..f84463cc9b
--- /dev/null
+++ b/indra/newview/llpanelprofilepicks.h
@@ -0,0 +1,248 @@
+/**
+ * @file llpanelprofilepicks.h
+ * @brief LLPanelProfilePicks and related class definitions
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, 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_LLPANELPICKS_H
+#define LL_LLPANELPICKS_H
+
+#include "llpanel.h"
+#include "lluuid.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llpanelavatar.h"
+#include "llremoteparcelrequest.h"
+
+class LLTabContainer;
+class LLTextureCtrl;
+class LLMediaCtrl;
+class LLLineEditor;
+class LLTextEditor;
+
+
+/**
+* Panel for displaying Avatar's picks.
+*/
+class LLPanelProfilePicks
+ : public LLPanelProfilePropertiesProcessorTab
+{
+public:
+ LLPanelProfilePicks();
+ /*virtual*/ ~LLPanelProfilePicks();
+
+ BOOL postBuild() override;
+
+ void onOpen(const LLSD& key) override;
+
+ void createPick(const LLPickData &data);
+ void selectPick(const LLUUID& pick_id);
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLAvatarPicks* avatar_picks);
+
+ void resetData() override;
+
+ void updateButtons();
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ /**
+ * Sends update data request to server.
+ */
+ void updateData() override;
+
+ bool hasUnsavedChanges() override;
+ void commitUnsavedChanges() override;
+
+ friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+
+private:
+ void onClickNewBtn();
+ void onClickDelete();
+ void callbackDeletePick(const LLSD& notification, const LLSD& response);
+
+ bool canAddNewPick();
+ bool canDeletePick();
+
+ LLTabContainer* mTabContainer;
+ LLUICtrl* mNoItemsLabel;
+ LLButton* mNewButton;
+ LLButton* mDeleteButton;
+
+ LLUUID mPickToSelectOnLoad;
+ std::list<LLPickData> mSheduledPickCreation;
+};
+
+
+class LLPanelProfilePick
+ : public LLPanelProfilePropertiesProcessorTab
+ , public LLRemoteParcelInfoObserver
+{
+public:
+
+ // Creates new panel
+ static LLPanelProfilePick* create();
+
+ LLPanelProfilePick();
+
+ /*virtual*/ ~LLPanelProfilePick();
+
+ BOOL postBuild() override;
+
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ void setPickId(const LLUUID& id) { mPickId = id; }
+ virtual LLUUID& getPickId() { return mPickId; }
+
+ virtual void setPickName(const std::string& name);
+ const std::string getPickName();
+
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLPickData* pick_data);
+
+ /**
+ * Returns true if any of Pick properties was changed by user.
+ */
+ BOOL isDirty() const override;
+
+ /**
+ * Saves changes.
+ */
+ virtual void apply();
+
+ void updateTabLabel(const std::string& title);
+
+ //This stuff we got from LLRemoteParcelObserver, in the last one we intentionally do nothing
+ void processParcelInfo(const LLParcelData& parcel_data) override;
+ void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; }
+ void setErrorStatus(S32 status, const std::string& reason) override {};
+
+protected:
+
+ /**
+ * Sends remote parcel info request to resolve parcel name from its ID.
+ */
+ void sendParcelInfoRequest();
+
+ /**
+ * "Location text" is actually the owner name, the original
+ * name that owner gave the parcel, and the location.
+ */
+ static std::string createLocationText(
+ const std::string& owner_name,
+ const std::string& original_name,
+ const std::string& sim_name,
+ const LLVector3d& pos_global);
+
+ /**
+ * Sets snapshot id.
+ *
+ * Will mark snapshot control as valid if id is not null.
+ * Will mark snapshot control as invalid if id is null. If null id is a valid value,
+ * you have to manually mark snapshot is valid.
+ */
+ virtual void setSnapshotId(const LLUUID& id);
+ virtual void setPickDesc(const std::string& desc);
+ virtual void setPickLocation(const std::string& location);
+
+ virtual void setPosGlobal(const LLVector3d& pos) { mPosGlobal = pos; }
+ virtual LLVector3d& getPosGlobal() { return mPosGlobal; }
+
+ /**
+ * Callback for "Map" button, opens Map
+ */
+ void onClickMap();
+
+ /**
+ * Callback for "Teleport" button, teleports user to Pick location.
+ */
+ void onClickTeleport();
+
+ /**
+ * Enables/disables "Save" button
+ */
+ void enableSaveButton(BOOL enable);
+
+ /**
+ * Called when snapshot image changes.
+ */
+ void onSnapshotChanged();
+
+ /**
+ * Callback for Pick snapshot, name and description changed event.
+ */
+ void onPickChanged(LLUICtrl* ctrl);
+
+ /**
+ * Resets panel and all cantrols to unedited state
+ */
+ void resetDirty() override;
+
+ /**
+ * Callback for "Set Location" button click
+ */
+ void onClickSetLocation();
+
+ /**
+ * Callback for "Save" and "Create" button click
+ */
+ void onClickSave();
+
+ /**
+ * Callback for "Save" button click
+ */
+ void onClickCancel();
+
+ std::string getLocationNotice();
+
+ /**
+ * Sends Pick properties to server.
+ */
+ void sendUpdate();
+
+protected:
+
+ LLTextureCtrl* mSnapshotCtrl;
+ LLLineEditor* mPickName;
+ LLTextEditor* mPickDescription;
+ LLButton* mSetCurrentLocationButton;
+ LLButton* mSaveButton;
+ LLButton* mCreateButton;
+ LLButton* mCancelButton;
+
+ LLVector3d mPosGlobal;
+ LLUUID mParcelId;
+ LLUUID mPickId;
+ LLUUID mRequestedId;
+
+ bool mLocationChanged;
+ bool mNewPick;
+ bool mIsEditing;
+
+ void onDescriptionFocusReceived();
+};
+
+#endif // LL_LLPANELPICKS_H
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 89c558e4f8..39f4c7485b 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -51,6 +51,7 @@
#include "llfocusmgr.h"
#include "llmanipscale.h"
#include "llinventorymodel.h"
+#include "llmenubutton.h"
#include "llpreviewscript.h"
#include "llresmgr.h"
#include "llselectmgr.h"
@@ -168,6 +169,9 @@ BOOL LLPanelVolume::postBuild()
mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution));
}
+ mMenuClipboardFeatures = getChild<LLMenuButton>("clipboard_features_params_btn");
+ mMenuClipboardLight = getChild<LLMenuButton>("clipboard_light_params_btn");
+
std::map<std::string, std::string> material_name_map;
material_name_map["Stone"]= LLTrans::getString("Stone");
material_name_map["Metal"]= LLTrans::getString("Metal");
@@ -208,6 +212,8 @@ LLPanelVolume::LLPanelVolume()
{
setMouseOpaque(FALSE);
+ mCommitCallbackRegistrar.add("PanelVolume.menuDoToSelected", boost::bind(&LLPanelVolume::menuDoToSelected, this, _2));
+ mEnableCallbackRegistrar.add("PanelVolume.menuEnable", boost::bind(&LLPanelVolume::menuEnableItem, this, _2));
}
@@ -409,7 +415,6 @@ void LLPanelVolume::getState( )
gAgentAvatarp->updateMeshVisibility();
}
}
-
// Flexible properties
BOOL is_flexible = volobjp && volobjp->isFlexible();
@@ -564,6 +569,9 @@ void LLPanelVolume::getState( )
mObject = objectp;
mRootObject = root_objectp;
+
+ mMenuClipboardFeatures->setEnabled(editable && single_volume && volobjp); // Note: physics doesn't need to be limited by single volume
+ mMenuClipboardLight->setEnabled(editable && single_volume && volobjp);
}
// static
@@ -587,13 +595,6 @@ void LLPanelVolume::refresh()
mRootObject = NULL;
}
- BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE;
-
- getChildView("Light FOV")->setVisible( visible);
- getChildView("Light Focus")->setVisible( visible);
- getChildView("Light Ambiance")->setVisible( visible);
- getChildView("light texture control")->setVisible( visible);
-
bool enable_mesh = false;
LLSD sim_features;
@@ -831,6 +832,290 @@ void LLPanelVolume::onLightSelectTexture(const LLSD& data)
}
}
+void LLPanelVolume::onCopyFeatures()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLSD clipboard;
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Flexi Prim
+ if (volobjp && volobjp->isFlexible())
+ {
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ clipboard["flex"]["lod"] = attributes->getSimulateLOD();
+ clipboard["flex"]["gav"] = attributes->getGravity();
+ clipboard["flex"]["ten"] = attributes->getTension();
+ clipboard["flex"]["fri"] = attributes->getAirFriction();
+ clipboard["flex"]["sen"] = attributes->getWindSensitivity();
+ LLVector3 force = attributes->getUserForce();
+ clipboard["flex"]["forx"] = force.mV[0];
+ clipboard["flex"]["fory"] = force.mV[1];
+ clipboard["flex"]["forz"] = force.mV[2];
+ }
+ }
+
+ // Physics
+ {
+ clipboard["physics"]["shape"] = objectp->getPhysicsShapeType();
+ clipboard["physics"]["gravity"] = objectp->getPhysicsGravity();
+ clipboard["physics"]["friction"] = objectp->getPhysicsFriction();
+ clipboard["physics"]["density"] = objectp->getPhysicsDensity();
+ clipboard["physics"]["restitution"] = objectp->getPhysicsRestitution();
+
+ U8 material_code = 0;
+ struct f : public LLSelectedTEGetFunctor<U8>
+ {
+ U8 get(LLViewerObject* object, S32 te)
+ {
+ return object->getMaterial();
+ }
+ } func;
+ bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func, material_code);
+ // This should always be true since material should be per object.
+ if (material_same)
+ {
+ clipboard["physics"]["material"] = material_code;
+ }
+ }
+
+ mClipboardParams["features"] = clipboard;
+}
+
+void LLPanelVolume::onPasteFeatures()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp && mClipboardParams.has("features"))
+ {
+ return;
+ }
+
+ LLSD &clipboard = mClipboardParams["features"];
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Physics
+ bool is_root = objectp->isRoot();
+
+ // Not sure if phantom should go under physics, but doesn't fit elsewhere
+ BOOL is_phantom = clipboard["is_phantom"].asBoolean() && is_root;
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom);
+
+ BOOL is_physical = clipboard["is_physical"].asBoolean() && is_root;
+ LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical);
+
+ if (clipboard.has("physics"))
+ {
+ objectp->setPhysicsShapeType((U8)clipboard["physics"]["shape"].asInteger());
+ U8 cur_material = objectp->getMaterial();
+ U8 material = (U8)clipboard["physics"]["material"].asInteger() | (cur_material & ~LL_MCODE_MASK);
+
+ objectp->setMaterial(material);
+ objectp->sendMaterialUpdate();
+ objectp->setPhysicsGravity(clipboard["physics"]["gravity"].asReal());
+ objectp->setPhysicsFriction(clipboard["physics"]["friction"].asReal());
+ objectp->setPhysicsDensity(clipboard["physics"]["density"].asReal());
+ objectp->setPhysicsRestitution(clipboard["physics"]["restitution"].asReal());
+ objectp->updateFlags(TRUE);
+ }
+
+ // Flexible
+ bool is_flexible = clipboard.has("flex");
+ if (is_flexible && volobjp->canBeFlexible())
+ {
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ BOOL update_shape = FALSE;
+
+ // do before setParameterEntry or it will think that it is already flexi
+ update_shape = volobjp->setIsFlexible(is_flexible);
+
+ if (objectp->getClickAction() == CLICK_ACTION_SIT)
+ {
+ objectp->setClickAction(CLICK_ACTION_NONE);
+ }
+
+ LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ if (attributes)
+ {
+ LLFlexibleObjectData new_attributes;
+ new_attributes = *attributes;
+ new_attributes.setSimulateLOD(clipboard["flex"]["lod"].asInteger());
+ new_attributes.setGravity(clipboard["flex"]["gav"].asReal());
+ new_attributes.setTension(clipboard["flex"]["ten"].asReal());
+ new_attributes.setAirFriction(clipboard["flex"]["fri"].asReal());
+ new_attributes.setWindSensitivity(clipboard["flex"]["sen"].asReal());
+ F32 fx = (F32)clipboard["flex"]["forx"].asReal();
+ F32 fy = (F32)clipboard["flex"]["fory"].asReal();
+ F32 fz = (F32)clipboard["flex"]["forz"].asReal();
+ LLVector3 force(fx, fy, fz);
+ new_attributes.setUserForce(force);
+ objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true);
+ }
+
+ if (update_shape)
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+ }
+ else
+ {
+ LLVOVolume *volobjp = (LLVOVolume *)objectp;
+ if (volobjp->setIsFlexible(false))
+ {
+ mObject->sendShapeUpdate();
+ LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom());
+ }
+ }
+}
+
+void LLPanelVolume::onCopyLight()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp)
+ {
+ return;
+ }
+
+ LLSD clipboard;
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Light Source
+ if (volobjp && volobjp->getIsLight())
+ {
+ clipboard["light"]["intensity"] = volobjp->getLightIntensity();
+ clipboard["light"]["radius"] = volobjp->getLightRadius();
+ clipboard["light"]["falloff"] = volobjp->getLightFalloff();
+ LLColor3 color = volobjp->getLightSRGBColor();
+ clipboard["light"]["r"] = color.mV[0];
+ clipboard["light"]["g"] = color.mV[1];
+ clipboard["light"]["b"] = color.mV[2];
+
+ // Spotlight
+ if (volobjp->isLightSpotlight())
+ {
+ LLUUID id = volobjp->getLightTextureID();
+ if (id.notNull() && get_can_copy_texture(id))
+ {
+ clipboard["spot"]["id"] = id;
+ LLVector3 spot_params = volobjp->getSpotLightParams();
+ clipboard["spot"]["fov"] = spot_params.mV[0];
+ clipboard["spot"]["focus"] = spot_params.mV[1];
+ clipboard["spot"]["ambiance"] = spot_params.mV[2];
+ }
+ }
+ }
+
+ mClipboardParams["light"] = clipboard;
+}
+
+void LLPanelVolume::onPasteLight()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp && mClipboardParams.has("light"))
+ {
+ return;
+ }
+
+ LLSD &clipboard = mClipboardParams["light"];
+
+ LLVOVolume *volobjp = NULL;
+ if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME))
+ {
+ volobjp = (LLVOVolume *)objectp;
+ }
+
+ // Light Source
+ if (volobjp)
+ {
+ if (clipboard.has("light"))
+ {
+ volobjp->setIsLight(TRUE);
+ volobjp->setLightIntensity((F32)clipboard["light"]["intensity"].asReal());
+ volobjp->setLightRadius((F32)clipboard["light"]["radius"].asReal());
+ volobjp->setLightFalloff((F32)clipboard["light"]["falloff"].asReal());
+ F32 r = (F32)clipboard["light"]["r"].asReal();
+ F32 g = (F32)clipboard["light"]["g"].asReal();
+ F32 b = (F32)clipboard["light"]["b"].asReal();
+ volobjp->setLightSRGBColor(LLColor3(r, g, b));
+ }
+ else
+ {
+ volobjp->setIsLight(FALSE);
+ }
+
+ if (clipboard.has("spot"))
+ {
+ volobjp->setLightTextureID(clipboard["spot"]["id"].asUUID());
+ LLVector3 spot_params;
+ spot_params.mV[0] = (F32)clipboard["spot"]["fov"].asReal();
+ spot_params.mV[1] = (F32)clipboard["spot"]["focus"].asReal();
+ spot_params.mV[2] = (F32)clipboard["spot"]["ambiance"].asReal();
+ volobjp->setSpotLightParams(spot_params);
+ }
+ }
+}
+
+void LLPanelVolume::menuDoToSelected(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste
+ if (command == "features_paste")
+ {
+ onPasteFeatures();
+ }
+ else if (command == "light_paste")
+ {
+ onPasteLight();
+ }
+ // copy
+ else if (command == "features_copy")
+ {
+ onCopyFeatures();
+ }
+ else if (command == "light_copy")
+ {
+ onCopyLight();
+ }
+}
+
+bool LLPanelVolume::menuEnableItem(const LLSD& userdata)
+{
+ std::string command = userdata.asString();
+
+ // paste options
+ if (command == "features_paste")
+ {
+ return mClipboardParams.has("features");
+ }
+ else if (command == "light_paste")
+ {
+ return mClipboardParams.has("light");
+ }
+ return false;
+}
+
// static
void LLPanelVolume::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
{
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index 6e49ccb742..d9198f3693 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -37,6 +37,7 @@ class LLCheckBoxCtrl;
class LLTextBox;
class LLUICtrl;
class LLButton;
+class LLMenuButton;
class LLViewerObject;
class LLComboBox;
class LLColorSwatchCtrl;
@@ -76,6 +77,13 @@ public:
static void setLightTextureID(const LLUUID &asset_id, const LLUUID &item_id, LLVOVolume* volobjp);
+ void onCopyFeatures();
+ void onPasteFeatures();
+ void onCopyLight();
+ void onPasteLight();
+
+ void menuDoToSelected(const LLSD& userdata);
+ bool menuEnableItem(const LLSD& userdata);
protected:
void getState();
@@ -123,6 +131,11 @@ protected:
LLSpinCtrl* mSpinPhysicsFriction;
LLSpinCtrl* mSpinPhysicsDensity;
LLSpinCtrl* mSpinPhysicsRestitution;
+
+ LLMenuButton* mMenuClipboardFeatures;
+ LLMenuButton* mMenuClipboardLight;
+
+ LLSD mClipboardParams;
};
#endif
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 94d20828ec..9b60d1ae2f 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -38,154 +38,11 @@
#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
#endif
-// See EXT-4301.
-/**
- * class LLAvalineUpdater - observe the list of voice participants in session and check
- * presence of Avaline Callers among them.
- *
- * LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation:
- * - whether Avaline caller presence among participants;
- * - whether watched Avaline caller still exists in voice channel.
- * Both validations have callbacks which will notify subscriber if any of event occur.
- *
- * @see findAvalineCaller()
- * @see checkIfAvalineCallersExist()
- */
-class LLAvalineUpdater : public LLVoiceClientParticipantObserver
-{
-public:
- typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t;
-
- LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb)
- : mAvalineFoundCallback(found_cb)
- , mAvalineRemovedCallback(removed_cb)
- {
- LLVoiceClient::getInstance()->addObserver(this);
- }
- ~LLAvalineUpdater()
- {
- if (LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
- }
-
- /**
- * Adds UUID of Avaline caller to watch.
- *
- * @see checkIfAvalineCallersExist().
- */
- void watchAvalineCaller(const LLUUID& avaline_caller_id)
- {
- mAvalineCallers.insert(avaline_caller_id);
- }
-
- void onParticipantsChanged()
- {
- uuid_set_t participant_uuids;
- LLVoiceClient::getInstance()->getParticipantList(participant_uuids);
-
-
- // check whether Avaline caller exists among voice participants
- // and notify Participant List
- findAvalineCaller(participant_uuids);
-
- // check whether watched Avaline callers still present among voice participant
- // and remove if absents.
- checkIfAvalineCallersExist(participant_uuids);
- }
-
-private:
- typedef std::set<LLUUID> uuid_set_t;
-
- /**
- * Finds Avaline callers among voice participants and calls mAvalineFoundCallback.
- *
- * When Avatar is in group call with Avaline caller and then ends call Avaline caller stays
- * in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again
- * Avaline caller is added to voice channel AFTER Avatar is connected to group call.
- * But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information
- * if a speaker is Avaline caller.
- *
- * In this case this speaker is created as avatar and will be recreated when it appears in
- * Avatar's Voice session.
- *
- * @see LLParticipantList::onAvalineCallerFound()
- */
- void findAvalineCaller(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end();
-
- for(; it != it_end; ++it)
- {
- const LLUUID& participant_id = *it;
- if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id))
- {
- LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL;
-
- if (mAvalineFoundCallback)
- {
- mAvalineFoundCallback(participant_id);
- }
- }
- }
- }
-
- /**
- * Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback.
- *
- * The problem is when Avaline caller ends a call it is removed from Voice Client session but
- * still exists in LLSpeakerMgr. Server does not send such information.
- * This method implements a HUCK to notify subscribers that watched Avaline callers by class
- * are not anymore in the call.
- *
- * @see LLParticipantList::onAvalineCallerRemoved()
- */
- void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids)
- {
- uuid_set_t::iterator it = mAvalineCallers.begin();
- uuid_set_t::const_iterator participants_it_end = participant_uuids.end();
-
- while (it != mAvalineCallers.end())
- {
- const LLUUID participant_id = *it;
- LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL;
- bool not_found = participant_uuids.find(participant_id) == participants_it_end;
- if (not_found)
- {
- LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL;
-
- // notify Participant List
- if (mAvalineRemovedCallback)
- {
- mAvalineRemovedCallback(participant_id);
- }
-
- // remove from the watch list
- mAvalineCallers.erase(it++);
- }
- else
- {
- ++it;
- }
- }
- }
-
- process_avaline_callback_t mAvalineFoundCallback;
- process_avaline_callback_t mAvalineRemovedCallback;
-
- uuid_set_t mAvalineCallers;
-};
-
LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
LLConversationItemSession(data_source->getSessionID(), root_view_model),
mSpeakerMgr(data_source),
mValidateSpeakerCallback(NULL)
{
-
- mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1),
- boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1));
-
mSpeakerAddListener = new SpeakerAddListener(*this);
mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
mSpeakerClearListener = new SpeakerClearListener(*this);
@@ -243,32 +100,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewMode
LLParticipantList::~LLParticipantList()
{
- delete mAvalineUpdater;
-}
-
-/*
- Seems this method is not necessary after onAvalineCallerRemoved was implemented;
-
- It does nothing because list item is always created with correct class type for Avaline caller.
- For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client
- session.
- This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call.
-
- Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself.
- Asked in EXT-4301.
-*/
-void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
-{
- removeParticipant(participant_id);
- // re-add avaline caller with a correct class instance.
- addAvatarIDExceptAgent(participant_id);
-}
-
-void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
-{
- LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL;
-
- mSpeakerMgr->removeAvalineSpeaker(participant_id);
}
void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
@@ -386,7 +217,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
// Create a participant view model instance
participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
- mAvalineUpdater->watchAvalineCaller(avatar_id);
}
// *TODO : Need to update the online/offline status of the participant
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 3a3ae76604..14c0a63692 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -32,7 +32,6 @@
class LLSpeakerMgr;
class LLUICtrl;
-class LLAvalineUpdater;
class LLParticipantList : public LLConversationItemSession
{
@@ -133,8 +132,6 @@ protected:
};
private:
- void onAvalineCallerFound(const LLUUID& participant_id);
- void onAvalineCallerRemoved(const LLUUID& participant_id);
/**
* Adjusts passed participant to work properly.
@@ -156,7 +153,6 @@ private:
LLPointer<SpeakerMuteListener> mSpeakerMuteListener;
validate_speaker_callback_t mValidateSpeakerCallback;
- LLAvalineUpdater* mAvalineUpdater;
};
#endif // LL_PARTICIPANTLIST_H
diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp
index 6e3e375488..a7011dfad5 100644
--- a/indra/newview/llpatchvertexarray.cpp
+++ b/indra/newview/llpatchvertexarray.cpp
@@ -69,11 +69,9 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p
// (The -1 is there because an LLSurface has a buffer of 1 on
// its East and North edges).
U32 power_of_two = 1;
- U32 surface_order = 0;
while (power_of_two < (surface_width-1))
{
power_of_two *= 2;
- surface_order += 1;
}
if (power_of_two == (surface_width-1))
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9bc77393dc..9bf771db8a 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -163,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications()
LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
}
-void LLPersistentNotificationStorage::initialize()
+void LLPersistentNotificationStorage::reset()
{
- std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
- setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
- setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+ std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml";
+ setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name));
+ setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"));
+}
+void LLPersistentNotificationStorage::initialize()
+{
+ reset();
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
}
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
index 1fb4487286..335d85aaf6 100644
--- a/indra/newview/llpersistentnotificationstorage.h
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -52,6 +52,7 @@ public:
void saveNotifications();
void loadNotifications();
+ void reset();
protected:
diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp
index 5bfe5c9941..9603ee6329 100644
--- a/indra/newview/llphysicsshapebuilderutil.cpp
+++ b/indra/newview/llphysicsshapebuilderutil.cpp
@@ -29,7 +29,7 @@
#include "llphysicsshapebuilderutil.h"
/* static */
-void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut )
+void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut)
{
const LLProfileParams& profile_params = volume_params.getProfileParams();
const LLPathParams& path_params = volume_params.getPathParams();
@@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
if ( volume_params.shouldForceConvex() )
{
+ // Server distinguishes between convex of a prim vs isSculpt, but we don't care.
specOut.mType = PhysicsShapeSpecification::USER_CONVEX;
}
// Make a simpler convex shape if we can.
@@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
{
specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
}
+ else if (volume_params.isMeshSculpt() &&
+ // Check overall dimensions, not individual triangles.
+ (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ||
+ scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE
+ ) )
+ {
+ // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't.
+ specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX;
+ }
else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy)
{
specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT;
diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h
index bd5b7d799c..b3b100296f 100644
--- a/indra/newview/llphysicsshapebuilderutil.h
+++ b/indra/newview/llphysicsshapebuilderutil.h
@@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f;
const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f;
const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE;
const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE;
+const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f;
class LLPhysicsVolumeParams : public LLVolumeParams
{
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index c267c3c699..30d0a22ef0 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -332,7 +332,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
else
{
ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType");
- bool new_camera_offsets = false;
if (IS_CAMERA)
{
if (isDefaultCameraPreset(name))
@@ -354,7 +353,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n
{
new_camera_preset = CAMERA_PRESET_CUSTOM;
}
- new_camera_offsets = (!isDefaultCameraPreset(name) || (ECameraPreset)gSavedSettings.getU32("CameraPresetType") != new_camera_preset);
}
for (std::vector<std::string>::iterator it = name_list.begin(); it != name_list.end(); ++it)
{
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 230def5362..3fd4f51559 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -866,7 +866,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index a32dc8beda..d677a996c1 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -601,7 +601,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename)
buffer[nread] = '\0';
fclose(file);
- mEditor->setText(LLStringExplicit(buffer));
+ std::string text = std::string(buffer);
+ LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab());
+
+ mEditor->setText(text);
delete[] buffer;
return true;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index cd7b93aba7..10177c8023 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -367,7 +367,10 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
// add space for dimensions and aspect ratio
S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
-
+ if (getChild<LLLayoutPanel>("buttons_panel")->getVisible())
+ {
+ info_height += getChild<LLLayoutPanel>("buttons_panel")->getRect().getHeight();
+ }
LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
@@ -412,6 +415,16 @@ void LLPreviewTexture::openToSave()
mPreviewToSave = TRUE;
}
+void LLPreviewTexture::hideCtrlButtons()
+{
+ getChildView("desc txt")->setVisible(false);
+ getChildView("desc")->setVisible(false);
+ getChild<LLLayoutStack>("preview_stack")->collapsePanel(getChild<LLLayoutPanel>("buttons_panel"), true);
+ getChild<LLLayoutPanel>("buttons_panel")->setVisible(false);
+ getChild<LLComboBox>("combo_aspect_ratio")->setCurrentByIndex(0); //unconstrained
+ reshape(getRect().getWidth(), getRect().getHeight());
+}
+
// static
void LLPreviewTexture::onFileLoadedForSave(BOOL success,
LLViewerFetchedTexture *src_vi,
diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h
index 9b6a843875..16db51332e 100644
--- a/indra/newview/llpreviewtexture.h
+++ b/indra/newview/llpreviewtexture.h
@@ -67,6 +67,8 @@ public:
static void onSaveAsBtn(void* data);
+ void hideCtrlButtons();
+
/*virtual*/ void setObjectID(const LLUUID& object_id);
protected:
void init();
diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp
index 83b0c4f1bf..0faf6bf889 100644
--- a/indra/newview/llrecentpeople.cpp
+++ b/indra/newview/llrecentpeople.cpp
@@ -42,14 +42,6 @@ bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata)
if (is_not_group_id)
{
- // For each avaline call the id of caller is different even if
- // the phone number is the same.
- // To avoid duplication of avaline list items in the recent list
- // of panel People, deleting id's with similar phone number.
- const LLUUID& caller_id = getIDByPhoneNumber(userdata);
- if (caller_id.notNull())
- mPeople.erase(caller_id);
-
//[] instead of insert to replace existing id->llsd["date"] with new date value
mPeople[id] = userdata;
mChangedSignal();
@@ -90,35 +82,6 @@ const LLSD& LLRecentPeople::getData(const LLUUID& id) const
return no_data;
}
-bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const
-{
- recent_people_t::const_iterator it = mPeople.find(id);
-
- if (it != mPeople.end())
- {
- const LLSD& user = it->second;
- return user["avaline_call"].asBoolean();
- }
-
- return false;
-}
-
-const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata)
-{
- if (!userdata["avaline_call"].asBoolean())
- return LLUUID::null;
-
- for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it)
- {
- const LLSD& user_info = it->second;
-
- if (user_info["call_number"].asString() == userdata["call_number"].asString())
- return it->first;
- }
-
- return LLUUID::null;
-}
-
// virtual
bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
{
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index 18b669ff4f..1b322f2c0a 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -62,9 +62,7 @@ public:
* @param id avatar to add.
*
* @param userdata additional information about last interaction party.
- * For example when last interaction party is not an avatar
- * but an avaline caller, additional info (such as phone
- * number, session id and etc.) should be added.
+ * For example session id can be added.
*
* @return false if the avatar is in the list already, true otherwise
*/
@@ -97,13 +95,6 @@ public:
const LLSD& getData(const LLUUID& id) const;
/**
- * Checks whether specific participant is an avaline caller
- *
- * @param id identifier of specific participant
- */
- bool isAvalineCaller(const LLUUID& id) const;
-
- /**
* Set callback to be called when the list changed.
*
* Multiple callbacks can be set.
@@ -122,8 +113,6 @@ public:
private:
- const LLUUID& getIDByPhoneNumber(const LLSD& userdata);
-
typedef std::map<LLUUID, LLSD> recent_people_t;
recent_people_t mPeople;
signal_t mChangedSignal;
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 055ccd5818..f4ace52faa 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -213,7 +213,12 @@ void LLRemoteParcelInfoProcessor::regionParcelInfoCoro(std::string url,
if (!status)
{
- observer->setErrorStatus(status.getStatus(), status.getMessage());
+ std::string message = status.getMessage();
+ if (message.empty())
+ {
+ message = status.toString();
+ }
+ observer->setErrorStatus(status.getStatus(), message);
}
else
{
diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp
index f7aa63e34d..e250f9bc7a 100644
--- a/indra/newview/llsceneview.cpp
+++ b/indra/newview/llsceneview.cpp
@@ -266,14 +266,11 @@ void LLSceneView::draw()
U32 count = triangles[idx].size();
- U32 total = 0;
-
gGL.begin(LLRender::LINE_STRIP);
//plot triangles
for (U32 i = 0; i < count; ++i)
{
U32 tri_count = triangles[idx][i];
- total += tri_count;
F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom;
F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft;
@@ -290,15 +287,8 @@ void LLSceneView::draw()
gGL.end();
gGL.flush();
- U32 total_visible = 0;
count = visible_triangles[idx].size();
- for (U32 i = 0; i < count; ++i)
- {
- U32 tri_count = visible_triangles[idx][i];
- total_visible += tri_count;
- }
-
std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)",
category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f);
diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h
index e033cae3ab..31f11eb8ef 100644
--- a/indra/newview/llsearchableui.h
+++ b/indra/newview/llsearchableui.h
@@ -41,9 +41,9 @@ namespace ll
struct PanelData;
struct TabContainerData;
- typedef boost::shared_ptr< SearchableItem > SearchableItemPtr;
- typedef boost::shared_ptr< PanelData > PanelDataPtr;
- typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr;
+ typedef std::shared_ptr< SearchableItem > SearchableItemPtr;
+ typedef std::shared_ptr< PanelData > PanelDataPtr;
+ typedef std::shared_ptr< TabContainerData > TabContainerDataPtr;
typedef std::vector< TabContainerData > tTabContainerDataList;
typedef std::vector< SearchableItemPtr > tSearchableItemList;
@@ -55,7 +55,7 @@ namespace ll
LLView const *mView;
ll::ui::SearchableControl const *mCtrl;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
virtual ~SearchableItem();
@@ -68,8 +68,8 @@ namespace ll
LLPanel const *mPanel;
std::string mLabel;
- std::vector< boost::shared_ptr< SearchableItem > > mChildren;
- std::vector< boost::shared_ptr< PanelData > > mChildPanel;
+ std::vector< std::shared_ptr< SearchableItem > > mChildren;
+ std::vector< std::shared_ptr< PanelData > > mChildPanel;
virtual ~PanelData();
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 82a165cb35..86f7d2bf25 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -310,14 +310,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle)
{
struct f : public LLSelectedNodeFunctor
{
+ f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {}
+ bool mAvatarOverridesPersist;
+ LLSelectMgr* mManager;
virtual bool apply(LLSelectNode* node)
{
+ if (mAvatarOverridesPersist)
+ {
+ LLViewerObject* object = node->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object));
+ }
+ }
+ }
node->mLastPositionLocal.setVec(0, 0, 0);
node->mLastRotation = LLQuaternion();
node->mLastScale.setVec(0, 0, 0);
return true;
}
- } func;
+ } func(mAllowSelectAvatar, this);
selected_handle->applyToNodes(&func);
}
@@ -351,6 +366,93 @@ void LLSelectMgr::overrideObjectUpdates()
getSelection()->applyToNodes(&func);
}
+void LLSelectMgr::resetAvatarOverrides()
+{
+ mAvatarOverridesMap.clear();
+}
+
+void LLSelectMgr::overrideAvatarUpdates()
+{
+ if (mAvatarOverridesMap.size() == 0)
+ {
+ return;
+ }
+
+ if (!mAllowSelectAvatar || !gFloaterTools)
+ {
+ resetAvatarOverrides();
+ return;
+ }
+
+ if (!gFloaterTools->getVisible() && getSelection()->isEmpty())
+ {
+ // when user switches selection, floater is invisible and selection is empty
+ LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset();
+ if (toolset->isShowFloaterTools()
+ && toolset->isToolSelected(0)) // Pie tool
+ {
+ resetAvatarOverrides();
+ return;
+ }
+ }
+
+ // remove selected avatars from this list,
+ // but set object overrides to make sure avatar won't snap back
+ struct f : public LLSelectedNodeFunctor
+ {
+ f(LLSelectMgr* p) : mManager(p) {}
+ LLSelectMgr* mManager;
+ virtual bool apply(LLSelectNode* selectNode)
+ {
+ LLViewerObject* object = selectNode->getObject();
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID());
+ if (iter != mManager->mAvatarOverridesMap.end())
+ {
+ if (selectNode->mLastPositionLocal.isExactlyZero())
+ {
+ selectNode->mLastPositionLocal = iter->second.mLastPositionLocal;
+ }
+ if (selectNode->mLastRotation == LLQuaternion())
+ {
+ selectNode->mLastRotation = iter->second.mLastRotation;
+ }
+ mManager->mAvatarOverridesMap.erase(iter);
+ }
+ }
+ }
+ return true;
+ }
+ } func(this);
+ getSelection()->applyToNodes(&func);
+
+ // Override avatar positions
+ uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin();
+ while (it != mAvatarOverridesMap.end())
+ {
+ if (it->second.mObject->isDead())
+ {
+ it = mAvatarOverridesMap.erase(it);
+ }
+ else
+ {
+ if (!it->second.mLastPositionLocal.isExactlyZero())
+ {
+ it->second.mObject->setPosition(it->second.mLastPositionLocal);
+ }
+ if (it->second.mLastRotation != LLQuaternion())
+ {
+ it->second.mObject->setRotation(it->second.mLastRotation);
+ }
+ it++;
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// Select just the object, not any other group members.
//-----------------------------------------------------------------------------
@@ -886,7 +988,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to
// Can't select yourself
if (objectp->mID == gAgentID
- && !LLSelectMgr::getInstance()->mAllowSelectAvatar)
+ && !mAllowSelectAvatar)
{
continue;
}
@@ -6281,6 +6383,24 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
LLSelectNode::~LLSelectNode()
{
+ LLSelectMgr *manager = LLSelectMgr::getInstance();
+ if (manager->mAllowSelectAvatar
+ && (!mLastPositionLocal.isExactlyZero()
+ || mLastRotation != LLQuaternion()))
+ {
+ LLViewerObject* object = getObject(); //isDead() check
+ if (object && !object->getParent())
+ {
+ LLVOAvatar* avatar = object->asAvatar();
+ if (avatar)
+ {
+ // Avatar was moved and needs to stay that way
+ manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object));
+ }
+ }
+ }
+
+
delete mPermissions;
mPermissions = NULL;
}
@@ -6788,6 +6908,10 @@ void LLSelectMgr::updateSelectionCenter()
const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection
// center (tractor beam)
+ // override any avatar updates received
+ // Works only if avatar was repositioned
+ // and edit floater is visible
+ overrideAvatarUpdates();
//override any object updates received
//for selected objects
overrideObjectUpdates();
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index ce0316e610..199141fc32 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -467,6 +467,30 @@ public:
void resetObjectOverrides(LLObjectSelectionHandle selected_handle);
void overrideObjectUpdates();
+ void resetAvatarOverrides();
+ void overrideAvatarUpdates();
+
+ struct AvatarPositionOverride
+ {
+ AvatarPositionOverride();
+ AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) :
+ mLastPositionLocal(vec),
+ mLastRotation(quat),
+ mObject(obj)
+ {
+ }
+ LLVector3 mLastPositionLocal;
+ LLQuaternion mLastRotation;
+ LLPointer<LLViewerObject> mObject;
+ };
+
+ // Avatar overrides should persist even after selection
+ // was removed as long as edit floater is up
+ typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t;
+ uuid_av_override_map_t mAvatarOverridesMap;
+public:
+
+
// Returns the previous value of mForceSelection
BOOL setForceSelection(BOOL force);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 0d53950889..42cd1133a2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1567,6 +1567,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
}
}
+// return false if drawable is rigged and:
+// - a linked rigged drawable has a different spatial group
+// - a linked rigged drawable face has the wrong draw order index
+bool check_rigged_group(LLDrawable* drawable)
+{
+ if (drawable->isState(LLDrawable::RIGGED))
+ {
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ LLDrawable* root = drawable->getRoot();
+
+ if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+
+ S32 last_draw_index = -1;
+ if (root->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : root->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ for (auto& child : root->getVObj()->getChildren())
+ {
+ if (child->mDrawable->isState(LLDrawable::RIGGED))
+ {
+ for (auto& face : child->mDrawable->getFaces())
+ {
+ if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ {
+ llassert(false);
+ return false;
+ }
+ last_draw_index = face->getDrawOrderIndex();
+ }
+ }
+
+ if (child->mDrawable->getSpatialGroup() != group)
+ {
+ llassert(false);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
void renderOctree(LLSpatialGroup* group)
{
//render solid object bounding box, color
@@ -1611,6 +1667,9 @@ void renderOctree(LLSpatialGroup* group)
{
continue;
}
+
+ llassert(check_rigged_group(drawable));
+
if (!group->getSpatialPartition()->isBridge())
{
gGL.pushMatrix();
@@ -3028,7 +3087,7 @@ public:
}
- void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
+ void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0);
@@ -3070,7 +3129,7 @@ public:
}
gGL.begin(LLRender::TRIANGLES);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd();
++iter)
{
@@ -3164,14 +3223,14 @@ void renderRaycast(LLDrawable* drawablep)
{
F32 t = 1.f;
- if (!face.mOctree)
+ if (!face.getOctree())
{
((LLVolumeFace*) &face)->createOctree();
}
LLRenderOctreeRaycast render(start, dir, &t);
- render.traverse(face.mOctree);
+ render.traverse(face.getOctree());
}
gGL.popMatrix();
@@ -3787,7 +3846,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v)
}
LL_ALIGN_PREFIX(16)
-class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry>
+class LLOctreeIntersect : public LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>>
{
public:
LL_ALIGN_16(LLVector4a mStart);
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index abb936c3e5..ea671a130e 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -534,7 +534,7 @@ void LLSpeakerMgr::updateSpeakerList()
}
else if (mSpeakers.size() == 0)
{
- // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
+ // For all other session type (ad-hoc, P2P), we use the initial participants targets list
for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
{
// Add buddies if they are on line, add any other avatar.
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index d1dbf72fe9..ed795b5155 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -245,14 +245,6 @@ public:
bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
/**
- * Removes avaline speaker.
- *
- * This is a HACK due to server does not send information that Avaline caller ends call.
- * It can be removed when server is updated. See EXT-4301 for details
- */
- bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); }
-
- /**
* Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant.
*
* Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0829b1a213..054e9530d4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -97,6 +97,7 @@
#include "llfloateravatarpicker.h"
#include "llcallbacklist.h"
#include "llcallingcard.h"
+#include "llclassifiedinfo.h"
#include "llconsole.h"
#include "llcontainerview.h"
#include "llconversationlog.h"
@@ -124,8 +125,6 @@
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llavatarpropertiesprocessor.h"
-#include "llpanelclassified.h"
-#include "llpanelpick.h"
#include "llpanelgrouplandmoney.h"
#include "llpanelgroupnotices.h"
#include "llparcel.h"
@@ -194,6 +193,7 @@
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
#include "llpathfindingmanager.h"
+#include "llremoteparcelrequest.h"
#include "lllogin.h"
#include "llevents.h"
@@ -255,6 +255,7 @@ static bool mLoginStatePastUI = false;
static bool mBenefitsSuccessfullyInit = false;
const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds
+const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances
std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
@@ -661,7 +662,7 @@ bool idle_startup()
#else
void* window_handle = NULL;
#endif
- bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle());
+ bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle());
if(init)
{
gAudiop->setMuted(TRUE);
@@ -927,6 +928,12 @@ bool idle_startup()
LLPersistentNotificationStorage::initParamSingleton();
LLDoNotDisturbNotificationStorage::initParamSingleton();
}
+ else
+ {
+ // reinitialize paths in case user switched grids or accounts
+ LLPersistentNotificationStorage::getInstance()->reset();
+ LLDoNotDisturbNotificationStorage::getInstance()->reset();
+ }
// Set PerAccountSettingsFile to the default value.
std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"));
@@ -1388,10 +1395,21 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED );
}
+ else if (regionp->capabilitiesError())
+ {
+ // Try to connect despite capabilities' error state
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
else
{
U32 num_retries = regionp->getNumSeedCapRetries();
- if (num_retries > 0)
+ if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN)
+ {
+ // Region will keep trying to get capabilities,
+ // but for now continue as if caps were granted
+ LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ }
+ else if (num_retries > 0)
{
LLStringUtil::format_map_t args;
args["[NUMBER]"] = llformat("%d", num_retries + 1);
@@ -2385,6 +2403,11 @@ void login_callback(S32 option, void *userdata)
void show_release_notes_if_required()
{
static bool release_notes_shown = false;
+ // We happen to know that instantiating LLVersionInfo implicitly
+ // instantiates the LLEventMailDrop named "relnotes", which we (might) use
+ // below. If viewer release notes stop working, might be because that
+ // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been
+ // instantiated.
if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion)
&& LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds
&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
@@ -2652,7 +2675,6 @@ void register_viewer_callbacks(LLMessageSystem* msg)
msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply);
msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply);
-// msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply);
msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply);
msg->setHandlerFunc("ParcelInfoReply", LLRemoteParcelInfoProcessor::processParcelInfoReply);
msg->setHandlerFunc("ScriptDialog", process_script_dialog);
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index d4fc6f3de2..9403e73b87 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1042,7 +1042,8 @@ void LLTextureCache::setReadOnly(BOOL read_only)
mReadOnly = read_only ;
}
-//called in the main thread.
+// Called in the main thread.
+// Returns the unused amount of max_size if any
S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch)
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 1c4a56b549..0ce82a1297 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -48,6 +48,7 @@
#include "llui.h"
#include "llviewerinventory.h"
#include "llpermissions.h"
+#include "llpreviewtexture.h"
#include "llsaleinfo.h"
#include "llassetstorage.h"
#include "lltextbox.h"
@@ -80,6 +81,67 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
//static const char NO_IMAGE_NAME[] = "None";
+
+
+//static
+bool get_is_predefined_texture(LLUUID asset_id)
+{
+ if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture"))
+ || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID"))
+ || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID"))
+ || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE))
+ {
+ return true;
+ }
+ return false;
+}
+
+LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm)
+{
+ LLViewerInventoryCategory::cat_array_t cats;
+ LLViewerInventoryItem::item_array_t items;
+ LLAssetIDMatches asset_id_matches(asset_id);
+ gInventory.collectDescendentsIf(LLUUID::null,
+ cats,
+ items,
+ LLInventoryModel::INCLUDE_TRASH,
+ asset_id_matches);
+
+ LLUUID res;
+ if (items.size())
+ {
+ for (S32 i = 0; i < items.size(); i++)
+ {
+ LLViewerInventoryItem* itemp = items[i];
+ if (itemp)
+ {
+ LLPermissions item_permissions = itemp->getPermissions();
+ if (item_permissions.allowOperationBy(PERM_COPY,
+ gAgent.getID(),
+ gAgent.getGroupID()))
+ {
+ bool allow_trans = item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID());
+ if (allow_trans != no_trans_perm)
+ {
+ return itemp->getUUID();
+ }
+ res = itemp->getUUID();
+ }
+ }
+ }
+ }
+ return res;
+}
+
+bool get_can_copy_texture(LLUUID asset_id)
+{
+ // User is allowed to copy a texture if:
+ // library asset or default texture,
+ // or copy perm asset exists in user's inventory
+
+ return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull();
+}
+
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLView* owner,
LLUUID image_asset_id,
@@ -1154,6 +1216,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
mShowLoadingPlaceholder( TRUE ),
+ mOpenTexPreview(false),
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
@@ -1410,12 +1473,31 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
if (!handled && mBorder->parentPointInView(x, y))
{
- showPicker(FALSE);
- //grab textures first...
- LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
- //...then start full inventory fetch.
- LLInventoryModelBackgroundFetch::instance().start();
- handled = TRUE;
+ if (!mOpenTexPreview)
+ {
+ showPicker(FALSE);
+ //grab textures first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
+ //...then start full inventory fetch.
+ LLInventoryModelBackgroundFetch::instance().start();
+ handled = TRUE;
+ }
+ else
+ {
+ if (getImageAssetID().notNull())
+ {
+ LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", getValue());
+ if (preview_texture && !preview_texture->isDependent())
+ {
+ LLFloater* root_floater = gFloaterView->getParentFloater(this);
+ if (root_floater)
+ {
+ root_floater->addDependentFloater(preview_texture);
+ preview_texture->hideCtrlButtons();
+ }
+ }
+ }
+ }
}
return handled;
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 92f6f89af6..fbb38c4464 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -52,6 +52,16 @@ class LLViewerFetchedTexture;
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
+// Helper functions for UI that work with picker
+bool get_is_predefined_texture(LLUUID asset_id);
+
+// texture picker works by asset ids since objects normaly do
+// not retain inventory ids as result these functions are looking
+// for textures in inventory by asset ids
+// This search can be performance unfriendly and doesn't warranty
+// that the texture is original source of asset
+LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false);
+bool get_can_copy_texture(LLUUID image_id);
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
@@ -159,6 +169,8 @@ public:
void setBlankImageAssetID( const LLUUID& id ) { mBlankImageAssetID = id; }
const LLUUID& getBlankImageAssetID() const { return mBlankImageAssetID; }
+ void setOpenTexPreview(bool open_preview) { mOpenTexPreview = open_preview; }
+
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
@@ -238,6 +250,8 @@ private:
BOOL mShowLoadingPlaceholder;
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
+ bool mOpenTexPreview;
+ BOOL mBakeTextureEnabled;
};
//////////////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8baad30e8f..692e8d91a9 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -291,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
- if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
+ if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 50868d0fa5..b16b26b96e 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -60,6 +60,7 @@
#include "llvoavatarself.h"
#include "llworld.h"
#include "llpanelface.h"
+#include "lluiusage.h"
// syntactic sugar
#define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember))
@@ -1100,7 +1101,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
S32 hit_face,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
- const LLUUID& src_id)
+ const LLUUID& src_id,
+ S32 tex_channel)
{
if (hit_face == -1) return;
if (!item)
@@ -1124,7 +1126,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
if (gFloaterTools->getVisible() && panel_face)
{
- switch (LLSelectMgr::getInstance()->getTextureChannel())
+ tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel();
+ switch (tex_channel)
{
case 0:
@@ -1303,10 +1306,12 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
LLMessageSystem* msg = gMessageSystem;
if (mSource == SOURCE_NOTECARD)
{
+ LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard");
msg->newMessageFast(_PREHASH_RezObjectFromNotecard);
}
else
{
+ LLUIUsage::instance().logCommand("Object.RezObject");
msg->newMessageFast(_PREHASH_RezObject);
}
msg->nextBlockFast(_PREHASH_AgentData);
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 24a712029c..4537d73332 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -244,7 +244,8 @@ public:
static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face,
LLInventoryItem* item,
ESource source,
- const LLUUID& src_id);
+ const LLUUID& src_id,
+ S32 tex_channel = -1);
static void dropTextureAllFaces(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 43deac60d9..5fb83bf08e 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -71,6 +71,7 @@
#include "llui.h"
#include "llweb.h"
#include "pipeline.h" // setHighlightObject
+#include "lluiusage.h"
extern BOOL gDebugClicks;
@@ -568,6 +569,8 @@ bool LLToolPie::walkToClickedLocation()
return false;
}
+ LLUIUsage::instance().logCommand("Agent.WalkToClickedLocation");
+
LLPickInfo saved_pick = mPick;
if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
{
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 814bade56a..7cdd7cc5c8 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -62,6 +62,7 @@
#include "llprimitive.h"
#include "llwindow.h" // incBusyCount()
#include "material_codes.h"
+#include "lluiusage.h"
const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
@@ -227,6 +228,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
}
+ LLUIUsage::instance().logCommand("Build.ObjectAdd");
gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 3f7e8531fb..14fae8d035 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -50,6 +50,10 @@
#include "llpreviewnotecard.h"
#include "llpreviewgesture.h"
#include "llcoproceduremanager.h"
+#include "llthread.h"
+#include "llkeyframemotion.h"
+#include "lldatapacker.h"
+#include "llvoavatarself.h"
void dialog_refresh_all();
@@ -450,9 +454,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
errorLabel = "DoNotSupportBulkAnimationUpload";
error = true;
}
- else if (assetType == LLAssetType::AT_ANIMATION)
+ else if (exten == "anim")
+ {
+ // Default unless everything succeeds
+ errorLabel = "ProblemWithFile";
+ error = true;
+
+ // read from getFileName()
+ LLAPRFile infile;
+ infile.open(getFileName(),LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL;
+ errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str());
+ }
+ else
+ {
+ S32 size = LLAPRFile::size(getFileName());
+ U8* buffer = new U8[size];
+ S32 size_read = infile.read(buffer,size);
+ if (size_read != size)
+ {
+ errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read);
+ }
+ else
+ {
+ LLDataPackerBinaryBuffer dp(buffer, size);
+ LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId());
+ motionp->setCharacter(gAgentAvatarp);
+ if (motionp->deserialize(dp, getAssetId(), false))
+ {
+ // write to temp file
+ bool succ = motionp->dumpToFile(filename);
+ if (succ)
+ {
+ assetType = LLAssetType::AT_ANIMATION;
+ errorLabel = "";
+ error = false;
+ }
+ else
+ {
+ errorMessage = "Failed saving temporary animation file";
+ }
+ }
+ else
+ {
+ errorMessage = "Failed reading animation file";
+ }
+ }
+ }
+ }
+ else
{
- filename = getFileName();
+ // Unknown extension
+ errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str());
+ errorLabel = "ErrorMessage";
+ error = TRUE;;
}
if (error)
@@ -863,6 +920,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
{
args["FILE"] = uploadInfo->getDisplayName();
args["REASON"] = reason;
+ args["ERROR"] = reason;
}
LLNotificationsUtil::add(label, args);
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index 782285ce36..febae36ae8 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -33,8 +33,6 @@
// comment out to turn off wind
#define kAUDIO_ENABLE_WIND
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
-#define kAUDIO_NUM_BUFFERS 30
-#define kAUDIO_NUM_SOURCES 30
void init_audio();
void audio_update_volume(bool force_update = true);
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 9036e87514..bc46a61fb0 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -639,157 +639,186 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
////////////////////////////////////////////////////////////////////////////
+LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const std::string& setting)
+{
+ LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);
+ if (cntrl_ptr.isNull())
+ {
+ LL_ERRS() << "Unable to set up setting listener for " << setting
+ << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall."
+ << LL_ENDL;
+ }
+ return cntrl_ptr;
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void(const LLSD& newvalue)> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback(new_val);
+ });
+}
+
+void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function<void()> callback)
+{
+ setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val)
+ {
+ callback();
+ });
+}
+
void settings_setup_listeners()
{
- gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2));
- gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2));
- gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2));
- gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2));
- gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2));
- gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2));
- gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2));
- gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2));
- gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2));
- gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));
- gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));
- gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2));
- gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2));
- gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2));
- gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));
- gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));
- gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2));
- gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2));
- gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2));
- gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
- gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
- gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
- gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
- gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
- gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2));
- gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2));
- gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2));
- gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2));
- gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2));
- gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
- gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
- gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
- gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2));
- gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2));
- gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2));
- gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2));
- gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2));
- gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2));
- gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus));
- gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2));
- gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2));
- gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
- gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
- gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
- gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
- gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
- gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
- gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
- gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
- gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
+ setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
+ setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
+ setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
+ setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
+ setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
+ setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged);
+ setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged);
+ setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged);
+ setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged);
+ setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate);
+ setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus);
+ setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause);
+ setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel);
+ setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost);
+ setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid);
+ setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
+ setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
+ setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
+
+ setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged);
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 6a2b06d9b5..bc0fafb29f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -739,7 +739,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glh::matrix4f proj = get_current_projection();
glh::matrix4f mod = get_current_modelview();
glViewport(0,0,512,512);
- LLVOAvatar::updateFreezeCounter() ;
LLVOAvatar::updateImpostors();
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
new file mode 100644
index 0000000000..cec08c4f15
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -0,0 +1,226 @@
+/**
+ * @file llviewerdisplayname.cpp
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 "llviewerdisplayname.h"
+
+// viewer includes
+#include "llagent.h"
+#include "llfloaterprofile.h"
+#include "llfloaterreg.h"
+#include "llviewerregion.h"
+#include "llvoavatar.h"
+
+// library includes
+#include "llavatarnamecache.h"
+#include "llhttpnode.h"
+#include "llnotificationsutil.h"
+#include "llui.h" // getLanguage()
+
+namespace LLViewerDisplayName
+{
+ // Fired when viewer receives server response to display name change
+ set_name_signal_t sSetDisplayNameSignal;
+
+ // Fired when there is a change in the agent's name
+ name_changed_signal_t sNameChangedSignal;
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb)
+ {
+ sNameChangedSignal.connect(cb);
+ }
+
+ void doNothing() { }
+}
+
+void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot)
+{
+ // TODO: simple validation here
+
+ LLViewerRegion* region = gAgent.getRegion();
+ llassert(region);
+ std::string cap_url = region->getCapability("SetDisplayName");
+ if (cap_url.empty())
+ {
+ // this server does not support display names, report error
+ slot(false, "unsupported", LLSD());
+ return;
+ }
+
+ // People API requires both the old and new value to change a variable.
+ // Our display name will be in cache before the viewer's UI is available
+ // to request a change, so we can use direct lookup without callback.
+ LLAvatarName av_name;
+ if (!LLAvatarNameCache::get( gAgent.getID(), &av_name))
+ {
+ slot(false, "name unavailable", LLSD());
+ return;
+ }
+
+ // People API expects array of [ "old value", "new value" ]
+ LLSD change_array = LLSD::emptyArray();
+ change_array.append(av_name.getDisplayName());
+ change_array.append(display_name);
+
+ LL_INFOS() << "Set name POST to " << cap_url << LL_ENDL;
+
+ // Record our caller for when the server sends back a reply
+ sSetDisplayNameSignal.connect(slot);
+
+ // POST the requested change. The sim will not send a response back to
+ // this request directly, rather it will send a separate message after it
+ // communicates with the back-end.
+ LLSD body;
+ body["display_name"] = change_array;
+ LLCoros::instance().launch("LLViewerDisplayName::SetDisplayNameCoro",
+ boost::bind(&LLViewerDisplayName::setDisplayNameCoro, cap_url, body));
+}
+
+void LLViewerDisplayName::setDisplayNameCoro(const std::string& cap_url, const LLSD& body)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("SetDisplayNameCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+ // People API can return localized error messages. Indicate our
+ // language preference via header.
+ httpHeaders->append(HTTP_OUT_HEADER_ACCEPT_LANGUAGE, LLUI::getLanguage());
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, body, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS() << "Unable to set display name. Status: " << status.toString() << LL_ENDL;
+ LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+}
+
+class LLSetDisplayNameReply : public LLHTTPNode
+{
+ LOG_CLASS(LLSetDisplayNameReply);
+public:
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+
+ S32 status = body["status"].asInteger();
+ bool success = (status == HTTP_OK);
+ std::string reason = body["reason"].asString();
+ LLSD content = body["content"];
+
+ LL_INFOS() << "status " << status << " reason " << reason << LL_ENDL;
+
+ // If viewer's concept of display name is out-of-date, the set request
+ // will fail with 409 Conflict. If that happens, fetch up-to-date
+ // name information.
+ if (status == HTTP_CONFLICT)
+ {
+ LLUUID agent_id = gAgent.getID();
+ // Flush stale data
+ LLAvatarNameCache::getInstance()->erase( agent_id );
+ // Queue request for new data: nothing to do on callback though...
+ // Note: no need to disconnect the callback as it never gets out of scope
+ LLAvatarNameCache::getInstance()->get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
+ // Kill name tag, as it is wrong
+ LLVOAvatar::invalidateNameTag( agent_id );
+ }
+
+ // inform caller of result
+ LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content);
+ LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
+ }
+};
+
+
+class LLDisplayNameUpdate : public LLHTTPNode
+{
+ /*virtual*/ void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body = input["body"];
+ LLUUID agent_id = body["agent_id"];
+ std::string old_display_name = body["old_display_name"];
+ // By convention this record is called "agent" in the People API
+ LLSD name_data = body["agent"];
+
+ // Inject the new name data into cache
+ LLAvatarName av_name;
+ av_name.fromLLSD( name_data );
+
+ LL_INFOS() << "name-update now " << LLDate::now()
+ << " next_update " << LLDate(av_name.mNextUpdate)
+ << LL_ENDL;
+
+ // Name expiration time may be provided in headers, or we may use a
+ // default value
+ // *TODO: get actual headers out of ResponsePtr
+ //LLSD headers = response->mHeaders;
+ LLSD headers;
+ av_name.mExpires =
+ LLAvatarNameCache::getInstance()->nameExpirationFromHeaders(headers);
+
+ LLAvatarNameCache::getInstance()->insert(agent_id, av_name);
+
+ // force name tag to update
+ LLVOAvatar::invalidateNameTag(agent_id);
+
+ LLSD args;
+ args["OLD_NAME"] = old_display_name;
+ args["SLID"] = av_name.getUserName();
+ args["NEW_NAME"] = av_name.getDisplayName();
+ LLNotificationsUtil::add("DisplayNameUpdate", args);
+ if (agent_id == gAgent.getID())
+ {
+ LLViewerDisplayName::sNameChangedSignal();
+ }
+
+ LLFloaterProfile* profile_floater = dynamic_cast<LLFloaterProfile*>(LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id)));
+ if (profile_floater)
+ {
+ profile_floater->refreshName();
+ }
+ }
+};
+
+LLHTTPRegistration<LLSetDisplayNameReply>
+ gHTTPRegistrationMessageSetDisplayNameReply(
+ "/message/SetDisplayNameReply");
+
+LLHTTPRegistration<LLDisplayNameUpdate>
+ gHTTPRegistrationMessageDisplayNameUpdate(
+ "/message/DisplayNameUpdate");
diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h
new file mode 100644
index 0000000000..337aaa68b6
--- /dev/null
+++ b/indra/newview/llviewerdisplayname.h
@@ -0,0 +1,55 @@
+/**
+ * @file llviewerdisplayname.h
+ * @brief Wrapper for display name functionality
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, 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 LLVIEWERDISPLAYNAME_H
+#define LLVIEWERDISPLAYNAME_H
+
+#include <boost/signals2.hpp>
+
+class LLSD;
+class LLUUID;
+
+namespace LLViewerDisplayName
+{
+ typedef boost::signals2::signal<
+ void (bool success, const std::string& reason, const LLSD& content)>
+ set_name_signal_t;
+ typedef set_name_signal_t::slot_type set_name_slot_t;
+
+ typedef boost::signals2::signal<void (void)> name_changed_signal_t;
+ typedef name_changed_signal_t::slot_type name_changed_slot_t;
+
+ // Sends an update to the server to change a display name
+ // and call back when done. May not succeed due to service
+ // unavailable or name not available.
+ void set(const std::string& display_name, const set_name_slot_t& slot);
+
+ void setDisplayNameCoro(const std::string& cap_url, const LLSD& body);
+
+ void addNameChangedCallback(const name_changed_signal_t::slot_type& cb);
+}
+
+#endif // LLVIEWERDISPLAYNAME_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index dd03d6cfdd..06a6c5e373 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -57,11 +57,13 @@
#include "llfloatercamera.h"
#include "llfloatercamerapresets.h"
#include "llfloaterchatvoicevolume.h"
+#include "llfloaterclassified.h"
#include "llfloaterconversationlog.h"
#include "llfloaterconversationpreview.h"
#include "llfloatercreatelandmark.h"
#include "llfloaterdeleteprefpreset.h"
#include "llfloaterdestinations.h"
+#include "llfloaterdisplayname.h"
#include "llfloatereditextdaycycle.h"
#include "llfloaterenvironmentadjust.h"
#include "llfloaterexperienceprofile.h"
@@ -111,6 +113,7 @@
#include "llfloaterpreference.h"
#include "llfloaterpreferenceviewadvanced.h"
#include "llfloaterpreviewtrash.h"
+#include "llfloaterprofile.h"
#include "llfloaterproperties.h"
#include "llfloaterregiondebugconsole.h"
#include "llfloaterregioninfo.h"
@@ -141,7 +144,6 @@
#include "llfloateruipreview.h"
#include "llfloatervoiceeffect.h"
#include "llfloaterwebcontent.h"
-#include "llfloaterwebprofile.h"
#include "llfloatervoicevolume.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindowsize.h"
@@ -155,7 +157,7 @@
#include "llmoveview.h"
#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
-#include "llpanelclassified.h"
+#include "llpanelprofileclassifieds.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -228,6 +230,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("camera_presets", "floater_camera_presets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCameraPresets>);
LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
+ LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>);
LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
@@ -275,6 +278,7 @@ void LLViewerFloaterReg::registerFloaters()
LLInspectRemoteObjectUtil::registerFloater();
LLFloaterVoiceVolumeUtil::registerFloater();
LLNotificationsUI::registerFloater();
+ LLFloaterDisplayNameUtil::registerFloater();
LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>);
LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>);
@@ -320,7 +324,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
- LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
@@ -367,8 +370,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
- LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
- LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
+ LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 812f804ea9..a1cb152e1e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -48,7 +48,7 @@
#include "llmutelist.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
-#include "llpanelprofile.h"
+#include "llavataractions.h"
#include "llparcel.h"
#include "llpluginclassmedia.h"
#include "llurldispatcher.h"
@@ -3194,7 +3194,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const
}
// If this media's class is not supposed to be shown, unload
- if (!shouldShowBasedOnClass())
+ if (!shouldShowBasedOnClass() || isObscured())
{
return true;
}
@@ -3881,6 +3881,40 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const
//////////////////////////////////////////////////////////////////////////////////////////
//
+bool LLViewerMediaImpl::isObscured() const
+{
+ if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false;
+
+ LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (!agent_parcel)
+ {
+ return false;
+ }
+
+ if (agent_parcel->getObscureMOAP() && !isInAgentParcel())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLViewerMediaImpl::isAttachedToHUD() const
+{
+ std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
+ std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
+ for ( ; iter != end; iter++)
+ {
+ if ((*iter)->isHUDAttachment())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//
bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
{
bool result = false;
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 806692929a..f1f42afd81 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -411,6 +411,8 @@ public:
void cancelMimeTypeProbe();
+ bool isAttachedToHUD() const;
+
// Is this media attached to an avatar *not* self
bool isAttachedToAnotherAvatar() const;
@@ -423,6 +425,7 @@ public:
private:
bool isAutoPlayable() const;
bool shouldShowBasedOnClass() const;
+ bool isObscured() const;
static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj);
static bool isObjectInAgentParcel(LLVOVolume *obj);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8522c2ed55..3573af40cb 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -33,10 +33,11 @@
#include "llviewermenu.h"
// linden library includes
-#include "llavatarnamecache.h" // IDEVO
+#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
+#include "llcombobox.h"
+#include "llcoros.h"
#include "llfloaterreg.h"
#include "llfloatersidepanelcontainer.h"
-#include "llcombobox.h"
#include "llinventorypanel.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
@@ -53,6 +54,7 @@
#include "llcompilequeue.h"
#include "llconsole.h"
#include "lldebugview.h"
+#include "lldiskcache.h"
#include "llenvironment.h"
#include "llfilepicker.h"
#include "llfirstuse.h"
@@ -93,6 +95,7 @@
#include "llmarketplacefunctions.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
+#include "llnavigationbar.h"
#include "llparcel.h"
#include "llrootview.h"
#include "llsceneview.h"
@@ -2100,6 +2103,32 @@ class LLAdvancedDropPacket : public view_listener_t
}
};
+//////////////////////
+// PURGE DISK CACHE //
+//////////////////////
+
+
+class LLAdvancedPurgeDiskCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+ main_queue->postTo(
+ general_queue,
+ []() // Work done on general queue
+ {
+ LLDiskCache::getInstance()->purge();
+ // Nothing needed to return
+ },
+ [](){}); // Callback to main thread is empty as there is nothing left to do
+
+ return true;
+ }
+};
+
////////////////////
// EVENT Recorder //
@@ -2324,25 +2353,13 @@ class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t
};
/////////////////////////////////////
-// Enable Framebuffer Objects ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderFBO: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = gGLManager.mHasFramebufferObject;
- return new_value;
- }
-};
-
-/////////////////////////////////////
// Enable Deferred Rendering ///
/////////////////////////////////////
class LLAdvancedEnableRenderDeferred: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
+ bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
return new_value;
}
@@ -2355,7 +2372,7 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
+ bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");
return new_value;
}
@@ -2407,6 +2424,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
return true;
}
};
+
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2416,6 +2434,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
}
};
+class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorBadMemoryAccessCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_bad_memory_access(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2434,6 +2468,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t
}
};
+class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLCoros::instance().launch(
+ "AdvancedForceErrorSoftwareExceptionCoro",
+ [](){
+ // Wait for one mainloop() iteration, letting the enclosing
+ // handleEvent() method return.
+ llcoro::suspend();
+ force_error_software_exception(NULL);
+ });
+ return true;
+ }
+};
+
class LLAdvancedForceErrorDriverCrash : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2725,6 +2775,32 @@ void handle_object_touch()
send_ObjectDeGrab_message(object, pick);
}
+void handle_object_show_original()
+{
+ LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ if (!object)
+ {
+ return;
+ }
+
+ LLViewerObject *parent = (LLViewerObject*)object->getParent();
+ while (parent)
+ {
+ if(parent->isAvatar())
+ {
+ break;
+ }
+ object = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
+
+ if (!object || object->isAvatar())
+ {
+ return;
+ }
+
+ show_item_original(object->getAttachmentItemID());
+}
static void init_default_item_label(const std::string& item_name)
@@ -3609,6 +3685,11 @@ bool my_profile_visible()
return floaterp && floaterp->isInVisibleChain();
}
+bool picks_tab_visible()
+{
+ return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID);
+}
+
bool enable_freeze_eject(const LLSD& avatar_id)
{
// Use avatar_id if available, otherwise default to right-click avatar
@@ -5334,12 +5415,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
{
bool returnValue = false;
- if (LLPathfindingManager::getInstance() != NULL)
- {
- LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance();
- returnValue = (rebakeInstance->canRebakeRegion() &&
- (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available));
- }
+ if (LLNavigationBar::instanceExists())
+ {
+ returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable();
+ }
return returnValue;
}
};
@@ -6302,6 +6381,29 @@ class LLAvatarToggleMyProfile : public view_listener_t
}
};
+class LLAvatarTogglePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
+ if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
+ {
+ instance->setMinimized(FALSE);
+ instance->setFocus(TRUE);
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ else if (picks_tab_visible())
+ {
+ instance->closeFloater();
+ }
+ else
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ }
+ return true;
+ }
+};
+
class LLAvatarToggleSearch : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -6772,6 +6874,15 @@ class LLShowAgentProfile : public view_listener_t
}
};
+class LLShowAgentProfilePicks : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLAvatarActions::showPicks(gAgent.getID());
+ return true;
+ }
+};
+
class LLToggleAgentProfile : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -9310,7 +9421,6 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
- view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
@@ -9409,6 +9519,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
+ // Advanced > Cache
+ view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache");
+
// Advanced > Recorder
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
@@ -9419,8 +9532,10 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
+ view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
+ view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
@@ -9495,12 +9610,14 @@ void initialize_menus()
enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
+ view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
+ enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
@@ -9510,6 +9627,7 @@ void initialize_menus()
// Object pie menu
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
commit.add("Object.Touch", boost::bind(&handle_object_touch));
+ commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
commit.add("Object.Delete", boost::bind(&handle_object_delete));
view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
@@ -9576,6 +9694,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
+ view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index be80d0bc0a..d97ed61e11 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -33,6 +33,7 @@
#include "llavataractions.h"
#include "llavatarnamecache.h" // IDEVO HACK
#include "lleventtimer.h"
+#include "llfloatercreatelandmark.h"
#include "llfloaterreg.h"
#include "llfolderview.h"
#include "llfollowcamparams.h"
@@ -122,6 +123,7 @@
#include "llexperiencecache.h"
#include "llexperiencecache.h"
+#include "lluiusage.h"
extern void on_new_message(const LLSD& msg);
@@ -261,6 +263,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
{
case 0:
{
+ LLUIUsage::instance().logCommand("Agent.AcceptFriendship");
// accept
LLAvatarTracker::formFriendship(payload["from_id"]);
@@ -303,6 +306,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
// fall-through
case 2: // Send IM - decline and start IM session
{
+ LLUIUsage::instance().logCommand("Agent.DeclineFriendship");
// decline
// We no longer notify other viewers, but we DO still send
// the rejection to the simulator to delete the pending userop.
@@ -833,6 +837,11 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep
EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE;
+ if (accept_invite)
+ {
+ LLUIUsage::instance().logCommand("Group.Join");
+ }
+
send_improved_im(group_id,
std::string("name"),
std::string("message"),
@@ -1560,6 +1569,17 @@ bool highlight_offered_object(const LLUUID& obj_id)
}
}
+ if (obj->getType() == LLAssetType::AT_LANDMARK)
+ {
+ LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance<LLFloaterCreateLandmark>("add_landmark");
+ if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id)
+ {
+ // LLFloaterCreateLandmark is supposed to handle this,
+ // keep landmark creation floater at the front
+ return false;
+ }
+ }
+
return true;
}
@@ -3334,13 +3354,6 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// trigger a control event.
U32 control_flags = gAgent.getControlFlags();
- // Rotation into both directions should cancel out
- U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG;
- if ((control_flags & mask) == mask)
- {
- control_flags &= ~mask;
- }
-
MASK key_mask = gKeyboard->currentMask(TRUE);
if (key_mask & MASK_ALT || key_mask & MASK_CONTROL)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index a95636ff23..aad6c14b4d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -356,6 +356,13 @@ LLViewerObject::~LLViewerObject()
mPartSourcep = NULL;
}
+ if (mText)
+ {
+ // something recovered LLHUDText when object was already dead
+ mText->markDead();
+ mText = NULL;
+ }
+
// Delete memory associated with extra parameters.
std::map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
@@ -2457,11 +2464,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
needs_refresh = needs_refresh || child->mUserSelected;
}
+ static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE);
if (needs_refresh)
{
LLSelectMgr::getInstance()->updateSelectionCenter();
dialog_refresh_all();
- }
+ }
+ else if (allow_select_avatar && asAvatar())
+ {
+ // Override any avatar position updates received
+ // Works only if avatar was repositioned using build
+ // tools and build floater is visible
+ LLSelectMgr::getInstance()->overrideAvatarUpdates();
+ }
// Mark update time as approx. now, with the ping delay.
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 55e2386d10..e930b58111 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -571,7 +571,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if(update_cache)
{
- objectp = regionp->updateCacheEntry(local_id, objectp, update_type);
+ //update object cache if the object receives a full-update or terse update
+ objectp = regionp->updateCacheEntry(local_id, objectp);
}
// This looks like it will break if the local_id of the object doesn't change
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 12624ec3a2..36b2bd4c32 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -948,6 +948,7 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_M
break;
case STATE_MODE_DIFF:
+ if (mOctreeNode)
{
LLSpatialSetOcclusionStateDiff setter(state);
setter.traverse(mOctreeNode);
@@ -955,6 +956,7 @@ void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_M
break;
case STATE_MODE_BRANCH:
+ if (mOctreeNode)
{
LLSpatialSetOcclusionState setter(state);
setter.traverse(mOctreeNode);
@@ -1024,6 +1026,7 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE
break;
case STATE_MODE_DIFF:
+ if (mOctreeNode)
{
LLSpatialClearOcclusionStateDiff clearer(state);
clearer.traverse(mOctreeNode);
@@ -1031,6 +1034,7 @@ void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE
break;
case STATE_MODE_BRANCH:
+ if (mOctreeNode)
{
LLSpatialClearOcclusionState clearer(state);
clearer.traverse(mOctreeNode);
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index e6974b0f84..7666062f99 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -45,11 +45,11 @@ class LLViewerOctreeGroup;
class LLViewerOctreeEntry;
class LLViewerOctreePartition;
-typedef LLOctreeListener<LLViewerOctreeEntry> OctreeListener;
-typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
-typedef LLOctreeNode<LLViewerOctreeEntry> OctreeNode;
-typedef LLOctreeRoot<LLViewerOctreeEntry> OctreeRoot;
-typedef LLOctreeTraveler<LLViewerOctreeEntry> OctreeTraveler;
+typedef LLOctreeListener<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeListener;
+typedef LLTreeNode<LLViewerOctreeEntry> TreeNode;
+typedef LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeNode;
+typedef LLOctreeRoot<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeRoot;
+typedef LLOctreeTraveler<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry>> OctreeTraveler;
#if LL_OCTREE_PARANOIA_CHECK
#define assert_octree_valid(x) x->validate()
@@ -179,7 +179,7 @@ protected:
//defines an octree group for an octree node, which contains multiple entries.
//LL_ALIGN_PREFIX(16)
class LLViewerOctreeGroup
-: public LLOctreeListener<LLViewerOctreeEntry>
+: public OctreeListener
{
LL_ALIGN_NEW
friend class LLViewerOctreeCull;
@@ -198,8 +198,8 @@ public:
};
public:
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_iter element_iter;
- typedef LLOctreeNode<LLViewerOctreeEntry>::element_list element_list;
+ typedef OctreeNode::element_iter element_iter;
+ typedef OctreeNode::element_list element_list;
LLViewerOctreeGroup(OctreeNode* node);
LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs)
@@ -245,7 +245,6 @@ public:
const LLVector4a* getObjectExtents() const {return mObjectExtents;}
//octree wrappers to make code more readable
- element_list& getData() { return mOctreeNode->getData(); }
element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index e69b0347f8..75eb16c085 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1553,6 +1553,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
BOOL region_allow_environment_override = true;
S32 parcel_environment_version = 0;
BOOL agent_parcel_update = false; // updating previous(existing) agent parcel
+ U32 extended_flags = 0; //obscure MOAP
S32 other_clean_time = 0;
@@ -1591,6 +1592,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
+ // *TODO: Does it really make sense to set the agent parcel to this
+ // parcel if the client doesn't know what kind of parcel data this is?
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
@@ -1642,6 +1645,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override);
}
+ if (msg->getNumberOfBlocks(_PREHASH_ParcelExtendedFlags))
+ {
+ msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags);
+ }
+
if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock))
{
msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version);
@@ -1698,6 +1706,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
parcel->setParcelEnvironmentVersion(cur_parcel_environment_version);
parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override);
+ parcel->setObscureMOAP((bool)extended_flags);
+
parcel->unpackMessage(msg);
if (parcel == parcel_mgr.mAgentParcel)
@@ -1879,8 +1889,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- // Check for video
- LLViewerParcelMedia::getInstance()->update(parcel);
+ if (gNonInteractive)
+ {
+ return;
+ }
+
+ // Check for video
+ LLViewerParcelMedia::getInstance()->update(parcel);
// Then check for music
if (gAudiop)
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 02f7bbeed8..785c84c38d 100644..100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -264,7 +264,7 @@ BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return PARCEL_SOUND_LOCAL & mOwnership[row * mParcelGridsPerEdge + column];
+ return parcelFlags(row, column, PARCEL_SOUND_LOCAL);
}
U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const
@@ -278,12 +278,19 @@ U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const
{
S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
- return parcelLineFlags(row, column);
+ return parcelFlags(row, column, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
}
U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const
{
- U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE;
- if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge)
+ return parcelFlags(row, col, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE);
+}
+
+U8 LLViewerParcelOverlay::parcelFlags(S32 row, S32 col, U8 flags) const
+{
+ if (row >= mParcelGridsPerEdge
+ || col >= mParcelGridsPerEdge
+ || row < 0
+ || col < 0)
{
LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL;
return flags;
@@ -908,8 +915,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Always fudge a little vertically.
pull_toward_camera.mV[VZ] += 0.01f;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
@@ -1014,7 +1021,66 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
}
- gGL.popMatrix();
+ gGL.popMatrix();
return drawn;
}
+
+// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
+void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom)
+{
+ gGL.begin(LLRender::LINES);
+
+ if (has_left)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(left, top);
+ }
+ if (has_bottom)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(right, bottom);
+ }
+
+ gGL.end();
+}
+
+void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (!mOwnership)
+ {
+ return;
+ }
+ if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ return;
+ }
+
+ LLVector3 origin_agent = mRegion->getOriginAgent();
+ LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
+ F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter;
+ F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter;
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ glLineWidth(1.0f);
+ gGL.color4fv(parcel_outline_color);
+ for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
+ {
+ const F32 bottom = region_bottom + (i * map_parcel_width);
+ const F32 top = bottom + map_parcel_width;
+ for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
+ {
+ const F32 left = region_left + (j * map_parcel_width);
+ const F32 right = left + map_parcel_width;
+ const bool is_region_boundary = i == GRIDS_PER_EDGE || j == GRIDS_PER_EDGE;
+ const U8 overlay = is_region_boundary ? 0 : mOwnership[(i * GRIDS_PER_EDGE) + j];
+ // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a
+ // 2D map
+ const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE));
+ const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE));
+ grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index e30dbf17b3..c466cc3b6b 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -69,6 +69,7 @@ public:
// Returns the number of vertices drawn
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@@ -82,12 +83,14 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
-
+
private:
// This is in parcel rows and columns, not grid rows and columns
// Stored in bottom three bits.
U8 ownership(S32 row, S32 col) const
- { return 0x7 & mOwnership[row * mParcelGridsPerEdge + col]; }
+ { return parcelFlags(row, col, (U8)0x7); }
+
+ U8 parcelFlags(S32 row, S32 col, U8 flags) const;
void addPropertyLine(std::vector<LLVector3>& vertex_array,
std::vector<LLColor4U>& color_array,
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b282a2b90c..ad7321ca4b 100644..100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -95,8 +95,6 @@
// The server only keeps our pending agent info for 60 seconds.
// We want to allow for seed cap retry, but its not useful after that 60 seconds.
-// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up.
-const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3;
// Even though we gave up on login, keep trying for caps after we are logged in:
const S32 MAX_CAP_REQUEST_ATTEMPTS = 30;
const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
@@ -178,7 +176,6 @@ public:
mCompositionp(NULL),
mEventPoll(NULL),
mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS),
- mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN),
mSeedCapAttempts(0),
mHttpResponderID(0),
mLastCameraUpdate(0),
@@ -231,7 +228,6 @@ public:
LLEventPoll* mEventPoll;
S32 mSeedCapMaxAttempts;
- S32 mSeedCapMaxAttemptsBeforeLogin;
S32 mSeedCapAttempts;
S32 mHttpResponderID;
@@ -266,14 +262,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
return;
}
- LLWorld *world_inst = LLWorld::getInstance(); // Not a singleton!
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Attempting to get capabilities for region that no longer exists!" << LL_ENDL;
@@ -287,19 +282,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ regionp->setCapabilitiesError();
return; // this error condition is not recoverable.
}
// record that we just entered a new region
newRegionEntry(*regionp);
- // After a few attempts, continue login. But keep trying to get the caps:
- if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin &&
- STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts)
{
// *TODO: Give a user pop-up about this error?
@@ -321,7 +310,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
regionp = NULL;
impl = NULL;
- world_inst = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
if (STATE_WORLD_INIT > LLStartUp::getStartupState())
@@ -332,17 +320,17 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
if (LLApp::isExiting() || gDisconnected)
{
+ LL_DEBUGS("AppInit", "Capabilities") << "Shutting down" << LL_ENDL;
return;
}
- world_inst = LLWorld::getInstance();
- if (!world_inst)
+ if (!LLWorld::instanceExists())
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL;
return;
}
- regionp = world_inst->getRegionFromHandle(regionHandle);
+ regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle);
if (!regionp) //region was removed
{
LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL;
@@ -351,14 +339,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
impl = regionp->getRegionImplNC();
- ++impl->mSeedCapAttempts;
-
- if (id != impl->mHttpResponderID) // region is no longer referring to this request
- {
- LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
- // setup for retry.
- continue;
- }
+ ++(impl->mSeedCapAttempts);
if (!result.isMap() || result.has("error"))
{
@@ -379,6 +360,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
// remove the http_result from the llsd
result.erase("http_result");
+ if (id != impl->mHttpResponderID) // region is no longer referring to this request
+ {
+ LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL;
+ // setup for retry.
+ continue;
+ }
+
LLSD::map_const_iterator iter;
for (iter = result.beginMap(); iter != result.endMap(); ++iter)
{
@@ -396,11 +384,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
<< " region name " << regionp->getName() << LL_ENDL;
regionp->setCapabilitiesReceived(true);
- if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
- {
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
- }
-
break;
}
while (true);
@@ -444,6 +427,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
if (url.empty())
{
LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL;
+ if (regionp->getCapability("Seed").empty())
+ {
+ // initial attempt failed to get this cap as well
+ regionp->setCapabilitiesError();
+ }
break; // this error condition is not recoverable.
}
@@ -645,7 +633,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCacheLoaded(FALSE),
mCacheDirty(FALSE),
mReleaseNotesRequested(FALSE),
- mCapabilitiesReceived(false),
+ mCapabilitiesState(CAPABILITIES_STATE_INIT),
mSimulatorFeaturesReceived(false),
mBitsReceived(0.f),
mPacketsReceived(0.f),
@@ -1080,6 +1068,15 @@ S32 LLViewerRegion::renderPropertyLines()
}
}
+void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color);
+ }
+}
+
+
// This gets called when the height field changes.
void LLViewerRegion::dirtyHeights()
{
@@ -1820,13 +1817,8 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
//update object cache if the object receives a full-update or terse update
//update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL
-LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type)
+LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp)
{
- if(objectp && update_type != (U32)OUT_TERSE_IMPROVED)
- {
- return objectp; //no need to access cache
- }
-
LLVOCacheEntry* entry = getCacheEntry(local_id);
if (!entry)
{
@@ -1838,11 +1830,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o
objectp = addNewObject(entry);
}
- //remove from cache if terse update
- if(update_type == (U32)OUT_TERSE_IMPROVED)
- {
- killCacheEntry(entry, true);
- }
+ //remove from cache.
+ killCacheEntry(entry, true);
return objectp;
}
@@ -2302,6 +2291,11 @@ void LLViewerRegion::requestSimulatorFeatures()
std::string coroname =
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle()));
+
+ // requestSimulatorFeatures can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3002,6 +2996,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("AcceptFriendship");
capabilityNames.append("AcceptGroupInvite"); // ReadOfflineMsgs recieved messages only!!!
capabilityNames.append("AgentPreferences");
+ capabilityNames.append("AgentProfile");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
@@ -3096,6 +3091,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateScriptTask");
capabilityNames.append("UpdateSettingsAgentInventory");
capabilityNames.append("UpdateSettingsTaskInventory");
+ capabilityNames.append("UploadAgentProfileImage");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
@@ -3121,6 +3117,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
std::string coroname =
LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle()));
+
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
return;
}
@@ -3134,6 +3136,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle()));
+ // setSeedCapability can be called from other coros,
+ // launch() acts like a suspend()
+ // Make sure we are still good to do
+ LLCoros::checkStop();
+
LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;
}
@@ -3255,12 +3262,17 @@ bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const
bool LLViewerRegion::capabilitiesReceived() const
{
- return mCapabilitiesReceived;
+ return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED;
+}
+
+bool LLViewerRegion::capabilitiesError() const
+{
+ return mCapabilitiesState == CAPABILITIES_STATE_ERROR;
}
void LLViewerRegion::setCapabilitiesReceived(bool received)
{
- mCapabilitiesReceived = received;
+ mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT;
// Tell interested parties that we've received capabilities,
// so that they can safely use getCapability().
@@ -3275,6 +3287,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
}
}
+void LLViewerRegion::setCapabilitiesError()
+{
+ mCapabilitiesState = CAPABILITIES_STATE_ERROR;
+}
+
boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb)
{
return mCapabilitiesReceivedSignal.connect(cb);
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index fcbf56c81f..6548e8d372 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -154,6 +154,8 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
+
// Call this whenever you change the height data in the region.
// (Automatically called by LLSurfacePatch's update routine)
@@ -268,7 +270,9 @@ public:
// has region received its final (not seed) capability list?
bool capabilitiesReceived() const;
+ bool capabilitiesError() const;
void setCapabilitiesReceived(bool received);
+ void setCapabilitiesError();
boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb);
static bool isSpecialCapabilityName(const std::string &name);
@@ -352,7 +356,7 @@ public:
void requestCacheMisses();
void addCacheMissFull(const U32 local_id);
//update object cache if the object receives a full-update or terse update
- LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type);
+ LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp);
void findOrphans(U32 parent_id);
void clearCachedVisibleObjects();
void dumpCache();
@@ -527,12 +531,20 @@ private:
BOOL mCacheLoaded;
BOOL mCacheDirty;
BOOL mAlive; // can become false if circuit disconnects
- BOOL mCapabilitiesReceived;
BOOL mSimulatorFeaturesReceived;
BOOL mReleaseNotesRequested;
BOOL mDead; //if true, this region is in the process of deleting.
BOOL mPaused; //pause processing the objects in the region
+ typedef enum
+ {
+ CAPABILITIES_STATE_INIT = 0,
+ CAPABILITIES_STATE_ERROR,
+ CAPABILITIES_STATE_RECEIVED
+ } eCababilitiesState;
+
+ eCababilitiesState mCapabilitiesState;
+
typedef std::map<U32, std::vector<U32> > orphan_list_t;
orphan_list_t mOrphanMap;
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index c084e1d521..5475d66216 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -558,15 +558,14 @@ void LLViewerShaderMgr::setShaders()
mShaderLevel[SHADER_DEFERRED] = deferred_class;
mShaderLevel[SHADER_TRANSFORM] = transform_class;
- BOOL loaded = loadBasicShaders();
- if (loaded)
+ std::string shader_name = loadBasicShaders();
+ if (shader_name.empty())
{
LL_INFOS() << "Loaded basic shaders." << LL_ENDL;
}
else
{
- LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL;
- llassert(loaded);
+ LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL;
reentrance = false; // For hygiene only, re-try probably helps nothing
return;
}
@@ -574,7 +573,7 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mShadersLoaded = true;
// Load all shaders to set max levels
- loaded = loadShadersEnvironment();
+ BOOL loaded = loadShadersEnvironment();
if (loaded)
{
@@ -864,7 +863,7 @@ void LLViewerShaderMgr::unloadShaders()
gPipeline.mShadersLoaded = false;
}
-BOOL LLViewerShaderMgr::loadBasicShaders()
+std::string LLViewerShaderMgr::loadBasicShaders()
{
// Load basic dependency shaders first
// All of these have to load for any shaders to function
@@ -950,8 +949,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// Note usage of GL_VERTEX_SHADER_ARB
if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
@@ -1010,12 +1009,12 @@ BOOL LLViewerShaderMgr::loadBasicShaders()
// Note usage of GL_FRAGMENT_SHADER_ARB
if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
{
- LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
- return FALSE;
+ LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
+ return shaders[i].first;
}
}
- return TRUE;
+ return std::string();
}
BOOL LLViewerShaderMgr::loadShadersEnvironment()
@@ -1517,6 +1516,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
@@ -1575,6 +1580,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ if (alpha_mode != 0)
+ {
+ gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true;
+ gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1");
+ }
+
if (use_sun_shadow)
{
gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1");
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index d8eeccbb22..59ba384bf7 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -49,7 +49,11 @@ public:
void setShaders();
void unloadShaders();
S32 getShaderLevel(S32 type);
- BOOL loadBasicShaders();
+
+ // loadBasicShaders in case of a failure returns
+ // name of a file error happened at, otherwise
+ // returns an empty string
+ std::string loadBasicShaders();
BOOL loadShadersEffects();
BOOL loadShadersDeferred();
BOOL loadShadersObject();
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 18e84fe4f0..327f121caf 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -553,6 +553,7 @@ void send_viewer_stats(bool include_preferences)
system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
system["os"] = LLOSInfo::instance().getOSStringSimple();
system["cpu"] = gSysCPU.getCPUString();
+ system["cpu_sse"] = gSysCPU.getSSEVersions();
system["address_size"] = ADDRESS_SIZE;
system["os_bitness"] = LLOSInfo::instance().getOSBitness();
unsigned char MACAddress[MAC_ADDRESS_BYTES];
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index bbbf9ea7a3..da3c860ddb 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1148,15 +1148,14 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
total_update_count--;
}
}
-
- S32 fetch_count = 0;
+
size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
S32 min_count = max_priority_count + min_update_count;
for (entries_list_t::iterator iter3 = entries.begin();
iter3 != entries.end(); )
{
LLViewerFetchedTexture* imagep = *iter3++;
- fetch_count += (imagep->updateFetch() ? 1 : 0);
+ imagep->updateFetch();
if (min_count <= min_update_count)
{
mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
@@ -1262,7 +1261,8 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
const std::string& out_filename,
- const U8 codec)
+ const U8 codec,
+ const S32 max_image_dimentions)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Load the image
@@ -1291,7 +1291,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
return FALSE;
}
// Convert to j2c (JPEG2000) and save the file locally
- LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);
+ LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image, max_image_dimentions);
if (compressedImage.isNull())
{
image->setLastError("Couldn't convert the image to jpeg2000.");
@@ -1316,10 +1316,10 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
}
// note: modifies the argument raw_image!!!!
-LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image)
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ raw_image->biasedScaleToPowerOfTwo(max_image_dimentions);
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index fead2e52b2..6fb0d3552e 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -92,8 +92,11 @@ class LLViewerTextureList
friend class LLLocalBitmap;
public:
- static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec);
- static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image);
+ static BOOL createUploadFile(const std::string& filename,
+ const std::string& out_filename,
+ const U8 codec,
+ const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
+ static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
static void receiveImageHeader(LLMessageSystem *msg, void **user_data);
static void receiveImagePacket(LLMessageSystem *msg, void **user_data);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 24e4a02b61..8a7d5f12d0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -103,7 +103,6 @@
#include "llfilepicker.h"
#include "llfirstuse.h"
#include "llfloater.h"
-#include "llfloaterbuildoptions.h"
#include "llfloaterbuyland.h"
#include "llfloatercamera.h"
#include "llfloaterland.h"
@@ -773,6 +772,12 @@ public:
ypos += y_inc;
addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f)));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f)));
ypos += y_inc;
}
@@ -1568,9 +1573,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
showCursor();
getWindow()->setMouseClipping(FALSE);
- // If losing focus while keys are down, reset them.
+ // If losing focus while keys are down, handle them as
+ // an 'up' to correctly release states, then reset states
if (gKeyboard)
{
+ gKeyboard->resetKeyDownAndHandle();
gKeyboard->resetKeys();
}
@@ -1998,7 +2005,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
}
LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
- gGL.init() ;
+ gGL.init(true);
if (LLFeatureManager::getInstance()->isSafe()
|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
@@ -2511,10 +2518,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
//glViewport(0, 0, width, height );
- if (height > 0)
+ LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist
+ if (height > 0 && camera)
{
- LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
- LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+ camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+ camera->setAspect( getWorldViewAspectRatio() );
}
calcDisplayScale();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 314c22eb6c..42550ed48d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @File llvoavatar.cpp
* @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject
*
@@ -183,8 +183,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32;
// Should probably be 4 or 3, but didn't want to change it while change other logic - SJB
const S32 SWITCH_TO_BAKED_DISCARD = 5;
-const F32 FOOT_COLLIDE_FUDGE = 0.04f;
-
const F32 HOVER_EFFECT_MAX_SPEED = 3.f;
const F32 HOVER_EFFECT_STRENGTH = 0.f;
const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f;
@@ -585,7 +583,6 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -610,7 +607,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0;
BOOL LLVOAvatar::sDebugInvisible = FALSE;
BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;
BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
-BOOL LLVOAvatar::sShowFootPlane = FALSE;
BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
F32 LLVOAvatar::sLODFactor = 1.f;
F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
@@ -779,6 +775,13 @@ std::string LLVOAvatar::avString() const
void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)
{
+ if (gDisconnected)
+ {
+ // If we disconected, these values are likely to be invalid and
+ // avString() might crash due to a dead sAvatarDictionary
+ return;
+ }
+
LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32()
<< "sec ]"
<< avString()
@@ -2810,6 +2813,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (detailed_update)
{
U32 draw_order = 0;
+ S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment();
for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
iter != mAttachmentPoints.end();
++iter)
@@ -2849,7 +2853,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
}
// if selecting any attachments, update all of them as non-damped
- if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment())
+ if (attachment_selected)
{
gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
}
@@ -4105,8 +4109,7 @@ void LLVOAvatar::computeUpdatePeriod()
&& (!isSelf() || visually_muted)
&& !isUIAvatar()
&& (sLimitNonImpostors || visually_muted)
- && !mNeedsAnimUpdate
- && !sFreezeCounter)
+ && !mNeedsAnimUpdate)
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
@@ -4619,7 +4622,12 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent)
}
else if (!getParent() && isSitting() && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))
{
- getOffObject();
+ // If we are starting up, motion might be loading
+ LLMotion *motionp = mMotionController.findMotion(ANIM_AGENT_SIT_GROUND_CONSTRAINED);
+ if (!motionp || !mMotionController.isMotionLoading(motionp))
+ {
+ getOffObject();
+ }
}
//--------------------------------------------------------------------
@@ -5074,42 +5082,6 @@ U32 LLVOAvatar::renderSkinned()
return num_indices;
}
- // render collision normal
- // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due
- // to DEV-14477. the code is left here to aid in tracking down the cause
- // of the crash in the future. -brad
- if (sShowFootPlane && mDrawable.notNull())
- {
- LLVector3 slaved_pos = mDrawable->getPositionAgent();
- LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]);
- F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW];
- LLVector3 collide_point = slaved_pos;
- collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE);
-
- gGL.begin(LLRender::LINES);
- {
- F32 SQUARE_SIZE = 0.2f;
- gGL.color4f(1.f, 0.f, 0.f, 1.f);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
-
- gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]);
- gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]);
-
- }
- gGL.end();
- gGL.flush();
- }
//--------------------------------------------------------------------
// render all geometry attached to the skeleton
//--------------------------------------------------------------------
@@ -6184,7 +6156,21 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
if (iter == mJointMap.end() || iter->second == NULL)
{ //search for joint and cache found joint in lookup table
- jointp = mRoot->findJoint(name);
+ if (mJointAliasMap.empty())
+ {
+ getJointAliases();
+ }
+ joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name);
+ std::string canonical_name;
+ if (alias_iter != mJointAliasMap.end())
+ {
+ canonical_name = alias_iter->second;
+ }
+ else
+ {
+ canonical_name = name;
+ }
+ jointp = mRoot->findJoint(canonical_name);
mJointMap[name] = jointp;
}
else
@@ -7236,6 +7222,14 @@ LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx)
}
//-----------------------------------------------------------------------------
+// hideHair()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::hideHair()
+{
+ mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE);
+}
+
+//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
void LLVOAvatar::hideSkirt()
@@ -10240,23 +10234,6 @@ LLHost LLVOAvatar::getObjectHost() const
}
}
-//static
-void LLVOAvatar::updateFreezeCounter(S32 counter)
-{
- if(counter)
- {
- sFreezeCounter = counter;
- }
- else if(sFreezeCounter > 0)
- {
- sFreezeCounter--;
- }
- else
- {
- sFreezeCounter = 0;
- }
-}
-
BOOL LLVOAvatar::updateLOD()
{
if (mDrawable.isNull())
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 3c3decaad6..8d1dcbcda2 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -326,7 +326,6 @@ public:
static bool sLimitNonImpostors; // use impostors for far away avatars
static F32 sRenderDistance; // distance at which avatars will render.
static BOOL sShowAnimationDebug; // show animation debug info
- static BOOL sShowFootPlane; // show foot collision plane reported by server
static BOOL sShowCollisionVolumes; // show skeletal collision volumes
static BOOL sVisibleInFirstPerson;
static S32 sNumLODChangesThisFrame;
@@ -618,14 +617,6 @@ private:
BOOL mCulled;
//--------------------------------------------------------------------
- // Freeze counter
- //--------------------------------------------------------------------
-public:
- static void updateFreezeCounter(S32 counter = 0);
-private:
- static S32 sFreezeCounter;
-
- //--------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------
public:
@@ -808,6 +799,7 @@ public:
void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
void processAvatarAppearance(LLMessageSystem* mesgsys);
void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params);
+ void hideHair();
void hideSkirt();
void startAppearanceAnimation();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 60a69a4ac4..8fc1dcd81f 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -67,6 +67,7 @@
#include "llsdserialize.h"
#include "llcallstack.h"
#include "llcorehttputil.h"
+#include "lluiusage.h"
#if LL_MSVC
// disable boost::lexical_cast warning
@@ -2663,6 +2664,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
{
if (isAgentAvatarValid())
{
+ LLUIUsage::instance().logCommand("Avatar.CustomizeStart");
if (!gAgentAvatarp->mEndCustomizeCallback.get())
{
gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index db8ad183f0..55fc663496 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -366,15 +366,6 @@ void LLVOCacheEntry::updateDebugSettings()
}
timer.reset();
- //the number of frames invisible objects stay in memory
- static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
- sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum
-
- //min radius: all objects within this radius remain loaded in memory
- static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
- sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance
- sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m
-
//objects within the view frustum whose visible area is greater than this threshold will be loaded
static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold");
sFrontPixelThreshold = front_pixel_threshold;
@@ -384,29 +375,38 @@ void LLVOCacheEntry::updateDebugSettings()
sRearPixelThreshold = rear_pixel_threshold;
sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold.
- // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
- static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
- sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m
- sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius".
- sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance.
-
- //make the above parameters adaptive to memory usage
+ //make parameters adaptive to memory usage
//starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB
static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound");
static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound");
LLMemory::updateMemoryInfo() ;
U32 allocated_mem = LLMemory::getAllocatedMemKB().value();
- allocated_mem /= 1024; //convert to MB.
- if(allocated_mem < low_mem_bound_MB)
- {
- return;
- }
- F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB));
-
- sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f]
- sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64]
- sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f);
+ static const F32 KB_to_MB = 1.f / 1024.f;
+ U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB);
+ const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB;
+ const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1]
+
+ //min radius: all objects within this radius remain loaded in memory
+ static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
+ static const F32 MIN_RADIUS = 1.0f;
+ const F32 draw_radius = gAgentCamera.mDrawDistance;
+ const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
+ sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
+
+ // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
+ static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
+ const F32 min_radius_plus_one = sNearRadius + 1.f;
+ const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance;
+ const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]
+ sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor);
+
+ //the number of frames invisible objects stay in memory
+ static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime");
+ static const U32 MIN_FRAMES = 10;
+ static const U32 MAX_FRAMES = 64;
+ const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
+ sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
//static
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index f971554c9d..b0eb8d962c 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -770,8 +770,6 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string
mReceivedCall(FALSE)
{
// make sure URI reflects encoded version of other user's agent id
- // *NOTE: in case of Avaline call generated SIP URL will be incorrect.
- // But it will be overridden in LLVoiceChannelP2P::setSessionHandle() called when agent accepts call
setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));
}
@@ -911,8 +909,6 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s
else
{
LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL;
- // In the case of an incoming AvaLine call, the generated URI will be different from the
- // original one. This is because the P2P URI is based on avatar UUID but Avaline is not.
// See LLVoiceClient::sessionAddedEvent()
setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));
}
@@ -947,22 +943,5 @@ void LLVoiceChannelP2P::setState(EState state)
void LLVoiceChannelP2P::addToTheRecentPeopleList()
{
- bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType();
-
- if (avaline_call)
- {
- LLSD call_data;
- std::string call_number = LLVoiceChannel::getSessionName();
-
- call_data["avaline_call"] = true;
- call_data["session_id"] = mSessionID;
- call_data["call_number"] = call_number;
- call_data["date"] = LLDate::now();
-
- LLRecentPeople::instance().add(mOtherUserID, call_data);
- }
- else
- {
- LLRecentPeople::instance().add(mOtherUserID);
- }
+ LLRecentPeople::instance().add(mOtherUserID);
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index e2bd1a39c7..2ef2d66f18 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -37,6 +37,7 @@
#include "llui.h"
#include "llkeyboard.h"
#include "llagent.h"
+#include "lluiusage.h"
const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
@@ -200,6 +201,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
LLVoiceVersionInfo result;
result.serverVersion = std::string();
result.serverType = std::string();
+ result.mBuildVersion = std::string();
return result;
}
}
@@ -602,6 +604,10 @@ void LLVoiceClient::setMuteMic(bool muted)
void LLVoiceClient::setUserPTTState(bool ptt)
{
+ if (ptt)
+ {
+ LLUIUsage::instance().logCommand("Agent.EnableMicrophone");
+ }
mUserPTTState = ptt;
updateMicMuteLogic();
mMicroChangedSignal();
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index cf527a4464..246883b611 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -95,6 +95,7 @@ struct LLVoiceVersionInfo
{
std::string serverType;
std::string serverVersion;
+ std::string mBuildVersion;
};
//////////////////////////////////
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 19036a3f77..ac6369e4e2 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -690,6 +690,10 @@ void LLVivoxVoiceClient::voiceControlCoro()
// surviving longer than LLVivoxVoiceClient
voiceControlStateMachine(state);
}
+ catch (const LLCoros::Stop&)
+ {
+ LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL;
+ }
catch (const LLContinueError&)
{
LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient");
@@ -1606,13 +1610,33 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo()
}
else
{
- LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
-
+ LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
+ if (channel != NULL)
+ {
+ if (channel->getSessionName().empty() && channel->getSessionID().isNull())
+ {
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL;
+ }
+ }
}
}
else
{
- LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ if (LLViewerParcelMgr::getInstance()->allowAgentVoice())
+ {
+ LL_WARNS("Voice") << "No voice credentials" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL;
+ }
}
// set the spatial channel. If no voice credentials or uri are
@@ -4572,6 +4596,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st
}
}
+void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id)
+{
+ // We don't generally need to process this. However, one occurence is when we first connect, and so it is the
+ // earliest opportunity to learn what we're connected to.
+ if (statusCode)
+ {
+ LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode <<
+ "statusString: " << statusString << LL_ENDL;
+ return;
+ }
+ if (build_id.empty())
+ {
+ return;
+ }
+ mVoiceVersion.mBuildVersion = build_id;
+}
+
void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy)
{
LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL;
@@ -4758,7 +4799,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions()
if ((*it).expired())
{
LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL;
- mSession.erase(it++);
+ it = mSession.erase(it);
}
else
++it;
@@ -6815,7 +6856,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id)
if (list_iter->second == id)
{
LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL;
- mVoiceFontList.erase(list_iter++);
+ list_iter = mVoiceFontList.erase(list_iter);
mVoiceFontListDirty = true;
}
else
@@ -7554,6 +7595,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
connectorHandle = string;
else if (!stricmp("VersionID", tag))
versionID = string;
+ else if (!stricmp("Version", tag))
+ mBuildID = string;
else if (!stricmp("AccountHandle", tag))
accountHandle = string;
else if (!stricmp("State", tag))
@@ -7856,7 +7899,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
// We don't need to process this, but we also shouldn't warn on it, since that confuses people.
}
else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent"))
- { // Yet another ignored event
+ {
+ LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID);
}
else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent"))
{
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index cf30a4e86a..ebc3a62c35 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -465,6 +465,7 @@ protected:
void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType);
void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString);
void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
+ void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id);
void auxAudioPropertiesEvent(F32 energy);
void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString);
void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string &notificationType);
@@ -969,6 +970,7 @@ protected:
std::string actionString;
std::string connectorHandle;
std::string versionID;
+ std::string mBuildID;
std::string accountHandle;
std::string sessionHandle;
std::string sessionGroupHandle;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 068e8a131d..f3affbeb33 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -845,9 +845,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
- U32 index_count = 0;
- U32 vertex_count = 0;
-
group->clearDrawMap();
LLVertexBuffer* buffer = group->mVertexBuffer;
@@ -913,9 +910,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
llassert(facep->getIndicesCount() == 6);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
-
S32 idx = draw_vec.size()-1;
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index bae3d540e3..a4e0d367c8 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -230,6 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mMediaImplList.resize(getNumTEs());
mLastFetchedMediaVersion = -1;
+ mServerDrawableUpdateCount = 0;
memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
mMDCImplCount = 0;
mLastRiggingInfoLOD = -1;
@@ -325,6 +326,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
LLColor4U color;
const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
+ const bool previously_volume_changed = mVolumeChanged;
+ const bool previously_face_mapping_changed = mFaceMappingChanged;
+ const bool previously_color_changed = mColorChanged;
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@@ -548,9 +552,31 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// ...and clean up any media impls
cleanUpMediaImpls();
+ if ((
+ (mVolumeChanged && !previously_volume_changed) ||
+ (mFaceMappingChanged && !previously_face_mapping_changed) ||
+ (mColorChanged && !previously_color_changed)
+ )
+ && !mLODChanged) {
+ onDrawableUpdateFromServer();
+ }
+
return retval;
}
+// Called when a volume, material, etc is updated by the server, possibly by a
+// script. If this occurs too often for this object, mark it as active so that
+// it doesn't disrupt the octree/render batches, thereby potentially causing a
+// big performance penalty.
+void LLVOVolume::onDrawableUpdateFromServer()
+{
+ constexpr U32 UPDATES_UNTIL_ACTIVE = 8;
+ ++mServerDrawableUpdateCount;
+ if (mDrawable && !mDrawable->isActive() && mServerDrawableUpdateCount > UPDATES_UNTIL_ACTIVE)
+ {
+ mDrawable->makeActive();
+ }
+}
void LLVOVolume::animateTextures()
{
@@ -1670,7 +1696,7 @@ void LLVOVolume::regenFaces()
}
}
-BOOL LLVOVolume::genBBoxes(BOOL force_global)
+BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED;
BOOL res = TRUE;
@@ -1689,7 +1715,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
// updates needed, set REBUILD_RIGGED accordingly.
// Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about.
- updateRiggedVolume();
+ updateRiggedVolume(false);
}
LLVolume* volume = mRiggedVolume;
@@ -1746,20 +1772,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
}
}
- bool rigged = false;
-
- if (!isAnimatedObject())
- {
- rigged = isRiggedMesh() && isAttachment();
- }
- else
- {
- rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying;
- }
-
if (any_valid_boxes)
{
- if (rebuild)
+ if (rebuild && should_update_octree_bounds)
{
//get the Avatar associated with this object if it's rigged
LLVOAvatar* avatar = nullptr;
@@ -1921,7 +1936,7 @@ void LLVOVolume::updateRelativeXform(bool force_identity)
}
}
-bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
+bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &should_update_octree_bounds)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool regen_faces = false;
@@ -1953,6 +1968,9 @@ bool LLVOVolume::lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled)
}
compiled = TRUE;
+ // new_lod > old_lod breaks a feedback loop between LOD updates and
+ // bounding box updates.
+ should_update_octree_bounds = should_update_octree_bounds || mSculptChanged || new_lod > old_lod;
sNumLODChanges += new_num_faces;
if ((S32)getNumTEs() != getVolume()->getNumFaces())
@@ -1991,7 +2009,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mDrawable->isState(LLDrawable::REBUILD_RIGGED))
{
- updateRiggedVolume();
+ updateRiggedVolume(false);
genBBoxes(FALSE);
mDrawable->clearState(LLDrawable::REBUILD_RIGGED);
}
@@ -2012,8 +2030,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
group->dirtyMesh();
}
- BOOL compiled = FALSE;
-
updateRelativeXform();
if (mDrawable.isNull()) // Not sure why this is happening, but it is...
@@ -2021,49 +2037,55 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
return TRUE; // No update to complete
}
+ BOOL compiled = FALSE;
+ // This should be true in most cases, unless we're sure no octree update is
+ // needed.
+ BOOL should_update_octree_bounds = bool(getRiggedVolume()) || mDrawable->isState(LLDrawable::REBUILD_POSITION) || !mDrawable->getSpatialExtents()->isFinite3();
+
if (mVolumeChanged || mFaceMappingChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
bool was_regen_faces = false;
+ should_update_octree_bounds = true;
if (mVolumeChanged)
{
- was_regen_faces = lodOrSculptChanged(drawable, compiled);
+ was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
drawable->setState(LLDrawable::REBUILD_VOLUME);
}
else if (mSculptChanged || mLODChanged || mColorChanged)
{
compiled = TRUE;
- was_regen_faces = lodOrSculptChanged(drawable, compiled);
+ was_regen_faces = lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
}
if (!was_regen_faces) {
regenFaces();
}
-
- genBBoxes(FALSE);
}
else if (mLODChanged || mSculptChanged || mColorChanged)
{
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
- lodOrSculptChanged(drawable, compiled);
+ lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
{
updateRiggedVolume(false);
}
- genBBoxes(FALSE);
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
else
{
compiled = TRUE;
// All it did was move or we changed the texture coordinate offset
- genBBoxes(FALSE);
}
+ // Generate bounding boxes if needed, and update the object's size in the
+ // octree
+ genBBoxes(FALSE, should_update_octree_bounds);
+
// Update face flags
updateFaceFlags();
@@ -4593,7 +4615,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- updateRiggedVolume(true);
+ updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES);
volume = mRiggedVolume;
transform = false;
}
@@ -4668,6 +4690,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
continue;
}
+ // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree.
+ // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking.
+ updateRiggedVolume(true, i, false);
face_hit = volume->lineSegmentIntersect(local_start, local_end, i,
&p, &tc, &n, &tn);
@@ -4791,13 +4816,13 @@ void LLVOVolume::clearRiggedVolume()
}
}
-void LLVOVolume::updateRiggedVolume(bool force_update)
+void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
- if ((!force_update) && (!treatAsRigged()))
+ if ((!force_treat_as_rigged) && (!treatAsRigged()))
{
clearRiggedVolume();
@@ -4826,10 +4851,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update)
updateRelativeXform();
}
- mRiggedVolume->update(skin, avatar, volume);
+ mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
-void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
+void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool copy = false;
@@ -4860,7 +4885,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if (is_paused)
{
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
- if (frames_paused > 2)
+ if (frames_paused > 1)
{
return;
}
@@ -4879,7 +4904,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
LLVector4a box_min, box_max;
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ S32 face_begin;
+ S32 face_end;
+ if (face_index == DO_NOT_UPDATE_FACES)
+ {
+ face_begin = 0;
+ face_end = 0;
+ }
+ else if (face_index == UPDATE_ALL_FACES)
+ {
+ face_begin = 0;
+ face_end = volume->getNumVolumeFaces();
+ }
+ else
+ {
+ face_begin = face_index;
+ face_end = face_begin + 1;
+ }
+ for (S32 i = face_begin; i < face_end; ++i)
{
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
@@ -4964,15 +5006,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
+ if (rebuild_face_octrees)
{
- delete dst_face.mOctree;
- dst_face.mOctree = NULL;
-
- LLVector4a size;
- size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]);
- size.splat(size.getLength3().getF32()*0.5f);
-
- dst_face.createOctree(1.f);
+ dst_face.destroyOctree();
+ dst_face.createOctree();
}
}
}
@@ -5495,6 +5532,7 @@ static inline void add_face(T*** list, U32* count, T* face)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5652,7 +5690,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
avatar->addAttachmentOverridesForObject(vobj, NULL, false);
}
-
+
// Standard rigged mesh attachments:
bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
@@ -5696,7 +5734,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (facep->isState(LLFace::RIGGED))
{
//face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
if (pool)
{
pool->removeFace(facep);
@@ -5882,7 +5920,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
else
{
drawablep->clearState(LLDrawable::RIGGED);
- vobj->updateRiggedVolume();
+ vobj->updateRiggedVolume(false);
}
}
}
@@ -5992,7 +6030,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
+ if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL))
{
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -6026,8 +6064,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- llassert(!face->isState(LLFace::RIGGED));
-
if (!face->getGeometryVolume(*volume, face->getTEOffset(),
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
{ //something's gone wrong with the vertex buffer accounting, rebuild this group
@@ -6156,7 +6192,6 @@ struct CompareBatchBreakerRigged
}
};
-
U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 4cb7a5481c..01ad40274b 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -65,7 +65,10 @@ public:
{
}
- void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume);
+ using FaceIndex = S32;
+ static const FaceIndex UPDATE_ALL_FACES = -1;
+ static const FaceIndex DO_NOT_UPDATE_FACES = -2;
+ void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true);
std::string mExtraDebugText;
};
@@ -232,7 +235,7 @@ public:
void updateFaceFlags();
void regenFaces();
- BOOL genBBoxes(BOOL force_global);
+ BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE);
void preRebuild();
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
virtual F32 getBinRadius();
@@ -362,8 +365,9 @@ public:
S32 getMDCImplCount() { return mMDCImplCount; }
- //rigged volume update (for raycasting)
- void updateRiggedVolume(bool force_update = false);
+ // Rigged volume update (for raycasting)
+ // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting
+ void updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true);
LLRiggedVolume* getRiggedVolume();
//returns true if volume should be treated as a rigged volume
@@ -386,13 +390,14 @@ protected:
static S32 mRenderComplexity_last;
static S32 mRenderComplexity_current;
+ void onDrawableUpdateFromServer();
void requestMediaDataUpdate(bool isNew);
void cleanUpMediaImpls();
void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
void removeMediaImpl(S32 texture_index) ;
private:
- bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled);
+ bool lodOrSculptChanged(LLDrawable *drawable, BOOL &compiled, BOOL &shouldUpdateOctreeBounds);
public:
@@ -424,6 +429,7 @@ private:
LLPointer<LLViewerFetchedTexture> mLightTexture;
media_list_t mMediaImplList;
S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1
+ U32 mServerDrawableUpdateCount;
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index ff899fe895..3cc82621c4 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -36,7 +36,7 @@
#include "llstring.h"
// newview
-#include "llpanelprofile.h" // for getProfileURL(). FIXME: move the method to LLAvatarActions
+#include "llavataractions.h" // for getProfileURL()
#include "llviewermedia.h" // FIXME: don't use LLViewerMedia internals
#include "llcorehttputil.h"
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8abb49fba8..aa32ef04b2 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -763,14 +763,13 @@ void LLWorld::updateParticles()
void LLWorld::renderPropertyLines()
{
S32 region_count = 0;
- S32 vertex_count = 0;
for (region_list_t::iterator iter = mVisibleRegionList.begin();
iter != mVisibleRegionList.end(); ++iter)
{
LLViewerRegion* regionp = *iter;
region_count++;
- vertex_count += regionp->renderPropertyLines();
+ regionp->renderPropertyLines();
}
}
@@ -778,7 +777,6 @@ void LLWorld::renderPropertyLines()
void LLWorld::updateNetStats()
{
F64Bits bits;
- U32 packets = 0;
for (region_list_t::iterator iter = mActiveRegionList.begin();
iter != mActiveRegionList.end(); ++iter)
@@ -786,7 +784,6 @@ void LLWorld::updateNetStats()
LLViewerRegion* regionp = *iter;
regionp->updateNetStats();
bits += regionp->mBitsReceived;
- packets += llfloor( regionp->mPacketsReceived );
regionp->mBitsReceived = (F32Bits)0.f;
regionp->mPacketsReceived = 0.f;
}
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 59ac4554d7..6e994b4e68 100644..100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -58,9 +58,15 @@
#include "llglheaders.h"
+// # Constants
+static const F32 MAP_DEFAULT_SCALE = 128.f;
+static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f;
+static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f;
+static const F32 MAP_ZOOM_MAX_INTERP = 0.5f;
+static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f;
+
// Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py
// Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...)
-// # Constants
// OCEAN_COLOR = "#1D475F"
const F32 OCEAN_RED = (F32)(0x1D)/255.f;
const F32 OCEAN_GREEN = (F32)(0x47)/255.f;
@@ -92,14 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL;
-F32 LLWorldMapView::sPanX = 0.f;
-F32 LLWorldMapView::sPanY = 0.f;
-F32 LLWorldMapView::sTargetPanX = 0.f;
-F32 LLWorldMapView::sTargetPanY = 0.f;
S32 LLWorldMapView::sTrackingArrowX = 0;
S32 LLWorldMapView::sTrackingArrowY = 0;
bool LLWorldMapView::sVisibleTilesLoaded = false;
-F32 LLWorldMapView::sMapScale = 128.f;
+F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE;
+LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f);
+LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer();
std::map<std::string,std::string> LLWorldMapView::sStringsMap;
@@ -166,20 +170,27 @@ void LLWorldMapView::cleanupClass()
sForSaleAdultImage = NULL;
}
-LLWorldMapView::LLWorldMapView()
-: LLPanel(),
- mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ),
- mItemPicked(FALSE),
- mPanning( FALSE ),
- mMouseDownPanX( 0 ),
- mMouseDownPanY( 0 ),
- mMouseDownX( 0 ),
- mMouseDownY( 0 ),
- mSelectIDStart(0)
+LLWorldMapView::LLWorldMapView() :
+ LLPanel(),
+ mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)),
+ mItemPicked(FALSE),
+ mPanX(0.f),
+ mPanY(0.f),
+ mTargetPanX(0.f),
+ mTargetPanY(0.f),
+ mPanning(FALSE),
+ mMouseDownPanX(0),
+ mMouseDownPanY(0),
+ mMouseDownX(0),
+ mMouseDownY(0),
+ mSelectIDStart(0),
+ mMapScale(0.f),
+ mTargetMapScale(0.f),
+ mMapIterpTime(MAP_ITERP_TIME_CONSTANT)
{
- //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
+ // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
- clearLastClick();
+ clearLastClick();
}
BOOL LLWorldMapView::postBuild()
@@ -210,6 +221,9 @@ BOOL LLWorldMapView::postBuild()
mTextBoxNorthEast ->reshapeToFitText();
mTextBoxSouthWest->reshapeToFitText();
mTextBoxNorthWest ->reshapeToFitText();
+
+ sZoomTimer.stop();
+ setScale(sMapScaleSetting, true);
return true;
}
@@ -227,59 +241,111 @@ void LLWorldMapView::cleanupTextures()
{
}
+void LLWorldMapView::zoom(F32 zoom)
+{
+ mTargetMapScale = scaleFromZoom(zoom);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomPivot = LLVector2(0, 0);
+ sZoomTimer.start();
+ }
+}
-// static
-void LLWorldMapView::setScale( F32 scale )
+void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y)
{
- if (scale != sMapScale)
- {
- F32 old_scale = sMapScale;
+ mTargetMapScale = scaleFromZoom(zoom);
+ sZoomPivot = LLVector2(x, y);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+}
- sMapScale = scale;
- if (sMapScale <= 0.f)
- {
- sMapScale = 0.1f;
- }
+F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); }
- F32 ratio = (scale / old_scale);
- sPanX *= ratio;
- sPanY *= ratio;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
- }
-}
+F32 LLWorldMapView::getScale() { return mMapScale; }
+// static
+void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; }
+
+// static
+F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; }
+
+void LLWorldMapView::setScale(F32 scale, bool snap)
+{
+ if (scale != mMapScale)
+ {
+ F32 old_scale = mMapScale;
+
+ mMapScale = scale;
+ // Set the scale used when saving the setting
+ sMapScaleSetting = scale;
+ if (mMapScale <= 0.f)
+ {
+ mMapScale = 0.1f;
+ }
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ F32 ratio = (scale / old_scale);
+ mPanX *= ratio;
+ mPanY *= ratio;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
+
+ // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here
+ if (!sZoomPivot.isExactlyZero())
+ {
+ LLVector2 relative_pivot;
+ relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0);
+ relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0);
+ LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale);
+ mPanX += zoom_pan_offset.mV[VX];
+ mPanY += zoom_pan_offset.mV[VY];
+ mTargetPanX += zoom_pan_offset.mV[VX];
+ mTargetPanY += zoom_pan_offset.mV[VY];
+ }
+ }
+
+ if (snap)
+ {
+ mTargetMapScale = scale;
+ }
+}
// static
-void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y )
+void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y)
{
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
}
// static
-void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap )
+void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap)
{
- sTargetPanX = (F32)x;
- sTargetPanY = (F32)y;
- if (snap)
- {
- sPanX = sTargetPanX;
- sPanY = sTargetPanY;
- }
- sVisibleTilesLoaded = false;
+ mMapIterpTime = MAP_ITERP_TIME_CONSTANT;
+ mTargetPanX = (F32) x;
+ mTargetPanY = (F32) y;
+ if (snap)
+ {
+ mPanX = mTargetPanX;
+ mPanY = mTargetPanY;
+ }
+ sVisibleTilesLoaded = false;
}
-bool LLWorldMapView::showRegionInfo()
+// static
+void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time)
{
- return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false);
+ setPan(x, y, snap);
+ mMapIterpTime = interp_time;
}
+bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); }
+
///////////////////////////////////////////////////////////////////////////////////
// HELPERS
@@ -300,9 +366,28 @@ void LLWorldMapView::draw()
mVisibleRegions.clear();
- // animate pan if necessary
- sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f));
- sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));
+ // animate pan if necessary
+ mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+ mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime));
+
+ //RN: snaps to zoom value because interpolation caused jitter in the text rendering
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+ bool snap_scale = false;
+ F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME);
+ F32 current_zoom_val = zoomFromScale(mMapScale);
+ F32 target_zoom_val = zoomFromScale(mTargetMapScale);
+ F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp);
+ if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD)
+ {
+ sZoomTimer.stop();
+ snap_scale = true;
+ new_zoom_val = target_zoom_val;
+ }
+ F32 map_scale = scaleFromZoom(new_zoom_val);
+ setScale(map_scale, snap_scale);
const S32 width = getRect().getWidth();
const S32 height = getRect().getHeight();
@@ -310,7 +395,7 @@ void LLWorldMapView::draw()
const F32 half_height = F32(height) / 2.0f;
LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
LLLocalClipRect clip(getLocalRect());
{
@@ -347,15 +432,15 @@ void LLWorldMapView::draw()
// Find x and y position relative to camera's center.
LLVector3d rel_region_pos = origin_global - camera_global;
- F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale;
- F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale;
+ F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale;
+ F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale;
// Coordinates of the sim in pixels in the UI panel
// When the view isn't panned, 0,0 = center of rectangle
- F32 bottom = sPanY + half_height + relative_y;
- F32 left = sPanX + half_width + relative_x;
- F32 top = bottom + sMapScale ;
- F32 right = left + sMapScale ;
+ F32 bottom = mPanY + half_height + relative_y;
+ F32 left = mPanX + half_width + relative_x;
+ F32 top = bottom + mMapScale ;
+ F32 right = left + mMapScale ;
// Discard if region is outside the screen rectangle (not visible on screen)
if ((top < 0.f) || (bottom > height) ||
@@ -416,7 +501,7 @@ void LLWorldMapView::draw()
if (overlayimage)
{
// Inform the fetch mechanism of the size we need
- S32 draw_size = ll_round(sMapScale);
+ S32 draw_size = ll_round(mMapScale);
overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY]));
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
@@ -444,7 +529,7 @@ void LLWorldMapView::draw()
}
// Draw the region name in the lower left corner
- if (sMapScale >= DRAW_TEXT_THRESHOLD)
+ if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD));
std::string mesg;
@@ -464,7 +549,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
S32_MAX, //max_chars
- sMapScale, //max_pixels
+ mMapScale, //max_pixels
NULL,
TRUE); //use ellipses
}
@@ -591,7 +676,7 @@ void LLWorldMapView::setVisible(BOOL visible)
void LLWorldMapView::drawMipmap(S32 width, S32 height)
{
// Compute the level of the mipmap to use for the current scale level
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// Set the tile boost level so that unused tiles get to 0
LLWorldMap::getInstance()->equalizeBoostLevels();
@@ -874,7 +959,7 @@ void LLWorldMapView::drawAgents()
void LLWorldMapView::drawFrustum()
{
// Draw frustum
- F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS;
+ F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS;
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -884,8 +969,8 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
- F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]);
- F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
+ F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]);
+ F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -942,13 +1027,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
- pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS;
- pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS;
// leave Z component in meters
- pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX;
- pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY;
+ pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX;
+ pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY;
return pos_local;
}
@@ -1019,12 +1104,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
// If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well
LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
{
- x -= llfloor((getRect().getWidth() / 2 + sPanX));
- y -= llfloor((getRect().getHeight() / 2 + sPanY));
+ x -= llfloor((getRect().getWidth() / 2 + mPanX));
+ y -= llfloor((getRect().getHeight() / 2 + mPanY));
LLVector3 pos_local( (F32)x, (F32)y, 0.f );
- pos_local *= ( REGION_WIDTH_METERS / sMapScale );
+ pos_local *= ( REGION_WIDTH_METERS / mMapScale );
LLVector3d pos_global;
pos_global.setVec( pos_local );
@@ -1481,7 +1566,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
LLWorldMap::getInstance()->cancelTracking();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// If the zoom level is not too far out already, test hits
if (level <= DRAW_SIMINFO_THRESHOLD)
{
@@ -1598,8 +1683,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )
{
gFocusMgr.setMouseCapture( this );
- mMouseDownPanX = ll_round(sPanX);
- mMouseDownPanY = ll_round(sPanY);
+ mMouseDownPanX = ll_round(mPanX);
+ mMouseDownPanY = ll_round(mPanY);
mMouseDownX = x;
mMouseDownY = y;
sHandledLastClick = TRUE;
@@ -1614,8 +1699,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
{
// restore mouse cursor
S32 local_x, local_y;
- local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX);
- local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY);
+ local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX);
+ local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY);
LLRect clip_rect = getRect();
clip_rect.stretch(-8);
clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y);
@@ -1643,7 +1728,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
void LLWorldMapView::updateVisibleBlocks()
{
- if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD)
+ if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD)
{
// If we're zoomed out too much, we just don't load all those sim info: too much!
return;
@@ -1659,16 +1744,16 @@ void LLWorldMapView::updateVisibleBlocks()
const F32 half_height = F32(height) / 2.0f;
// Compute center into sim grid coordinates
- S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
- S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
+ S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
+ S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
// Compute the boundaries into sim grid coordinates
- S32 world_left = world_center_x - S32(half_width / sMapScale) - 1;
- S32 world_right = world_center_x + S32(half_width / sMapScale) + 1;
- S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1;
- S32 world_top = world_center_y + S32(half_height / sMapScale) + 1;
+ S32 world_left = world_center_x - S32(half_width / mMapScale) - 1;
+ S32 world_right = world_center_x + S32(half_width / mMapScale) + 1;
+ S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1;
+ S32 world_top = world_center_y + S32(half_height / mMapScale) + 1;
- //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
+ //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top);
}
@@ -1689,10 +1774,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY());
// Set pan to value at start of drag + offset
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
gViewerWindow->moveCursorToCenter();
}
@@ -1789,4 +1874,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
return FALSE;
}
+// static
+F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; }
+// static
+F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); }
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index a2a6dc53fb..ce8af76a82 100644
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
@@ -67,12 +67,22 @@ public:
bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track);
void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id);
- // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered)
- static void setScale( F32 scale );
- static void translatePan( S32 delta_x, S32 delta_y );
- static void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered)
+ // Zoom is used for UI and will interpolate the map scale over multiple frames.
+ void zoom(F32 zoom);
+ void zoomWithPivot(F32 zoom, S32 x, S32 y);
+ F32 getZoom();
+ // Scale is a linear scaling factor of in-world coordinates
+ F32 getScale();
+ // setScaleSetting/getScaleSetting are for the default map setting on login
+ static void setScaleSetting(F32 scaleSetting);
+ static F32 getScaleSetting();
+ // Pan is in pixels relative to the center of the map.
+ void translatePan( S32 delta_x, S32 delta_y );
+ void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time);
// Return true if the current scale level is above the threshold for accessing region info
- static bool showRegionInfo();
+ bool showRegionInfo();
LLVector3 globalPosToView(const LLVector3d& global_pos);
LLVector3d viewPosToGlobal(S32 x,S32 y);
@@ -153,14 +163,12 @@ public:
static LLUIImagePtr sForSaleImage;
static LLUIImagePtr sForSaleAdultImage;
- static F32 sMapScale; // scale = size of a region in pixels
-
BOOL mItemPicked;
- static F32 sPanX; // in pixels
- static F32 sPanY; // in pixels
- static F32 sTargetPanX; // in pixels
- static F32 sTargetPanY; // in pixels
+ F32 mPanX; // in pixels
+ F32 mPanY; // in pixels
+ F32 mTargetPanX; // in pixels
+ F32 mTargetPanY; // in pixels
static S32 sTrackingArrowX;
static S32 sTrackingArrowY;
static bool sVisibleTilesLoaded;
@@ -194,6 +202,19 @@ public:
private:
void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right);
+
+ void setScale(F32 scale, bool snap = true);
+
+ static F32 scaleFromZoom(F32 zoom);
+ static F32 zoomFromScale(F32 scale);
+
+ F32 mMapScale;
+ F32 mTargetMapScale;
+ static F32 sMapScaleSetting;
+ static LLVector2 sZoomPivot;
+ static LLFrameTimer sZoomTimer;
+
+ F32 mMapIterpTime;
};
#endif
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 32c8ce66a0..5c56a1d34f 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -40,6 +40,7 @@
#include "httpoptions.h"
#include "httpheaders.h"
#include "bufferarray.h"
+#include "llversioninfo.h"
#include "llviewercontrol.h"
// Have to include these last to avoid queue redefinition!
@@ -378,6 +379,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+ std::string user_agent = llformat("%s %d.%d.%d (%d)",
+ LLVersionInfo::instance().getChannel().c_str(),
+ LLVersionInfo::instance().getMajor(),
+ LLVersionInfo::instance().getMinor(),
+ LLVersionInfo::instance().getPatch(),
+ LLVersionInfo::instance().getBuild());
+
+ httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
///* Setting the DNS cache timeout to -1 disables it completely.
//This might help with bug #503 */
//httpOpts->setDNSCacheTimeout(-1);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c297f0f080..96ba80dacc 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3939,7 +3939,7 @@ void LLPipeline::postSort(LLCamera& camera)
}
LL_PUSH_CALLSTACKS();
// If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
- if (LLFloaterTelehub::renderBeacons())
+ if (LLFloaterTelehub::renderBeacons() && !sShadowRender)
{
LLFloaterTelehub::addBeacons();
}
@@ -7238,6 +7238,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
mResetVertexBuffers = false;
mCubeVB = NULL;
+ mDeferredVB = NULL;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -7271,10 +7272,11 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPathingLib::getInstance()->cleanupVBOManager();
}
LLVOPartGroup::destroyGL();
+ gGL.resetVertexBuffer();
SUBSYSTEM_CLEANUP(LLVertexBuffer);
- if (LLVertexBuffer::sGLCount > 0)
+ if (LLVertexBuffer::sGLCount != 0)
{
LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
}
@@ -7295,6 +7297,10 @@ void LLPipeline::doResetVertexBuffers(bool forced)
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+ gGL.initVertexBuffer();
+
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
+ mDeferredVB->allocateBuffer(8, 0, true);
LLVOPartGroup::restoreGL();
}
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7beb013fba..c3ce83e834 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -514,8 +514,8 @@
name="MapFrustumColor"
reference="White_10" />
<color
- name="MapFrustumRotatingColor"
- value="1 1 1 0.2" />
+ name="MapParcelOutlineColor"
+ value="1 1 0 0.5" />
<color
name="MapTrackColor"
reference="Red" />
@@ -607,10 +607,10 @@
value="0 0 0 1" />
<color
name="NetMapGroupOwnAboveWater"
- reference="Purple" />
+ value="0.85 0 0.85 1" />
<color
name="NetMapGroupOwnBelowWater"
- value="0.78 0 0.78 1" />
+ value="0.63 0 0.63 1" />
<color
name="NetMapOtherOwnAboveWater"
value="0.24 0.24 0.24 1" />
@@ -619,10 +619,10 @@
value="0.12 0.12 0.12 1" />
<color
name="NetMapYouOwnAboveWater"
- value="0 1 1 1" />
+ value="0 0.85 0.85 1" />
<color
name="NetMapYouOwnBelowWater"
- value="0 0.78 0.78 1" />
+ value="0 0.63 0.63 1" />
<color
name="NotifyBoxColor"
value="LtGray" />
@@ -886,6 +886,22 @@
name="PanelNotificationListItem"
value="0.3 0.3 0.3 .3" />
+ <!-- profiles -->
+ <color
+ name="StatusUserOnline"
+ reference="White" />
+ <color
+ name="StatusUserOffline"
+ reference="LtGray_35" />
+ <!-- Groups visible in own profiles -->
+ <color
+ name="GroupVisibleInProfile"
+ reference="TextBgFocusColor" />
+ <color
+ name="GroupHiddenInProfile"
+ reference="Gray" />
+
+
<!-- Generic color names (legacy) -->
<color
name="white"
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
new file mode 100644
index 0000000000..9a81c5f94b
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
new file mode 100644
index 0000000000..88012cf8d1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
new file mode 100644
index 0000000000..ab02e7d42d
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png
new file mode 100644
index 0000000000..63b4bd2127
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png
new file mode 100644
index 0000000000..4200182b0c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png
new file mode 100644
index 0000000000..e12887f489
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/ClipboardSmallMenu_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/CopyBright.png b/indra/newview/skins/default/textures/icons/CopyBright.png
new file mode 100644
index 0000000000..8d21c47295
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/CopyBright.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
new file mode 100644
index 0000000000..aeba6b70f7
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Offline.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
new file mode 100644
index 0000000000..d668fd8dfa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Friend_Online.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
new file mode 100644
index 0000000000..8f8caa10d8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
new file mode 100644
index 0000000000..42a209dda5
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Find_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
new file mode 100644
index 0000000000..644edf0ef6
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
new file mode 100644
index 0000000000..629c05ecb8
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Objects_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
new file mode 100644
index 0000000000..ecf66c0ee1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
new file mode 100644
index 0000000000..26123938fa
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Profile_Perm_Online_Enabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
deleted file mode 100644
index 3bb7f7183c..0000000000
--- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
new file mode 100644
index 0000000000..3a2ed399b2
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
new file mode 100644
index 0000000000..789f59a491
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_off_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
new file mode 100644
index 0000000000..4fb56c389c
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
new file mode 100644
index 0000000000..ae04a256a4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_group_visibility_eye_on_pressed.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_ui_collapse_icon.png b/indra/newview/skins/default/textures/map_ui_collapse_icon.png
new file mode 100644
index 0000000000..e4de49d4af
--- /dev/null
+++ b/indra/newview/skins/default/textures/map_ui_collapse_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/map_ui_expand_icon.png b/indra/newview/skins/default/textures/map_ui_expand_icon.png
new file mode 100644
index 0000000000..08734b4cc0
--- /dev/null
+++ b/indra/newview/skins/default/textures/map_ui_expand_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 03e23b5ba3..4429a1677e 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -67,8 +67,6 @@ with the same filename but different name
<texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" />
<texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" />
- <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" />
-
<texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" />
<texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" />
@@ -191,6 +189,7 @@ with the same filename but different name
<texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
<texture name="Copy" file_name="icons/Copy.png" preload="false" />
+ <texture name="CopyBright" file_name="icons/CopyBright.png" preload="false" />
<texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
@@ -447,6 +446,13 @@ with the same filename but different name
<texture name="OptionsMenu_Off" file_name="icons/OptionsMenu_Off.png" preload="false" />
<texture name="OptionsMenu_Press" file_name="icons/OptionsMenu_Press.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Disabled" file_name="icons/ClipboardSmallMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Off" file_name="icons/ClipboardSmallMenu_Off.png" preload="false" />
+ <texture name="ClipboardSmallMenu_Press" file_name="icons/ClipboardSmallMenu_Press.png" preload="false" />
+ <texture name="ClipboardMenu_Disabled" file_name="icons/ClipboardMenu_Disabled.png" preload="false" />
+ <texture name="ClipboardMenu_Off" file_name="icons/ClipboardMenu_Off.png" preload="false" />
+ <texture name="ClipboardMenu_Press" file_name="icons/ClipboardMenu_Press.png" preload="false" />
+
<texture name="OutboxStatus_Success" file_name="green_checkmark.png" preload="false" />
<texture name="OutboxStatus_Warning" file_name="icons/pop_up_caution.png" preload="false" />
<texture name="OutboxStatus_Error" file_name="red_x.png" preload="false" />
@@ -505,6 +511,19 @@ with the same filename but different name
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
+ <texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/>
+ <texture name="Profile_Group_Visibility_On_Pressed" file_name="icons/profile_group_visibility_eye_on_pressed.png" preload="true"/>
+ <texture name="Profile_Friend_Offline" file_name="icons/Profile_Friend_Offline.png" preload="true"/>
+ <texture name="Profile_Friend_Online" file_name="icons/Profile_Friend_Online.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Disabled" file_name="icons/Profile_Perm_Find_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Find_Enabled" file_name="icons/Profile_Perm_Find_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Disabled" file_name="icons/Profile_Perm_Objects_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Objects_Enabled" file_name="icons/Profile_Perm_Objects_Enabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Disabled" file_name="icons/Profile_Perm_Online_Disabled.png" preload="true"/>
+ <texture name="Profile_Perm_Online_Enabled" file_name="icons/Profile_Perm_Online_Enabled.png" preload="true"/>
+
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressBarSolid" file_name="widgets/ProgressBarSolid.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
@@ -803,6 +822,8 @@ with the same filename but different name
<texture name="map_infohub.tga" />
<texture name="map_telehub.tga" />
<texture name="map_track_16.tga" />
+ <texture name="map_ui_collapse_icon.png" />
+ <texture name="map_ui_expand_icon.png" />
<texture name="notify_caution_icon.tga" />
diff --git a/indra/newview/skins/default/xui/da/panel_me.xml b/indra/newview/skins/default/xui/da/panel_me.xml
deleted file mode 100644
index f98ced5f91..0000000000
--- a/indra/newview/skins/default/xui/da/panel_me.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Min profil" name="panel_me">
- <tab_container name="tabs">
- <panel label="MIN PROFIL" name="panel_profile"/>
- <panel label="MINE FAVORITTER" name="panel_picks"/>
- </tab_container>
-</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml
index 45946fd222..c8a3ad328e 100644
--- a/indra/newview/skins/default/xui/da/panel_region_texture.xml
+++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml
@@ -7,8 +7,8 @@
ukendt
</text>
<text name="detail_texture_text">
- Terræn teksturer (kræver 512x512, 24 bit .tga filer)
- </text>
+ Terræn teksturer (kræver 1024x1024, 24 bit .tga filer)
+ </text>
<text name="height_text_lbl">
1 (Lav)
</text>
diff --git a/indra/newview/skins/default/xui/da/panel_side_tray.xml b/indra/newview/skins/default/xui/da/panel_side_tray.xml
deleted file mode 100644
index 66c3e69904..0000000000
--- a/indra/newview/skins/default/xui/da/panel_side_tray.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<!-- Side tray cannot show background because it is always
- partially on screen to hold tab buttons. -->
-<side_tray name="sidebar">
- <sidetray_tab description="Åbn/luk sidebar" name="sidebar_openclose" tab_title="Åbn/luk sidebar"/>
- <sidetray_tab description="Hjem." name="sidebar_home" tab_title="Hjem">
- <panel label="hjem" name="panel_home"/>
- </sidetray_tab>
- <sidetray_tab description="Redigér din profile og favoritter." name="sidebar_me" tab_title="Min profil">
- <panel_container name="panel_container">
- <panel label="Mig" name="panel_me"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find venner, kontakter og personer tæt på." name="sidebar_people" tab_title="Personer">
- <panel_container name="panel_container">
- <panel label="Gruppe profil" name="panel_group_info_sidetray"/>
- <panel label="Blokerede beboere og objekter" name="panel_block_list_sidetray"/>
- </panel_container>
- </sidetray_tab>
- <sidetray_tab description="Find steder du vil hen og steder du har været før." label="Steder" name="sidebar_places" tab_title="Steder">
- <panel label="Steder" name="panel_places"/>
- </sidetray_tab>
- <sidetray_tab description="Browse din beholdning." name="sidebar_inventory" tab_title="Min beholdning">
- <panel label="Redigér beholdning" name="sidepanel_inventory"/>
- </sidetray_tab>
- <sidetray_tab description="Ændre dit nuværende udseende" name="sidebar_appearance" tab_title="Mit udseende">
- <panel label="Redigér udseende" name="sidepanel_appearance"/>
- </sidetray_tab>
-</side_tray>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index 5f1bf73f26..e4f99d14e9 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -443,9 +443,6 @@ Prøv venligst om lidt igen.
<string name="GroupNameNone">
(ingen)
</string>
- <string name="AvalineCaller">
- Avaline opkalder [ORDER]
- </string>
<string name="AssetErrorNone">
Ingen fejl
</string>
diff --git a/indra/newview/skins/default/xui/de/floater_preview_texture.xml b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
index eacd11c3e6..b386d0288c 100644
--- a/indra/newview/skins/default/xui/de/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/de/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
In Inventar kopieren
</floater.string>
- <text name="desc txt">
- Beschreibung:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Vorschau Seitenverhältnis
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen">
- <combo_item name="Unconstrained">
- keines
- </combo_item>
- <combo_item name="1:1" tool_tip="Gruppeninsignien oder Beschreibung">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE]-Profil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Anzeigen und Suchergebnisse, Landmarken">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Über Land">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profilauswahl">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Verwerfen" name="Discard"/>
- <button label="Speichern unter" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Beschreibung:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Vorschau Seitenverhältnis
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Mit einem vordefinierten Seitenverhältnis anzeigen"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Verwerfen" name="Discard"/>
+ <button label="Speichern unter" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_profile.xml b/indra/newview/skins/default/xui/de/floater_profile.xml
new file mode 100644
index 0000000000..eb03463930
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessen" name="panel_profile_interests"/>
+ <panel label="Auswahlen" name="panel_profile_picks"/>
+ <panel label="Anzeige" name="panel_profile_classifieds"/>
+ <panel label="Echtes Leben" name="panel_profile_firstlife"/>
+ <panel label="Hinweise" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Profiländerungen speichern und schließen"/>
+ <button label="Abbrechen" label_selected="Abbrechen" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index f0152ad8cd..636f320a95 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-Mail senden
</string>
+ <string name="facebook_progress_str">
+ Auf Facebook posten
+ </string>
<string name="profile_progress_str">
Posten
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Speichern auf Computer
</string>
+ <string name="facebook_succeeded_str">
+ Bild hochgeladen
+ </string>
<string name="profile_succeeded_str">
Bild hochgeladen
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Auf Computer gespeichert!
</string>
+ <string name="facebook_failed_str">
+ Fehler beim Hochladen des Bilds in Ihre Facebook-Chronik.
+ </string>
<string name="profile_failed_str">
Fehler beim Hochladen des Bilds in Ihr Profil.
</string>
diff --git a/indra/newview/skins/default/xui/de/menu_name_field.xml b/indra/newview/skins/default/xui/de/menu_name_field.xml
new file mode 100644
index 0000000000..1d293c9361
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Anzeigenamen kopieren" name="copy_display"/>
+ <menu_item_call label="Agent-Namen kopieren" name="copy_name"/>
+ <menu_item_call label="Agent-ID kopieren" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 359a835630..a72784f70b 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2698,6 +2698,9 @@ Wählen Sie eine kleinere Landfläche.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
index bd270697ea..8adacb4a5f 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Abbrechen" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
index f6a8fda23e..1a0bbc7d30 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_friends.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die gleichzeitig Einwohner von Second Life sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
- <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, gehen Sie zur Registerkarte „Status“."/>
+ <string name="facebook_friends_empty" value="Sie haben gegenwärtig keine Facebook-Freunde, die ebenfalls Second Life-Einwohner sind. Laden Sie Ihre Facebook-Freunde ein, Second Life beizutreten!"/>
+ <string name="facebook_friends_no_connected" value="Sie sind gegenwärtig nicht mit Facebook verbunden. Um eine Verbindung herzustellen und diese Funktion zu aktivieren, wechseln Sie zur Registerkarte &quot;Status&quot;."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL-Freunde"/>
<accordion_tab name="tab_suggested_friends" title="Diese Personen als SL-Freunde hinzufügen"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
index bc48931129..fac9fe9984 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_photo.xml
@@ -2,10 +2,10 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Bildauflösung">
<combo_box.item label="Aktuelles Fenster" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Bildfilter">
<combo_box.item label="Kein Filter" name="NoFilter"/>
diff --git a/indra/newview/skins/default/xui/de/panel_facebook_status.xml b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
index 23c9d3b75f..1fefef548e 100644
--- a/indra/newview/skins/default/xui/de/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/de/panel_facebook_status.xml
@@ -13,7 +13,7 @@
</text>
</panel>
<text name="status_caption_label">
- Was machst du gerade?
+ Was machen Sie gerade?
</text>
<button label="Posten" name="post_status_btn"/>
<button label="Abbrechen" name="cancel_status_btn"/>
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml
index 9fec5a242d..e50124c37e 100644
--- a/indra/newview/skins/default/xui/de/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_group_general.xml
@@ -46,7 +46,7 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen.
<check_box label="Jeder kann beitreten" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/>
<check_box label="Kosten für Beitritt" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Wenn Beitrittsgebühr aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/>
- <combo_box name="group_mature_check" tool_tip="Inhaltseinstufungen kennzeichnen die in einer Gruppe zulässigen Inhalte und Verhaltensweisen">
+ <combo_box name="group_mature_check" tool_tip="Legt fest, ob Ihre Gruppe als moderat eingestufte Informationen enthält">
<combo_item name="select_mature">
- Inhaltseinstufung auswählen -
</combo_item>
diff --git a/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fc911a64df
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Unbekannt"/>
+ <button name="info_btn" tool_tip="Mehr Infos"/>
+ <button name="profile_btn" tool_tip="Profil anzeigen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_me.xml b/indra/newview/skins/default/xui/de/panel_me.xml
deleted file mode 100644
index f49446fbbf..0000000000
--- a/indra/newview/skins/default/xui/de/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mein Profil" name="panel_me">
- <panel label="MEINE AUSWAHLEN" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 81de679429..e4a4c1033e 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -40,6 +40,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Alle"/>
+ <accordion_tab name="tab_suggested_friends" title="Potenzielle Freunde"/>
</accordion>
</panel>
<panel label="GRUPPEN" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classified.xml b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
new file mode 100644
index 0000000000..5c11a01977
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderat
+ </panel.string>
+ <panel.string name="type_pg">
+ Generelle Inhalte
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] Teleportieren, [MAP] Karten, [PROFILE] Profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Aktiviert
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Deaktiviert
+ </panel.string>
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <string name="publish_label">
+ Veröffentlichen
+ </string>
+ <string name="save_label">
+ Speichern
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Klicken, um ein Bild auszuwählen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Standort:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Erstellungsdatum:"/>
+ <text_editor name="creation_date" tool_tip="Erstellungsdatum" value="[date]"/>
+ <text name="price_for_listing_label" value="Preis für Auflistung:"/>
+ <text_editor name="price_for_listing" tool_tip="Preis für Auflistung.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Klicks:"/>
+ <text_editor name="click_through_text" tool_tip="Click-Through-Daten" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Autom. erneuern:"/>
+ <text name="auto_renew" value="Aktiviert"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Beschreibung:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titel:
+ </text>
+ <text name="description_label">
+ Beschreibung:
+ </text>
+ <text name="location_label">
+ Standort:
+ </text>
+ <text name="classified_location_edit">
+ Laden...
+ </text>
+ <button label="Aktuellen Standort verwenden" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategorie:"/>
+ <text name="content_type_label" value="Inhaltsart:"/>
+ <icons_combo_box label="Generelle Inhalte" name="content_type_edit">
+ <icons_combo_box.item label="Moderate Inhalte" name="mature_ci" value="Adult"/>
+ <icons_combo_box.item label="Generelle Inhalte" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Jede Woche automatisch erneuern" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preis für Auflistung:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preis für Auflistung." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleportieren" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Karte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Bearbeiten" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Abbrechen" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..83549cb138
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anzeige" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Keine Anzeigen"/>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/floater_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
index 2521920e83..0f65090209 100644
--- a/indra/newview/skins/default/xui/de/floater_picks.xml
+++ b/indra/newview/skins/default/xui/de/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Auswahlen"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_interests.xml b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
new file mode 100644
index 0000000000..0f36f76aa0
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessen" name="panel_profile_interests">
+ <text name="I Want To:">
+ Ich möchte:
+ </text>
+ <check_box label="Erstellen" name="chk0"/>
+ <check_box label="Erkunden" name="chk1"/>
+ <check_box label="Treffen" name="chk2"/>
+ <check_box label="Angestellt werden" name="chk6"/>
+ <check_box label="Gruppe" name="chk3"/>
+ <check_box label="Kaufen" name="chk4"/>
+ <check_box label="Verkaufen" name="chk5"/>
+ <check_box label="Anstellen" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Skills:">
+ Fähigkeiten:
+ </text>
+ <check_box label="Texturen" name="schk0"/>
+ <check_box label="Architektur" name="schk1"/>
+ <check_box label="Modellierung" name="schk3"/>
+ <check_box label="Eventplanung" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Benutzerdefinierte Charaktere" name="schk5"/>
+ <line_editor name="skills_edit">
+ (wird geladen...)
+ </line_editor>
+ <text name="Languages:">
+ Sprachen:
+ </text>
+ <line_editor name="languages_edit">
+ (wird geladen...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_notes.xml b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
new file mode 100644
index 0000000000..05c46ff858
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anmerkungen &amp; Privatsphäre" name="panel_notes">
+ <text name="status_message" value="Private Anmerkungen zu diesem Avatar:"/>
+ <text name="status_message2" value="Dieser Avatar darf:"/>
+ <check_box label="Sehen, wenn ich online bin" name="status_check"/>
+ <check_box label="Mich auf der Weltkarte sehen" name="map_check"/>
+ <check_box label="Meine Objekte bearbeiten, löschen oder nehmen" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_pick.xml b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
new file mode 100644
index 0000000000..1f44ba8b1b
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (wird nach dem Speichern aktualisiert)
+ </panel.string>
+ <line_editor name="pick_location">
+ Laden...
+ </line_editor>
+ <button label="Teleportieren" name="teleport_btn"/>
+ <button label="Auf Karte anzeigen" name="show_on_map_btn"/>
+ <button label="Standort festlegen" name="set_to_curr_location_btn" tool_tip="Aktuellen Standort verwenden"/>
+ <button label="Auswahl speichern" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_picks.xml b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
new file mode 100644
index 0000000000..96403715e4
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Auswahlen" name="panel_picks">
+ <string name="no_picks" value="Keine Auswahl"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Erzählen Sie von Ihren Lieblingsorten in Second Life.
+ </text>
+ <button label="Neu..." name="new_btn"/>
+ <button label="Löschen..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Laden...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..baaa58e1d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Zurzeit online
+ </string>
+ <string name="status_offline">
+ Zurzeit offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=de
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=de
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Keine"/>
+ <string name="no_group_text" value="Keine"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Entwickler"/>
+ <string name="FSSupp" value="Support"/>
+ <string name="FSQualityAssurance" value="Fehlersuche"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Name:"/>
+ <button label="Name:" name="set_name" tool_tip="Anzeigenamen festlegen"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(wird geladen...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status unbekannt"/>
+ <text name="label" value="Second Life-Geburtsdatum:"/>
+ <text name="label2" value="Konto:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppen:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="In Gruppe einladen"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Info:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Objekt geben:"/>
+ <text name="Give inventory" tool_tip="Legen Sie hier Inventarobjekte ab, um Sie dieser Person zu geben.">
+ Inventarobjekt hier ablegen.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Auf Karte anzeigen" label_selected="Auf Karte anzeigen" name="show_on_map_btn" tool_tip="Einwohner auf Karte lokalisieren"/>
+ <button label="Bezahlen" label_selected="Bezahlen" name="pay" tool_tip="Geld an den Einwohner zahlen"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teleportation anbieten" label_selected="Teleportation anbieten" name="teleport" tool_tip="Dem Einwohner eine Teleportation anbieten"/>
+ <button label="Instant Message" label_selected="Instant Message" name="im" tool_tip="Instant Message-Sitzung öffnen"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Freund hinzufügen" label_selected="Freund hinzufügen" name="add_friend" tool_tip="Dem Einwohner die Freundschaft anbieten"/>
+ <button label="Blockieren" name="block" tool_tip="Diesen Einwohner blockieren"/>
+ <button label="Blockierung aufheben" name="unblock" tool_tip="Diesen Einwohner nicht mehr blockieren"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="In Suche anzeigen" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_profile_web.xml b/indra/newview/skins/default/xui/de/panel_profile_web.xml
new file mode 100644
index 0000000000..a03918f4b5
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Ladezeit: [TIME] Sekunden"/>
+ <line_editor name="url_edit">
+ (wird geladen..)
+ </line_editor>
+ <flyout_button label="Laden" name="load" tool_tip="Lädt diese Profilseite im integrierten Webbrowser.">
+ <flyout_button.item label="Im Viewer-Browser öffnen" name="open_item"/>
+ <flyout_button.item label="In externem Browser öffnen" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Webprofil ausklappen"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
index 7801be30e4..42ba5b5269 100644
--- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Obere Terraingrenze" name="terrain_raise_spin"/>
<spinner label="Untere Terraingrenze" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512)
- </text>
+ Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024)
+ </text>
<text name="height_text_lbl">
1 (niedrig)
</text>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index 97ace4fc18..0120f7e5bd 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -356,6 +356,24 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="TestingDisconnect">
Verbindungsabbruch wird getestet
</string>
+ <string name="SocialFacebookConnecting">
+ Mit Facebook verbinden...
+ </string>
+ <string name="SocialFacebookPosting">
+ Posten...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook-Verbindung trennen...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problem beim Verbinden mit Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problem beim Posten auf Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problem beim Trennen der Facebook-Verbindung
+ </string>
<string name="SocialFlickrConnecting">
Verbinden mit Flickr...
</string>
@@ -673,9 +691,6 @@ nächsten Eigentümer angehängt werden.
<string name="GroupNameNone">
(keiner)
</string>
- <string name="AvalineCaller">
- Avaline-Anfrufer [ORDER]
- </string>
<string name="AssetErrorNone">
Kein Fehler
</string>
@@ -2578,9 +2593,21 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo
<string name="NoPicksClassifiedsText">
Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus&quot;-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen.
</string>
+ <string name="NoPicksText">
+ Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Auswahl zu erstellen.
+ </string>
+ <string name="NoClassifiedsText">
+ Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche &quot;Neu&quot;, um eine Anzeige zu erstellen.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Der Einwohner hat keine Auswahl oder Anzeigen
</string>
+ <string name="NoAvatarPicksText">
+ Der Einwohner hat keine Auswahl
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Der Einwohner hat keine Anzeigen
+ </string>
<string name="PicksClassifiedsLoadingText">
Wird geladen...
</string>
@@ -4558,6 +4585,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="share_alert">
Objekte aus dem Inventar hier her ziehen
</string>
+ <string name="facebook_post_success">
+ Sie haben auf Facebook gepostet.
+ </string>
<string name="flickr_post_success">
Sie haben auf Flickr gepostet.
</string>
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 dee5e29a3c..4678d65b85 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1893,7 +1893,29 @@ Only large parcels can be listed in search.
left="110"
name="parcel_enable_voice_channel_local"
width="300" />
- </panel>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ mouse_opaque="false"
+ name="media"
+ top_pad="10"
+ width="100">
+ Media:
+ </text>
+ <check_box
+ height="16"
+ label="Obscure MOAP"
+ layout="topleft"
+ left="110"
+ left_pad="0"
+ name="obscure_moap"
+ tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa."
+ width="300" />
+ </panel>
<panel
border="true"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/floater_picks.xml b/indra/newview/skins/default/xui/en/floater_classified.xml
index 984894b016..5b14c827d0 100644
--- a/indra/newview/skins/default/xui/en/floater_picks.xml
+++ b/indra/newview/skins/default/xui/en/floater_classified.xml
@@ -2,20 +2,19 @@
<floater
positioning="cascading"
can_close="true"
- can_resize="true"
+ can_resize="false"
height="572"
help_topic="sidebar_me"
min_width="333"
min_height="440"
- name="floater_picks"
+ name="floater_classified"
save_rect="true"
- save_visibility="true"
- reuse_instance="true"
- title="Picks"
+ save_visibility="false"
+ title="Classified"
width="333" >
<panel
- class="panel_me"
+ class="panel_classified_info"
name="main_panel"
- filename="panel_me.xml"
+ filename="panel_classified_info.xml"
follows="all"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
index bba30626b2..632daaec7e 100644
--- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -88,6 +88,7 @@
spellcheck="true"
text_readonly_color="white"
text_type="ascii_with_newline"
+ commit_on_focus_lost="true"
top_pad="5"
width="290"
wrap="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml
index 9a9fd32a77..3c8f415860 100644
--- a/indra/newview/skins/default/xui/en/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/en/floater_display_name.xml
@@ -23,7 +23,7 @@
use_ellipses="true"
width="380"
wrap="true">
- The name you give your avatar is called your Display Name. You can change it once a week.
+ Your display name is what other people see above your head. It is different from your login name. You can change it once a week.
</text>
<text
type="string"
@@ -85,19 +85,10 @@
width="120" />
<button
height="23"
- label="Reset"
- layout="topleft"
- font="SansSerif"
- left_pad="5"
- name="reset_btn"
- tool_tip="Make Display Name the same as Username"
- width="120" />
- <button
- height="23"
label="Cancel"
font="SansSerif"
layout="topleft"
- left_pad="5"
+ left_pad="125"
name="cancel_btn"
width="120" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index b8893e11d9..9639e70544 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -16,11 +16,35 @@
width="200">
<floater.string
name="ToolTipMsg">
- [REGION](Double-click to open Map, shift-drag to pan)
+ [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG]
+ </floater.string>
+ <floater.string
+ name="ParcelNameMsg">
+ [PARCEL_NAME]
+ </floater.string>
+ <floater.string
+ name="ParcelSalePriceMsg">
+ Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²)
+ </floater.string>
+ <floater.string
+ name="ParcelSaleAreaMsg">
+ Area: [AREA]m²
+ </floater.string>
+ <floater.string
+ name="ParcelOwnerMsg">
+ Owner: [PARCEL_OWNER]
+ </floater.string>
+ <floater.string
+ name="RegionNameMsg">
+ Region: [REGION_NAME]
</floater.string>
<floater.string
- name="AltToolTipMsg">
- [REGION](Double-click to teleport, shift-drag to pan)
+ name="ToolTipHintMsg">
+ Double-click to open map
+ </floater.string>
+ <floater.string
+ name="AltToolTipHintMsg">
+ Double-click to teleport
</floater.string>
<floater.string name="mini_map_caption">
Mini-map
@@ -37,105 +61,73 @@
<text
type="string"
length="1"
- bottom="218"
label="N"
layout="topleft"
- left="0"
name="floater_map_north"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
N
</text>
<text
type="string"
length="1"
- bottom="218"
label="E"
layout="topleft"
- left="0"
name="floater_map_east"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
E
</text>
<text
type="string"
length="1"
- bottom="205"
label="W"
layout="topleft"
- left="0"
name="floater_map_west"
- right="11"
- text_color="1 1 1 0.7"
- top="175">
+ text_color="1 1 1 0.7">
W
</text>
<text
type="string"
length="1"
- bottom="218"
label="S"
layout="topleft"
- left="0"
name="floater_map_south"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
S
</text>
<text
type="string"
length="1"
- bottom="218"
label="SE"
layout="topleft"
- left="0"
name="floater_map_southeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SE
</text>
<text
type="string"
length="1"
- bottom="218"
label="NE"
layout="topleft"
- left="0"
name="floater_map_northeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NE
</text>
<text
type="string"
length="1"
- bottom="218"
label="SW"
layout="topleft"
- left="0"
name="floater_map_southwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SW
</text>
<text
type="string"
length="1"
- bottom="218"
label="NW"
layout="topleft"
- left="0"
name="floater_map_northwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NW
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index e499ddbc2f..21c894d3af 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -830,6 +830,7 @@
<combo_item name="physics_medium"> Medium </combo_item>
<combo_item name="physics_low"> Low </combo_item>
<combo_item name="physics_lowest"> Lowest </combo_item>
+ <combo_item name="physics_bounding_box"> Bounding Box </combo_item>
<combo_item name="load_from_file"> From file </combo_item>
</combo_box>
<line_editor
diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
index e1e7e1c8c8..048cf7df62 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml
@@ -17,94 +17,122 @@
name="Copy">
Copy To Inventory
</floater.string>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerif"
- height="19"
- layout="topleft"
- left="10"
- name="desc txt"
- top="21"
- width="90">
- Description:
- </text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top|right"
- font="SansSerif"
- height="19"
- layout="topleft"
- left_pad="0"
- max_length_bytes="127"
- name="desc"
- width="190" />
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left="110"
- name="dimensions"
- top="255"
- width="200">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text
- type="string"
- halign="right"
- length="1"
- follows="right|bottom"
- height="16"
- layout="topleft"
- left_delta="-110"
- name="aspect_ratio"
- top_pad="5"
- width="200">
- Preview aspect ratio
- </text>
- <combo_box
- allow_text_entry="true"
- top_delta="-3"
- follows="right|bottom"
- height="23"
- left_pad="10"
- max_chars="20"
- mouse_opaque="true"
- enabled="true"
- width="108"
- name="combo_aspect_ratio"
- tool_tip="Preview at a fixed aspect ratio">
- </combo_box>
- <button
- follows="right|bottom"
- height="22"
- label="OK"
- layout="topleft"
- left="6"
- name="Keep"
- top_pad="5"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Discard"
- layout="topleft"
- left_pad="5"
- name="Discard"
- top_delta="0"
- width="110" />
- <button
- follows="right|bottom"
- height="22"
- label="Save As"
- layout="topleft"
- left_pad="5"
- name="save_tex_btn"
- top_delta="0"
- width="110" />
+ <layout_stack
+ animate="false"
+ name="preview_stack"
+ top_pad="15"
+ left="0"
+ follows="all"
+ orientation="vertical"
+ height="350"
+ width="370"
+ layout="topleft">
+ <layout_panel
+ name="texture_panel"
+ height="305"
+ top_pad="0"
+ left="0"
+ follows="left|top"
+ layout="topleft">
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left="10"
+ name="desc txt"
+ top="6"
+ width="90">
+ Description:
+ </text>
+ <line_editor
+ border_style="line"
+ border_thickness="1"
+ follows="left|top|right"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ left_pad="0"
+ max_length_bytes="127"
+ name="desc"
+ width="190" />
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left="110"
+ name="dimensions"
+ bottom="-40"
+ width="200">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text
+ type="string"
+ halign="right"
+ length="1"
+ follows="right|bottom"
+ height="16"
+ layout="topleft"
+ left_delta="-110"
+ name="aspect_ratio"
+ top_pad="5"
+ width="200">
+ Preview aspect ratio
+ </text>
+ <combo_box
+ allow_text_entry="true"
+ top_delta="-3"
+ follows="right|bottom"
+ height="23"
+ left_pad="10"
+ max_chars="20"
+ mouse_opaque="true"
+ enabled="true"
+ width="108"
+ name="combo_aspect_ratio"
+ tool_tip="Preview at a fixed aspect ratio">
+ </combo_box>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="45"
+ bottom="-40"
+ left="0"
+ follows="right|bottom"
+ auto_resize="false"
+ layout="topleft">
+ <button
+ follows="right|bottom"
+ height="22"
+ label="OK"
+ layout="topleft"
+ left="6"
+ name="Keep"
+ top_pad="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Discard"
+ layout="topleft"
+ left_pad="5"
+ name="Discard"
+ top_delta="0"
+ width="110" />
+ <button
+ follows="right|bottom"
+ height="22"
+ label="Save As"
+ layout="topleft"
+ left_pad="5"
+ name="save_tex_btn"
+ top_delta="0"
+ width="110" />
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile.xml b/indra/newview/skins/default/xui/en/floater_profile.xml
new file mode 100644
index 0000000000..32ab811a6e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater
+ name="avatarinfo"
+ height="510"
+ width="510"
+ layout="topleft"
+ can_close="true"
+ can_resize="true"
+ help_topic="panel_my_profile_tab"
+ min_height="510"
+ min_width="510"
+ positioning="centered"
+ save_rect="true"
+ title="Profile"
+>
+ <panel
+ name="panel_profile_view"
+ top="0"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ class="panel_profile"
+ >
+ <tab_container
+ name="panel_profile_tabs"
+ top_pad="5"
+ left="0"
+ height="500"
+ width="505"
+ follows="all"
+ layout="topleft"
+ halign="center"
+ tab_min_width="81"
+ tab_height="30"
+ tab_position="top"
+ >
+ <panel
+ name="panel_profile_secondlife"
+ label="BIO"
+ layout="topleft"
+ class="panel_profile_secondlife"
+ filename="panel_profile_secondlife.xml"
+ help_topic="profile_secondlife_tab"
+ />
+ <panel
+ name="panel_profile_web"
+ label="FEED"
+ layout="topleft"
+ class="panel_profile_web"
+ filename="panel_profile_web.xml"
+ help_topic="profile_web_tab"
+ />
+ <panel
+ name="panel_profile_picks"
+ label="PICKS"
+ layout="topleft"
+ class="panel_profile_picks"
+ filename="panel_profile_picks.xml"
+ help_topic="profile_picks_tab"
+ />
+ <panel
+ name="panel_profile_classifieds"
+ label="CLASSIFIEDS"
+ layout="topleft"
+ class="panel_profile_classifieds"
+ filename="panel_profile_classifieds.xml"
+ help_topic="profile_classified_tab"
+ />
+ <panel
+ name="panel_profile_firstlife"
+ label="REAL LIFE"
+ layout="topleft"
+ class="panel_profile_firstlife"
+ filename="panel_profile_firstlife.xml"
+ help_topic="profile_firstlife_tab"
+ />
+ <panel
+ name="panel_profile_notes"
+ label="MY NOTES"
+ layout="topleft"
+ class="panel_profile_notes"
+ filename="panel_profile_notes.xml"
+ help_topic="profile_notes_tab"
+ />
+ </tab_container>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_permissions.xml b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
new file mode 100644
index 0000000000..9f3b4d9a00
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_permissions.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ height="115"
+ layout="topleft"
+ name="profile_permissions"
+ width="300">
+ <string
+ name="description_string"
+ value="Allow [AGENT_NAME] to:" />
+ <text
+ name="perm_description"
+ value="Allow agent to:"
+ top="1"
+ left="12"
+ right="-6"
+ height="16"
+ follows="top|left"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <check_box
+ name="online_check"
+ label="See when I am online"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="map_check"
+ label="Find me on the world map"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <check_box
+ name="objects_check"
+ label="Edit, delete or take my objects from my land"
+ top_pad="5"
+ left="16"
+ height="16"
+ width="293"
+ follows="top|left"
+ layout="topleft"
+ />
+ <button
+ name="perms_btn_ok"
+ label="OK"
+ top_pad="5"
+ left="42"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="perms_btn_cancel"
+ label="Cancel"
+ top_delta="0"
+ left_pad="12"
+ height="20"
+ width="100"
+ follows="top|left"
+ layout="topleft"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_profile_texture.xml b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
new file mode 100644
index 0000000000..3b351a3325
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_profile_texture.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ height="223"
+ width="200"
+ layout="topleft"
+ min_height="128"
+ min_width="128"
+ name="profile_texture">
+ <layout_stack
+ name="preview_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="vertical"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ name="texture_panel"
+ height="196"
+ follows="left|top"
+ auto_resize="true"
+ layout="topleft">
+ <icon
+ name="profile_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ top="5"
+ left="5"
+ bottom="-1"
+ right="-5"/>
+ </layout_panel>
+ <layout_panel
+ name="buttons_panel"
+ height="26"
+ auto_resize="false"
+ layout="topleft">
+ <layout_stack
+ name="buttons_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ orientation="horizontal"
+ layout="topleft"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="close_panel"
+ auto_resize="false"
+ width="112">
+ <button
+ follows="top|left"
+ height="22"
+ label="Close"
+ layout="topleft"
+ left="1"
+ top="0"
+ width="110"
+ name="close_btn"/>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index d07e3cb31b..343e72f057 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -11,6 +11,11 @@
name="Screenshot">
Screenshot
</floater.string>
+ <floater.string
+ name="chat_report_format">
+Time: [MSG_TIME]
+Text: [MSG_DESCRIPTION]
+ </floater.string>
<texture_picker
allow_no_texture="true"
default_image_name="None"
@@ -19,7 +24,7 @@
layout="topleft"
left="60"
name="screenshot"
- top="15"
+ top="20"
width="220" />
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 0abee2ff80..ade79b8884 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
<floater
positioning="cascading"
legacy_header_height="18"
- height="600"
+ height="609"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
@@ -68,7 +68,7 @@
</floater.string>
<floater.string
name="status_selectcount">
- [OBJ_COUNT] objects selected, land impact [LAND_IMPACT]
+ [OBJ_COUNT] objects selected, land impact [LAND_IMPACT] [secondlife:///app/openfloater/object_weights More info]
</floater.string>
<floater.string
name="status_remaining_capacity">
@@ -763,11 +763,12 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="selection_count"
+ name="selection_faces"
top_delta="0"
visible="false"
width="280">
- </text>
+ Faces selected: [FACES_STRING]
+ </text>
<text
text_color="LtGray_50"
type="string"
@@ -777,11 +778,10 @@
font="SansSerifSmall"
layout="topleft"
left="10"
- name="remaining_capacity"
+ name="selection_count"
top_pad="0"
visible="false"
width="280">
- [CAPACITY_STRING] [secondlife:///app/openfloater/object_weights More info]
</text>
<!-- <text -->
<!-- text_color="LtGray_50" -->
@@ -820,7 +820,7 @@
width="282"/>
<tab_container
follows="left|top"
- height="410"
+ height="426"
halign="center"
left="0"
name="Object Info Tabs"
@@ -1430,16 +1430,40 @@ even though the user gets a free copy.
tool_tip="Causes object to not collide with other objects or avatars"
top_pad="0"
width="123" />
- <text
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left_delta="0"
+ name="object_horizontal"
+ top_pad="10"
+ width="95" />
+ <menu_button
+ menu_filename="menu_copy_paste_pos.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_pos_btn"
+ tool_tip="Paste options"
+ width="19"/>
+ <text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
name="label position"
- top_pad="10"
+ tool_tip="Position (meters)"
+ left_pad="8"
+ top_delta="0"
width="121">
- Position (meters)
+ Position (m)
</text>
<spinner
follows="left|top"
@@ -1449,12 +1473,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="512"
min_val="-256"
name="Pos X"
text_enabled_color="1 0 0.3 .7"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
follows="left|top"
@@ -1481,21 +1505,36 @@ even though the user gets a free copy.
layout="topleft"
left_delta="0"
max_val="4096"
+ min_val="-32"
name="Pos Z"
text_enabled_color="0 0.8 1 .65"
top_pad="3"
width="87" />
+ <menu_button
+ menu_filename="menu_copy_paste_size.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_size_btn"
+ tool_tip="Paste options"
+ width="19"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left_pad="8"
+ top_delta="0"
name="label size"
- top_pad="6"
+ tool_tip="Size (meters)"
width="121">
- Size (meters)
+ Size (m)
</text>
<spinner
follows="left|top"
@@ -1505,12 +1544,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="64"
min_val="0.01"
name="Scale X"
text_enabled_color="1 1 1 1"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
follows="left|top"
@@ -1542,17 +1581,31 @@ even though the user gets a free copy.
text_enabled_color="1 1 1 1"
top_pad="3"
width="87" />
+ <menu_button
+ menu_filename="menu_copy_paste_rot.xml"
+ follows="top|left"
+ height="11"
+ image_disabled="ClipboardSmallMenu_Disabled"
+ image_selected="ClipboardSmallMenu_Press"
+ image_unselected="ClipboardSmallMenu_Off"
+ layout="topleft"
+ left_delta="0"
+ top_pad="13"
+ name="clipboard_rot_btn"
+ tool_tip="Paste options"
+ width="19"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left_pad="8"
+ top_delta="0"
name="label rotation"
- top_pad="10"
+ tool_tip="Rotation (degrees)"
width="121">
- Rotation (degrees)
+ Rotation (°)
</text>
<spinner
decimal_digits="2"
@@ -1563,12 +1616,12 @@ even though the user gets a free copy.
label="X"
label_width="10"
layout="topleft"
- left_delta="0"
+ left_delta="-27"
max_val="9999"
min_val="-9999"
name="Rot X"
text_enabled_color="1 1 1 1"
- top_pad="5"
+ top_pad="8"
width="87" />
<spinner
decimal_digits="2"
@@ -1614,13 +1667,23 @@ even though the user gets a free copy.
width="150">
Prim Type
</text>-->
+
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ layout="topleft"
+ name="object_vertical"
+ left="117"
+ top="6"
+ height="500"
+ width="0"/>
<combo_box
height="19"
layout="topleft"
name="comboBaseType"
top="6"
left="125"
- width="150">
+ width="125">
<combo_box.item
label="Box"
name="Box"
@@ -1654,13 +1717,26 @@ even though the user gets a free copy.
name="Sculpted"
value="Sculpted" />
</combo_box>
+ <menu_button
+ menu_filename="menu_copy_paste_object.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left_pad="8"
+ top_delta="2"
+ name="clipboard_obj_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
- left_delta="0"
+ left="125"
name="text cut"
top_pad="5"
width="150">
@@ -1700,7 +1776,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text hollow"
- top_pad="6"
+ top_pad="7"
width="68">
Hollow
</text>
@@ -1748,7 +1824,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="Hollow Shape"
- top_pad="4"
+ top_pad="7"
width="150">
Hollow Shape
</text>
@@ -1784,7 +1860,7 @@ even though the user gets a free copy.
layout="topleft"
left_delta="0"
name="text twist"
- top_pad="5"
+ top_pad="7"
width="150">
Twist (begin/end)
</text>
@@ -1826,12 +1902,12 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="scale_taper"
- top_pad="3"
+ top_pad="7"
width="150">
Taper
</text>
<text
- visible="false"
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1879,7 +1955,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text topshear"
- top_pad="3"
+ top_pad="5"
width="141">
Top Shear
</text>
@@ -1922,12 +1998,12 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="advanced_cut"
- top_pad="3"
+ top_pad="7"
width="150">
Profile Cut (begin/end)
</text>
<text
- visible="false"
+ visible="false"
type="string"
length="1"
follows="left|top"
@@ -1986,7 +2062,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text taper2"
- top_pad="3"
+ top_pad="7"
width="150">
Taper
</text>
@@ -2029,7 +2105,7 @@ even though the user gets a free copy.
layout="topleft"
left="125"
name="text radius delta"
- top_pad="2"
+ top_pad="7"
width="78">
Radius
</text>
@@ -2157,6 +2233,19 @@ even though the user gets a free copy.
<panel.string name="None">None</panel.string>
<panel.string name="Prim">Prim</panel.string>
<panel.string name="Convex Hull">Convex Hull</panel.string>
+ <menu_button
+ menu_filename="menu_copy_paste_features.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top="8"
+ name="clipboard_features_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
@@ -2309,6 +2398,15 @@ even though the user gets a free copy.
name="FlexForceZ"
top_pad="4"
width="128" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="8"
+ name="object_horizontal"
+ top_pad="10"
+ width="278" />
<check_box
height="16"
@@ -2317,7 +2415,7 @@ even though the user gets a free copy.
left="10"
name="Light Checkbox Ctrl"
tool_tip="Causes object to emit light"
- top_pad="15"
+ top_pad="8"
width="60" />
<color_swatch
can_apply_immediately="true"
@@ -2344,6 +2442,19 @@ even though the user gets a free copy.
name="light texture control"
tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"
width="32" />
+ <menu_button
+ menu_filename="menu_copy_paste_light.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top_delta="0"
+ name="clipboard_light_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<spinner
follows="left|top"
height="19"
@@ -2353,7 +2464,7 @@ even though the user gets a free copy.
layout="topleft"
left="10"
name="Light Intensity"
- top_pad="3"
+ top_pad="26"
width="128" />
<spinner bottom_delta="0"
decimal_digits="3"
@@ -2575,7 +2686,7 @@ even though the user gets a free copy.
border_visible="true"
bevel_style="in"
follows="left|top|right"
- height="325"
+ height="335"
layout="topleft"
left="10"
name="contents_inventory"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 83407069d2..c965a4427c 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -14,6 +14,31 @@
single_instance="true"
title="WORLD MAP"
width="650">
+ <string
+ name="collapse_icon"
+ value="map_ui_collapse_icon.png"/>
+ <string
+ name="expand_icon"
+ value="map_ui_expand_icon.png"/>
+ <string
+ name="collapse_tooltip"
+ value="Hide map controls"/>
+ <string
+ name="expand_tooltip"
+ value="Show map controls"/>
+ <layout_stack
+ animate="false"
+ follows="all"
+ name="floater_map_stack"
+ tab_group="1"
+ top="16"
+ left="0"
+ right="-1"
+ bottom="-1">
+ <layout_panel
+ name="map_lp"
+ width="385"
+ height="575">
<panel
filename="panel_world_map.xml"
follows="all"
@@ -21,17 +46,48 @@
layout="topleft"
left="10"
name="objects_mapview"
- top="25"
+ top="6"
width="375" />
+ <panel
+ follows="top|right"
+ height="30"
+ layout="topleft"
+ left_pad="-29"
+ name="expand_btn_panel"
+ background_visible="true"
+ bg_opaque_color="FloaterFocusBackgroundColor"
+ bg_alpha_color="FloaterDefaultBackgroundColor"
+ background_opaque="true"
+ tool_tip="Hide map controls"
+ top="350"
+ width="30">
+ <icon
+ follows="top|right"
+ height="16"
+ width="16"
+ top="7"
+ left="7"
+ scale_image="false"
+ image_name="map_ui_collapse_icon.png"
+ layout="topleft"
+ mouse_opaque="true"
+ name="expand_collapse_icon"
+ tool_tip="Hide map controls" />
+ </panel>
+ </layout_panel>
+ <layout_panel
+ height="575"
+ width="265"
+ expanded_min_dim="265"
+ name="controls_lp">
<panel
- name="layout_panel_1"
- height="22"
- width="238"
- follows="right|top"
- top="25"
- left_pad="5"
- background_visible="true"
- bg_alpha_color="DkGray2">
+ name="layout_panel_1"
+ height="22"
+ width="238"
+ follows="right|top"
+ top="6"
+ background_visible="true"
+ bg_alpha_color="DkGray2">
<text
text_color="White"
font="SansSerifLarge"
@@ -43,17 +99,17 @@
layout="topleft"
left="15"
name="events_label"
- top="3"
width="215">
Legend
</text>
</panel>
-<panel
- follows="right|top"
- height="126"
- top_pad="0"
- width="238"
- name="layout_panel_2">
+ <panel
+ follows="right|top"
+ height="126"
+ top_pad="4"
+ width="238"
+ left="1"
+ name="layout_panel_2">
<button
follows="right|top"
height="22"
@@ -677,6 +733,7 @@
name="zoom_icon"
top_pad="7"
width="16" ></icon>
+ <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons -->
<slider
follows="left|bottom"
height="16"
@@ -684,10 +741,12 @@
initial_value="-2"
left_pad="0"
layout="topleft"
- max_val="0"
+ max_val="4"
min_val="-8"
name="zoom slider"
show_text="false"
width="200" />
</panel>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index ef4f19cd4c..fceb9b2184 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -85,6 +85,8 @@
use_ellipses="true" />
<text
follows="left|top|right"
+ trusted_content="false"
+ always_show_icons="true"
height="35"
left="8"
name="user_details"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 26b1c86c53..3b91b9df7a 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -33,6 +33,13 @@
function="Object.EnableTouch"
name="EnableTouch"/>
</menu_item_call>
+ <menu_item_call
+ label="Show in inventory"
+ layout="topleft"
+ name="Show original">
+ <menu_item_call.on_click
+ function="Object.ShowOriginal" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
index 05ab4d35a0..9f394a4c74 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -96,6 +96,13 @@
name="Pay">
<on_click function="AvatarIcon.Action" parameter="pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="AvatarIcon.Action" parameter="report_abuse" />
+ <on_enable function="AvatarIcon.Enable" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index 500b6fffc2..20f3ad080b 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -290,4 +290,11 @@
<menu_item_call.on_visible
function="EnableMuteParticle" />
</menu_item_call>
+ <menu_item_separator/>
+ <menu_item_call label="View Profile"
+ layout="topleft"
+ name="show_avatar_profile">
+ <menu_item_call.on_click
+ function="Avatar.ToggleMyProfile" />
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index ed362b36e5..59e6106a28 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -132,6 +132,13 @@
<on_click function="Avatar.DoToSelected" parameter="pay" />
<on_enable function="Avatar.EnableItem" parameter="can_pay" />
</menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <on_click function="Avatar.DoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml
new file mode 100644
index 0000000000..4c12180daf
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Color Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="color_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="color_paste" />
+ <on_enable function="PanelFace.menuEnable" parameter="color_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml
new file mode 100644
index 0000000000..4823d74a26
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Features Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="features_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="features_paste" />
+ <on_enable function="PanelVolume.menuEnable" parameter="features_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml
new file mode 100644
index 0000000000..5de23dfee3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Light Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="light_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelVolume.menuDoToSelected" parameter="light_paste" />
+ <on_enable function="PanelVolume.menuEnable" parameter="light_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml
new file mode 100644
index 0000000000..bdc4537a9d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_object.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Object Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="params_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="params_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
new file mode 100644
index 0000000000..3ea95b281f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Position Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy position"
+ layout="topleft"
+ name="pos_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste position"
+ layout="topleft"
+ name="pos_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="pos_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="pos_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
new file mode 100644
index 0000000000..06ce80f897
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Rotation Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy rotation"
+ layout="topleft"
+ name="rot_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste rotation"
+ layout="topleft"
+ name="rot_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="rot_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="rot_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
new file mode 100644
index 0000000000..7082a0e65b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Size Menu">
+ <menu_item_call
+ label="Copy all"
+ layout="topleft"
+ name="psr_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_copy" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy size"
+ layout="topleft"
+ name="size_copy"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste all"
+ layout="topleft"
+ name="psr_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="psr_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="psr_paste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste size"
+ layout="topleft"
+ name="size_paste"
+ visible="true">
+ <on_click function="PanelObject.menuDoToSelected" parameter="size_paste" />
+ <on_enable function="PanelObject.menuEnable" parameter="size_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml
new file mode 100644
index 0000000000..f358affc23
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Copy Paste Texture Menu">
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="params_copy"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="texture_copy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="params_paste"
+ visible="true">
+ <on_click function="PanelFace.menuDoToSelected" parameter="texture_paste" />
+ <on_enable function="PanelFace.menuEnable" parameter="texture_paste" />
+ </menu_item_call>
+</toggleable_menu>
+
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 5cae643e44..359c093eff 100644
--- a/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_gesture_gear.xml
@@ -9,7 +9,7 @@
layout="topleft"
name="activate">
<on_click
- function="Gesture.Action.ToogleActiveState" />
+ function="Gesture.Action.ToggleActiveState" />
</menu_item_call>
<menu_item_call
label="Rename"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
index 43287c6ec3..b38fae4404 100644
--- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -79,6 +79,13 @@
</menu_item_call>
<menu_item_separator
layout="topleft"/>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" />
+ <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" />
+ </menu_item_call>
<menu_item_check
label="Block Voice"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 78ca170813..aa3d0ae071 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -912,6 +912,25 @@
function="Inventory.DoToSelected"
parameter="apply_settings_parcel" />
</menu_item_call>
+ <menu_item_separator
+ layout="topleft"
+ name="Subfolder Separator" />
+ <menu_item_call
+ label="Create folder from selected"
+ layout="topleft"
+ name="New folder from selected">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="new_folder_from_selected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Ungroup folder items"
+ layout="topleft"
+ name="Ungroup folder items">
+ <menu_item_call.on_click
+ function="Inventory.DoToSelected"
+ parameter="ungroup_folder_items" />
+ </menu_item_call>
<menu_item_separator
layout="topleft"
name="Marketplace Separator" />
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index ea263d05ce..2715c916d4 100644
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -8,63 +8,109 @@
top="724"
visible="false"
width="128">
- <menu_item_call
- label="Zoom Close"
- name="Zoom Close">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check
+ label="Zoom very close"
+ name="Zoom very close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
+ parameter="very close" />
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="very close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom close"
+ name="Zoom close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="close" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Medium"
- name="Zoom Medium">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom medium"
+ name="Zoom medium">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="medium" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Far"
- name="Zoom Far">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="medium" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom far"
+ name="Zoom far">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="far" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- name="Zoom Default">
- <menu_item_call.on_click
- function="Minimap.Zoom"
- parameter="default" />
- </menu_item_call>
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="far" />
+ </menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Rotate Map"
- name="Rotate Map">
+ label="North at top"
+ name="North at top">
<menu_item_check.on_check
- control="MiniMapRotate" />
+ function="Minimap.MapOrientation.Check"
+ parameter="north_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapRotate" />
+ function="Minimap.MapOrientation.Set"
+ parameter="north_at_top" />
</menu_item_check>
<menu_item_check
- label="Auto Center"
- name="Auto Center">
+ label="Camera at top"
+ name="Camera at top">
<menu_item_check.on_check
- control="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Check"
+ parameter="camera_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Set"
+ parameter="camera_at_top" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Show parcel boundaries"
+ name="Show parcel boundaries">
+ <menu_item_check.on_check
+ control="MiniMapShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapShowPropertyLines" />
</menu_item_check>
<menu_item_separator />
+ <menu_item_check
+ label="Auto-center map"
+ name="Auto-center map">
+ <menu_item_check.on_check
+ control="MiniMapAutoCenter" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapAutoCenter" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="Re-center map"
+ name="Re-center map">
+ <menu_item_call.on_click
+ function="Minimap.Center.Activate" />
+ </menu_item_call>
<menu_item_call
- label="Stop Tracking"
- name="Stop Tracking">
+ label="Stop tracking"
+ name="Stop tracking">
<menu_item_call.on_click
function="Minimap.Tracker"
parameter="task_properties" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
+ label="About Land"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Minimap.AboutLand" />
+ </menu_item_call>
+ <menu_item_call
label="World Map"
name="World Map">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_profile_other.xml b/indra/newview/skins/default/xui/en/menu_profile_other.xml
new file mode 100644
index 0000000000..4db4d0922b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_other.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu">
+ <menu_item_call
+ label="IM"
+ layout="topleft"
+ name="im">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="im"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Offer Teleport"
+ name="offer_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="offer_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="offer_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Request Teleport"
+ name="request_teleport">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="request_teleport"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="request_teleport"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Voice call"
+ layout="topleft"
+ name="voice_call">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="voice_call"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="voice_call"/>
+ </menu_item_call>
+ <menu_item_separator />
+ <menu_item_call
+ label="View chat history..."
+ layout="topleft"
+ name="chat_history">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="chat_history"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="chat_history"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_chat_history"/>
+ <menu_item_call
+ label="Add Friend"
+ layout="topleft"
+ name="add_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="add_friend"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="add_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Friend"
+ layout="topleft"
+ name="remove_friend">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_friend"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_friend"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Invite to group..."
+ layout="topleft"
+ name="invite_to_group">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="invite_to_group"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_invite_to_group"/>
+ <menu_item_call
+ label="Permissions"
+ layout="topleft"
+ name="agent_permissions">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="agent_permissions"/>
+ <menu_item_call.on_visible
+ function="Profile.EnableItem"
+ parameter="agent_permissions"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Map"
+ layout="topleft"
+ name="map">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="can_show_on_map"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="can_show_on_map"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Share"
+ layout="topleft"
+ name="share">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="share"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Pay"
+ layout="topleft"
+ name="pay">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="pay"/>
+ </menu_item_call>
+ <menu_item_check
+ label="Block/Unblock"
+ layout="topleft"
+ name="block_unblock">
+ <menu_item_check.on_click
+ function="Profile.Commit"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_check
+ function="Profile.CheckItem"
+ parameter="toggle_block_agent"/>
+ <menu_item_check.on_enable
+ function="Profile.EnableItem"
+ parameter="toggle_block_agent"/>
+ </menu_item_check>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_profile_self.xml b/indra/newview/skins/default/xui/en/menu_profile_self.xml
new file mode 100644
index 0000000000..d0bd4000f8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_profile_self.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Avatar Profile Menu Self">
+ <menu_item_call
+ label="Edit Display Name"
+ layout="topleft"
+ name="edit_display_name">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Partner"
+ layout="topleft"
+ name="edit_partner">
+ <on_click
+ function="Profile.Commit"
+ parameter="edit_partner"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Upload Photo"
+ layout="topleft"
+ name="upload_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="upload_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="upload_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Change Photo"
+ layout="topleft"
+ name="change_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="change_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="change_photo"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Remove Photo"
+ layout="topleft"
+ name="remove_photo">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="remove_photo"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="remove_photo"/>
+ </menu_item_call>
+ <menu_item_separator name="separator_copy_options"/>
+ <menu_item_call
+ label="Copy Display Name"
+ layout="topleft"
+ name="copy_display_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_display_name"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_display_name"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Name"
+ layout="topleft"
+ name="copy_name">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_username"/>
+ <menu_item_call.on_enable
+ function="Profile.EnableItem"
+ parameter="copy_username"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Copy Agent Id"
+ layout="topleft"
+ name="copy_id">
+ <menu_item_call.on_click
+ function="Profile.Commit"
+ parameter="copy_user_id"/>
+ </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index e8b6116026..5ca8be2123 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -29,7 +29,14 @@
name="remove_friend">
<menu_item_call.on_click
function="Url.RemoveFriend" />
- </menu_item_call>
+ </menu_item_call>
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="report_abuse">
+ <menu_item_call.on_click
+ function="Url.ReportAbuse" />
+ </menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1caa0908ea..58584345a9 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -47,8 +47,7 @@
label="Picks..."
name="Picks">
<menu_item_call.on_click
- function="Floater.ToggleOrBringToFront"
- parameter="picks" />
+ function="ShowAgentProfilePicks" />
</menu_item_call>
<menu_item_call
label="Experiences..."
@@ -423,7 +422,9 @@
</menu_item_call>
<menu_item_call
label="Stop animations"
- name="Stop Animating My Avatar">
+ name="Stop Animating My Avatar"
+ allow_key_repeat="true"
+ shortcut="alt|shift|A">
<menu_item_call.on_click
function="Tools.StopAllAnimations" />
</menu_item_call>
@@ -2647,6 +2648,12 @@ function="World.EnvPreset"
function="Advanced.ForceErrorBadMemoryAccess" />
</menu_item_call>
<menu_item_call
+ label="Force Bad Memory Access in Coroutine"
+ name="Force Bad Memory Access in Coroutine">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBadMemoryAccessCoro" />
+ </menu_item_call>
+ <menu_item_call
label="Force Infinite Loop"
name="Force Infinite Loop">
<menu_item_call.on_click
@@ -3326,6 +3333,18 @@ function="World.EnvPreset"
function="Advanced.DropPacket" />
</menu_item_call>
</menu>
+ <menu
+ create_jump_keys="true"
+ label="Cache"
+ name="Cache"
+ tear_off="true">
+ <menu_item_call
+ label="Purge Disk Cache"
+ name="Purge Disk Cache">
+ <menu_item_call.on_click
+ function="Advanced.PurgeDiskCache" />
+ </menu_item_call>
+ </menu>
<menu_item_call
label="Dump Scripted Camera"
name="Dump Scripted Camera">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index aa93601669..1ddec93668 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1496,7 +1496,19 @@ Insufficient funds to create classified.
<notification
icon="alertmodal.tga"
- name="DeleteAvatarPick"
+ name="ProfileDeleteClassified"
+ type="alertmodal">
+Delete classified &lt;nolink&gt;[CLASSIFIED]&lt;/nolink&gt;?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="ProfileDeletePick"
type="alertmodal">
Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
<tag>confirm</tag>
@@ -1507,6 +1519,32 @@ Delete pick &lt;nolink&gt;[PICK]&lt;/nolink&gt;?
</notification>
<notification
+ icon="alert.tga"
+ name="ProfileUnpublishedClassified"
+ type="alertmodal">
+ You have unpublished classifieds. They will be lost if you close the window.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="ProfileUnsavedChanges"
+ type="alertmodal">
+ You have usaved changes.
+ <tag>confirm</tag>
+ <tag>save</tag>
+ <usetemplate
+ canceltext="Cancel"
+ name="yesnocancelbuttons"
+ notext="Discard"
+ yestext="Save"/>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="DeleteOutfits"
type="alertmodal">
@@ -3907,7 +3945,7 @@ Are you sure you want to return objects owned by [USER_NAME]?
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
<tag>fail</tag>
</notification>
@@ -3918,7 +3956,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click
Couldn&apos;t set region textures:
Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y].
-Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click &quot;Apply&quot; again.
+Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click &quot;Apply&quot; again.
</notification>
<notification
@@ -9040,6 +9078,29 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran
<notification
icon="alertmodal.tga"
+ name="FacePasteFailed"
+ type="alertmodal">
+Paste failed. [REASON]
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FacePasteTexturePermissions"
+ type="alertmodal">
+ You applied a texture with limited permissions, object will inherit permissions from texture.
+ <usetemplate
+ ignoretext="Paste: You applied a texture with limited permissions"
+ name="notifyignore"/>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmLeaveCall"
type="alertmodal">
Are you sure you want to leave this call?
@@ -11640,7 +11701,7 @@ This Region does not support environmental settings.
<notification
icon="alertmodal.tga"
- label="Save Outfit"
+ label="Save Environmental Settings"
name="SaveSettingAs"
type="alertmodal">
<unique/>
@@ -11819,4 +11880,38 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB
</form>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ label="Create subfolder"
+ name="CreateSubfolder"
+ type="alertmodal">
+ <unique/>
+ Name the new folder:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+ <notification
+ icon="alertmodal.tga"
+ name="SameFolderRequired"
+ type="alert">
+ Selected items must be in the same folder.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index aa1b929412..54f038c24f 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -155,6 +155,7 @@
right="-3"
mouse_opaque="true"
name="speaking_indicator"
+ tool_tip="Voice volume"
visible="true"
width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index d4a2745d1d..04a0bc800d 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -38,28 +38,15 @@
name="auto_renew_off">
Disabled
</panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
<text
follows="top|left|right"
font="SansSerifHugeBold"
height="26"
layout="topleft"
- left_pad="4"
+ left="12"
name="title"
text_color="LtGray"
- top="0"
+ top="2"
value="Classified Info"
use_ellipses="true"
width="275" />
@@ -420,7 +407,7 @@
height="23"
label="Teleport"
layout="topleft"
- left="0"
+ left="2"
name="teleport_btn"
top="0"
width="101" />
@@ -443,24 +430,6 @@
top="0"
width="100" />
</layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top="0"
- width="101" />
- </layout_panel>
</layout_stack>
</panel>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
deleted file mode 100644
index e846edf1d4..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ /dev/null
@@ -1,354 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Classified"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_classified"
- help_topic="profile_edit_classified"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <string name="publish_label">
- Publish
- </string>
- <string name="save_label">
- Save
- </string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="0"
- width="250">
- Edit Classified
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="502"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- reserve_scroll_corner="false"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="690"
- left="0"
- width="285">
- <panel
- name="snapshot_panel"
- layout="topleft"
- follows="left|top|right"
- height="197"
- left="10"
- top="10"
- width="272">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- top="0"
- left="0"
- name="classified_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="0"
- left="0"
- width="272" />
- </panel>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="30"
- name="classified_name"
- prevalidate_callback="ascii"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="256"
- name="classified_desc"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="30"
- layout="topleft"
- left="10"
- name="classified_location"
- right="-10"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="10"
- top_pad="5"
- name="set_to_curr_location_btn"
- width="200" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="category_label"
- text_color="white"
- top_pad="15"
- value="Category:"
- width="250" />
- <combo_box
- follows="left|top"
- height="23"
- label=""
- left="10"
- name="category"
- top_pad="5"
- width="156" />
- <text
- follows="left|top"
- font.style="BOLD"
- height="10"
- layout="topleft"
- left="10"
- name="content_type_label"
- text_color="white"
- top_pad="15"
- value="Content type:"
- width="250" />
- <icons_combo_box
- follows="left|top"
- height="23"
- label="General Content"
- layout="topleft"
- left="10"
- name="content_type"
- top_pad="5"
- width="156">
- <icons_combo_box.drop_down_button
- image_overlay="Parcel_PG_Light"
- image_overlay_alignment="left"
- imgoverlay_label_space="3"
- pad_left="3"/>
- <icons_combo_box.item
- label="Moderate Content"
- name="mature_ci"
- value="Mature">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_M_Light"
- width="20"/>
- </icons_combo_box.item>
- <icons_combo_box.item
- label="General Content"
- name="pg_ci"
- value="PG">
- <item.columns
- halign="center"
- type="icon"
- value="Parcel_PG_Light"
- width="20"/>
- </icons_combo_box.item>
- </icons_combo_box>
- <check_box
- height="16"
- label="Auto renew each week"
- layout="topleft"
- left="10"
- name="auto_renew"
- top_pad="15"
- width="250" />
- <text
- follows="left|top"
- height="10"
- layout="topleft"
- left="10"
- name="price_for_listing_label"
- text_color="white"
- top_pad="15"
- value="Price for listing:"
- width="250" />
- <spinner
- decimal_digits="0"
- follows="left|top"
- halign="left"
- height="23"
- increment="1"
- label_width="20"
- label="L$"
- v_pad="10"
- layout="topleft"
- left="10"
- value="50"
- min_val="50"
- max_val="99999"
- name="price_for_listing"
- top_pad="5"
- tool_tip="Price for listing."
- width="105" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="303">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="bottom_panel_ls"
- left="1"
- orientation="horizontal"
- top_pad="0"
- width="309">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="save_changes_btn_lp"
- auto_resize="true"
- width="156">
- <button
- follows="bottom|left|right"
- height="23"
- label="[LABEL]"
- layout="topleft"
- name="save_changes_btn"
- left="1"
- top="0"
- width="155" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="157">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- left="1"
- top="0"
- width="156" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
deleted file mode 100644
index 357a5559bf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- bevel_style="in"
- follows="left|top|right|bottom"
- height="569"
- label="Edit Pick"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_edit_pick"
- help_topic="profile_edit_pick"
- top="0"
- width="333">
- <panel.string
- name="location_notice">
- (will update after save)
- </panel.string>
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="4"
- width="30"
- use_draw_context_alpha="false" />
- <text
- type="string"
- length="1"
- follows="top"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="4"
- width="250">
- Edit Pick
- </text>
- <scroll_container
- color="DkGray2"
- follows="all"
- height="501"
- layout="topleft"
- left="8"
- top_pad="9"
- name="profile_scroll"
- opaque="true"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="500"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- follows="left|top|right"
- height="197"
- width="272"
- layout="topleft"
- no_commit_on_selection="true"
- top="10"
- left="11"
- name="pick_snapshot" />
- <icon
- height="197"
- image_name="spacer24.tga"
- layout="topleft"
- name="edit_icon"
- label=""
- tool_tip="Click to select an image"
- top="10"
- left="11"
- width="286" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top="215"
- name="Name:"
- text_color="white"
- width="280">
- Title:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerif"
- height="20"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length_bytes="63"
- name="pick_name"
- text_color="black"
- width="273" />
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="15"
- font="SansSerifSmall"
- font.style="BOLD"
- layout="topleft"
- left="10"
- top_pad="20"
- name="description_label"
- text_color="white"
- width="280">
- Description:
- </text>
- <text_editor
- follows="left|top|right"
- height="100"
- width="273"
- hide_scrollbar="false"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- spellcheck="true"
- text_color="black"
- word_wrap="true" />
- <text
- type="string"
- length="1"
- font="SansSerifSmall"
- font.style="BOLD"
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="location_label"
- text_color="white"
- top_pad="20"
- width="280">
- Location:
- </text>
- <text
- type="string"
- length="1"
- follows="left|top|right"
- height="50"
- layout="topleft"
- left="10"
- name="pick_location"
- top_pad="2"
- width="280"
- word_wrap="true">
- loading...
- </text>
- <button
- follows="left|top"
- height="23"
- label="Set to Current Location"
- layout="topleft"
- left="8"
- top_pad="0"
- name="set_to_curr_location_btn"
- width="200" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- label="bottom_panel"
- layout="topleft"
- left="8"
- name="bottom_panel"
- top_pad="5"
- width="315">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="150">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Pick"
- layout="topleft"
- name="save_changes_btn"
- top="0"
- left="1"
- width="149" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- left_pad="4"
- name="layout_panel2"
- auto_resize="true"
- width="146">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- name="cancel_btn"
- top="0"
- left="1"
- width="145" />
- </layout_panel>
- </layout_stack>
-
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml
deleted file mode 100644
index 2c7c8133d1..0000000000
--- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml
+++ /dev/null
@@ -1,472 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- class="edit_profile_panel"
- follows="all"
- height="585"
- label="Profile Edit"
- layout="topleft"
- left="0"
- name="edit_profile_panel"
- top="0"
- width="313">
- <string
- name="CaptionTextAcctInfo">
- [ACCTTYPE]
-[PAYMENTINFO] [AGEVERIFICATION]
- </string>
- <string
- name="RegisterDateFormat">
- [REG_DATE] ([AGE])
- </string>
- <string
- name="AcctTypeResident"
- value="Resident" />
- <string
- name="AcctTypeTrial"
- value="Trial" />
- <string
- name="AcctTypeCharterMember"
- value="Charter Member" />
- <string
- name="AcctTypeEmployee"
- value="Linden Lab Employee" />
- <string
- name="PaymentInfoUsed"
- value="Payment Info Used" />
- <string
- name="PaymentInfoOnFile"
- value="Payment Info On File" />
- <string
- name="NoPaymentInfoOnFile"
- value="No Payment Info On File" />
- <string
- name="AgeVerified"
- value="Age-verified" />
- <string
- name="NotAgeVerified"
- value="Not Age-verified" />
- <string
- name="partner_edit_link_url">
- http://www.secondlife.com/account/partners.php?lang=en
- </string>
- <string
- name="my_account_link_url">
- http://secondlife.com/my
- </string>
- <string
- name="no_partner_text"
- value="None" />
- <scroll_container
- color="DkGray2"
- follows="all"
- height="537"
- min_height="300"
- layout="topleft"
- left="8"
- width="292"
- name="profile_scroll"
- reserve_scroll_corner="true"
- opaque="true"
- top="10">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <panel
- name="data_panel"
- follows="left|top|right"
- layout="topleft"
- top="0"
- height="537"
- min_height="300"
- left="0"
- width="292">
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="display_name_label"
- text_color="LtGray"
- value="Display Name:"
- width="80" />
- <text
- top="5"
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="solo_username_label"
- text_color="LtGray"
- value="Username:"
- visible="false"
- width="80" />
- <button
- name="set_name"
- layout="topleft"
- follows="top|left"
- image_overlay="Edit_Wrench"
- top="21"
- left="10"
- height="23"
- width="23"
- tool_tip="Set Display Name"/>
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="10"
- name="solo_user_name"
- text_color="white"
- top_delta="3"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- width="275" />
- <text
- follows="top|left"
- font="SansSerifBigBold"
- height="20"
- layout="topleft"
- left="43"
- name="user_name"
- text_color="white"
- top_delta="0"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="true"
- width="250" />
- <text
- follows="top|left"
- font="SansSerifBold"
- height="20"
- layout="topleft"
- left_delta="0"
- name="user_name_small"
- text_color="white"
- top_delta="-4"
- translate="false"
- value="TestString PleaseIgnore"
- use_ellipses="true"
- visible="false"
- wrap="true"
- width="245" />
- <text
- follows="top|left"
- height="13"
- layout="topleft"
- left="10"
- name="user_label"
- text_color="LtGray"
- top_pad="8"
- value="Username:"
- width="70" />
- <text
- follows="top|left"
- height="20"
- layout="topleft"
- left_pad="0"
- name="user_slid"
- text_color="EmphasisColor"
- font="SansSerifBold"
- top_delta="-2"
- translate="false"
- use_ellipses="true"
- value="teststring.pleaseignore"
- wrap="true"
- width="205" />
- <panel
- name="lifes_images_panel"
- follows="left|top|right"
- height="244"
- layout="topleft"
- top="65"
- left="0"
- width="292">
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- left="10"
- name="second_life_image_panel"
- top="0"
- width="282">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top="10"
- name="second_life_photo_title_text"
- text_color="white"
- value="[SECOND_LIFE]:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="default_profile_picture.j2c"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="2nd_life_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="2nd_life_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- </panel>
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- top="90"
- max_length="512"
- name="sl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <panel
- follows="left|top"
- height="117"
- layout="topleft"
- top_pad="5"
- left="10"
- name="first_life_image_panel"
- width="285">
- <text
- follows="left|top|right"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="0"
- top_pad="10"
- name="real_world_photo_title_text"
- text_color="white"
- value="Real World:"
- width="100" />
- <texture_picker
- allow_no_texture="true"
- default_image_name="None"
- enabled="false"
- fallback_image="Generic_Person_Large"
- follows="top|left"
- height="124"
- layout="topleft"
- left="1"
- name="real_world_pic"
- top_pad="0"
- width="102" />
- </panel>
- <icon
- height="102"
- image_name="spacer24.tga"
- layout="topleft"
- name="real_world_edit_icon"
- label=""
- left="11"
- top_pad="-92"
- tool_tip="Click to select an image"
- width="102" />
- <text_editor
- type="string"
- length="1"
- follows="left|top|right"
- font="SansSerifSmall"
- height="102"
- layout="topleft"
- left="123"
- max_length="512"
- top="223"
- name="fl_description_edit"
- width="157"
- word_wrap="true">
- </text_editor>
- <text
- type="string"
- length="1"
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_homepage_text"
- text_color="white"
- top_pad="10"
- width="100">
- Homepage:
- </text>
- <line_editor
- follows="left|top|right"
- font="SansSerifSmall"
- height="20"
- layout="topleft"
- left="10"
- top_pad="0"
- value="http://"
- name="homepage_edit"
- width="272">
- </line_editor>
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_acc_status_text"
- text_color="white"
- top_pad="10"
- value="My Account:"
- width="100" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="28"
- layout="topleft"
- left="10"
- name="acc_status_text"
- read_only="true"
- top_pad="5"
- v_pad="0"
- value="Resident. No payment info on file."
- width="200"
- word_wrap="true" />
- <text
- type="string"
- follows="left|top"
- font="SansSerifSmall"
- height="15"
- layout="topleft"
- left="10"
- name="my_account_link"
- value="[[URL] Go to My Dashboard]"
- width="200" />
- <text
- follows="left|top"
- font="SansSerifSmall"
- font.style="BOLD"
- height="15"
- layout="topleft"
- left="10"
- name="title_partner_text"
- text_color="white"
- top_pad="10"
- value="My Partner:"
- width="150" />
- <panel
- follows="left|top|right"
- height="15"
- layout="topleft"
- left="10"
- name="partner_data_panel"
- width="200">
- <text
- follows="left|top|right"
- height="12"
- initial_value="(retrieving)"
- layout="topleft"
- left="0"
- name="partner_text"
- top="0"
- use_ellipses="true"
- width="280"/>
- </panel>
- <text
- follows="left|top"
- height="15"
- layout="topleft"
- link="true"
- left="10"
- name="partner_edit_link"
- value="[[URL] Edit]"
- width="70" />
- </panel>
- </panel>
- </scroll_container>
- <panel
- follows="bottom|left|right"
- height="28"
- left="0"
- name="profile_me_buttons_panel"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- name="bottom_panel_ls"
- left="7"
- orientation="horizontal"
- top_pad="0"
- width="295">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="save_changes_btn_lp"
- top="0"
- auto_resize="true"
- width="153">
- <button
- follows="bottom|left|right"
- height="23"
- label="Save Changes"
- layout="topleft"
- left="1"
- name="save_btn"
- top="0"
- width="152" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- top="0"
- auto_resize="true"
- width="154">
- <button
- follows="bottom|left|right"
- height="23"
- label="Cancel"
- layout="topleft"
- left="1"
- name="cancel_btn"
- top="0"
- width="153" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b72af7221e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="group_list_item"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+>
+ <icon
+ name="hovered_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Over"
+ visible="false"
+ />
+ <icon
+ name="selected_icon"
+ top="0"
+ left="0"
+ height="16"
+ width="320"
+ follows="top|right|left"
+ layout="topleft"
+ image_name="ListItem_Select"
+ visible="false"
+ />
+ <group_icon
+ name="group_icon"
+ top="2"
+ left="5"
+ height="14"
+ width="14"
+ image_name="Generic_Group"
+ mouse_opaque="true"
+ use_draw_context_alpha="false"
+ />
+ <text
+ name="group_name"
+ value="Unknown"
+ top="2"
+ left_pad="5"
+ right="-2"
+ height="16"
+ follows="left|right"
+ layout="topleft"
+ parse_urls="false"
+ text_color="ScrollUnselectedColor"
+ use_ellipses="true"
+ />
+ <button
+ name="visibility_hide_btn"
+ tool_tip="Hide group on my profile"
+ top_delta="-3"
+ left_pad="3"
+ right="-53"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_Off_Pressed"
+ image_unselected="Profile_Group_Visibility_Off"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="visibility_show_btn"
+ tool_tip="Show group on my profile"
+ top_delta="0"
+ right_delta="0"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Profile_Group_Visibility_On_Pressed"
+ image_unselected="Profile_Group_Visibility_On"
+ tab_stop="false"
+ visible="false"
+ />
+ <button
+ name="info_btn"
+ tool_tip="More info"
+ top_delta="2"
+ left_pad="3"
+ right="-30"
+ height="16"
+ width="16"
+ follows="right"
+ image_pressed="Info_Press"
+ image_unselected="Info_Over"
+ tab_stop="false"
+ />
+ <!--*TODO: Should only appear on rollover-->
+ <button
+ name="profile_btn"
+ tool_tip="View profile"
+ top_delta="-2"
+ left_pad="5"
+ right="-3"
+ height="20"
+ width="20"
+ follows="right"
+ layout="topleft"
+ image_overlay="Web_Profile_Off"
+ tab_stop="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_me.xml b/indra/newview/skins/default/xui/en/panel_me.xml
deleted file mode 100644
index 23e7814cad..0000000000
--- a/indra/newview/skins/default/xui/en/panel_me.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- border="false"
- follows="all"
- height="570"
- label="My Profile"
- layout="topleft"
- left="0"
- name="panel_me"
- top="0"
- width="333">
- <panel
- class="panel_picks"
- filename="panel_picks.xml"
- label="MY PICKS"
- help_topic="panel_my_picks_tab"
- name="panel_picks"/>
-</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
deleted file mode 100644
index 99c47eb825..0000000000
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- background_visible="true"
- follows="all"
- height="570"
- layout="topleft"
- left="0"
- min_height="350"
- name="panel_pick_info"
- help_topic="profile_pick_info"
- top="0"
- width="333">
- <button
- follows="top|left"
- height="24"
- image_hover_unselected="BackButton_Over"
- image_pressed="BackButton_Press"
- image_unselected="BackButton_Off"
- layout="topleft"
- name="back_btn"
- left="10"
- tab_stop="false"
- top="2"
- width="30"
- use_draw_context_alpha="false" />
- <text
- follows="top|left|right"
- font="SansSerifHugeBold"
- height="26"
- layout="topleft"
- left_pad="4"
- name="title"
- text_color="LtGray"
- top="2"
- value="Pick Info"
- use_ellipses="true"
- width="275" />
- <scroll_container
- color="DkGray2"
- opaque="true"
- follows="all"
- height="503"
- layout="topleft"
- left="8"
- top_pad="10"
- name="profile_scroll"
- width="312">
- <panel
- name="scroll_content_panel"
- follows="left|top|right"
- min_height="300"
- layout="topleft"
- top="0"
- background_visible="false"
- height="400"
- left="0"
- width="285">
- <texture_picker
- fallback_image="default_land_picture.j2c"
- enabled="false"
- follows="left|top|right"
- height="197"
- layout="topleft"
- left="11"
- name="pick_snapshot"
- top="10"
- width="272" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="35"
- width="280"
- layout="topleft"
- font="SansSerifBig"
- font.style="BOLD"
- left="10"
- top_pad="10"
- name="pick_name"
- read_only="true"
- text_color="white"
- v_pad="0"
- value="[name]"
- use_ellipses="true" />
- <text_editor
- allow_scroll="false"
- bg_visible="false"
- follows="left|top|right"
- h_pad="0"
- height="25"
- layout="topleft"
- left="10"
- name="pick_location"
- read_only="true"
- width="280"
- word_wrap="true"
- v_pad="0"
- value="[loading...]" />
- <text_editor
- bg_readonly_color="DkGray2"
- follows="all"
- height="100"
- width="280"
- parse_urls="true"
- layout="topleft"
- left="10"
- top_pad="2"
- max_length="1023"
- name="pick_desc"
- read_only="true"
- text_readonly_color="white"
- value="[description]"
- wrap="true" />
- </panel>
- </scroll_container>
- <panel
- follows="left|right|bottom"
- height="23"
- layout="topleft"
- top_pad="5"
- left="8"
- name="buttons">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="topleft"
- name="layout_stack1"
- left="0"
- orientation="horizontal"
- top_pad="0"
- width="312">
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left="0"
- name="layout_panel1"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- top="0"
- width="101" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="show_on_map_btn_lp"
- auto_resize="true"
- width="100">
- <button
- follows="bottom|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- top_pad="0"
- width="100" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- left_pad="3"
- name="edit_btn_lp"
- auto_resize="true"
- width="101">
- <button
- follows="bottom|left|right"
- height="23"
- label="Edit"
- layout="topleft"
- name="edit_btn"
- top_pad="0"
- width="101" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
deleted file mode 100644
index 8def96cada..0000000000
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ /dev/null
@@ -1,227 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- follows="all"
- height="571"
- label="Picks"
- layout="topleft"
- left="8"
- name="panel_picks"
- top_pad="0"
- width="313">
- <string
- name="no_picks"
- value="No Picks" />
- <string
- name="no_classifieds"
- value="No Classifieds" />
- <text
- type="string"
- follows="all"
- height="535"
- layout="topleft"
- left="6"
- name="picks_panel_text"
- wrap="true"
- top="10"
- width="313"/>
- <accordion
- fit_parent="true"
- follows="all"
- height="514"
- layout="topleft"
- left="0"
- name="accordion"
- top="0"
- single_expansion="true"
- width="313">
- <accordion_tab
- layout="topleft"
- height="235"
- min_height="150"
- name="tab_picks"
- title="Picks"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="picks_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- <accordion_tab
- layout="topleft"
- height="235"
- name="tab_classifieds"
- title="Classifieds"
- visible="false">
- <flat_list_view
- color="DkGray2"
- follows="all"
- layout="topleft"
- left="0"
- name="classifieds_list"
- opaque="true"
- top="0"
- width="313" />
- </accordion_tab>
- </accordion>
- <panel
- bg_opaque_color="DkGray2"
- background_visible="true"
- background_opaque="true"
- bevel_style="none"
- enabled="false"
- follows="bottom|left|right"
- left="1"
- height="27"
- label="bottom_panel"
- layout="topleft"
- name="edit_panel"
- top_pad="0"
- width="312">
-
- <layout_stack
- follows="bottom|left|right"
- height="23"
- layout="bottomleft"
- name="edit_panel_ls"
- left="10"
- orientation="horizontal"
- top_pad="0"
- width="293">
-
- <layout_panel
- follows="bottom|left"
- height="18"
- layout="bottomleft"
- left="0"
- name="gear_menu_btn"
- auto_resize="true"
- width="51">
- <button
- follows="bottom|left"
- height="18"
- image_disabled="AddItem_Disabled"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
- layout="topleft"
- left="0"
- name="new_btn"
- tool_tip="Create a new pick or classified at the current location"
- top="0"
- width="18" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|right"
- height="18"
- layout="bottomleft"
- name="trash_btn_lp"
- auto_resize="true"
- width="18">
- <button
- follows="bottom|right"
- height="18"
- image_disabled="TrashItem_Disabled"
- image_selected="TrashItem_Press"
- image_unselected="TrashItem_Off"
- layout="topleft"
- name="trash_btn"
- top="0"
- width="18" />
- </layout_panel>
-
- </layout_stack>
- </panel>
-
- <panel
- bg_opaque_color="DkGray"
- background_visible="true"
- background_opaque="true"
- follows="bottom|left|right"
- layout="topleft"
- left="0"
- height="30"
- name="buttons_cucks"
- top_pad="0"
- width="313">
-
- <layout_stack
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="2"
- name="buttons_cucks_ls"
- orientation="horizontal"
- top="0"
- width="313">
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="topleft"
- left="0"
- name="info_btn_lp"
- auto_resize="true"
- top="0"
- width="95">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Info"
- layout="topleft"
- name="info_btn"
- tab_stop="false"
- tool_tip="Show pick information"
- width="95" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- left_pad="2"
- name="teleport_btn_lp"
- auto_resize="true"
- width="117">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Teleport"
- layout="topleft"
- name="teleport_btn"
- tab_stop="false"
- tool_tip="Teleport to the corresponding area"
- width="117" />
- </layout_panel>
-
- <layout_panel
- follows="bottom|left|right"
- height="28"
- layout="bottomleft"
- name="show_on_map_btn_lp"
- auto_resize="true"
- left_pad="2"
- width="90">
- <button
- enabled="false"
- follows="top|left|right"
- height="23"
- label="Map"
- layout="topleft"
- name="show_on_map_btn"
- tab_stop="false"
- tool_tip="Show the corresponding area on the World Map"
- width="88" />
- </layout_panel>
- </layout_stack>
- </panel>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classified.xml b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
new file mode 100644
index 0000000000..c9e8b242d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classified.xml
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classified"
+ top="0"
+ left="0"
+ height="420"
+ width="315"
+ follows="all"
+ layout="topleft"
+ help_topic="panel_profile_classified"
+ min_height="250"
+>
+ <panel.string
+ name="type_mature"
+ >
+ Moderate
+ </panel.string>
+ <panel.string
+ name="type_pg"
+ >
+ General Content
+ </panel.string>
+ <panel.string
+ name="l$_price"
+ >
+ L$[PRICE]
+ </panel.string>
+ <panel.string
+ name="click_through_text_fmt"
+ >
+ [TELEPORT] teleport, [MAP] map, [PROFILE] profile
+ </panel.string>
+ <panel.string
+ name="date_fmt"
+ >
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string
+ name="auto_renew_on"
+ >
+ Enabled
+ </panel.string>
+ <panel.string
+ name="auto_renew_off"
+ >
+ Disabled
+ </panel.string>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+ <string
+ name="publish_label"
+ >
+ Publish
+ </string>
+ <string
+ name="save_label"
+ >
+ Save
+ </string>
+
+ <layout_stack
+ name="main_classifieds_stack"
+ top="0"
+ bottom="-1"
+ left="0"
+ width="310"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ width="310"
+ height="300"
+ layout="topleft"
+ name="scroll_layout_panel"
+ auto_resize="true">
+ <scroll_container
+ name="profile_scroll"
+ top="0"
+ left="0"
+ height="300"
+ width="310"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ reserve_scroll_corner="false"
+ >
+ <panel
+ name="info_scroll_content_panel"
+ top="0"
+ left="0"
+ height="562"
+ width="280"
+ follows="left|top|right"
+ layout="topleft"
+ background_visible="false"
+ min_height="200"
+ >
+ <texture_picker
+ name="classified_snapshot"
+ enabled="false"
+ top="0"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <icon
+ name="edit_icon"
+ label=""
+ tool_tip="Click to select an image"
+ top="0"
+ left="0"
+ height="161"
+ width="260"
+ layout="topleft"
+ follows="left|top"
+ image_name="spacer24.tga"
+ visible="false"
+ />
+ <layout_stack
+ name="info_panel"
+ top="145"
+ left="0"
+ height="375"
+ width="310"
+ follows="all"
+ layout="topleft"
+ visible="true"
+ animate="false"
+ orientation="vertical"
+ >
+ <layout_panel
+ name="main_info_panel"
+ top="0"
+ left="0"
+ height="160"
+ width="280"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text_editor
+ name="classified_name"
+ top="0"
+ left="10"
+ height="35"
+ width="270"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ font="SansSerifBig"
+ font.style="BOLD"
+ h_pad="0"
+ read_only="true"
+ text_color="white"
+ use_ellipses="true"
+ v_pad="0"
+ >
+ [name]
+ </text_editor>
+ <text
+ name="classified_location_label"
+ value="Location:"
+ top_pad="-2"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_location"
+ value="[loading...]"
+ top_pad="5"
+ left="10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ <text
+ name="content_type_label"
+ value="Content Type:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icon
+ name="content_type_moderate"
+ top_pad="-11"
+ left_pad="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_M_Light"
+ />
+ <icon
+ name="content_type_general"
+ top_delta="0"
+ left_delta="0"
+ height="16"
+ width="18"
+ follows="top|left"
+ layout="topleft"
+ image_name="Parcel_PG_Light"
+ />
+ <text_editor
+ name="content_type"
+ value="[content type]"
+ top_delta="1"
+ left_pad="2"
+ height="18"
+ width="130"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="category"
+ value="[category]"
+ top_pad="-10"
+ left_pad="0"
+ height="18"
+ width="150"
+ follows="left|top|right"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="creation_date_label"
+ value="Creation date:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="creation_date"
+ value="[date]"
+ tool_tip="Creation date"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ <text
+ name="price_for_listing_label"
+ value="Price for listing:"
+ top_pad="5"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="price_for_listing"
+ tool_tip="Price for listing."
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="105"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ >
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel
+ name="clickthrough_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="click_through_label"
+ value="Clicks:"
+ top_pad="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="click_through_text"
+ value="[clicks]"
+ tool_tip="Click through data"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="left|top"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ halign="left"
+ read_only="true"
+ v_pad="0"
+ />
+ </layout_panel>
+ <layout_panel
+ name="auto_renew_layout_panel"
+ top="0"
+ left="0"
+ height="16"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="false"
+ >
+ <text
+ name="auto_renew_label"
+ value="Auto renew:"
+ top="0"
+ left="10"
+ height="10"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text
+ name="auto_renew"
+ value="Enabled"
+ top_pad="-10"
+ left_pad="0"
+ height="16"
+ width="150"
+ follows="top|left"
+ layout="topleft"
+ />
+ </layout_panel>
+ <layout_panel
+ name="descr_layout_panel"
+ top="0"
+ left="0"
+ height="220"
+ width="290"
+ follows="all"
+ layout="topleft"
+ auto_resize="true"
+ >
+ <text
+ name="classified_desc_label"
+ value="Description:"
+ top="0"
+ left="10"
+ height="10"
+ width="250"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <text_editor
+ name="classified_desc"
+ trusted_content="false"
+ value="[description]"
+ top_pad="7"
+ left="10"
+ height="200"
+ width="280"
+ follows="all"
+ layout="topleft"
+ allow_scroll="false"
+ bg_visible="false"
+ h_pad="0"
+ max_length="1023"
+ parse_urls="true"
+ read_only="true"
+ v_pad="0"
+ word_wrap="true"
+ />
+ </layout_panel>
+ </layout_stack>
+ <panel
+ name="edit_panel"
+ top="145"
+ left="0"
+ height="420"
+ width="320"
+ follows="left|top|right"
+ layout="topleft"
+ visible="false"
+ >
+ <text
+ name="Name:"
+ top="0"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="classified_name_edit"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ font="SansSerif"
+ max_length_bytes="30"
+ prevalidate_callback="ascii"
+ commit_on_focus_lost="false"
+ text_color="black"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="classified_desc_edit"
+ top_pad="2"
+ left="10"
+ height="100"
+ width="273"
+ follows="left|top|right"
+ layout="topleft"
+ max_length="256"
+ text_color="black"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <text
+ name="classified_location_edit"
+ top_pad="2"
+ left="10"
+ right="-10"
+ height="30"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ length="1"
+ type="string"
+ word_wrap="true"
+ >
+ loading...
+ </text>
+ <button
+ name="set_to_curr_location_btn"
+ label="Set to Current Location"
+ top_pad="5"
+ left="10"
+ height="23"
+ width="200"
+ follows="left|top"
+ layout="topleft"
+ />
+ <text
+ name="category_label"
+ value="Category:"
+ top_pad="10"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <combo_box
+ name="category_edit"
+ label=""
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ />
+ <text
+ name="content_type_label"
+ value="Content type:"
+ top_pad="15"
+ left="10"
+ height="10"
+ width="120"
+ follows="left|top"
+ layout="topleft"
+ font.style="BOLD"
+ text_color="white"
+ />
+ <icons_combo_box
+ name="content_type_edit"
+ label="General Content"
+ top_delta="-3"
+ left_pad="0"
+ height="23"
+ width="156"
+ follows="left|top"
+ layout="topleft"
+ >
+ <icons_combo_box.drop_down_button
+ image_overlay="Parcel_PG_Light"
+ image_overlay_alignment="left"
+ imgoverlay_label_space="3"
+ pad_left="3"
+ />
+ <icons_combo_box.item
+ name="mature_ci"
+ label="Moderate Content"
+ value="Mature"
+ >
+ <item.columns
+ value="Parcel_M_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ <icons_combo_box.item
+ name="pg_ci"
+ label="General Content"
+ value="PG"
+ >
+ <item.columns
+ value="Parcel_PG_Light"
+ width="20"
+ halign="center"
+ type="icon"
+ />
+ </icons_combo_box.item>
+ </icons_combo_box>
+ <check_box
+ name="auto_renew_edit"
+ label="Auto renew each week"
+ top_pad="10"
+ left="10"
+ height="16"
+ width="250"
+ layout="topleft"
+ />
+ </panel>
+ </panel>
+ </scroll_container>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ width="310"
+ height="25"
+ layout="topleft"
+ name="util_buttons_lp"
+ auto_resize="true">
+ <layout_stack
+ name="util_buttons_stack"
+ bottom="-1"
+ left="1"
+ right="-1"
+ height="25"
+ follows="left|bottom|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="topleft"
+ left="0"
+ name="teleport_btn_lp"
+ auto_resize="false"
+ top="0"
+ width="85">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ top="0"
+ left="0"
+ height="23"
+ max_width="101"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="show_on_map_btn"
+ label="Map"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ height="25"
+ layout="bottomleft"
+ left_pad="2"
+ name="edit_btn_lp"
+ auto_resize="false"
+ max_width="101"
+ width="85">
+ <button
+ name="edit_btn"
+ label="Edit"
+ top="0"
+ left="0"
+ height="23"
+ width="85"
+ follows="bottom|left|right"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+ </layout_stack>
+ </layout_panel>
+ <layout_panel
+ follows="all"
+ width="310"
+ height="41"
+ layout="topleft"
+ name="publish_layout_panel"
+ auto_resize="false">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="publish_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="publish_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false"
+ >
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_left"
+ auto_resize="true"
+ user_resize="false"
+ width="1"/>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="save_changes_btn"
+ label="[LABEL]"
+ top="0"
+ left="0"
+ left_pad="5"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="134">
+ <button
+ name="cancel_btn"
+ label="Cancel"
+ top="0"
+ left="0"
+ height="23"
+ width="134"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="pbl_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2b2f60e0c2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_classifieds.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_classifieds"
+ label="Classified"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_classifieds"
+ value="No Classifieds"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new classified at the current location"
+ enabled="false"
+ top="25"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected classified"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_classifieds"
+ top="0"
+ bottom="-1"
+ left="4"
+ right="-4"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ tab_width="150"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="classifieds_panel_text"
+ top="250"
+ left="110"
+ right="-110"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..ca1e405a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_firstlife"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="5"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <icon
+ name="real_world_pic"
+ image_name="Generic_Person_Large"
+ follows="top|left"
+ layout="topleft"
+ top="10"
+ left="8"
+ height="160"
+ width="160"/>
+ <loading_indicator
+ name="image_upload_indicator"
+ top="79"
+ left="77"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ <button
+ name="fl_upload_image"
+ label="Upload Photo"
+ top="102"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_change_image"
+ label="Change Photo"
+ top_pad="5"
+ left="175"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <button
+ name="fl_remove_image"
+ label="Remove Photo"
+ top_pad="5"
+ left_delta="0"
+ height="20"
+ width="120"
+ follows="top|left"
+ layout="topleft"/>
+ <text_editor
+ name="fl_description_edit"
+ trusted_content="false"
+ enabled="false"
+ top="180"
+ left="6"
+ right="-6"
+ height="224"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ <button
+ name="fl_save_changes"
+ label="Save"
+ top_pad="5"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+ <button
+ name="fl_discard_changes"
+ label="Discard"
+ top_delta="0"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="right|bottom"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_notes.xml b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
new file mode 100644
index 0000000000..16e7365042
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_notes.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_notes"
+ label="Notes &amp; Privacy"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <loading_indicator
+ name="progress_indicator"
+ top="3"
+ right="-10"
+ height="23"
+ width="23"
+ follows="top|right"
+ layout="topleft"
+ visible="false"
+ />
+ <text
+ name="status_message"
+ value="Make notes about this person here. No one else can see your notes."
+ top="6"
+ left="6"
+ right="-6"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ font.style="BOLD"
+ />
+ <text_editor
+ name="notes_edit"
+ enabled="false"
+ top="28"
+ left="6"
+ right="-6"
+ bottom="-26"
+ follows="all"
+ layout="topleft"
+ max_length="65530"
+ word_wrap="true"
+ />
+ <button
+ name="notes_save_changes"
+ label="Save"
+ bottom="-1"
+ right="-108"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+ <button
+ name="notes_discard_changes"
+ label="Discard"
+ bottom="-1"
+ right="-4"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="bottom|right"
+ layout="topleft"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
new file mode 100644
index 0000000000..3e91640093
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_pick_info"
+ top="0"
+ left="0"
+ height="360"
+ width="310"
+ follows="all"
+ layout="topleft"
+ help_topic="profile_pick_info"
+>
+ <panel.string
+ name="location_notice"
+ >
+ (will update after save)
+ </panel.string>
+
+ <layout_stack
+ name="main_pick_stack"
+ left="1"
+ right="-1"
+ top="0"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ orientation="vertical"
+ animate="false">
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="main_pick_lp"
+ auto_resize="true"
+ height="314">
+ <texture_picker
+ name="pick_snapshot"
+ top="10"
+ left="10"
+ height="161"
+ width="260"
+ follows="left|top"
+ layout="topleft"
+ fallback_image="default_land_picture.j2c"
+ />
+ <text
+ name="title_label"
+ top_pad="-15"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Title:
+ </text>
+ <line_editor
+ name="pick_name"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="20"
+ width="290"
+ follows="left|right|top"
+ layout="topleft"
+ />
+ <text
+ name="description_label"
+ top_pad="10"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|top"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Description:
+ </text>
+ <text_editor
+ name="pick_desc"
+ trusted_content="false"
+ always_show_icons="true"
+ enabled="false"
+ top_pad="2"
+ left="10"
+ height="45"
+ width="290"
+ follows="all"
+ layout="topleft"
+ allow_html="true"
+ border_visible="true"
+ h_pad="4"
+ max_length="1023"
+ v_pad="3"
+ word_wrap="true"
+ />
+ <text
+ name="location_label"
+ bottom="-25"
+ left="10"
+ height="15"
+ width="280"
+ follows="left|right|bottom"
+ layout="topleft"
+ font="SansSerifSmall"
+ font.style="BOLD"
+ length="1"
+ text_color="white"
+ type="string"
+ >
+ Location:
+ </text>
+ <line_editor
+ name="pick_location"
+ enabled="false"
+ bottom="-1"
+ left="10"
+ height="23"
+ width="290"
+ follows="left|right|bottom"
+ layout="topleft"
+ length="1"
+ type="string"
+ >
+ Loading...
+ </line_editor>
+ </layout_panel>
+
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="25">
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="0"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="map_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="show_on_map_btn"
+ label="Show on Map"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="tp_btn_lp"
+ auto_resize="false"
+ width="100">
+ <button
+ name="teleport_btn"
+ label="Teleport"
+ left="0"
+ top="0"
+ height="23"
+ width="100"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="util_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ name="save_changes_lp"
+ auto_resize="false"
+ height="41">
+ <view_border
+ bevel_style="none"
+ height="0"
+ follows="left|top|right"
+ layout="topleft"
+ left="0"
+ name="save_emphasis_border"
+ top="5"
+ width="310"/>
+ <layout_stack
+ name="save_changes_stack"
+ left="1"
+ right="-1"
+ top="11"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ orientation="horizontal"
+ animate="false">
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_left"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="create_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="create_changes_btn"
+ label="Create Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="save_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="save_changes_btn"
+ label="Save Pick"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="bottomleft"
+ left_pad="2"
+ name="cancel_btn_lp"
+ auto_resize="false"
+ width="130">
+ <button
+ name="cancel_changes_btn"
+ label="Cancel"
+ left="0"
+ top="0"
+ height="23"
+ width="130"
+ follows="left|top"
+ layout="topleft"
+ />
+ </layout_panel>
+
+ <layout_panel
+ follows="all"
+ layout="topleft"
+ name="save_resizer_right"
+ auto_resize="true"
+ width="1">
+ </layout_panel>
+
+ </layout_stack>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_picks.xml b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
new file mode 100644
index 0000000000..44d5c448c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_picks.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_picks"
+ label="Picks"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="no_picks"
+ value="No Picks"
+ />
+
+ <layout_stack
+ name="main_stack"
+ top="0"
+ left="0"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="header_text"
+ top="5"
+ left="5"
+ right="-5"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ >
+ Tell everyone about your favorite places in Second Life.
+ </text>
+ <button
+ name="new_btn"
+ label="New..."
+ tool_tip="Create a new pick at the current location"
+ enabled="false"
+ top_pad="4"
+ left="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ <button
+ name="delete_btn"
+ label="Delete..."
+ tool_tip="Delete currently selected pick"
+ enabled="false"
+ left_pad="5"
+ height="20"
+ width="70"
+ follows="left|top"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="main_body"
+ follows="all"
+ layout="topleft"
+ height="430"
+ auto_resize="true"
+ user_resize="false">
+ <tab_container
+ name="tab_picks"
+ top="0"
+ bottom="-5"
+ left="4"
+ right="-4"
+ tab_width="150"
+ follows="all"
+ layout="topleft"
+ halign="left"
+ tab_position="left"
+ use_ellipses="true"
+ />
+
+ <layout_stack
+ name="indicator_stack"
+ top="220"
+ left="0"
+ right="-1"
+ height="28"
+ follows="top|left|right"
+ layout="topleft"
+ animate="false"
+ orientation="horizontal">
+ <layout_panel
+ name="indicator_spacer_left"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ <layout_panel
+ name="buttons_header"
+ follows="all"
+ layout="topleft"
+ width="25"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ top="1"
+ left="1"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"
+ />
+ </layout_panel>
+ <layout_panel
+ name="indicator_spacer_right"
+ follows="all"
+ layout="topleft"
+ width="100"
+ auto_resize="true"
+ user_resize="false">
+ </layout_panel>
+ </layout_stack>
+ <text
+ name="picks_panel_text"
+ top="250"
+ left="100"
+ right="-100"
+ height="25"
+ follows="left|top|right"
+ layout="topleft"
+ halign="center"
+ mouse_opaque="false"
+ wrap="true"
+ >
+ Loading...
+ </text>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..551b477876
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -0,0 +1,549 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile"
+ label="Profile"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <string
+ name="date_format"
+ value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" />
+ <string
+ name="age_format"
+ value="[AGE]" />
+ <string
+ name="partner_text"
+ value="Partner: [LINK]" />
+ <string
+ name="CaptionTextAcctInfo">
+Account: [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+
+ <layout_stack
+ name="image_stack"
+ top="8"
+ left="6"
+ bottom="-1"
+ width="160"
+ border_size="0"
+ follows="left|top|bottom"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="image_panel"
+ follows="all"
+ layout="topleft"
+ width="160"
+ height="160"
+ auto_resize="false"
+ user_resize="false">
+
+ <icon
+ name="2nd_life_pic"
+ image_name="Generic_Person_Large"
+ layout="topleft"
+ follows="all"
+ interactable="true"
+ top="0"
+ left="2"
+ bottom="-1"
+ right="-1"/>
+
+ <loading_indicator
+ name="image_upload_indicator"
+ top="69"
+ left="69"
+ height="23"
+ width="23"
+ follows="top|left"
+ layout="topleft"
+ visible="false"/>
+ </layout_panel>
+
+ <layout_panel
+ name="basics_panel"
+ follows="all"
+ layout="topleft"
+ height="54"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <line_editor
+ name="user_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top="4"
+ left="3"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="sl_birth_date"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <line_editor
+ name="user_age"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ top_pad="0"
+ left_delta="0"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ </layout_panel>
+ <layout_panel
+ name="partner_layout"
+ follows="all"
+ layout="topleft"
+ height="30"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ <text
+ type="string"
+ name="partner_link"
+ value="Partner: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="28"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ use_ellipses="true"
+ word_wrap="true"
+ visible="true"/>
+ </layout_panel>
+
+ <layout_panel
+ name="partner_spacer_layout"
+ follows="all"
+ layout="topleft"
+ height="14"
+ auto_resize="false"
+ user_resize="false"
+ visible="true">
+ </layout_panel>
+
+ <layout_panel
+ name="frind_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <text
+ name="frind_text"
+ value="You are friends"
+ text_color="ConversationFriendColor"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="online_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="online_icon"
+ image_name="Profile_Friend_Online"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="online_text"
+ value="Online"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="offline_layout"
+ follows="all"
+ layout="topleft"
+ height="16"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="offline_icon"
+ image_name="Profile_Friend_Offline"
+ layout="topleft"
+ follows="left|top"
+ top="0"
+ left="5"
+ height="10"
+ width="10"/>
+ <text
+ name="offline_text"
+ value="Offline"
+ top="0"
+ left="18"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="account_layout"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <text
+ name="account_info"
+ value="Account: (loading...)"
+ top="0"
+ left="5"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ word_wrap="true"/>
+ </layout_panel>
+ <layout_panel
+ name="indicator_stack"
+ follows="all"
+ layout="topleft"
+ height="33"
+ auto_resize="false"
+ user_resize="false">
+ <loading_indicator
+ name="progress_indicator"
+ left="67"
+ top="0"
+ height="23"
+ width="23"
+ follows="left|top"
+ layout="topleft"
+ visible="true"/>
+ </layout_panel>
+ <layout_panel
+ name="settings_panel"
+ follows="all"
+ layout="topleft"
+ height="50"
+ auto_resize="false"
+ user_resize="false">
+ <!-- only for self -->
+ <text
+ name="search_label"
+ value="Show my profile in search:"
+ top="1"
+ left="6"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <combo_box
+ name="show_in_search"
+ tool_tip="Let people see you in search results"
+ left="1"
+ top="18"
+ height="23"
+ width="140"
+ follows="left|top"
+ layout="topleft"
+ visible="true"
+ enabled="false">
+ <combo_box.item
+ name="Hide"
+ label="Hide"
+ value="0" />
+ <combo_box.item
+ name="Show"
+ label="Show"
+ value="1" />
+ </combo_box>
+ </layout_panel>
+
+ <layout_panel
+ name="menu_panel"
+ follows="all"
+ layout="topleft"
+ height="55"
+ auto_resize="false"
+ user_resize="false"
+ >
+ <menu_button
+ layout="topleft"
+ follows="left|top"
+ left="1"
+ top="25"
+ height="25"
+ width="140"
+ label="Actions"
+ halign="left"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_On"
+ image_pressed="DropDown_Press"
+ image_pressed_selected="DropDown_Press"
+ image_disabled="DropDown_Disabled"
+ name="agent_actions_menu" />
+ </layout_panel>
+ </layout_stack>
+
+ <layout_stack
+ name="main_stack"
+ top="8"
+ left="168"
+ bottom="-1"
+ right="-1"
+ follows="all"
+ layout="topleft"
+ animate="false"
+ orientation="vertical">
+ <layout_panel
+ name="display_name_panel"
+ follows="all"
+ layout="topleft"
+ height="24"
+ auto_resize="false"
+ user_resize="false">
+ <line_editor
+ name="display_name"
+ border_thickness="0"
+ use_bg_color="false"
+ background_image_disabled=""
+ background_image_focused=""
+ enabled="false"
+ value="(loading...)"
+ font="SansSerifBigLarge"
+ top="0"
+ left="6"
+ height="19"
+ right="-86"
+ follows="left|top|right"
+ layout="topleft"/>
+
+ <icon
+ tool_tip="Friend can see my online status"
+ mouse_opaque="true"
+ name="can_see_online"
+ image_name="Profile_Perm_Online_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see my online status"
+ mouse_opaque="true"
+ name="cant_see_online"
+ image_name="Profile_Perm_Online_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-61"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can see me on map"
+ mouse_opaque="true"
+ name="can_see_on_map"
+ image_name="Profile_Perm_Find_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not see me on map"
+ mouse_opaque="true"
+ name="cant_see_on_map"
+ image_name="Profile_Perm_Find_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-30"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can edit my objects"
+ mouse_opaque="true"
+ name="can_edit_objects"
+ image_name="Profile_Perm_Objects_Enabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ <icon
+ tool_tip="Friend can not edit my objects"
+ mouse_opaque="true"
+ name="cant_edit_objects"
+ image_name="Profile_Perm_Objects_Disabled"
+ layout="topleft"
+ follows="right|top"
+ interactable="true"
+ top="0"
+ right="-1"
+ height="24"
+ width="24"
+ left_pad="2" />
+
+ </layout_panel>
+
+ <layout_panel
+ name="about_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text_editor
+ name="sl_description_edit"
+ trusted_content="false"
+ always_show_icons="true"
+ commit_on_focus_lost="false"
+ enabled="false"
+ top="0"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ bg_readonly_color="Transparent"
+ border_visible="true"
+ font="SansSerifSmall"
+ h_pad="2"
+ max_length="65000"
+ parse_urls="true"
+ word_wrap="true"
+ />
+ </layout_panel>
+ <layout_panel
+ name="about_buttons_panel"
+ follows="all"
+ layout="topleft"
+ height="34"
+ auto_resize="false"
+ user_resize="false">
+ <button
+ name="save_description_changes"
+ label="Save"
+ top="1"
+ right="-105"
+ height="20"
+ width="80"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <button
+ name="discard_description_changes"
+ label="Discard"
+ top="1"
+ right="-1"
+ height="20"
+ width="100"
+ enabled="false"
+ follows="top|right"
+ layout="topleft"/>
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="cost_text_border"
+ top_pad="9"
+ width="492"/>
+ </layout_panel>
+
+ <layout_panel
+ name="groups_panel"
+ follows="all"
+ layout="topleft"
+ height="159"
+ auto_resize="true"
+ user_resize="false">
+ <text
+ name="group_label"
+ value="Group memberships"
+ top="1"
+ left="2"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"/>
+ <group_list
+ name="group_list"
+ top="18"
+ left="2"
+ right="-1"
+ bottom="-1"
+ follows="all"
+ layout="topleft"
+ border_visible="true"
+ color="ScrollBgWriteableColor"
+ for_agent="false"/>
+
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_web.xml b/indra/newview/skins/default/xui/en/panel_profile_web.xml
new file mode 100644
index 0000000000..e0cb4d3d06
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_profile_web.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ name="panel_profile_web"
+ label="Web"
+ top="0"
+ left="0"
+ height="480"
+ width="420"
+ follows="all"
+ layout="topleft"
+>
+ <panel.string
+ name="LoadTime"
+ value="Load Time: [TIME] seconds"
+ />
+ <web_browser
+ name="profile_html"
+ top="10"
+ bottom="-18"
+ left="10"
+ right="-10"
+ follows="all"
+ layout="topleft"
+ start_url=""
+ />
+ <text
+ name="status_text"
+ bottom="-4"
+ left="110"
+ right="-110"
+ follows="bottom|left|right"
+ layout="topleft"
+ halign="center"
+ parse_urls="false"
+ />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
index 8243c2715d..2aaea04a6d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml
@@ -86,7 +86,7 @@
name="detail_texture_text"
top="110"
width="300">
- Terrain Textures (requires 512x512, 24 bit .tga files)
+ Terrain Textures (requires 1024x1024, 24 bit .tga files)
</text>
<texture_picker
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index 90f32ae452..c7052bb737 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -11,6 +11,36 @@
name="Texture"
top="0"
width="295">
+ <panel.string
+ name="paste_error_face_selection_mismatch">
+ When multiple faces are copied, the target object must have the same number of faces selected.
+ </panel.string>
+ <panel.string
+ name="paste_error_object_face_count_mismatch">
+ When all faces of an object are copied, the target object must have the same number of faces.
+ </panel.string>
+ <panel.string
+ name="paste_error_inventory_not_found">
+ One or more texture not found in inventory.
+ </panel.string>
+ <panel.string
+ name="paste_options">
+ Paste options
+ </panel.string>
+
+ <menu_button
+ menu_filename="menu_copy_paste_color.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top="8"
+ name="clipboard_color_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<text
type="string"
length="1"
@@ -36,7 +66,7 @@
name="colorswatch"
tool_tip="Click to open color picker"
top="20"
- width="64" />
+ width="54" />
<text
type="string"
length="1"
@@ -84,7 +114,7 @@
left_delta="0"
name="glow"
top_pad="4"
- width="80" />
+ width="77" />
<check_box
height="19"
label="Full Bright"
@@ -93,13 +123,22 @@
name="checkbox fullbright"
top_pad="4"
width="81" />
+ <view_border
+ bevel_style="none"
+ follows="top|left"
+ height="0"
+ layout="topleft"
+ left="8"
+ name="object_horizontal"
+ top_pad="4"
+ width="278" />
<combo_box
height="23"
layout="topleft"
left="10"
name="combobox matmedia"
- top_pad="5"
- width="100">
+ top_pad="17"
+ width="90">
<combo_box.item
label="Materials"
name="Materials"
@@ -113,7 +152,7 @@
control_name="ComboMaterialType"
height="50"
layout="topleft"
- left_pad="20"
+ left_pad="5"
top_delta="-10"
width="150"
visible = "false"
@@ -139,7 +178,20 @@
layout="topleft"
top_pad="1"
value="2"/>
- </radio_group>
+ </radio_group>
+ <menu_button
+ menu_filename="menu_copy_paste_texture.xml"
+ follows="top|left"
+ height="15"
+ image_disabled="ClipboardMenu_Disabled"
+ image_selected="ClipboardMenu_Press"
+ image_unselected="ClipboardMenu_Off"
+ layout="topleft"
+ left="258"
+ top_delta="0"
+ name="clipboard_texture_params_btn"
+ tool_tip="Paste options"
+ width="22"/>
<check_box
control_name="SyncMaterialSettings"
follows="top|left"
@@ -150,7 +202,7 @@
left="8"
name="checkbox_sync_settings"
tool_tip="Adjust all maps repeats simultaneously"
- top_pad="-16"
+ top_pad="19"
width="160" />
<texture_picker
can_apply_immediately="true"
@@ -498,10 +550,7 @@
top_pad="4"
tool_tip="Add Media"
label="Choose..."
- width="85">
- <button.commit_callback
- function="BuildTool.AddMedia"/>
- </button>
+ width="85"/>
<button
follows="top|left"
height="18"
@@ -511,10 +560,7 @@
tool_tip="Delete this media texture"
top_delta="0"
label="Remove"
- width="85">
- <button.commit_callback
- function="BuildTool.DeleteMedia"/>
- </button>
+ width="85"/>
<button
follows="left|top"
height="18"
@@ -771,14 +817,14 @@
top_delta="16"
width="260" />
<button
- left="10"
- top="222"
+ follows="left|top"
+ layout="topleft"
+ left="9"
+ top="204"
height="20"
label="Align"
label_selected="Align current texture layers"
- layout="topleft"
name="button align textures"
- top_delta="0"
tool_tip="Align current texture layers"
width="66" />
<web_browser
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 8a3e18707f..1c9d750aa6 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -459,7 +459,7 @@
label="Price: L$"
label_width="73"
width="150"
- min_val="1"
+ min_val="0"
height="20"
max_val="999999999"
tool_tip="Object cost." />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 8382e3970c..6f95e282ca 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -348,8 +348,6 @@ can be attached to notecards.
<!-- Group name: text shown for LLUUID::null -->
<string name="GroupNameNone">(none)</string>
- <string name="AvalineCaller">Avaline Caller [ORDER]</string>
-
<!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. -->
<string name="AssetErrorNone">No error</string>
<string name="AssetErrorRequestFailed">Asset request: failed</string>
@@ -2342,6 +2340,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
An error occurred while opening Marketplace Listings.
If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
</string>
+ <string name="InventoryMarketplaceConnectionError">
+Marketplace Listings failed to connect.
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
+ <string name="InventoryMarketplaceConnectionErrorReason">
+Marketplace Listings failed to connect. Reason: [REASON]
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
+ </string>
<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>
<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>
<string name="InventoryMarketplaceListingsNoItems">
@@ -2808,10 +2814,14 @@ If you continue to receive this message, please contact Second Life support for
<string name="ClassifiedClicksTxt">Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile</string>
<string name="ClassifiedUpdateAfterPublish">(will update after publish)</string>
- <!-- panel picks -->
- <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
- <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
- <string name="PicksClassifiedsLoadingText">Loading...</string>
+ <!-- panel picks -->
+ <string name="NoPicksClassifiedsText">You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified.</string>
+ <string name="NoPicksText">You haven't created any Picks. Click the New button to create a Pick.</string>
+ <string name="NoClassifiedsText">You haven't created any Classifieds. Click the New button to create a Classified.</string>
+ <string name="NoAvatarPicksClassifiedsText">User has no picks or classifieds</string>
+ <string name="NoAvatarPicksText">This person has no picks</string>
+ <string name="NoAvatarClassifiedsText">This person has no classifieds</string>
+ <string name="PicksClassifiedsLoadingText">Loading...</string>
<!-- Multi Preview Floater -->
<string name="MultiPreviewTitle">Preview</string>
diff --git a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
index 4f3c177976..87f93e8fcf 100644
--- a/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Hitos" name="check_landmark"/>
<check_box label="Notas" name="check_notecard"/>
- <check_box label="Redes" name="check_mesh"/>
+ <check_box label="Meshs" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sonidos" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/es/floater_preview_texture.xml b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
index b0afd44750..2543508c40 100644
--- a/indra/newview/skins/default/xui/es/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/es/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar al inventario
</floater.string>
- <text name="desc txt">
- Descripción:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Previsualizar la ratio de las proporciones
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta">
- <combo_item name="Unconstrained">
- Sin restricciones
- </combo_item>
- <combo_item name="1:1" tool_tip="Emblema del grupo o perfil del Mundo real">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Perfil de [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Clasificados (también en las listas de búsqueda), hitos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Acerca del terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Destacados del perfil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Guardar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descripción:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Previsualizar la ratio de las proporciones
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Vista previa en una proporción concreta"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Guardar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_profile.xml b/indra/newview/skins/default/xui/es/floater_profile.xml
new file mode 100644
index 0000000000..c9448a0d4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Intereses" name="panel_profile_interests"/>
+ <panel label="Destacados" name="panel_profile_picks"/>
+ <panel label="Clasificado" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Notas" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar cambios en el perfil y cerrar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/es/floater_snapshot.xml b/indra/newview/skins/default/xui/es/floater_snapshot.xml
index c2c996aa8a..2dfaecf3e3 100644
--- a/indra/newview/skins/default/xui/es/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/es/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando el correo electrónico
</string>
+ <string name="facebook_progress_str">
+ Publicando en Facebook
+ </string>
<string name="profile_progress_str">
Publicando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Guardando en el equipo
</string>
+ <string name="facebook_succeeded_str">
+ Imagen subida
+ </string>
<string name="profile_succeeded_str">
Imagen subida
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
¡Guardado en el equipo!
</string>
+ <string name="facebook_failed_str">
+ Error al subir la imagen a tu biografía de Facebook.
+ </string>
<string name="profile_failed_str">
Error al subir la imagen a los comentarios de tu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/es/menu_name_field.xml b/indra/newview/skins/default/xui/es/menu_name_field.xml
new file mode 100644
index 0000000000..0d51fbffeb
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copiar Nombre mostrado" name="copy_display"/>
+ <menu_item_call label="Copiar Nombre de agente" name="copy_name"/>
+ <menu_item_call label="Copiar ID de agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 54707116d4..36f27bc3c6 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2690,6 +2690,9 @@ Inténtalo seleccionando un trozo más pequeño de terreno.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_classified.xml b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
index ffad843732..09f87015cc 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/es/panel_facebook_place.xml b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
index 5139bd1d0b..29f6147f23 100644
--- a/indra/newview/skins/default/xui/es/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/es/panel_facebook_place.xml
@@ -3,7 +3,7 @@
<text name="place_caption_label">
Cuenta algo del lugar donde te encuentras:
</text>
- <check_box initial_value="false" label="Incluir una vista general del lugar" name="add_place_view_cb"/>
+ <check_box initial_value="false" label="Incluye una vista general del lugar" name="add_place_view_cb"/>
<button label="Publicar" name="post_place_btn"/>
<button label="Cancelar" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml
index a17814d15d..ef919f396e 100644
--- a/indra/newview/skins/default/xui/es/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_group_general.xml
@@ -46,7 +46,7 @@ Deja el cursor sobre las opciones para ver más ayuda.
<check_box label="Cualquiera puede entrar" name="open_enrollement" tool_tip="Configura si se permite la entrada de nuevos miembros sin ser invitados."/>
<check_box label="Cuota de entrada" name="check_enrollment_fee" tool_tip="Configura si hay que pagar una cuota para entrar al grupo"/>
<spinner label="L$" left_delta="130" name="spin_enrollment_fee" tool_tip="Si la opción Cuota de entrada está marcada, los nuevos miembros han de pagar esta cuota para entrar al grupo." width="60"/>
- <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="La calificación de contenido designa el tipo de contenido y conducta que se permiten en un grupo" width="150">
+ <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si tu grupo contiene información clasificada como Moderada" width="150">
<combo_item name="select_mature">
- Selecciona el nivel de calificación -
</combo_item>
diff --git a/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..4d682068d7
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconocido"/>
+ <button name="info_btn" tool_tip="Más información"/>
+ <button name="profile_btn" tool_tip="Ver el perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_me.xml b/indra/newview/skins/default/xui/es/panel_me.xml
deleted file mode 100644
index 850cd6ec71..0000000000
--- a/indra/newview/skins/default/xui/es/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mi perfil" name="panel_me">
- <panel label="MIS DESTACADOS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 73b9af3665..2aaf7e89be 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Conectado"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Personas de las que podrías querer ser amigo"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classified.xml b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
new file mode 100644
index 0000000000..679026d350
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenido general
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activados
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Inhabilitado
+ </panel.string>
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Guardar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Pulsa para elegir una imagen"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Ubicación:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoría:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Fecha de creación:"/>
+ <text_editor name="creation_date" tool_tip="Fecha de creación" value="[date]"/>
+ <text name="price_for_listing_label" value="Precio por publicarlo:"/>
+ <text_editor name="price_for_listing" tool_tip="Precio por publicarlo.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics:"/>
+ <text_editor name="click_through_text" tool_tip="Información sobre Click through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovación:"/>
+ <text name="auto_renew" value="Activados"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descripción:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descripción:
+ </text>
+ <text name="location_label">
+ Ubicación:
+ </text>
+ <text name="classified_location_edit">
+ cargando...
+ </text>
+ <button label="Configurar en mi posición" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoría:"/>
+ <text name="content_type_label" value="Tipo de contenido:"/>
+ <icons_combo_box label="Contenido general" name="content_type_edit">
+ <icons_combo_box.item label="Contenido Moderado" name="mature_ci" value="Contenido para adultos"/>
+ <icons_combo_box.item label="Contenido general" name="pg_ci" value="General"/>
+ </icons_combo_box>
+ <check_box label="Renovar automáticamente cada semana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Precio por publicarlo:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Precio por publicarlo." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teleporte" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..2520348094
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Clasificado" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="No hay clasificados"/>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
index f058ff668b..0fb502e441 100644
--- a/indra/newview/skins/default/xui/fr/floater_picks.xml
+++ b/indra/newview/skins/default/xui/es/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Favoris"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_interests.xml b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
new file mode 100644
index 0000000000..86dd63390c
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Intereses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quiero:
+ </text>
+ <check_box label="Construye" name="chk0"/>
+ <check_box label="Explora" name="chk1"/>
+ <check_box label="Conoce" name="chk2"/>
+ <check_box label="Encuentra empleo" name="chk6"/>
+ <check_box label="Agrupa" name="chk3"/>
+ <check_box label="Compra" name="chk4"/>
+ <check_box label="Vende" name="chk5"/>
+ <check_box label="Contrata" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitectura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planificación de eventos" name="schk2"/>
+ <check_box label="Preparación de scripts" name="schk4"/>
+ <check_box label="Personajes personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (cargando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (cargando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_notes.xml b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
new file mode 100644
index 0000000000..4cc14e1487
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notas y Privacidad" name="panel_notes">
+ <text name="status_message" value="Notas privadas en este avatar:"/>
+ <text name="status_message2" value="Permitir que este avatar:"/>
+ <check_box label="Ver cuándo estoy conectado" name="status_check"/>
+ <check_box label="Encontrarme en el mapa del mundo" name="map_check"/>
+ <check_box label="Edita, borrar o tomar mis objetos" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_pick.xml b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
new file mode 100644
index 0000000000..4e9f5bbdd5
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (se actualizará tras guardarlo)
+ </panel.string>
+ <line_editor name="pick_location">
+ Cargando...
+ </line_editor>
+ <button label="Teleporte" name="teleport_btn"/>
+ <button label="Mostrar en el mapa" name="show_on_map_btn"/>
+ <button label="Establecer ubicación" name="set_to_curr_location_btn" tool_tip="Configurar en mi posición"/>
+ <button label="Guardar" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
new file mode 100644
index 0000000000..0641b72c13
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destacados" name="panel_picks">
+ <string name="no_picks" value="No hay destacados"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Cuéntale a todos sobre tus lugares favoritos de Second Life.
+ </text>
+ <button label="Nuevo..." name="new_btn"/>
+ <button label="Eliminar..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Cargando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..541593660d
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Actualmente en línea
+ </string>
+ <string name="status_offline">
+ Actualmente sin conexión
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Ninguno"/>
+ <string name="no_group_text" value="Ninguno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desarrollador"/>
+ <string name="FSSupp" value="Soporte"/>
+ <string name="FSQualityAssurance" value="Buscador de fallos"/>
+ <string name="FSGW" value="Portal"/>
+ <text name="name_label" value="Nombre:"/>
+ <button label="Nombre:" name="set_name" tool_tip="Configurar nombre mostrado"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(cargando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status Desconocido"/>
+ <text name="label" value="Fecha de nacimiento en Second Life:"/>
+ <text name="label2" value="Cuenta:"/>
+ <text name="partner_label" value="Compañero/a:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invitar al grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Acerca de:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar objeto:"/>
+ <text name="Give inventory" tool_tip="Soltar elementos de inventario aquí para dárselos a esta persona.">
+ Soltar aquí el nuevo elemento de inventario.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Encontrar en el mapa" label_selected="Encontrar en el mapa" name="show_on_map_btn" tool_tip="Mostrar al Residente en el mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pagar a este Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Ofrecer teleporte" label_selected="Ofrecer teleporte" name="teleport" tool_tip="Ofrecer teleporte al residente"/>
+ <button label="Mensaje instantáneo" label_selected="Mensaje instantáneo" name="im" tool_tip="Abrir una sesión de mensajes instantáneos"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Añadir como amigo" label_selected="Añadir como amigo" name="add_friend" tool_tip="Ofrecer amistad a este Residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear al residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear al residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar en la búsqueda" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_profile_web.xml b/indra/newview/skins/default/xui/es/panel_profile_web.xml
new file mode 100644
index 0000000000..f9a8f4b113
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tiempo de carga: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (cargando..)
+ </line_editor>
+ <flyout_button label="Cargar" name="load" tool_tip="Cargar esta página de perfil con el navegador incorporado.">
+ <flyout_button.item label="Abrir navegador in-viewer" name="open_item"/>
+ <flyout_button.item label="Abrir navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Perfil web emergente"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
index cb6c03dbb5..9aba5299cb 100644
--- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml
@@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Límite de bajada del
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas del terreno (requiere archivos .tga de 512x512, 24 bits)
- </text>
+ Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits)
+ </text>
<text name="height_text_lbl">
1 (bajo)
</text>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 4b7f6a0081..5a03e65b49 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -348,6 +348,24 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="TestingDisconnect">
Probando la desconexión del visor
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando con Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando de Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema al conectar con Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema al publicar en Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema al desconectar de Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectándose a Flickr...
</string>
@@ -662,9 +680,6 @@ pueden adjuntarse a las notas.
<string name="GroupNameNone">
(ninguno)
</string>
- <string name="AvalineCaller">
- Avaline: [ORDER]
- </string>
<string name="AssetErrorNone">
No hay ningún error
</string>
@@ -2549,9 +2564,21 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia
<string name="NoPicksClassifiedsText">
No has creado destacados ni clasificados. Pulsa el botón Más para crear uno.
</string>
+ <string name="NoPicksText">
+ No has creado destacados. Haz clic en el botón Más para crear uno.
+ </string>
+ <string name="NoClassifiedsText">
+ No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
El usuario no tiene clasificados ni destacados
</string>
+ <string name="NoAvatarPicksText">
+ El usuario no tiene destacados
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ El usuario no tiene clasificados
+ </string>
<string name="PicksClassifiedsLoadingText">
Cargando...
</string>
@@ -4469,6 +4496,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="share_alert">
Arrastra los ítems desde el invenbtario hasta aquí
</string>
+ <string name="facebook_post_success">
+ Has publicado en Facebook.
+ </string>
<string name="flickr_post_success">
Has publicado en Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/fr/floater_facebook.xml b/indra/newview/skins/default/xui/fr/floater_facebook.xml
index f5097e7a88..f6e8696e53 100644
--- a/indra/newview/skins/default/xui/fr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/fr/floater_facebook.xml
@@ -10,6 +10,6 @@
Erreur
</text>
<text name="connection_loading_text">
- Chargement...
+ En cours de chargement...
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
index d63d9903ec..46703fe612 100644
--- a/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copier dans l&apos;inventaire
</floater.string>
- <text name="desc txt">
- Description :
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Rapport d&apos;aspect fixe
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe">
- <combo_item name="Unconstrained">
- Sans contraintes
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo du groupe ou profil dans la vie réelle">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profil [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Petites annonces, repères">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="À propos du terrain">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Favoris du profil">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Jeter" name="Discard"/>
- <button label="Enregistrer sous" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Description :
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Rapport d&apos;aspect fixe
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Prévisualiser avec un rapport d&apos;aspect fixe"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Jeter" name="Discard"/>
+ <button label="Enregistrer sous" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_profile.xml b/indra/newview/skins/default/xui/fr/floater_profile.xml
new file mode 100644
index 0000000000..c4af79e946
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Centres d&apos;intérêt" name="panel_profile_interests"/>
+ <panel label="Favoris" name="panel_profile_picks"/>
+ <panel label="Petite annonce" name="panel_profile_classifieds"/>
+ <panel label="Vie réelle" name="panel_profile_firstlife"/>
+ <panel label="Remarques" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Enregistrer les changements apportés au profil et fermer"/>
+ <button label="Annuler" label_selected="Annuler" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
index 8eb05dd945..adb98a68d2 100644
--- a/indra/newview/skins/default/xui/fr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/fr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Envoi par e-mail
</string>
+ <string name="facebook_progress_str">
+ Publication sur Facebook
+ </string>
<string name="profile_progress_str">
Publication
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Enregistrement sur l&apos;ordinateur
</string>
+ <string name="facebook_succeeded_str">
+ Image chargée
+ </string>
<string name="profile_succeeded_str">
Image chargée
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Enregistrement sur l&apos;ordinateur effectué !
</string>
+ <string name="facebook_failed_str">
+ Échec de chargement de l&apos;image dans votre journal Facebook.
+ </string>
<string name="profile_failed_str">
Échec de chargement de l&apos;image sur le flux de votre profil.
</string>
diff --git a/indra/newview/skins/default/xui/fr/menu_name_field.xml b/indra/newview/skins/default/xui/fr/menu_name_field.xml
new file mode 100644
index 0000000000..6c3fba4110
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copier le Nom d&apos;affichage" name="copy_display"/>
+ <menu_item_call label="Copier le Nom de l&apos;agent" name="copy_name"/>
+ <menu_item_call label="Copier l&apos;ID de l&apos;agent" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index e84de375d8..09905f4e5d 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2683,6 +2683,9 @@ Veuillez sélectionner un terrain plus petit.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
index 7b58f2e825..b892d25f26 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annuler" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
index 319737a2af..0e36c2092c 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life !"/>
+ <string name="facebook_friends_empty" value="Vous n&apos;avez actuellement aucun ami Facebook qui est également résident de Second Life. Invitez vos amis Facebook à rejoindre Second Life aujourd&apos;hui !"/>
<string name="facebook_friends_no_connected" value="Vous n&apos;êtes pas connecté(e) à Facebook. Allez à l&apos;onglet Statut pour vous connecter et activer cette fonctionnalité."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amis SL"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
index 3236f35b55..cc4045bc74 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_photo.xml
@@ -4,14 +4,14 @@
<combo_box.item label="Fenêtre actuelle" name="CurrentWindow"/>
<combo_box.item label="640 x 480" name="640x480"/>
<combo_box.item label="800 x 600" name="800x600"/>
- <combo_box.item label="1 024 x 768" name="1024x768"/>
- <combo_box.item label="1 200 x 630" name="1200x630"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtres d&apos;image">
+ <combo_box name="filters_combobox" tool_tip="Filtres d’image">
<combo_box.item label="Aucun filtre" name="NoFilter"/>
</combo_box>
<button label="Actualiser" name="new_snapshot_btn" tool_tip="Cliquer pour actualiser"/>
- <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour activer/désactiver l&apos;aperçu"/>
+ <button label="Aperçu" name="big_preview_btn" tool_tip="Cliquer pour basculer l&apos;aperçu"/>
<text name="caption_label">
Commentaire (facultatif) :
</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
index 9afa42d2aa..dc8e4b9ecc 100644
--- a/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/fr/panel_facebook_status.xml
@@ -6,7 +6,7 @@
Pas connecté(e) à Facebook.
</text>
<panel name="panel_buttons">
- <button label="Connexion..." name="connect_btn"/>
+ <button label="Connexion en cours..." name="connect_btn"/>
<button label="Déconnexion" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Apprenez comment publier sur Facebook]
diff --git a/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..b1b32af7c6
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Inconnu"/>
+ <button name="info_btn" tool_tip="En savoir plus"/>
+ <button name="profile_btn" tool_tip="Voir le profil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_me.xml b/indra/newview/skins/default/xui/fr/panel_me.xml
deleted file mode 100644
index 5676986228..0000000000
--- a/indra/newview/skins/default/xui/fr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Mon profil" name="panel_me">
- <panel label="MES FAVORIS" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 3be6bae52a..e096b5cfe0 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -40,6 +40,7 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="En ligne"/>
<accordion_tab name="tab_all" title="Tout"/>
+ <accordion_tab name="tab_suggested_friends" title="Personnes avec lesquelles vous aimeriez peut-être devenir ami(e)"/>
</accordion>
</panel>
<panel label="GROUPES" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classified.xml b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
new file mode 100644
index 0000000000..b223684c60
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Modéré
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenu Général
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] téléporter, [MAP] carte, [PROFILE] profile
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Activé
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Désactivé
+ </panel.string>
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <string name="publish_label">
+ Publier
+ </string>
+ <string name="save_label">
+ Enregistrer
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Cliquer pour sélectionner une image"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Endroit :"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Date de création :"/>
+ <text_editor name="creation_date" tool_tip="Date de création" value="[date]"/>
+ <text name="price_for_listing_label" value="Coût de l&apos;annonce :"/>
+ <text_editor name="price_for_listing" tool_tip="Coût de l’annonce.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clics :"/>
+ <text_editor name="click_through_text" tool_tip="Parcourir les données en cliquant" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renouv. auto :"/>
+ <text name="auto_renew" value="Activé"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Description :"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titre :
+ </text>
+ <text name="description_label">
+ Description :
+ </text>
+ <text name="location_label">
+ Endroit :
+ </text>
+ <text name="classified_location_edit">
+ en cours de chargement...
+ </text>
+ <button label="Définir sur l’emplacement actuel" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Catégorie :"/>
+ <text name="content_type_label" value="Type de contenu :"/>
+ <icons_combo_box label="Contenu Général" name="content_type_edit">
+ <icons_combo_box.item label="Contenu Modéré" name="mature_ci" value="Adulte"/>
+ <icons_combo_box.item label="Contenu Général" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Renouvellement auto toutes les semaines" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Coût de l&apos;annonce :"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Coût de l’annonce." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Téléportation" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Carte" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifier" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annuler" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..adb3501422
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Petite annonce" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Pas de petites annonces"/>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/floater_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
index 255aa5dcdc..0f65090209 100644
--- a/indra/newview/skins/default/xui/es/floater_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destacados"/>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_interests.xml b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
new file mode 100644
index 0000000000..e8212817d2
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Centres d&apos;intérêt" name="panel_profile_interests">
+ <text name="I Want To:">
+ Je veux :
+ </text>
+ <check_box label="Construire" name="chk0"/>
+ <check_box label="Explorer" name="chk1"/>
+ <check_box label="Rencontrer" name="chk2"/>
+ <check_box label="Être recruté" name="chk6"/>
+ <check_box label="Grouper" name="chk3"/>
+ <check_box label="Acheter" name="chk4"/>
+ <check_box label="Vendre" name="chk5"/>
+ <check_box label="Louer" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Skills:">
+ Compétences :
+ </text>
+ <check_box label="Textures" name="schk0"/>
+ <check_box label="Architecture" name="schk1"/>
+ <check_box label="Modèle" name="schk3"/>
+ <check_box label="Planification des événements" name="schk2"/>
+ <check_box label="Langage de scripts" name="schk4"/>
+ <check_box label="Personnages personnalisés" name="schk5"/>
+ <line_editor name="skills_edit">
+ (en cours de chargement...)
+ </line_editor>
+ <text name="Languages:">
+ Langues :
+ </text>
+ <line_editor name="languages_edit">
+ (en cours de chargement...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
new file mode 100644
index 0000000000..03fb37d72b
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notes &amp; respect de la vie privée" name="panel_notes">
+ <text name="status_message" value="Notes personnelles sur cet avatar:"/>
+ <text name="status_message2" value="Autoriser cet avatar à :"/>
+ <check_box label="Voir quand je suis en ligne" name="status_check"/>
+ <check_box label="Me trouver sur la carte du monde" name="map_check"/>
+ <check_box label="Modifier, supprimer ou prendre mes objets" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_pick.xml b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
new file mode 100644
index 0000000000..017fcff88a
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (mise à jour après enregistrement)
+ </panel.string>
+ <line_editor name="pick_location">
+ En cours de chargement...
+ </line_editor>
+ <button label="Téléportation" name="teleport_btn"/>
+ <button label="Voir sur la carte" name="show_on_map_btn"/>
+ <button label="Définir l&apos;emplacement" name="set_to_curr_location_btn" tool_tip="Définir sur l’emplacement actuel"/>
+ <button label="Enregistrer les favoris" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_picks.xml b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
new file mode 100644
index 0000000000..1644722813
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoris" name="panel_picks">
+ <string name="no_picks" value="Pas de favoris"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Faites connaître aux autres résidents vos endroits favoris dans Second Life.
+ </text>
+ <button label="Nouveau..." name="new_btn"/>
+ <button label="Supprimer..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ En cours de chargement...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..de9cbf6dce
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Actuellement connecté
+ </string>
+ <string name="status_offline">
+ Actuellement déconnecté
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Aucun"/>
+ <string name="no_group_text" value="Aucun"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Développeur"/>
+ <string name="FSSupp" value="Assistance"/>
+ <string name="FSQualityAssurance" value="Suivi des anomalies"/>
+ <string name="FSGW" value="Portail"/>
+ <text name="name_label" value="Nom :"/>
+ <button label="Nom :" name="set_name" tool_tip="Définir un nom d&apos;affichage"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(en cours de chargement...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Statut inconnu"/>
+ <text name="label" value="Date de naissance dans Second Life :"/>
+ <text name="label2" value="Compte :"/>
+ <text name="partner_label" value="Partenaire :"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Groupes :"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Inviter dans le groupe"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="À propos :"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Donner des objets :"/>
+ <text name="Give inventory" tool_tip="Placer les objets de l&apos;inventaire ici pour les donner à cette personne">
+ Placer les objets de l&apos;inventaire ici.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Situer sur la carte" label_selected="Situer sur la carte" name="show_on_map_btn" tool_tip="Localiser le Résident sur la carte"/>
+ <button label="Payer" label_selected="Payer" name="pay" tool_tip="Payer le résident"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Proposer de téléporter" label_selected="Proposer de téléporter" name="teleport" tool_tip="Proposer une téléportation au Résident"/>
+ <button label="Message instantané" label_selected="Message instantané" name="im" tool_tip="Ouvrir une session IM."/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Ajouter un ami" label_selected="Ajouter un ami" name="add_friend" tool_tip="Proposer à ce résident de devenir votre ami"/>
+ <button label="Bloquer" name="block" tool_tip="Bloquer ce Résident"/>
+ <button label="Débloquer" name="unblock" tool_tip="Débloquer ce Résident"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Afficher avec la recherche" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_web.xml b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
new file mode 100644
index 0000000000..70e145ade9
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Heure de chargement : [TIME] secondes"/>
+ <line_editor name="url_edit">
+ (en cours de chargement..)
+ </line_editor>
+ <flyout_button label="Charger" name="load" tool_tip="Charger ce profil avec le navigateur Web incorporé">
+ <flyout_button.item label="Ouvrir dans mon navigateur Web" name="open_item"/>
+ <flyout_button.item label="Ouvrir dans un navigateur externe" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profil de fenêtres web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
index 97f486d3a3..bbab00ca24 100644
--- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite d&apos;abaissement
du terrain" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Textures du terrain (fichiers .tga 512 x 512, 24 bit requis)
- </text>
+ Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis)
+ </text>
<text name="height_text_lbl">
1 (Bas)
</text>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index 16423503e7..21825c6b2f 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -357,6 +357,24 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="TestingDisconnect">
Test de déconnexion du client
</string>
+ <string name="SocialFacebookConnecting">
+ Connexion à Facebook…
+ </string>
+ <string name="SocialFacebookPosting">
+ Publication…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Déconnexion de Facebook…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Un problème est survenu lors de la connexion à Facebook.
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Un problème est survenu lors de la publication sur Facebook.
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Un problème est survenu lors de la déconnexion à Facebook.
+ </string>
<string name="SocialFlickrConnecting">
Connexion à Flickr...
</string>
@@ -674,9 +692,6 @@ peuvent être joints aux notes.
<string name="GroupNameNone">
(aucun)
</string>
- <string name="AvalineCaller">
- Appelant Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Aucune erreur
</string>
@@ -2579,9 +2594,21 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life
<string name="NoPicksClassifiedsText">
Vous n&apos;avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce.
</string>
+ <string name="NoPicksText">
+ Vous n&apos;avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori
+ </string>
+ <string name="NoClassifiedsText">
+ Vous n&apos;avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utilisateur n&apos;a ni favoris ni petites annonces.
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utilisateur n&apos;a pas de favoris
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utilisateur n&apos;a pas de petites annonces
+ </string>
<string name="PicksClassifiedsLoadingText">
Chargement...
</string>
@@ -4559,6 +4586,9 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="share_alert">
Faire glisser les objets de l&apos;inventaire ici
</string>
+ <string name="facebook_post_success">
+ Vous avez publié sur Facebook.
+ </string>
<string name="flickr_post_success">
Vous avez publié sur Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/it/floater_preview_texture.xml b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
index 8e8d020067..02f15b6b7b 100644
--- a/indra/newview/skins/default/xui/it/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/it/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copia nell&apos;Inventario
</floater.string>
- <text name="desc txt">
- Descrizione:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Antreprima rapporto di visualizzazione
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso">
- <combo_item name="Unconstrained">
- Libero
- </combo_item>
- <combo_item name="1:1" tool_tip="Logo del gruppo o profilo nel mondo reale">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Profilo [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Annunci e inserzioni, punti di riferimento">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Informazioni sul terreno">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Preferiti del Profilo">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Elimina" name="Discard"/>
- <button label="Salva con nome" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrizione:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Antreprima rapporto di visualizzazione
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Anteprima con rapporto di visualizzazione fisso"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Elimina" name="Discard"/>
+ <button label="Salva con nome" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_profile.xml b/indra/newview/skins/default/xui/it/floater_profile.xml
new file mode 100644
index 0000000000..7e23f9bbbb
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profilo">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interessi" name="panel_profile_interests"/>
+ <panel label="Preferiti" name="panel_profile_picks"/>
+ <panel label="Annuncio" name="panel_profile_classifieds"/>
+ <panel label="Vita reale" name="panel_profile_firstlife"/>
+ <panel label="Note" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salva modifiche al profilo e chiudi"/>
+ <button label="Annulla" label_selected="Annulla" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/it/floater_snapshot.xml b/indra/newview/skins/default/xui/it/floater_snapshot.xml
index d21c206f6f..c9f71a167e 100644
--- a/indra/newview/skins/default/xui/it/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/it/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Invio e-mail in corso
</string>
+ <string name="facebook_progress_str">
+ Pubblicazione su Facebook in corso
+ </string>
<string name="profile_progress_str">
Caricamento post
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvataggio sul computer in corso
</string>
+ <string name="facebook_succeeded_str">
+ Immagine caricata
+ </string>
<string name="profile_succeeded_str">
Immagine caricata
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvato sul computer.
</string>
+ <string name="facebook_failed_str">
+ Caricamento immagine sul diario di Facebook non riuscito.
+ </string>
<string name="profile_failed_str">
Caricamento immagine sul feed del profilo non riuscito.
</string>
diff --git a/indra/newview/skins/default/xui/it/menu_name_field.xml b/indra/newview/skins/default/xui/it/menu_name_field.xml
new file mode 100644
index 0000000000..9ac863323c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Copia Nome Visualizzato" name="copy_display"/>
+ <menu_item_call label="Copia Nome Agente" name="copy_name"/>
+ <menu_item_call label="Copia ID Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 1c43013255..a69fa07c50 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2685,6 +2685,9 @@ Prova a selezionare una parte di terreno più piccola.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
index ad827696ff..57e422a25b 100644
--- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Annulla" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
index c1c0489f88..28769a010f 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti in Second Life. Invita i tuoi amici di Facebook a partecipare a Second Life!"/>
- <string name="facebook_friends_no_connected" value="Attualmente non sei in collegamento con Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
+ <string name="facebook_friends_empty" value="Attualmente non hai amici su Facebook che sono anche residenti Second Life. Invita ora i tuoi amici di Facebook a unirsi a Second Life!"/>
+ <string name="facebook_friends_no_connected" value="Non sei connesso a Facebook. Accedi alla scheda Stato per collegarti e attivare questa funzionalità."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Amici SL"/>
<accordion_tab name="tab_suggested_friends" title="Aggiungi queste persone come amici SL"/>
</accordion>
<text name="facebook_friends_status">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
index 044b8b6164..8d66f35c3c 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_photo.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
- <combo_box name="resolution_combobox" tool_tip="Risoluzione immagini">
+ <combo_box name="resolution_combobox" tool_tip="Risoluzione immagine">
<combo_box.item label="Finestra attuale" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
<combo_box.item label="1200x630" name="1200x630"/>
</combo_box>
- <combo_box name="filters_combobox" tool_tip="Filtri immagini">
+ <combo_box name="filters_combobox" tool_tip="Filtri immagine">
<combo_box.item label="Nessun filtro" name="NoFilter"/>
</combo_box>
<button label="Aggiorna" name="new_snapshot_btn" tool_tip="Fai clic per aggiornare"/>
diff --git a/indra/newview/skins/default/xui/it/panel_facebook_status.xml b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
index 9b5171043a..7fb1cec78e 100644
--- a/indra/newview/skins/default/xui/it/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/it/panel_facebook_status.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
- <string name="facebook_connected" value="Sei in collegamento con Facebook come:"/>
- <string name="facebook_disconnected" value="Non in collegamento con Facebook"/>
+ <string name="facebook_connected" value="Sei connesso a Facebook come:"/>
+ <string name="facebook_disconnected" value="Non connesso a Facebook"/>
<text name="account_caption_label">
- Non in collegamento con Facebook.
+ Non connesso a Facebook.
</text>
<panel name="panel_buttons">
- <button label="Collegamento..." name="connect_btn"/>
- <button label="Interrompi collegamento" name="disconnect_btn"/>
+ <button label="Connessione in corso..." name="connect_btn"/>
+ <button label="Disconnetti" name="disconnect_btn"/>
<text name="account_learn_more_label">
[http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Come pubblicare su Facebook]
</text>
diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml
index 60028e6098..168524d1ad 100644
--- a/indra/newview/skins/default/xui/it/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_group_general.xml
@@ -46,7 +46,7 @@ Muovi il tuo mouse sopra le opzioni per maggiore aiuto.
<check_box label="Chiunque può aderire" name="open_enrollement" tool_tip="Imposta se questo gruppo permette ai nuovi membri di aderire senza essere invitati."/>
<check_box label="Quota di adesione" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa d&apos;iscrizione per aderire al gruppo"/>
<spinner label="L$" left_delta="136" name="spin_enrollment_fee" tool_tip="I nuovi soci devono pagare questa tassa d&apos;iscrizione quando è selezionata." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Le categorie di accesso definiscono il tipo di contenuti e di comportamenti ammessi in un gruppo">
+ <combo_box name="group_mature_check" tool_tip="Determina se il tuo gruppo contiene informazioni contrassegnate come Moderate opppure no">
<combo_item name="select_mature">
- Seleziona categoria di accesso -
</combo_item>
diff --git a/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..72e644008c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Sconosciuto"/>
+ <button name="info_btn" tool_tip="Maggiori informazioni"/>
+ <button name="profile_btn" tool_tip="Vedi profilo"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_me.xml b/indra/newview/skins/default/xui/it/panel_me.xml
deleted file mode 100644
index a134f6f1de..0000000000
--- a/indra/newview/skins/default/xui/it/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Il mio profilo" name="panel_me">
- <panel label="I MIEI PREFERITI" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml
index 3df2368ae0..9eb93a26e5 100644
--- a/indra/newview/skins/default/xui/it/panel_people.xml
+++ b/indra/newview/skins/default/xui/it/panel_people.xml
@@ -40,6 +40,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Tutto"/>
+ <accordion_tab name="tab_suggested_friends" title="Persone che potresti voler aggiungere agli amici"/>
</accordion>
</panel>
<panel label="GRUPPI" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classified.xml b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
new file mode 100644
index 0000000000..3c88fbe92f
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderato
+ </panel.string>
+ <panel.string name="type_pg">
+ Contenuto Generale
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletrasporto, [MAP] mappa, [PROFILE] profilo
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Abilitato
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Disabilitato
+ </panel.string>
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <string name="publish_label">
+ Pubblica
+ </string>
+ <string name="save_label">
+ Salva
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Fai clic per selezionare un&apos;immagine"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Posizione:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data di creazione:"/>
+ <text_editor name="creation_date" tool_tip="Data di creazione" value="[date]"/>
+ <text name="price_for_listing_label" value="Prezzo per inserzione:"/>
+ <text_editor name="price_for_listing" tool_tip="Prezzo per inserzione.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Clic:"/>
+ <text_editor name="click_through_text" tool_tip="Numero di clic" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Rinnovo automatico:"/>
+ <text name="auto_renew" value="Abilitato"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrizione:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Titolo:
+ </text>
+ <text name="description_label">
+ Descrizione:
+ </text>
+ <text name="location_label">
+ Posizione:
+ </text>
+ <text name="classified_location_edit">
+ caricamento in corso...
+ </text>
+ <button label="Imposta come Luogo Attuale" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo di contenuto:"/>
+ <icons_combo_box label="Contenuto Generale" name="content_type_edit">
+ <icons_combo_box.item label="Contenuto Moderato" name="mature_ci" value="Per adulti"/>
+ <icons_combo_box.item label="Contenuto Generale" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Rinnovo automatico ogni settimana" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Prezzo per inserzione:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Prezzo per inserzione." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletrasporto" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mappa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Modifica" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Annulla" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..6fc0fd0729
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Annuncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nessuno annuncio"/>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..bf8ccef273
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_interests.xml b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
new file mode 100644
index 0000000000..9fe7331e5c
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interessi" name="panel_profile_interests">
+ <text name="I Want To:">
+ Desidero:
+ </text>
+ <check_box label="Costruire" name="chk0"/>
+ <check_box label="Esplorare" name="chk1"/>
+ <check_box label="Incontrare" name="chk2"/>
+ <check_box label="Essere assunto" name="chk6"/>
+ <check_box label="Gruppo" name="chk3"/>
+ <check_box label="Acquistare" name="chk4"/>
+ <check_box label="Vendere" name="chk5"/>
+ <check_box label="Assumere" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Skills:">
+ Abilità:
+ </text>
+ <check_box label="Texture" name="schk0"/>
+ <check_box label="Architettura" name="schk1"/>
+ <check_box label="Realizzazione modelli 3D" name="schk3"/>
+ <check_box label="Organizzazione eventi" name="schk2"/>
+ <check_box label="Scripting" name="schk4"/>
+ <check_box label="Personaggi personalizzati" name="schk5"/>
+ <line_editor name="skills_edit">
+ (caricamento in corso...)
+ </line_editor>
+ <text name="Languages:">
+ Lingue:
+ </text>
+ <line_editor name="languages_edit">
+ (caricamento in corso...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_notes.xml b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
new file mode 100644
index 0000000000..abd5a347c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Note e Privacy" name="panel_notes">
+ <text name="status_message" value="Annotazioni private su questo avatar:"/>
+ <text name="status_message2" value="Consenti a questo avatar di:"/>
+ <check_box label="Vedere quando sono in linea" name="status_check"/>
+ <check_box label="Trovarmi sulla mappa del mondo" name="map_check"/>
+ <check_box label="Modificare, eliminare o prendere i miei oggetti" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_pick.xml b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
new file mode 100644
index 0000000000..5d2b145565
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (si aggiornerà dopo il salvataggio)
+ </panel.string>
+ <line_editor name="pick_location">
+ Caricamento in corso...
+ </line_editor>
+ <button label="Teletrasporto" name="teleport_btn"/>
+ <button label="Mostra sulla mappa" name="show_on_map_btn"/>
+ <button label="Imposta Luogo" name="set_to_curr_location_btn" tool_tip="Imposta come Luogo Attuale"/>
+ <button label="Salva Luogo preferito" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_picks.xml b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
new file mode 100644
index 0000000000..37cffcf622
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Preferiti" name="panel_picks">
+ <string name="no_picks" value="Nessun preferito"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Comunica a tutti quali sono i tuoi posti preferiti in Second Life.
+ </text>
+ <button label="Nuovo..." name="new_btn"/>
+ <button label="Elimina..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Caricamento in corso...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..47af1960a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profilo" name="panel_profile">
+ <string name="status_online">
+ Ora in linea
+ </string>
+ <string name="status_offline">
+ Ora non in linea
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nessuno"/>
+ <string name="no_group_text" value="Nessuno"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Sviluppatore"/>
+ <string name="FSSupp" value="Assistenza"/>
+ <string name="FSQualityAssurance" value="Bug Hunter"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Imposta nome visualizzato"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(caricamento in corso...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Stato Sconosciuto"/>
+ <text name="label" value="Compleanno Second Life:"/>
+ <text name="label2" value="Account:"/>
+ <text name="partner_label" value="Partner:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruppi:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Invita al gruppo:"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Informazioni generali:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Consegna oggetto:"/>
+ <text name="Give inventory" tool_tip="Rilascia gli oggetti dell’inventario per consegnarli a questa persona.">
+ Rilascia l’oggetto dell’inventario qui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Trova sulla mappa" label_selected="Trova sulla mappa" name="show_on_map_btn" tool_tip="Localizza il Residente sulla mappa"/>
+ <button label="Paga" label_selected="Paga" name="pay" tool_tip="Paga del denaro al Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Offri Teletrasporto" label_selected="Offri Teletrasporto" name="teleport" tool_tip="Offri il teletrasporto al Residente"/>
+ <button label="Messaggio istantaneo" label_selected="Messaggio istantaneo" name="im" tool_tip="Apri sessione di messaggistica istantanea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Aggiungi come amico" label_selected="Aggiungi come amico" name="add_friend" tool_tip="Offri amicizia al Residente"/>
+ <button label="Blocca" name="block" tool_tip="Blocca questo Residente"/>
+ <button label="Sblocca" name="unblock" tool_tip="Sblocca questo Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostra nella ricerca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_profile_web.xml b/indra/newview/skins/default/xui/it/panel_profile_web.xml
new file mode 100644
index 0000000000..0c3a8ddcf5
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Tempo di caricamento: [TIME] secondi"/>
+ <line_editor name="url_edit">
+ (caricamento in corso..)
+ </line_editor>
+ <flyout_button label="Carica" name="load" tool_tip="Carica la pagina profilo con il browser Web integrato.">
+ <flyout_button.item label="Apri browser interno" name="open_item"/>
+ <flyout_button.item label="Apri browser esterno" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Profilo web a comparsa"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
index c61ac3ecce..e08c55f63b 100644
--- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite di abbassamento
del terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texture terreno (richiede file 512x512, 24 bit .tga)
- </text>
+ Texture terreno (richiede file 1024x1024, 24 bit .tga)
+ </text>
<text name="height_text_lbl">
1 (basso)
</text>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index ea972e5a13..1ebdadb930 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -353,6 +353,24 @@ Prova ad accedere nuovamente tra un minuto.
<string name="TestingDisconnect">
Verifica scollegamento viewer
</string>
+ <string name="SocialFacebookConnecting">
+ Connessione a Facebook in corso...
+ </string>
+ <string name="SocialFacebookPosting">
+ Caricamento post...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Disconnessione da Facebook in corso...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problemi con la connessione a Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problemi con la disconnessione da Facebook
+ </string>
<string name="SocialFlickrConnecting">
Collegamento a Flickr...
</string>
@@ -667,9 +685,6 @@ possono essere allegati ai biglietti.
<string name="GroupNameNone">
(nessuno)
</string>
- <string name="AvalineCaller">
- Chiamante Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nessun errore
</string>
@@ -2557,9 +2572,21 @@ Se continui a ricevere questo messaggio, contatta l&apos;assistenza Second Life
<string name="NoPicksClassifiedsText">
Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un&apos;inserzione.
</string>
+ <string name="NoPicksText">
+ Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito.
+ </string>
+ <string name="NoClassifiedsText">
+ Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
L&apos;utente non ha luoghi preferiti né inserzioni
</string>
+ <string name="NoAvatarPicksText">
+ L&apos;utente non ha luoghi preferiti
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ L&apos;utente non ha annunci
+ </string>
<string name="PicksClassifiedsLoadingText">
Caricamento in corso...
</string>
@@ -4474,6 +4501,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Offerta cartella di inventario &quot;[ITEM_NAME]&quot;
</string>
+ <string name="facebook_post_success">
+ Hai pubblicato su Facebook.
+ </string>
<string name="flickr_post_success">
Hai pubblicato su Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_picks.xml b/indra/newview/skins/default/xui/ja/floater_picks.xml
deleted file mode 100644
index 359585eb86..0000000000
--- a/indra/newview/skins/default/xui/ja/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="ピック"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
index 4617fd1d92..66ef13948a 100644
--- a/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ja/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
インベントリにコピー
</floater.string>
- <text name="desc txt">
- 説明:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- 縦横比のプレビュー
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー">
- <combo_item name="Unconstrained">
- 非拘束
- </combo_item>
- <combo_item name="1:1" tool_tip="グループ記章か現実世界のプロフィール">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] プロフィール">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="クラシファイド広告、検索一覧、ランドマーク">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地情報">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="プロフィールのピック">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="処分する" name="Discard"/>
- <button label="別名で保存" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 説明:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ 縦横比のプレビュー
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="固定した縦横比のプレビュー"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="処分する" name="Discard"/>
+ <button label="別名で保存" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_profile.xml b/indra/newview/skins/default/xui/ja/floater_profile.xml
new file mode 100644
index 0000000000..e06cd6e8f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="プロフィール">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="趣味" name="panel_profile_interests"/>
+ <panel label="ピック" name="panel_profile_picks"/>
+ <panel label="クラシファイド広告" name="panel_profile_classifieds"/>
+ <panel label="リアルライフ(現実世界)" name="panel_profile_firstlife"/>
+ <panel label="メモ" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="プロフィールの変更を保存して閉じる"/>
+ <button label="キャンセル" label_selected="キャンセル" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ja/floater_snapshot.xml b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
index f04193d034..64f292c75c 100644
--- a/indra/newview/skins/default/xui/ja/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ja/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
メールの送信
</string>
+ <string name="facebook_progress_str">
+ Facebook へ投稿中
+ </string>
<string name="profile_progress_str">
投稿
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
コンピュータに保存
</string>
+ <string name="facebook_succeeded_str">
+ 画像がアップロードされました
+ </string>
<string name="profile_succeeded_str">
画像がアップロードされました
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
コンピュータに保存されました
</string>
+ <string name="facebook_failed_str">
+ Facebook のタイムラインに画像をアップロードできませんでした。
+ </string>
<string name="profile_failed_str">
プロフィールフィードに画像をアップロードできませんでした。
</string>
diff --git a/indra/newview/skins/default/xui/ja/menu_name_field.xml b/indra/newview/skins/default/xui/ja/menu_name_field.xml
new file mode 100644
index 0000000000..8c37d95073
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="表示名をコピー" name="copy_display"/>
+ <menu_item_call label="エージェント名をコピー" name="copy_name"/>
+ <menu_item_call label="エージェント ID をコピー" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index a66552d3fe..92952f4c8a 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2727,6 +2727,9 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
index cf5f2489f1..619e9de65a 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="キャンセル" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
index c48f13456b..ee57d178e8 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_photo.xml
@@ -16,5 +16,5 @@
コメント (オプション):
</text>
<button label="投稿" name="post_photo_btn"/>
- <button label="取り消し" name="cancel_photo_btn"/>
+ <button label="キャンセル" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
index 61138f90c1..e97422a9df 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="場所の俯瞰図を含める" name="add_place_view_cb"/>
<button label="投稿" name="post_place_btn"/>
- <button label="取り消し" name="cancel_place_btn"/>
+ <button label="キャンセル" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
index 9d962c9d62..1f48c9c8c7 100644
--- a/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ja/panel_facebook_status.xml
@@ -9,12 +9,12 @@
<button label="接続..." name="connect_btn"/>
<button label="切断" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Facebook への投稿について]
</text>
</panel>
<text name="status_caption_label">
今、何を考えている?
</text>
<button label="投稿" name="post_status_btn"/>
- <button label="取り消し" name="cancel_status_btn"/>
+ <button label="キャンセル" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..77d3d8f391
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="不明"/>
+ <button name="info_btn" tool_tip="詳細"/>
+ <button name="profile_btn" tool_tip="プロフィールの表示"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_me.xml b/indra/newview/skins/default/xui/ja/panel_me.xml
deleted file mode 100644
index 9b1cf1c8a4..0000000000
--- a/indra/newview/skins/default/xui/ja/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="プロフィール" name="panel_me">
- <panel label="マイ ピック" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml
index 0a295855d0..be00a3c122 100644
--- a/indra/newview/skins/default/xui/ja/panel_people.xml
+++ b/indra/newview/skins/default/xui/ja/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="オンライン"/>
<accordion_tab name="tab_all" title="全員"/>
+ <accordion_tab name="tab_suggested_friends" title="友だちになりたくない人"/>
</accordion>
</panel>
<panel label="グループ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classified.xml b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d1bc07e2c
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderate
+ </panel.string>
+ <panel.string name="type_pg">
+ General コンテンツ
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] テレポート、 [MAP] 地図、 [PROFILE] プロフィール
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 有効
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 無効
+ </panel.string>
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <string name="publish_label">
+ 掲載
+ </string>
+ <string name="save_label">
+ 保存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="クリックして画像を選択"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="場所:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="制作日:"/>
+ <text_editor name="creation_date" tool_tip="制作日" value="[date]"/>
+ <text name="price_for_listing_label" value="掲載価格:"/>
+ <text_editor name="price_for_listing" tool_tip="掲載価格。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="クリック数:"/>
+ <text_editor name="click_through_text" tool_tip="クリックスルーデータ" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動更新:"/>
+ <text name="auto_renew" value="有効"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="説明:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ タイトル:
+ </text>
+ <text name="description_label">
+ 説明:
+ </text>
+ <text name="location_label">
+ 場所:
+ </text>
+ <text name="classified_location_edit">
+ ロード中...
+ </text>
+ <button label="現在地に設定" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="カテゴリ:"/>
+ <text name="content_type_label" value="コンテンツの種類:"/>
+ <icons_combo_box label="General コンテンツ" name="content_type_edit">
+ <icons_combo_box.item label="Moderate コンテンツ" name="mature_ci" value="Mature"/>
+ <icons_combo_box.item label="General コンテンツ" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="毎週自動更新" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="掲載価格:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="掲載価格。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="テレポート" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地図" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編集" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="キャンセル" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..1980c0fa62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="クラシファイド広告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="クラシファイド広告なし"/>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..a4ee262cb3
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_interests.xml b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
new file mode 100644
index 0000000000..93cde6ffec
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="趣味" name="panel_profile_interests">
+ <text name="I Want To:">
+ 次の内容を実行:
+ </text>
+ <check_box label="作る" name="chk0"/>
+ <check_box label="探検" name="chk1"/>
+ <check_box label="出会う" name="chk2"/>
+ <check_box label="雇ってもらう" name="chk6"/>
+ <check_box label="グループ" name="chk3"/>
+ <check_box label="買う" name="chk4"/>
+ <check_box label="販売する" name="chk5"/>
+ <check_box label="雇う" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Skills:">
+ スキル:
+ </text>
+ <check_box label="テクスチャ" name="schk0"/>
+ <check_box label="建築" name="schk1"/>
+ <check_box label="モデリング" name="schk3"/>
+ <check_box label="イベント計画" name="schk2"/>
+ <check_box label="スクリプト" name="schk4"/>
+ <check_box label="キャラクターのカスタマイズ" name="schk5"/>
+ <line_editor name="skills_edit">
+ (ロード中...)
+ </line_editor>
+ <text name="Languages:">
+ 言語:
+ </text>
+ <line_editor name="languages_edit">
+ (ロード中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_notes.xml b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
new file mode 100644
index 0000000000..4b4e0d5e4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="メモとプライバシー" name="panel_notes">
+ <text name="status_message" value="このアバターのプライベートメモ:"/>
+ <text name="status_message2" value="このアバターに次の許可を与える:"/>
+ <check_box label="自分のオンラインステータスを表示する" name="status_check"/>
+ <check_box label="世界地図で自分を探せるようにする" name="map_check"/>
+ <check_box label="自分のオブジェクトを編集・削除・取得できるようにする" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_pick.xml b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
new file mode 100644
index 0000000000..0a20c04ad6
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (掲載後更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ ロード中...
+ </line_editor>
+ <button label="テレポート" name="teleport_btn"/>
+ <button label="地図に表示" name="show_on_map_btn"/>
+ <button label="場所を設定" name="set_to_curr_location_btn" tool_tip="現在地に設定"/>
+ <button label="ピックを保存" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
new file mode 100644
index 0000000000..4cbfadd09d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="ピック" name="panel_picks">
+ <string name="no_picks" value="ピックなし"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life のお気に入りの場所を紹介しましょう。
+ </text>
+ <button label="新規…" name="new_btn"/>
+ <button label="削除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ ロード中...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..5470dc6c82
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="プロフィール" name="panel_profile">
+ <string name="status_online">
+ オンライン中
+ </string>
+ <string name="status_offline">
+ オフライン中
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="なし"/>
+ <string name="no_group_text" value="なし"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開発者"/>
+ <string name="FSSupp" value="サポート"/>
+ <string name="FSQualityAssurance" value="バグハンター"/>
+ <string name="FSGW" value="ゲートウェイ"/>
+ <text name="name_label" value="名前:"/>
+ <button label="名前:" name="set_name" tool_tip="表示名を設定"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(ロード中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="ステータス不明"/>
+ <text name="label" value="Second Life 生年月日:"/>
+ <text name="label2" value="アカウント:"/>
+ <text name="partner_label" value="パートナー:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="グループ:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="グループに招待"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="詳細:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="アイテムを渡す:"/>
+ <text name="Give inventory" tool_tip="インベントリのアイテムをここにドロップしてこの人に渡します。">
+ インベントリのアイテムをここにドロップしてください。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="地図上で見つける" label_selected="地図上で見つける" name="show_on_map_btn" tool_tip="住人を地図上で探す"/>
+ <button label="お金を払う" label_selected="お金を払う" name="pay" tool_tip="住人にお金を支払う"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="テレポートを送る" label_selected="テレポートを送る" name="teleport" tool_tip="住人にテレポートを送る"/>
+ <button label="インスタントメッセージ" label_selected="インスタントメッセージ" name="im" tool_tip="インスタントメッセージを開きます"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="フレンド登録" label_selected="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/>
+ <button label="ブロック" name="block" tool_tip="この住人をブロックする"/>
+ <button label="ブロック解除" name="unblock" tool_tip="この住人のブロックを解除する"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="検索に表示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_profile_web.xml b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
new file mode 100644
index 0000000000..4f56a7e98d
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="ロード時間:[TIME] 秒"/>
+ <line_editor name="url_edit">
+ (ロード中...)
+ </line_editor>
+ <flyout_button label="ロード" name="load" tool_tip="このプロフィールページを、組み込み Web ブラウザでロードします。">
+ <flyout_button.item label="ビューワ内のブラウザを開く" name="open_item"/>
+ <flyout_button.item label="外部ブラウザを開く" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Web プロフィールのポップアウト"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
index fb853c1925..c1080a7d7b 100644
--- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="地形の上昇限度" name="terrain_raise_spin"/>
<spinner label="地形の下降限度" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形テクスチャ(512x512 の 24 bit .tga ファイル)
- </text>
+ 地形テクスチャ(1024x1024 の 24 bit .tga ファイル)
+ </text>
<text name="height_text_lbl">
1(低)
</text>
diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
index 04dfc0176d..f222a4d61a 100644
--- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml
@@ -3,7 +3,7 @@
<button label="ディスクに保存" name="save_to_computer_btn"/>
<button label="持ち物に保存(L$[AMOUNT])" name="save_to_inventory_btn"/>
<button label="プロフィールフィードで共有する" name="save_to_profile_btn"/>
- <button label="Facebook で共有する" name="send_to_facebook_btn"/>
+ <button label="Facebook でシェア" name="send_to_facebook_btn"/>
<button label="Twitter で共有する" name="send_to_twitter_btn"/>
<button label="Flickr で共有する" name="send_to_flickr_btn"/>
<button label="メールにより送信" name="save_to_email_btn"/>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 344f9fcd94..d90772ab0a 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -356,6 +356,24 @@ support@secondlife.com にお問い合わせください。
<string name="TestingDisconnect">
ビューワの接続を切るテスト中
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook に接続中...
+ </string>
+ <string name="SocialFacebookPosting">
+ 投稿中...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook から切断中...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook への接続時のエラー
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook への投稿時のエラー
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook からの切断時のエラー
+ </string>
<string name="SocialFlickrConnecting">
Flickr に接続中...
</string>
@@ -673,9 +691,6 @@ support@secondlife.com にお問い合わせください。
<string name="GroupNameNone">
(なし)
</string>
- <string name="AvalineCaller">
- Avaline コール [ORDER]
- </string>
<string name="AssetErrorNone">
エラーなし
</string>
@@ -2577,9 +2592,21 @@ support@secondlife.com にお問い合わせください。
<string name="NoPicksClassifiedsText">
ピックやクラシファイド広告を作成していません。 作成するには、下にある「プラス」ボタンをクリックします。
</string>
+ <string name="NoPicksText">
+ ピックを作成していません。[新規] ボタンをクリックしてピックを作成する。
+ </string>
+ <string name="NoClassifiedsText">
+ クラシファイド広告を作成していません。[新規] ボタンをクリックしてクラシファイド広告を作成する。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
ピック、またはクラシファイド広告がありません
</string>
+ <string name="NoAvatarPicksText">
+ ピックがありません
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ クラシファイド広告がありません
+ </string>
<string name="PicksClassifiedsLoadingText">
ローディング...
</string>
@@ -4557,6 +4584,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
<string name="share_alert">
インベントリからここにアイテムをドラッグします
</string>
+ <string name="facebook_post_success">
+ Facebook に投稿しました。
+ </string>
<string name="flickr_post_success">
Flickr に投稿しました。
</string>
diff --git a/indra/newview/skins/default/xui/pl/floater_picks.xml b/indra/newview/skins/default/xui/pl/floater_picks.xml
deleted file mode 100644
index a329e834db..0000000000
--- a/indra/newview/skins/default/xui/pl/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<floater name="floater_picks" title="Miejsca" />
diff --git a/indra/newview/skins/default/xui/pl/panel_me.xml b/indra/newview/skins/default/xui/pl/panel_me.xml
deleted file mode 100644
index 431929420a..0000000000
--- a/indra/newview/skins/default/xui/pl/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel label="Mój Profil" name="panel_me">
- <panel label="MIEJSCA" name="panel_picks" />
-</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
index f086a52dcd..2d4286334f 100644
--- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml
@@ -7,7 +7,7 @@
<spinner label="Górny limit terenu" name="terrain_raise_spin" />
<spinner label="Dolny limit terenu" name="terrain_lower_spin" />
<text name="detail_texture_text">
- Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga)
+ Tekstury terenu (1024x1024, 24 bitowy plik .tga)
</text>
<text name="height_text_lbl">
1 (Nisko)
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index 2b182dc3cc..90d2d86c02 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -596,9 +596,6 @@ Spróbuj zalogować się ponownie za minutę.
<string name="GroupNameNone">
(brak danych)
</string>
- <string name="AvalineCaller">
- Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Brak błędu
</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
index c50d7dcda0..a43dec4e7b 100644
--- a/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Gestos" name="check_gesture"/>
<check_box label="Landmarks" name="check_landmark"/>
<check_box label="Anotações" name="check_notecard"/>
- <check_box label="Meshes:" name="check_mesh"/>
+ <check_box label="Malhas" name="check_mesh"/>
<check_box label="Objetos" name="check_object"/>
<check_box label="Scripts" name="check_script"/>
<check_box label="Sons" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_picks.xml b/indra/newview/skins/default/xui/pt/floater_picks.xml
deleted file mode 100644
index 9766196319..0000000000
--- a/indra/newview/skins/default/xui/pt/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Destaques"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
index 6f39635240..90102023a3 100644
--- a/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Copiar para inventário
</floater.string>
- <text name="desc txt">
- Descrição:
- </text>
- <text name="dimensions">
- [WIDTH]px x [HEIGHT]px
- </text>
- <text name="aspect_ratio">
- Visualizar relação de aspecto
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa">
- <combo_item name="Unconstrained">
- Sem limites
- </combo_item>
- <combo_item name="1:1" tool_tip="Símbolo ou perfil RW do grupo">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] perfil">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Procurar anúncios classificados e marcos">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Sobre terrenos">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Perfis destacados">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Descartar" name="Discard"/>
- <button label="Salvar como" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Descrição:
+ </text>
+ <text name="dimensions">
+ [WIDTH]px x [HEIGHT]px
+ </text>
+ <text name="aspect_ratio">
+ Visualizar relação de aspecto
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Visualizar com proporção de aspecto fixa"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Descartar" name="Discard"/>
+ <button label="Salvar como" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_profile.xml b/indra/newview/skins/default/xui/pt/floater_profile.xml
new file mode 100644
index 0000000000..0327211d8f
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Perfil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="Interesses" name="panel_profile_interests"/>
+ <panel label="Destaques" name="panel_profile_picks"/>
+ <panel label="Anúncio" name="panel_profile_classifieds"/>
+ <panel label="Vida real" name="panel_profile_firstlife"/>
+ <panel label="Observações" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Salvar alterações do perfil e fechar"/>
+ <button label="Cancelar" label_selected="Cancelar" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_snapshot.xml b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
index e3812ed708..89901b539f 100644
--- a/indra/newview/skins/default/xui/pt/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/pt/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Enviando e-mail
</string>
+ <string name="facebook_progress_str">
+ Como publicar no Facebook
+ </string>
<string name="profile_progress_str">
Postando
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Salvo no computador
</string>
+ <string name="facebook_succeeded_str">
+ Imagem carregada
+ </string>
<string name="profile_succeeded_str">
Imagem carregada
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Salvo no computador!
</string>
+ <string name="facebook_failed_str">
+ Falha ao carregar a imagem na sua linha do tempo no Facebook.
+ </string>
<string name="profile_failed_str">
Falha ao carregar a imagem no feed do seu perfil.
</string>
diff --git a/indra/newview/skins/default/xui/pt/menu_name_field.xml b/indra/newview/skins/default/xui/pt/menu_name_field.xml
new file mode 100644
index 0000000000..2157de9813
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Exibir Cópia do Nome" name="copy_display"/>
+ <menu_item_call label="Copiar Nome do Agente" name="copy_name"/>
+ <menu_item_call label="Copiar Id do Agente" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index bd1185bdd2..733ec2c709 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -2673,6 +2673,9 @@ Selecione só um objeto.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
index 23e00bfc3a..7b27c811f5 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="Cancelar" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml
index 64a7d13fdb..f6c6d11b87 100644
--- a/indra/newview/skins/default/xui/pt/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml
@@ -46,7 +46,7 @@ Para obter mais ajuda, passe o mouse sobre as opções.
<check_box label="Qualquer um pode entrar" name="open_enrollement" tool_tip="Controla a entrada de novos membros, com ou sem convite."/>
<check_box label="Taxa de inscrição" name="check_enrollment_fee" tool_tip="Controla a cobrança de uma taxa de associação ao grupo."/>
<spinner label="L$" left_delta="120" name="spin_enrollment_fee" tool_tip="Se a opção &apos;Taxa de associação&apos; estiver marcada, novos membros precisam pagar o valor definido para entrar no grupo." width="60"/>
- <combo_box name="group_mature_check" tool_tip="Os níveis de maturidade determinam o tipo de conteúdo e comportamento permitidos em um grupo" width="170">
+ <combo_box name="group_mature_check" tool_tip="Definir se o seu grupo contém informações classificadas como Moderado" width="170">
<combo_item name="select_mature">
- Selecione o nível de maturidade -
</combo_item>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0490878507
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Desconhecido"/>
+ <button name="info_btn" tool_tip="Mais informações"/>
+ <button name="profile_btn" tool_tip="Ver perfil"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_me.xml b/indra/newview/skins/default/xui/pt/panel_me.xml
deleted file mode 100644
index 281c886bd4..0000000000
--- a/indra/newview/skins/default/xui/pt/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Meu perfil" name="panel_me">
- <panel label="MEUS DESTAQUES" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index 2ef01841c5..ce50449b03 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -40,6 +40,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Online"/>
<accordion_tab name="tab_all" title="Todos"/>
+ <accordion_tab name="tab_suggested_friends" title="Pessoas que talvez você deseje adicionar"/>
</accordion>
</panel>
<panel label="GRUPOS" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classified.xml b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
new file mode 100644
index 0000000000..b43a0ad9f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Moderado
+ </panel.string>
+ <panel.string name="type_pg">
+ Conteúdo Geral
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]-
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Ativado
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Desativado
+ </panel.string>
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <string name="publish_label">
+ Publicar
+ </string>
+ <string name="save_label">
+ Salvar
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Selecione uma imagem"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Localização:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Categoria:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Data de criação:"/>
+ <text_editor name="creation_date" tool_tip="Data de criação" value="[date]"/>
+ <text name="price_for_listing_label" value="Preço do anúncio:"/>
+ <text_editor name="price_for_listing" tool_tip="Preço do anúncio.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Cliques:"/>
+ <text_editor name="click_through_text" tool_tip="Dados de click-through" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Renovação automática:"/>
+ <text name="auto_renew" value="Ativado"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Descrição:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Título:
+ </text>
+ <text name="description_label">
+ Descrição:
+ </text>
+ <text name="location_label">
+ Localização:
+ </text>
+ <text name="classified_location_edit">
+ Carregando...
+ </text>
+ <button label="Usar configuração local" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Categoria:"/>
+ <text name="content_type_label" value="Tipo de conteúdo:"/>
+ <icons_combo_box label="Conteúdo Geral" name="content_type_edit">
+ <icons_combo_box.item label="Conteúdo Moderado" name="mature_ci" value="Moderado"/>
+ <icons_combo_box.item label="Conteúdo Geral" name="pg_ci" value="Adequado para menores"/>
+ </icons_combo_box>
+ <check_box label="Renovar automaticamente todas as semanas" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Preço do anúncio:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Preço do anúncio." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Teletransportar" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Mapa" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Editar" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Cancelar" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..f8369954fd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anúncio" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Nenhum classificado"/>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
index dfc539da66..0fb502e441 100644
--- a/indra/newview/skins/default/xui/it/floater_picks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_profile_firstlife.xml
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Preferiti"/>
+<panel label="Perfil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_interests.xml b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
new file mode 100644
index 0000000000..edf74115f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Interesses" name="panel_profile_interests">
+ <text name="I Want To:">
+ Quero:
+ </text>
+ <check_box label="Crie" name="chk0"/>
+ <check_box label="Explore" name="chk1"/>
+ <check_box label="Encontrar" name="chk2"/>
+ <check_box label="Seja contratado" name="chk6"/>
+ <check_box label="Grupo" name="chk3"/>
+ <check_box label="Comprar" name="chk4"/>
+ <check_box label="Venda" name="chk5"/>
+ <check_box label="Contratar" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Skills:">
+ Habilidades:
+ </text>
+ <check_box label="Texturas" name="schk0"/>
+ <check_box label="Arquitetura" name="schk1"/>
+ <check_box label="Modelo" name="schk3"/>
+ <check_box label="Planejamento de evento" name="schk2"/>
+ <check_box label="Scripts" name="schk4"/>
+ <check_box label="Personagens personalizados" name="schk5"/>
+ <line_editor name="skills_edit">
+ (carregando...)
+ </line_editor>
+ <text name="Languages:">
+ Idiomas:
+ </text>
+ <line_editor name="languages_edit">
+ (carregando...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_notes.xml b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
new file mode 100644
index 0000000000..499e371bb7
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Anotações e Privacidade" name="panel_notes">
+ <text name="status_message" value="Notas particulares neste avatar:"/>
+ <text name="status_message2" value="Permitir que esse avatar:"/>
+ <check_box label="Ver quando eu estiver conectado" name="status_check"/>
+ <check_box label="Encontre-me no mapa-múndi" name="map_check"/>
+ <check_box label="Pegar, editar ou excluir objetos meus" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_pick.xml b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
new file mode 100644
index 0000000000..2dd37b38f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (salvar para atualizar)
+ </panel.string>
+ <line_editor name="pick_location">
+ Carregando...
+ </line_editor>
+ <button label="Teletransportar" name="teleport_btn"/>
+ <button label="Mostrar no mapa" name="show_on_map_btn"/>
+ <button label="Definir Localização" name="set_to_curr_location_btn" tool_tip="Usar configuração local"/>
+ <button label="Salvar destaque" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
new file mode 100644
index 0000000000..f9ead974dc
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Destaques" name="panel_picks">
+ <string name="no_picks" value="Nenhum"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Conte a todos sobre os seu lugares favoritos no Second Life.
+ </text>
+ <button label="Novo..." name="new_btn"/>
+ <button label="Excluir..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Carregando...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..8723b1bf58
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Perfil" name="panel_profile">
+ <string name="status_online">
+ Atualmente Online
+ </string>
+ <string name="status_offline">
+ Atualmente Offline
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Nenhum"/>
+ <string name="no_group_text" value="Nenhum"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Desenvolvedor"/>
+ <string name="FSSupp" value="Suporte"/>
+ <string name="FSQualityAssurance" value="Caçador de Bug"/>
+ <string name="FSGW" value="Gateway"/>
+ <text name="name_label" value="Nome:"/>
+ <button label="Nome:" name="set_name" tool_tip="Definir nome de tela"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(carregando...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Status desconhecido"/>
+ <text name="label" value="Aniversário Second Life:"/>
+ <text name="label2" value="Conta:"/>
+ <text name="partner_label" value="Parceiro(a):"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Grupos:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Convidar para entrar no grupo"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Sobre:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Dar o item:"/>
+ <text name="Give inventory" tool_tip="Arraste e solte o item novo do inventário aqui para dá-los a esta pessoa.">
+ Arraste e solte o item novo do inventário aqui.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Localizar no mapa" label_selected="Localizar no mapa" name="show_on_map_btn" tool_tip="Localizar o Residente no mapa"/>
+ <button label="Pagar" label_selected="Pagar" name="pay" tool_tip="Pague em dinheiro para o Residente"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Teletransportar?" label_selected="Teletransportar?" name="teleport" tool_tip="Oferecer teletransporte ao Residente"/>
+ <button label="Mensagem instantânea" label_selected="Mensagem instantânea" name="im" tool_tip="Abrir sessão de mensagem instantânea"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Adicionar amigo" label_selected="Adicionar amigo" name="add_friend" tool_tip="Oferecer amizade ao residente"/>
+ <button label="Bloquear" name="block" tool_tip="Bloquear este Residente"/>
+ <button label="Desbloquear" name="unblock" tool_tip="Desbloquear este Residente"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Mostrar nos resultados de busca" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_profile_web.xml b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
new file mode 100644
index 0000000000..0f556c7dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Carregar tempo: [TIME] segundos"/>
+ <line_editor name="url_edit">
+ (carregando..)
+ </line_editor>
+ <flyout_button label="Carregar" name="load" tool_tip="Carregar esta página de perfil com navegador embutido">
+ <flyout_button.item label="Abrir no visualizador do navegador" name="open_item"/>
+ <flyout_button.item label="Abrir no navegador externo" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Abra o perfil da web"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
index 74330a8946..1d312aeed9 100644
--- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
@@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/>
<spinner bottom_delta="-34" label="Limite mais baixo do
terreno" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Texturas de terreno (exige arquivos .tga 512x512, 24 bit)
- </text>
+ Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit)
+ </text>
<text name="height_text_lbl">
1 (Baixo)
</text>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 7c593ab3be..ae452d6a4d 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -47,7 +47,7 @@ Placa de vídeo: [GRAPHICS_CARD_VENDOR]
Placa gráfica: [GRAPHICS_CARD]
</string>
<string name="AboutDriver">
- Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR]
+ Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]
</string>
<string name="AboutOGL">
Versão do OpenGL: [OPENGL_VERSION]
@@ -313,6 +313,24 @@ Aguarde um minuto antes que tentar logar-se novamente.
<string name="TestingDisconnect">
Teste de desconexão
</string>
+ <string name="SocialFacebookConnecting">
+ Conectando ao Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Publicando...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Desconectando do Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Problema ao conectar ao Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Problema ao publicar no Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Problema ao desconectar do Facebook
+ </string>
<string name="SocialFlickrConnecting">
Conectando ao Flickr...
</string>
@@ -627,9 +645,6 @@ ser anexado às anotações.
<string name="GroupNameNone">
(nenhum)
</string>
- <string name="AvalineCaller">
- Interlocutor Avaline [ORDER]
- </string>
<string name="AssetErrorNone">
Nenhum erro
</string>
@@ -2517,9 +2532,21 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se
<string name="NoPicksClassifiedsText">
Você não criou nenhum Destaque ou Anúncio. Clique no botão &quot;+&quot; para criar um Destaque ou Anúncio.
</string>
+ <string name="NoPicksText">
+ Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher
+ </string>
+ <string name="NoClassifiedsText">
+ Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado
+ </string>
<string name="NoAvatarPicksClassifiedsText">
O usuário não tem nenhum destaque ou anúncio
</string>
+ <string name="NoAvatarPicksText">
+ Usuário não tem escolha
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Usuário não tem anúncio
+ </string>
<string name="PicksClassifiedsLoadingText">
Carregando...
</string>
@@ -4433,6 +4460,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="inventory_folder_offered-im">
Pasta do inventário &apos;[ITEM_NAME]&apos; oferecida
</string>
+ <string name="facebook_post_success">
+ Você publicou no Facebook.
+ </string>
<string name="flickr_post_success">
Você publicou no Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
index 7c1d3b52c5..bf90d898f9 100644
--- a/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/ru/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Жесты" name="check_gesture"/>
<check_box label="Закладки" name="check_landmark"/>
<check_box label="Заметки" name="check_notecard"/>
- <check_box label="Меши" name="check_mesh"/>
+ <check_box label="Полисетки" name="check_mesh"/>
<check_box label="Объекты" name="check_object"/>
<check_box label="Скрипты" name="check_script"/>
<check_box label="Звуки" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_picks.xml b/indra/newview/skins/default/xui/ru/floater_picks.xml
deleted file mode 100644
index e0ae8d6f03..0000000000
--- a/indra/newview/skins/default/xui/ru/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Подборка"/>
diff --git a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
index 46d2a37503..e3921a75ac 100644
--- a/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/ru/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Копировать в инвентарь
</floater.string>
- <text name="desc txt">
- Описание:
- </text>
- <text name="dimensions">
- [WIDTH]пикселей x [HEIGHT]пикселей
- </text>
- <text name="aspect_ratio">
- Просмотр изображения с соотношением сторон
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон">
- <combo_item name="Unconstrained">
- Без ограничения
- </combo_item>
- <combo_item name="1:1" tool_tip="Символ группы или профиль в реальном мире">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="Профиль для [SECOND_LIFE]">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="Реклама, поиск и закладки">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="О земле">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Профиль подборки">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="OK" name="Keep"/>
- <button label="Отменить" name="Discard"/>
- <button label="Сохранить как" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Описание:
+ </text>
+ <text name="dimensions">
+ [WIDTH]пикселей x [HEIGHT]пикселей
+ </text>
+ <text name="aspect_ratio">
+ Предварительный просмотр соотношения сторон
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Просмотр изображения с фиксированным соотношением сторон"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="OK" name="Keep"/>
+ <button label="Сбросить" name="Discard"/>
+ <button label="Сохранить как" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_profile.xml b/indra/newview/skins/default/xui/ru/floater_profile.xml
new file mode 100644
index 0000000000..6f8daf0a62
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Профиль">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Веб" name="panel_profile_web"/>
+ <panel label="Круг интересов" name="panel_profile_interests"/>
+ <panel label="Подборка" name="panel_profile_picks"/>
+ <panel label="Объявление" name="panel_profile_classifieds"/>
+ <panel label="Реальная жизнь" name="panel_profile_firstlife"/>
+ <panel label="Примечания" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="OK" name="ok_btn" tool_tip="Сохранить изменения в профиле и закрыть"/>
+ <button label="Отменить" label_selected="Отменить" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
index 3ac8cb74b4..89a453d9cd 100644
--- a/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/ru/floater_report_abuse.xml
@@ -67,7 +67,7 @@
<combo_box.item label="Земля &gt; Посягательство &gt; Объекты или текстуры" name="Land__Encroachment__Objects_textures"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Частицы" name="Land__Encroachment__Particles"/>
<combo_box.item label="Земля &gt; Посягательство &gt; Деревья/растения" name="Land__Encroachment__Trees_plants"/>
- <combo_box.item label="Нарушение правил игр на ловкость" name="Wagering_gambling"/>
+ <combo_box.item label="Нарушение игровых правил" name="Wagering_gambling"/>
<combo_box.item label="Другое" name="Other"/>
</combo_box>
<text name="abuser_name_title">
diff --git a/indra/newview/skins/default/xui/ru/floater_snapshot.xml b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
index 97de279b8f..a796d942f3 100644
--- a/indra/newview/skins/default/xui/ru/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/ru/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
Отправка письма
</string>
+ <string name="facebook_progress_str">
+ Публикация в Facebook
+ </string>
<string name="profile_progress_str">
Публикация
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Сохранение на компьютере
</string>
+ <string name="facebook_succeeded_str">
+ Изображение загружено
+ </string>
<string name="profile_succeeded_str">
Изображение отправлено
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Сохранено на компьютере!
</string>
+ <string name="facebook_failed_str">
+ Не удалось передать изображение на вашу хронику Facebook.
+ </string>
<string name="profile_failed_str">
Не удалось передать изображение в ваш профиль.
</string>
diff --git a/indra/newview/skins/default/xui/ru/menu_name_field.xml b/indra/newview/skins/default/xui/ru/menu_name_field.xml
new file mode 100644
index 0000000000..889f3c37ab
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Копировать отображаемое имя" name="copy_display"/>
+ <menu_item_call label="Копировать имя агента" name="copy_name"/>
+ <menu_item_call label="Копировать Id агента" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index bfcda798be..e75fd1fd82 100644
--- a/indra/newview/skins/default/xui/ru/notifications.xml
+++ b/indra/newview/skins/default/xui/ru/notifications.xml
@@ -2682,6 +2682,9 @@
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
index a2f06dbadf..ec457c4565 100644
--- a/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/ru/panel_edit_classified.xml
@@ -46,8 +46,8 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
- <button label="Отмена" name="cancel_btn"/>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
</layout_panel>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
index 746da8d523..1e4d1346f7 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_friends.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Сейчас у вас нет друзей по Facebook, которые также были бы жителями Second Life. Предложите своим друзьям по Facebook присоединиться к Second Life!"/>
+ <string name="facebook_friends_empty" value="Сейчас у вас нет друзей в Facebook, которые являются также жителями Second Life. Предложите своим друзьям в Facebook присоединиться к Second Life!"/>
<string name="facebook_friends_no_connected" value="Сейчас вы не подключены к Facebook. Перейдите на вкладку «Статус», чтобы подключиться и включить эту функцию."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="Друзья по SL"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
index 143a57fec7..50296778ff 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_photo.xml
@@ -2,19 +2,19 @@
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Разрешение изображения">
<combo_box.item label="Текущее окно" name="CurrentWindow"/>
- <combo_box.item label="640x480" name="640x480"/>
- <combo_box.item label="800x600" name="800x600"/>
- <combo_box.item label="1024x768" name="1024x768"/>
- <combo_box.item label="1200x630" name="1200x630"/>
+ <combo_box.item label="640 x 480" name="640x480"/>
+ <combo_box.item label="800 x 600" name="800x600"/>
+ <combo_box.item label="1024 x 768" name="1024x768"/>
+ <combo_box.item label="1200 x 630" name="1200x630"/>
</combo_box>
<combo_box name="filters_combobox" tool_tip="Фильтры изображений">
<combo_box.item label="Без фильтра" name="NoFilter"/>
</combo_box>
- <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкните для обновления"/>
- <button label="Просмотр" name="big_preview_btn" tool_tip="Щелкните для смены вида"/>
+ <button label="Обновить" name="new_snapshot_btn" tool_tip="Щелкнуть для обновления"/>
+ <button label="Предпросмотр" name="big_preview_btn" tool_tip="Щелкнуть для смены вида"/>
<text name="caption_label">
Комментарий (не обязательно):
</text>
<button label="Опубликовать" name="post_photo_btn"/>
- <button label="Отмена" name="cancel_photo_btn"/>
+ <button label="Отменить" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
index 7d0917a43a..a7fadca059 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_place.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_place">
<text name="place_caption_label">
- Напишите о том, где вы:
+ Сообщите, где вы находитесь:
</text>
<check_box initial_value="false" label="Включить вид места сверху" name="add_place_view_cb"/>
<button label="Опубликовать" name="post_place_btn"/>
- <button label="Отмена" name="cancel_place_btn"/>
+ <button label="Отменить" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
index c651a8087c..826ac6a08c 100644
--- a/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/ru/panel_facebook_status.xml
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Вы подключились к Facebook как:"/>
- <string name="facebook_disconnected" value="Не подключено к Facebook"/>
+ <string name="facebook_disconnected" value="Нет подключения к Facebook"/>
<text name="account_caption_label">
- Не подключено к Facebook.
+ Нет подключения к Facebook.
</text>
<panel name="panel_buttons">
- <button label="Подключение..." name="connect_btn"/>
- <button label="Отключить" name="disconnect_btn"/>
+ <button label="Соединение..." name="connect_btn"/>
+ <button label="Разъединить" name="disconnect_btn"/>
<text name="account_learn_more_label">
- [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 О публикации в Facebook]
+ [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Узнать о публикации в Facebook]
</text>
</panel>
<text name="status_caption_label">
О чем вы думаете?
</text>
<button label="Опубликовать" name="post_status_btn"/>
- <button label="Отмена" name="cancel_status_btn"/>
+ <button label="Отменить" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..3408969d09
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Неизвестно"/>
+ <button name="info_btn" tool_tip="Больше информации"/>
+ <button name="profile_btn" tool_tip="Посмотреть профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_me.xml b/indra/newview/skins/default/xui/ru/panel_me.xml
deleted file mode 100644
index 21a125af87..0000000000
--- a/indra/newview/skins/default/xui/ru/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Мой профиль" name="panel_me">
- <panel label="МОЯ ПОДБОРКА" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
index 5e3de180f9..331ba889d8 100644
--- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Перетаскивайте сюда закладки, чтобы было удобнее переходить в любимые места в Second Life!">
Избранное
</label>
- <more_button name="&gt;&gt;" tool_tip="Показать больше избранного">
+ <more_button name="&gt;&gt;" tool_tip="Показать больше избранного" width="60">
Больше ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/ru/panel_people.xml b/indra/newview/skins/default/xui/ru/panel_people.xml
index 0812eb7433..8170c8d26f 100644
--- a/indra/newview/skins/default/xui/ru/panel_people.xml
+++ b/indra/newview/skins/default/xui/ru/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Онлайн"/>
<accordion_tab name="tab_all" title="Все"/>
+ <accordion_tab name="tab_suggested_friends" title="С кем вы можете подружиться"/>
</accordion>
</panel>
<panel label="ГРУППЫ" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classified.xml b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
new file mode 100644
index 0000000000..2d3ed685c0
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Умеренная
+ </panel.string>
+ <panel.string name="type_pg">
+ Общий контент
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ Телепорт [TELEPORT], карта [MAP], профиль [PROFILE]
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Включен
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Отключен
+ </panel.string>
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <string name="publish_label">
+ Опубликовать
+ </string>
+ <string name="save_label">
+ Сохранить
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Щелкнуть для выбора изображения"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Местоположение:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Категория:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Дата создания:"/>
+ <text_editor name="creation_date" tool_tip="Дата создания" value="[date]"/>
+ <text name="price_for_listing_label" value="Стоимость размещения:"/>
+ <text_editor name="price_for_listing" tool_tip="Цена за размещение.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Клики:"/>
+ <text_editor name="click_through_text" tool_tip="Информация о переходах" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Автоматическое продление:"/>
+ <text name="auto_renew" value="Включен"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Описание:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Название:
+ </text>
+ <text name="description_label">
+ Описание:
+ </text>
+ <text name="location_label">
+ Местоположение:
+ </text>
+ <text name="classified_location_edit">
+ загрузка...
+ </text>
+ <button label="Установить в текущее местоположение" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Категория:"/>
+ <text name="content_type_label" value="Тип контента:"/>
+ <icons_combo_box label="Общий контент" name="content_type_edit">
+ <icons_combo_box.item label="Умеренный контент" name="mature_ci" value="Возрастной"/>
+ <icons_combo_box.item label="Общий контент" name="pg_ci" value="C разрешения родителей"/>
+ </icons_combo_box>
+ <check_box label="Автоматическое обновление каждую неделю" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="Стоимость размещения:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="Цена за размещение." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Телепорт" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Карта" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Редактировать" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="Отменить" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..fac494682a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Объявление" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="Нет рекламы"/>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..f5ac5e906a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_interests.xml b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
new file mode 100644
index 0000000000..ba1c3d0357
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Круг интересов" name="panel_profile_interests">
+ <text name="I Want To:">
+ Я собираюсь:
+ </text>
+ <check_box label="Построить" name="chk0"/>
+ <check_box label="Просмотреть" name="chk1"/>
+ <check_box label="Встретить" name="chk2"/>
+ <check_box label="Получить работу" name="chk6"/>
+ <check_box label="Группа" name="chk3"/>
+ <check_box label="Купить" name="chk4"/>
+ <check_box label="Продать" name="chk5"/>
+ <check_box label="Нанять" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Skills:">
+ Навыки:
+ </text>
+ <check_box label="Текстуры" name="schk0"/>
+ <check_box label="Архитектура" name="schk1"/>
+ <check_box label="Моделирование" name="schk3"/>
+ <check_box label="Планирование мероприятия" name="schk2"/>
+ <check_box label="Создавать сценарии" name="schk4"/>
+ <check_box label="Пользовательские символы" name="schk5"/>
+ <line_editor name="skills_edit">
+ (загрузка…)
+ </line_editor>
+ <text name="Languages:">
+ Языки:
+ </text>
+ <line_editor name="languages_edit">
+ (загрузка…)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_notes.xml b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
new file mode 100644
index 0000000000..41117c743a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Примечания и конфиденциальность" name="panel_notes">
+ <text name="status_message" value="Личные заметки об этом аватаре:"/>
+ <text name="status_message2" value="Разрешить этому аватару:"/>
+ <check_box label="Смотреть, когда я в сети" name="status_check"/>
+ <check_box label="Найти меня на карте мира" name="map_check"/>
+ <check_box label="Редактировать, удалять или брать мои объекты" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_pick.xml b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
new file mode 100644
index 0000000000..a2ff5710ea
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (будет обновлено после сохранения)
+ </panel.string>
+ <line_editor name="pick_location">
+ Загрузка...
+ </line_editor>
+ <button label="Телепорт" name="teleport_btn"/>
+ <button label="Показать на карте" name="show_on_map_btn"/>
+ <button label="Указать местоположение" name="set_to_curr_location_btn" tool_tip="Установить в текущее местоположение"/>
+ <button label="Сохранить подборку" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_picks.xml b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
new file mode 100644
index 0000000000..227b3f82b8
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Подборка" name="panel_picks">
+ <string name="no_picks" value="Нет подборки"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Сообщить всем о ваших избранных службах в Second Life.
+ </text>
+ <button label="Новый..." name="new_btn"/>
+ <button label="Удалить..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Загрузка...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..e7a66ba29e
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Профиль" name="panel_profile">
+ <string name="status_online">
+ В настоящее время в режиме онлайн
+ </string>
+ <string name="status_offline">
+ В настоящее время в режиме оффлайн
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Никто"/>
+ <string name="no_group_text" value="Никто"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Разработчик"/>
+ <string name="FSSupp" value="Поддержка"/>
+ <string name="FSQualityAssurance" value="Отладчик"/>
+ <string name="FSGW" value="Межсетевой интерфейс"/>
+ <text name="name_label" value="Имя:"/>
+ <button label="Имя:" name="set_name" tool_tip="Задать отображаемое имя"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(загрузка…)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Статус неизвестен"/>
+ <text name="label" value="Дата рождения в Second Life:"/>
+ <text name="label2" value="Аккаунт:"/>
+ <text name="partner_label" value="Партнер:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Группы:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Пригласить в группу"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="О нас:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Передать вещь:"/>
+ <text name="Give inventory" tool_tip="Сбросить вещи из инвентаря здесь для передачи их этому игроку.">
+ Сбросить вещь из инвентаря здесь.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Найти на карте" label_selected="Найти на карте" name="show_on_map_btn" tool_tip="Найти жителя на карте"/>
+ <button label="Оплатить" label_selected="Оплатить" name="pay" tool_tip="Выплатить деньги резиденту"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Предложить телепорт" label_selected="Предложить телепорт" name="teleport" tool_tip="Предложить телепорт этому жителю"/>
+ <button label="Мгновенное сообщение" label_selected="Мгновенное сообщение" name="im" tool_tip="Начать сеанс IM"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Добавить друга" label_selected="Добавить друга" name="add_friend" tool_tip="Предложить дружбу этому жителю"/>
+ <button label="Заблокировать" name="block" tool_tip="Заблокировать этого жителя"/>
+ <button label="Разблокировать" name="unblock" tool_tip="Разблокировать этого жителя"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Показать в поиске" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_profile_web.xml b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
new file mode 100644
index 0000000000..18a17e2586
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Веб" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Время загрузки: [TIME] секунд"/>
+ <line_editor name="url_edit">
+ (загрузка…)
+ </line_editor>
+ <flyout_button label="Загрузить" name="load" tool_tip="Загрузить эту страницу с профилем с помощью встроенного веб-браузера.">
+ <flyout_button.item label="Открыть в просмотрщике браузера" name="open_item"/>
+ <flyout_button.item label="Открыть во внешнем браузере" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Всплывающий веб-профиль"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
index af25565226..76b4f513a8 100644
--- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/>
<spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Текстуры ландшафта (требования: 512x512, 24-битные, TGA)
- </text>
+ Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA)
+ </text>
<text name="height_text_lbl">
1 (Низ)
</text>
diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml
index 95b1664279..61d836a2d1 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -357,6 +357,24 @@ support@secondlife.com.
<string name="TestingDisconnect">
Тестирование отключения клиента
</string>
+ <string name="SocialFacebookConnecting">
+ Подключение к Facebook...
+ </string>
+ <string name="SocialFacebookPosting">
+ Публикация...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Отключение от Facebook...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Проблема с подключением к Facebook
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Проблемы при публикации в Facebook
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Проблема с отключением от Facebook
+ </string>
<string name="SocialFlickrConnecting">
Подключение к Flickr...
</string>
@@ -671,9 +689,6 @@ support@secondlife.com.
<string name="GroupNameNone">
(нет)
</string>
- <string name="AvalineCaller">
- [ORDER] абонента Avaline
- </string>
<string name="AssetErrorNone">
Ошибок нет
</string>
@@ -2576,9 +2591,21 @@ support@secondlife.com.
<string name="NoPicksClassifiedsText">
Вы не создали подборки или рекламы. Нажмите кнопку со знаком «плюс» ниже, чтобы создать подборку или рекламу
</string>
+ <string name="NoPicksText">
+ Вы не сделали никакой подборки. Нажмите кнопку Создать, чтобы сделать подборку.
+ </string>
+ <string name="NoClassifiedsText">
+ Вы не сделали никакой рекламы. Нажмите кнопку Создать, чтобы сделать рекламу.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
У жителя нет подборки или рекламы
</string>
+ <string name="NoAvatarPicksText">
+ У пользователя нет подборки
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ У пользователя нет объявлений
+ </string>
<string name="PicksClassifiedsLoadingText">
Загрузка...
</string>
@@ -4553,6 +4580,9 @@ support@secondlife.com.
<string name="share_alert">
Перетаскивайте вещи из инвентаря сюда
</string>
+ <string name="facebook_post_success">
+ Вы опубликовали сообщение в Facebook.
+ </string>
<string name="flickr_post_success">
Вы опубликовали сообщение в Flickr.
</string>
diff --git a/indra/newview/skins/default/xui/tr/floater_facebook.xml b/indra/newview/skins/default/xui/tr/floater_facebook.xml
index 656a4a81c9..d8cbd84ed1 100644
--- a/indra/newview/skins/default/xui/tr/floater_facebook.xml
+++ b/indra/newview/skins/default/xui/tr/floater_facebook.xml
@@ -3,7 +3,7 @@
<tab_container name="tabs">
<panel label="DURUM" name="panel_facebook_status"/>
<panel label="FOTOĞRAF" name="panel_facebook_photo"/>
- <panel label="KONUMA GİRİŞ YAPIN" name="panel_facebook_place"/>
+ <panel label="GİRİŞ YAP" name="panel_facebook_place"/>
<panel label="ARKADAŞLAR" name="panel_facebook_friends"/>
</tab_container>
<text name="connection_error_text">
diff --git a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
index accb1ed71c..caa8497d3a 100644
--- a/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/tr/floater_inventory_view_finder.xml
@@ -6,7 +6,7 @@
<check_box label="Mimikler" name="check_gesture"/>
<check_box label="Yer İmleri" name="check_landmark"/>
<check_box label="Not Kartları" name="check_notecard"/>
- <check_box label="Örgüler" name="check_mesh"/>
+ <check_box label="Ağlar" name="check_mesh"/>
<check_box label="Nesneler" name="check_object"/>
<check_box label="Komut Dosyaları" name="check_script"/>
<check_box label="Sesler" name="check_sound"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_picks.xml b/indra/newview/skins/default/xui/tr/floater_picks.xml
deleted file mode 100644
index 5aee6ae091..0000000000
--- a/indra/newview/skins/default/xui/tr/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="Seçimler"/>
diff --git a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
index 8302c62070..8ba9123545 100644
--- a/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/tr/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
Envantere Kopyala
</floater.string>
- <text name="desc txt">
- Açıklama:
- </text>
- <text name="dimensions">
- [WIDTH] pks x [HEIGHT] pks
- </text>
- <text name="aspect_ratio">
- En boy oranını önizle
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle">
- <combo_item name="Unconstrained">
- Kısıtsız
- </combo_item>
- <combo_item name="1:1" tool_tip="Grup işaretleri veya Real World profili">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] profili">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="İlanlar ve arama listeleri, yer imleri">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="Arazi hakkında">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="Profil seçmeleri">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="Tamam" name="Keep"/>
- <button label="At" name="Discard"/>
- <button label="Farklı Kaydet" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ Açıklama:
+ </text>
+ <text name="dimensions">
+ [WIDTH]pks x [HEIGHT]pks
+ </text>
+ <text name="aspect_ratio">
+ En boy oranını önizle
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="Sabit en boy oranında önizle"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="Tamam" name="Keep"/>
+ <button label="At" name="Discard"/>
+ <button label="Farklı Kaydet" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_profile.xml b/indra/newview/skins/default/xui/tr/floater_profile.xml
new file mode 100644
index 0000000000..bb158ddf66
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="Profil">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="Second Life" name="panel_profile_secondlife"/>
+ <panel label="Web" name="panel_profile_web"/>
+ <panel label="İlgi alanları" name="panel_profile_interests"/>
+ <panel label="Favoriler" name="panel_profile_picks"/>
+ <panel label="İlan" name="panel_profile_classifieds"/>
+ <panel label="Gerçek Hayat" name="panel_profile_firstlife"/>
+ <panel label="Notlar" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="Tamam" name="ok_btn" tool_tip="Değişiklikleri profile kaydet ve kapat"/>
+ <button label="İptal Et" label_selected="İptal Et" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/tr/floater_snapshot.xml b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
index be6c58e8cf..8496194700 100644
--- a/indra/newview/skins/default/xui/tr/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/tr/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
E-posta Gönderiliyor
</string>
+ <string name="facebook_progress_str">
+ Facebook&apos;ta yayınlanıyor
+ </string>
<string name="profile_progress_str">
Yayınlanıyor
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
Bilgisayara Kaydediliyor
</string>
+ <string name="facebook_succeeded_str">
+ Görüntü yüklendi
+ </string>
<string name="profile_succeeded_str">
Görüntü yüklendi
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
Bilgisayara Kaydedildi!
</string>
+ <string name="facebook_failed_str">
+ Görüntü Facebook zaman tünelinize yüklenemedi.
+ </string>
<string name="profile_failed_str">
Görüntü Profil Akışınıza yüklenemedi.
</string>
diff --git a/indra/newview/skins/default/xui/tr/menu_name_field.xml b/indra/newview/skins/default/xui/tr/menu_name_field.xml
new file mode 100644
index 0000000000..b1afd737c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="Görünen Adı Kopyala" name="copy_display"/>
+ <menu_item_call label="Aracı Adını Kopyala" name="copy_name"/>
+ <menu_item_call label="Aracı Kimliğini Kopyala" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 5403a78f22..17d2969d19 100644
--- a/indra/newview/skins/default/xui/tr/notifications.xml
+++ b/indra/newview/skins/default/xui/tr/notifications.xml
@@ -2682,6 +2682,9 @@ Daha küçük bir arazi parçası seçmeyi deneyin.
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
index fc444f21f6..78c34a3ac0 100644
--- a/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/tr/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="İptal Et" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
index 8184d6d7cf..edbe87d74c 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_friends.xml
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_friends">
- <string name="facebook_friends_empty" value="Şu an için aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızı bugün Second Life&apos;a katılmaya davet edin!"/>
+ <string name="facebook_friends_empty" value="Şu anda aynı zamanda bir Second Life sakini olan hiçbir Facebook arkadaşınız yok. Facebook arkadaşlarınızdan bugün Second Life&apos;a katılmalarını isteyin!"/>
<string name="facebook_friends_no_connected" value="Şu anda Facebook&apos;a bağlı değilsiniz. Bağlanmak ve bu özelliği etkinleştirmek için lütfen Durum sekmesine gidin."/>
<accordion name="friends_accordion">
<accordion_tab name="tab_second_life_friends" title="SL arkadaşları"/>
<accordion_tab name="tab_suggested_friends" title="Bu kişileri SL arkadaşları olarak ekle"/>
</accordion>
<text name="facebook_friends_status">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
index d772aff937..e3150f258d 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_photo.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_photo">
<combo_box name="resolution_combobox" tool_tip="Görüntü çözünürlüğü">
- <combo_box.item label="Mevcut Pencere" name="CurrentWindow"/>
+ <combo_box.item label="Geçerli Pencere" name="CurrentWindow"/>
<combo_box.item label="640x480" name="640x480"/>
<combo_box.item label="800x600" name="800x600"/>
<combo_box.item label="1024x768" name="1024x768"/>
@@ -11,10 +11,10 @@
<combo_box.item label="Filtre Yok" name="NoFilter"/>
</combo_box>
<button label="Yenile" name="new_snapshot_btn" tool_tip="Yenilemek için tıklayın"/>
- <button label="Önizleme" name="big_preview_btn" tool_tip="Önizleme ayarları arasında geçiş yapmak için tıklayın"/>
+ <button label="Önizleme" name="big_preview_btn" tool_tip="Önizlemeye geçmek için tıklayın"/>
<text name="caption_label">
Yorum (isteğe bağlı):
</text>
<button label="Yayınla" name="post_photo_btn"/>
- <button label="İptal" name="cancel_photo_btn"/>
+ <button label="İptal Et" name="cancel_photo_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
index 85b401a1a0..96c34d03d0 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_place.xml
@@ -5,5 +5,5 @@
</text>
<check_box initial_value="false" label="Konumun üstten görünümünü ekle" name="add_place_view_cb"/>
<button label="Yayınla" name="post_place_btn"/>
- <button label="İptal" name="cancel_place_btn"/>
+ <button label="İptal Et" name="cancel_place_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
index e6feff5949..f5dba088de 100644
--- a/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
+++ b/indra/newview/skins/default/xui/tr/panel_facebook_status.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<panel name="panel_facebook_status">
<string name="facebook_connected" value="Facebook&apos;a şu kimlikle bağlandınız:"/>
- <string name="facebook_disconnected" value="Facebook&apos;a bağlanılmadı"/>
+ <string name="facebook_disconnected" value="Facebook&apos;a bağlanılamadı"/>
<text name="account_caption_label">
- Facebook&apos;a bağlanılmadı.
+ Facebook&apos;a bağlanılamadı.
</text>
<panel name="panel_buttons">
<button label="Bağlan..." name="connect_btn"/>
@@ -13,8 +13,8 @@
</text>
</panel>
<text name="status_caption_label">
- Ne düşünüyorsunuz?
+ Aklınızdan ne geçiyor?
</text>
<button label="Yayınla" name="post_status_btn"/>
- <button label="İptal" name="cancel_status_btn"/>
+ <button label="İptal Et" name="cancel_status_btn"/>
</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_general.xml b/indra/newview/skins/default/xui/tr/panel_group_general.xml
index c666778c69..5578b36f3f 100644
--- a/indra/newview/skins/default/xui/tr/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/tr/panel_group_general.xml
@@ -45,7 +45,7 @@ Daha fazla yardım edinmek için farenizi seçeneklerin üzerine getirin.
<check_box label="Herkes katılabilir" name="open_enrollement" tool_tip="Bu grubun davet edilmeden yeni üyelerin katılmasına imkan tanıyıp tanımayacağını belirler."/>
<check_box label="Katılma ücreti" name="check_enrollment_fee" tool_tip="Bu gruba katılmak için bir kayıt ücretinin gerekip gerekmeyeceğini belirler"/>
<spinner label="L$" name="spin_enrollment_fee" tool_tip="Kayıt Ücreti işaretlendiğinde yeni üyeler gruba katılmak için bu ücreti ödemelidir."/>
- <combo_box name="group_mature_check" tool_tip="Erişkinlik dereceleri bir grupta izin verilen içerik ve davranış türlerini belirler">
+ <combo_box name="group_mature_check" tool_tip="Grubunuzun Orta olarak sınıflandırılmış bilgiler içerip içermeyeceğini belirler">
<combo_item name="select_mature">
- Erişkinlik seviyesini seçin -
</combo_item>
diff --git a/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..0ed905ed35
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="Bilinmiyor"/>
+ <button name="info_btn" tool_tip="Ek bilgi"/>
+ <button name="profile_btn" tool_tip="Profili görüntüle"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_me.xml b/indra/newview/skins/default/xui/tr/panel_me.xml
deleted file mode 100644
index d9e79d171c..0000000000
--- a/indra/newview/skins/default/xui/tr/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Profilim" name="panel_me">
- <panel label="SEÇTİKLERİM" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
index 8d43e3fb5a..ae9bc33bfa 100644
--- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml
@@ -14,7 +14,7 @@
<label name="favorites_bar_label" tool_tip="Second Life içerisinde sık kullandığınız yerlere hızla erişmek için Yer İmlerini buraya sürükleyin!">
Favoriler Çubuğu
</label>
- <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster">
+ <more_button name="&gt;&gt;" tool_tip="Favorilerimden daha çok göster" width="65">
Daha Fazla ▼
</more_button>
</favorites_bar>
diff --git a/indra/newview/skins/default/xui/tr/panel_people.xml b/indra/newview/skins/default/xui/tr/panel_people.xml
index 25d29fcbb5..acbcd2a544 100644
--- a/indra/newview/skins/default/xui/tr/panel_people.xml
+++ b/indra/newview/skins/default/xui/tr/panel_people.xml
@@ -40,6 +40,7 @@ Birlikte takılacak kişiler mi arıyorsunuz? [secondlife:///app/worldmap Dünya
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="Çevrimiçi"/>
<accordion_tab name="tab_all" title="Tümü"/>
+ <accordion_tab name="tab_suggested_friends" title="Arkadaş olmak isteyebileceğiniz kişiler"/>
</accordion>
</panel>
<panel label="GRUPLAR" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classified.xml b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
new file mode 100644
index 0000000000..805de24c11
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ Orta
+ </panel.string>
+ <panel.string name="type_pg">
+ Genel İçerik
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] ışınlanma, [MAP] harita, [PROFILE] profil
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ Etkin
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ Devre dışı
+ </panel.string>
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <string name="publish_label">
+ Yayınla
+ </string>
+ <string name="save_label">
+ Kaydet
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="Bir görüntü seçmek için tıklayın"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="Konum:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="İçerik Türü:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="Kategori:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="Oluşturma tarihi:"/>
+ <text_editor name="creation_date" tool_tip="Oluşturma tarihi" value="[date]"/>
+ <text name="price_for_listing_label" value="İlan fiyatı:"/>
+ <text_editor name="price_for_listing" tool_tip="İlan fiyatı.">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="Tıklama sayısı:"/>
+ <text_editor name="click_through_text" tool_tip="Tıklama verileri" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="Otomatik yenileme:"/>
+ <text name="auto_renew" value="Etkin"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="Açıklama:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ Başlık:
+ </text>
+ <text name="description_label">
+ Açıklama:
+ </text>
+ <text name="location_label">
+ Konum:
+ </text>
+ <text name="classified_location_edit">
+ yükleniyor...
+ </text>
+ <button label="Geçerli Konuma Ayarla" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="Kategori:"/>
+ <text name="content_type_label" value="İçerik türü:"/>
+ <icons_combo_box label="Genel İçerik" name="content_type_edit">
+ <icons_combo_box.item label="Orta İçerik" name="mature_ci" value="Yetişkin"/>
+ <icons_combo_box.item label="Genel İçerik" name="pg_ci" value="PG"/>
+ </icons_combo_box>
+ <check_box label="Her hafta otomatik yenile" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="İlan fiyatı:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="İlan fiyatı." value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="Işınlanma" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="Harita" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="Düzenle" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="İptal Et" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..0edae1ab2a
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlan" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="İlan Yok"/>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..0f65090209
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_interests.xml b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
new file mode 100644
index 0000000000..b068aa3dad
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="İlgi alanları" name="panel_profile_interests">
+ <text name="I Want To:">
+ Şunu Yapmak İstiyorum:
+ </text>
+ <check_box label="İnşa Et" name="chk0"/>
+ <check_box label="Keşfet" name="chk1"/>
+ <check_box label="Tanış" name="chk2"/>
+ <check_box label="İşe Gir" name="chk6"/>
+ <check_box label="Gruplandır" name="chk3"/>
+ <check_box label="Satın Al" name="chk4"/>
+ <check_box label="Sat" name="chk5"/>
+ <check_box label="İşe Al" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Skills:">
+ Beceriler:
+ </text>
+ <check_box label="Dokular" name="schk0"/>
+ <check_box label="Mimari" name="schk1"/>
+ <check_box label="Modelleme" name="schk3"/>
+ <check_box label="Etkinlik Planlama" name="schk2"/>
+ <check_box label="Kodlama" name="schk4"/>
+ <check_box label="Özel Karakterler" name="schk5"/>
+ <line_editor name="skills_edit">
+ (yükleniyor...)
+ </line_editor>
+ <text name="Languages:">
+ Diller:
+ </text>
+ <line_editor name="languages_edit">
+ (yükleniyor...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_notes.xml b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
new file mode 100644
index 0000000000..fff75dd685
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Notlar ve Gizlilik" name="panel_notes">
+ <text name="status_message" value="Bu avatar ile ilgili özel notlar:"/>
+ <text name="status_message2" value="Bu avatar için şunlara izin ver:"/>
+ <check_box label="Çevrimiçi olduğumu görme" name="status_check"/>
+ <check_box label="Beni dünya haritasında bulma" name="map_check"/>
+ <check_box label="Nesnelerimi düzenleme, silme veya alma" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_pick.xml b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
new file mode 100644
index 0000000000..d42c1eff7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (kaydedildikten sonra güncellenir)
+ </panel.string>
+ <line_editor name="pick_location">
+ Yükleniyor...
+ </line_editor>
+ <button label="Işınlanma" name="teleport_btn"/>
+ <button label="Haritada Göster" name="show_on_map_btn"/>
+ <button label="Konumu Ayarla" name="set_to_curr_location_btn" tool_tip="Geçerli Konuma Ayarla"/>
+ <button label="Favoriyi Kaydet" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
new file mode 100644
index 0000000000..7222a2fc2e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Favoriler" name="panel_picks">
+ <string name="no_picks" value="Favori Yok"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ Second Life&apos;ta favori yerlerinizi herkese anlatın!
+ </text>
+ <button label="Yeni..." name="new_btn"/>
+ <button label="Sil..." name="delete_btn"/>
+ <text name="picks_panel_text">
+ Yükleniyor...
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..00e81d005e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Profil" name="panel_profile">
+ <string name="status_online">
+ Şu Anda Çevrimiçi
+ </string>
+ <string name="status_offline">
+ Şu Anda Çevrimdışı
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="Yok"/>
+ <string name="no_group_text" value="Yok"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="Geliştirici"/>
+ <string name="FSSupp" value="Destek"/>
+ <string name="FSQualityAssurance" value="Böcek bilimci"/>
+ <string name="FSGW" value="Ağ geçidi"/>
+ <text name="name_label" value="Ad:"/>
+ <button label="Ad:" name="set_name" tool_tip="Görünen Adı Ayarla"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(yükleniyor...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="Durum Bilinmiyor"/>
+ <text name="label" value="Second Life Doğum Tarihi:"/>
+ <text name="label2" value="Hesap:"/>
+ <text name="partner_label" value="Ortak:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="Gruplar:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="Gruba Davet Et"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="Hakkında:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="Öğe ver:"/>
+ <text name="Give inventory" tool_tip="Envanter öğelerini bu kişiye vermek için buraya bırakın.">
+ Envanter öğesini buraya bırakın.
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="Haritada Bul" label_selected="Haritada Bul" name="show_on_map_btn" tool_tip="Sakini haritada bul"/>
+ <button label="Öde" label_selected="Öde" name="pay" tool_tip="Sakine para öde"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="Işınlanma Teklif Et" label_selected="Işınlanma Teklif Et" name="teleport" tool_tip="Sakine ışınlanma teklif et"/>
+ <button label="Anlık İleti" label_selected="Anlık İleti" name="im" tool_tip="Anlık ileti oturumu aç"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="Arkadaş Ekle" label_selected="Arkadaş Ekle" name="add_friend" tool_tip="Sakine arkadaşlık teklif et"/>
+ <button label="Engelle" name="block" tool_tip="Bu Sakini engelle"/>
+ <button label="Engellemeyi Kaldır" name="unblock" tool_tip="Bu Sakinin engellemesini kaldır"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="Aramada göster" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_profile_web.xml b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
new file mode 100644
index 0000000000..265b1fee7e
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Web" name="panel_profile_web">
+ <panel.string name="LoadTime" value="Yükleme Süresi: [TIME] saniye"/>
+ <line_editor name="url_edit">
+ (yükleniyor..)
+ </line_editor>
+ <flyout_button label="Yükle" name="load" tool_tip="Bu profil sayfasını tümleşik web tarayıcı ile yükleyin.">
+ <flyout_button.item label="Görüntüleyici içindeki tarayıcıda aç" name="open_item"/>
+ <flyout_button.item label="Dış tarayıcıda aç" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="Açılır web profili"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
index 3226ee008e..e25047301d 100644
--- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml
@@ -10,8 +10,8 @@
<spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/>
<spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir)
- </text>
+ Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir)
+ </text>
<text name="height_text_lbl">
1 (Düşük)
</text>
diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml
index 74a6b3cac3..e709a4c5d6 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -357,6 +357,24 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="TestingDisconnect">
Görüntüleyici bağlantısının kesilmesi test ediliyor
</string>
+ <string name="SocialFacebookConnecting">
+ Facebook ile bağlantı kuruluyor...
+ </string>
+ <string name="SocialFacebookPosting">
+ Yayınlanıyor...
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ Facebook bağlantısı kesiliyor...
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ Facebook ile bağlantı kurulurken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ Facebook&apos;ta yayınlarken sorun oluştu
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ Facebook bağlantısı kesilirken sorun oluştu
+ </string>
<string name="SocialFlickrConnecting">
Flickr bağlantısı kuruluyor...
</string>
@@ -671,9 +689,6 @@ kartlarına eklenebilir.
<string name="GroupNameNone">
(hiçbiri)
</string>
- <string name="AvalineCaller">
- Avaline Arayanı [ORDER]
- </string>
<string name="AssetErrorNone">
Hata yok
</string>
@@ -2576,9 +2591,21 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin
<string name="NoPicksClassifiedsText">
Herhangi bir Seçme veya İlan oluşturmadınız. Bir Seçme veya İlan oluşturmak için aşağıdaki Artı düğmesine tıklayın.
</string>
+ <string name="NoPicksText">
+ Herhangi bir Favori oluşturmadınız. Bir Favori oluşturmak için Yeni düğmesine tıklayın.
+ </string>
+ <string name="NoClassifiedsText">
+ Herhangi bir İlan oluşturmadınız. Bir İlan oluşturmak için Yeni düğmesine tıklayın.
+ </string>
<string name="NoAvatarPicksClassifiedsText">
Kullanıcının herhangi bir seçmesi veya ilanı yok
</string>
+ <string name="NoAvatarPicksText">
+ Kullanıcının favorisi yok
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ Kullanıcının ilanı yok
+ </string>
<string name="PicksClassifiedsLoadingText">
Yükleniyor...
</string>
@@ -4556,6 +4583,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="share_alert">
Envanterinizden buraya öğeler sürükleyin
</string>
+ <string name="facebook_post_success">
+ Facebook&apos;ta yayınladınız.
+ </string>
<string name="flickr_post_success">
Flickr&apos;da yayınladınız.
</string>
diff --git a/indra/newview/skins/default/xui/zh/floater_picks.xml b/indra/newview/skins/default/xui/zh/floater_picks.xml
deleted file mode 100644
index a8bfcd99e3..0000000000
--- a/indra/newview/skins/default/xui/zh/floater_picks.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="floater_picks" title="精選地點"/>
diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
index 2b6eac48b3..9213cc212d 100644
--- a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
+++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml
@@ -6,42 +6,23 @@
<floater.string name="Copy">
覆製到收納區
</floater.string>
- <text name="desc txt">
- 描述:
- </text>
- <text name="dimensions">
- [WIDTH]像素 x [HEIGHT]像素
- </text>
- <text name="aspect_ratio">
- 預覽長寬比
- </text>
- <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽">
- <combo_item name="Unconstrained">
- 不受限
- </combo_item>
- <combo_item name="1:1" tool_tip="群組徽章或現實世界小檔案">
- 1:1
- </combo_item>
- <combo_item name="4:3" tool_tip="[SECOND_LIFE] 檔案">
- 4:3
- </combo_item>
- <combo_item name="10:7" tool_tip="個人廣告和搜索刊登廣告、地標">
- 10:7
- </combo_item>
- <combo_item name="3:2" tool_tip="土地資料">
- 3:2
- </combo_item>
- <combo_item name="16:10">
- 16:10
- </combo_item>
- <combo_item name="16:9" tool_tip="個人檔案精選">
- 16:9
- </combo_item>
- <combo_item name="2:1">
- 2:1
- </combo_item>
- </combo_box>
- <button label="確定" name="Keep"/>
- <button label="丟棄" name="Discard"/>
- <button label="另存為" name="save_tex_btn"/>
+ <layout_stack name="preview_stack">
+ <layout_panel name="texture_panel">
+ <text name="desc txt">
+ 描述:
+ </text>
+ <text name="dimensions">
+ [WIDTH]像素 x [HEIGHT]像素
+ </text>
+ <text name="aspect_ratio">
+ 預覽長寬比
+ </text>
+ <combo_box name="combo_aspect_ratio" tool_tip="以固定長寬比預覽"/>
+ </layout_panel>
+ <layout_panel name="buttons_panel">
+ <button label="確定" name="Keep"/>
+ <button label="丟棄" name="Discard"/>
+ <button label="另存為" name="save_tex_btn"/>
+ </layout_panel>
+ </layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_profile.xml b/indra/newview/skins/default/xui/zh/floater_profile.xml
new file mode 100644
index 0000000000..0f73f527a9
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/floater_profile.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="avatarinfo" title="簡覽">
+ <panel name="panel_profile_view">
+ <tab_container name="panel_profile_tabs">
+ <panel label="第二人生" name="panel_profile_secondlife"/>
+ <panel label="網頁" name="panel_profile_web"/>
+ <panel label="興趣" name="panel_profile_interests"/>
+ <panel label="精選地點" name="panel_profile_picks"/>
+ <panel label="分類廣告" name="panel_profile_classifieds"/>
+ <panel label="真實世界" name="panel_profile_firstlife"/>
+ <panel label="筆記" name="panel_profile_notes"/>
+ </tab_container>
+ <button label="確定" name="ok_btn" tool_tip="儲存變更到個人檔案後關閉"/>
+ <button label="取消" label_selected="取消" name="cancel_btn"/>
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
index 4090248083..6e1a156762 100644
--- a/indra/newview/skins/default/xui/zh/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
@@ -6,6 +6,9 @@
<string name="postcard_progress_str">
正在發送電郵
</string>
+ <string name="facebook_progress_str">
+ 發佈到臉書
+ </string>
<string name="profile_progress_str">
發佈
</string>
@@ -15,6 +18,9 @@
<string name="local_progress_str">
正在存到電腦
</string>
+ <string name="facebook_succeeded_str">
+ 圖像已上傳
+ </string>
<string name="profile_succeeded_str">
圖像已上傳
</string>
@@ -27,6 +33,9 @@
<string name="local_succeeded_str">
成功存入電腦!
</string>
+ <string name="facebook_failed_str">
+ 上傳圖像到你的臉書時間線時失敗。
+ </string>
<string name="profile_failed_str">
上傳圖像到你的檔案訊息發佈時出錯。
</string>
diff --git a/indra/newview/skins/default/xui/zh/menu_name_field.xml b/indra/newview/skins/default/xui/zh/menu_name_field.xml
new file mode 100644
index 0000000000..5eaf3461cd
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_name_field.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<toggleable_menu name="CopyMenu">
+ <menu_item_call label="複製顯示名稱" name="copy_display"/>
+ <menu_item_call label="複製代理名稱" name="copy_name"/>
+ <menu_item_call label="複製代理ID" name="copy_id"/>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml
index cfde824349..4d0f1cb85b 100644
--- a/indra/newview/skins/default/xui/zh/notifications.xml
+++ b/indra/newview/skins/default/xui/zh/notifications.xml
@@ -2666,6 +2666,9 @@ SHA1 指紋:[MD5_DIGEST]
<notification name="SystemMessage">
[MESSAGE]
</notification>
+ <notification name="FacebookConnect">
+ [MESSAGE]
+ </notification>
<notification name="FlickrConnect">
[MESSAGE]
</notification>
diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
index b06ece02ad..4d3248db46 100644
--- a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml
@@ -46,7 +46,7 @@
<layout_panel name="save_changes_btn_lp">
<button label="[LABEL]" name="save_changes_btn"/>
</layout_panel>
- <layout_panel name="show_on_map_btn_lp">
+ <layout_panel name="cancel_btn_lp">
<button label="取消" name="cancel_btn"/>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
new file mode 100644
index 0000000000..fec4bb572a
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_group_list_item_short.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="group_list_item">
+ <text name="group_name" value="未知"/>
+ <button name="info_btn" tool_tip="詳情"/>
+ <button name="profile_btn" tool_tip="察看檔案"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml
deleted file mode 100644
index aad1348e46..0000000000
--- a/indra/newview/skins/default/xui/zh/panel_me.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="我的個人檔案" name="panel_me">
- <panel label="我的精選地點" name="panel_picks"/>
-</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml
index b0e60218cf..b95dd96026 100644
--- a/indra/newview/skins/default/xui/zh/panel_people.xml
+++ b/indra/newview/skins/default/xui/zh/panel_people.xml
@@ -40,6 +40,7 @@
<accordion name="friends_accordion">
<accordion_tab name="tab_online" title="上線"/>
<accordion_tab name="tab_all" title="全部"/>
+ <accordion_tab name="tab_suggested_friends" title="你可能想要加為好友的人"/>
</accordion>
</panel>
<panel label="群組" name="groups_panel">
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classified.xml b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
new file mode 100644
index 0000000000..4eee4e8855
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classified.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_profile_classified">
+ <panel.string name="type_mature">
+ 適度成人
+ </panel.string>
+ <panel.string name="type_pg">
+ 一般普級內容
+ </panel.string>
+ <panel.string name="l$_price">
+ L$[PRICE]
+ </panel.string>
+ <panel.string name="click_through_text_fmt">
+ [TELEPORT] 瞬間傳送,[MAP] 地圖,[PROFILE] 檔案
+ </panel.string>
+ <panel.string name="date_fmt">
+ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]
+ </panel.string>
+ <panel.string name="auto_renew_on">
+ 已啟用
+ </panel.string>
+ <panel.string name="auto_renew_off">
+ 已停用
+ </panel.string>
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <string name="publish_label">
+ 發布
+ </string>
+ <string name="save_label">
+ 儲存
+ </string>
+ <scroll_container name="profile_scroll">
+ <panel name="info_scroll_content_panel">
+ <icon label="" name="edit_icon" tool_tip="點按以選擇圖像"/>
+ <layout_stack name="info_panel">
+ <layout_panel name="main_info_panel">
+ <text_editor name="classified_name">
+ [name]
+ </text_editor>
+ <text name="classified_location_label" value="位置:"/>
+ <text_editor name="classified_location" value="[loading...]"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <text_editor name="content_type" value="[content type]"/>
+ <text name="category_label" value="分類:"/>
+ <text_editor name="category" value="[category]"/>
+ <text name="creation_date_label" value="建立日期:"/>
+ <text_editor name="creation_date" tool_tip="建立日期" value="[date]"/>
+ <text name="price_for_listing_label" value="刊登費:"/>
+ <text_editor name="price_for_listing" tool_tip="刊登費。">
+ [PRICE]
+ </text_editor>
+ </layout_panel>
+ <layout_panel name="clickthrough_layout_panel">
+ <text name="click_through_label" value="點按狀況:"/>
+ <text_editor name="click_through_text" tool_tip="點按資料" value="[clicks]"/>
+ </layout_panel>
+ <layout_panel name="auto_renew_layout_panel">
+ <text name="auto_renew_label" value="自動續訂:"/>
+ <text name="auto_renew" value="已啟用"/>
+ </layout_panel>
+ <layout_panel name="descr_layout_panel">
+ <text name="classified_desc_label" value="描述:"/>
+ <text_editor name="classified_desc" value="[description]"/>
+ </layout_panel>
+ </layout_stack>
+ <panel name="edit_panel">
+ <text name="Name:">
+ 標題:
+ </text>
+ <text name="description_label">
+ 描述:
+ </text>
+ <text name="location_label">
+ 位置:
+ </text>
+ <text name="classified_location_edit">
+ 載入中...
+ </text>
+ <button label="設定為目前位置" name="set_to_curr_location_btn"/>
+ <text name="category_label" value="分類:"/>
+ <text name="content_type_label" value="內容類型:"/>
+ <icons_combo_box label="一般普級內容" name="content_type_edit">
+ <icons_combo_box.item label="適度成人內容" name="mature_ci" value="適度成人"/>
+ <icons_combo_box.item label="一般普級內容" name="pg_ci" value="一般普級"/>
+ </icons_combo_box>
+ <check_box label="每星期自動續訂" name="auto_renew_edit"/>
+ <text name="price_for_listing_edit_label" value="刊登費:"/>
+ <spinner label="L$" name="price_for_listing_edit" tool_tip="刊登費。" value="50"/>
+ </panel>
+ </panel>
+ </scroll_container>
+ <layout_stack name="edit_btns_pnl">
+ <layout_panel name="teleport_btn_lp">
+ <button label="瞬間傳送" name="teleport_btn"/>
+ </layout_panel>
+ <layout_panel name="map_btn_lp">
+ <button label="地圖" name="show_on_map_btn"/>
+ </layout_panel>
+ <layout_panel name="edit_btn_lp">
+ <button label="編輯" name="edit_btn"/>
+ </layout_panel>
+ <layout_panel name="save_btn_lp">
+ <button label="[LABEL]" name="save_changes_btn"/>
+ </layout_panel>
+ <layout_panel name="cancel_btn_lp">
+ <button label="取消" name="cancel_btn"/>
+ </layout_panel>
+ </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
new file mode 100644
index 0000000000..89b5cdf641
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_classifieds.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="分類廣告" name="panel_profile_classifieds">
+ <string name="no_classifieds" value="禁止個人廣告"/>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="classifieds_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
new file mode 100644
index 0000000000..9370661d7f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_firstlife.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile_firstlife"/>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_interests.xml b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
new file mode 100644
index 0000000000..150f3cca4f
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_interests.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="興趣" name="panel_profile_interests">
+ <text name="I Want To:">
+ 我想要:
+ </text>
+ <check_box label="建造" name="chk0"/>
+ <check_box label="探索" name="chk1"/>
+ <check_box label="見面" name="chk2"/>
+ <check_box label="受雇" name="chk6"/>
+ <check_box label="群組" name="chk3"/>
+ <check_box label="購買" name="chk4"/>
+ <check_box label="出售" name="chk5"/>
+ <check_box label="招人" name="chk7"/>
+ <line_editor name="want_to_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Skills:">
+ 技能:
+ </text>
+ <check_box label="材質" name="schk0"/>
+ <check_box label="架構" name="schk1"/>
+ <check_box label="建模" name="schk3"/>
+ <check_box label="計畫活動" name="schk2"/>
+ <check_box label="建腳本" name="schk4"/>
+ <check_box label="定製角色" name="schk5"/>
+ <line_editor name="skills_edit">
+ (載入中...)
+ </line_editor>
+ <text name="Languages:">
+ 語言:
+ </text>
+ <line_editor name="languages_edit">
+ (載入中...)
+ </line_editor>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_notes.xml b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
new file mode 100644
index 0000000000..17e1a997da
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_notes.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="筆記和隱私" name="panel_notes">
+ <text name="status_message" value="關於這化身的私人筆記:"/>
+ <text name="status_message2" value="允許這個化身:"/>
+ <check_box label="看見我何時上線" name="status_check"/>
+ <check_box label="在世界地圖上找到我" name="map_check"/>
+ <check_box label="邊輯,刪除或取下我的物件" name="objects_check"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_pick.xml b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
new file mode 100644
index 0000000000..5f8d6a2ba5
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_pick.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel name="panel_pick_info">
+ <panel.string name="location_notice">
+ (儲存後將會更新)
+ </panel.string>
+ <line_editor name="pick_location">
+ 載入中…
+ </line_editor>
+ <button label="瞬間傳送" name="teleport_btn"/>
+ <button label="顯示在地圖上" name="show_on_map_btn"/>
+ <button label="設定位置" name="set_to_curr_location_btn" tool_tip="設定為目前位置"/>
+ <button label="儲存精選地點" name="save_changes_btn"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
new file mode 100644
index 0000000000..8f189d1308
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="精選地點" name="panel_picks">
+ <string name="no_picks" value="無精選地點"/>
+ <text name="Tell everyone about your favorite places in Second Life.">
+ 告訴大家你在Second Life中最愛的去處。
+ </text>
+ <button label="新增…" name="new_btn"/>
+ <button label="刪除…" name="delete_btn"/>
+ <text name="picks_panel_text">
+ 載入中…
+ </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
new file mode 100644
index 0000000000..da4aafce55
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_secondlife.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="簡覽" name="panel_profile">
+ <string name="status_online">
+ 目前在線
+ </string>
+ <string name="status_offline">
+ 目前離線
+ </string>
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE]
+[PAYMENTINFO]
+ </string>
+ <string name="payment_update_link_url">
+ http://www.secondlife.com/account/billing.php?lang=en
+ </string>
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=en
+ </string>
+ <string name="my_account_link_url" value="http://secondlife.com/account"/>
+ <string name="no_partner_text" value="無"/>
+ <string name="no_group_text" value="無"/>
+ <string name="RegisterDateFormat">
+ [REG_DATE]
+ </string>
+ <string name="name_text_args">
+ [NAME]
+ </string>
+ <string name="display_name_text_args">
+ [DISPLAY_NAME]
+ </string>
+ <string name="FSDev" value="開發者"/>
+ <string name="FSSupp" value="支援"/>
+ <string name="FSQualityAssurance" value="除錯獵人"/>
+ <string name="FSGW" value="網關"/>
+ <text name="name_label" value="名稱:"/>
+ <button label="名稱:" name="set_name" tool_tip="設定顯示名稱"/>
+ <panel name="name_holder">
+ <text_editor name="complete_name" value="(載入中...)"/>
+ </panel>
+ <layout_stack name="imagepositioner">
+ <layout_panel name="label_stack">
+ <text name="status" value="狀態不明"/>
+ <text name="label" value="Second Life生日:"/>
+ <text name="label2" value="帳戶:"/>
+ <text name="partner_label" value="伴侶:"/>
+ </layout_panel>
+ </layout_stack>
+ <text name="Groups:" value="群組:"/>
+ <button label="+" label_selected="+" name="group_invite" tool_tip="邀請加入群組"/>
+ <layout_stack name="aboutpositioner">
+ <layout_panel name="about_stack">
+ <text name="About:" value="關於:"/>
+ </layout_panel>
+ <layout_panel name="give_stack">
+ <text name="Give item:" value="贈與物品:"/>
+ <text name="Give inventory" tool_tip="把收納區物品放到這裡,送給此人。">
+ 把收納區物品放到這裡。
+ </text>
+ </layout_panel>
+ </layout_stack>
+ <layout_stack name="buttonstack">
+ <layout_panel name="left_buttonstack">
+ <button label="在地圖上查找" label_selected="在地圖上查找" name="show_on_map_btn" tool_tip="在地圖上找出這個居民"/>
+ <button label="支付" label_selected="支付" name="pay" tool_tip="付款給這個居民"/>
+ </layout_panel>
+ <layout_panel name="middle_buttonstack">
+ <button label="發出瞬間傳送邀請" label_selected="發出瞬間傳送邀請" name="teleport" tool_tip="向這個居民發出瞬間傳送邀請"/>
+ <button label="即時訊息" label_selected="即時訊息" name="im" tool_tip="開啟即時訊息會話"/>
+ </layout_panel>
+ <layout_panel name="right_buttonstack">
+ <button label="加為朋友" label_selected="加為朋友" name="add_friend" tool_tip="向這個居民發出交友邀請"/>
+ <button label="封鎖" name="block" tool_tip="封鎖這位居民"/>
+ <button label="解除封鎖" name="unblock" tool_tip="不再封鎖這位居民"/>
+ </layout_panel>
+ </layout_stack>
+ <check_box label="在搜尋結果中顯示" name="show_in_search_checkbox"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_profile_web.xml b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
new file mode 100644
index 0000000000..566651dceb
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/panel_profile_web.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="網頁" name="panel_profile_web">
+ <panel.string name="LoadTime" value="載入時間:[TIME]秒"/>
+ <line_editor name="url_edit">
+ (載入中…)
+ </line_editor>
+ <flyout_button label="載入" name="load" tool_tip="用內嵌瀏覽器載入此個人檔案頁面。">
+ <flyout_button.item label="開啓内部瀏覽器" name="open_item"/>
+ <flyout_button.item label="開啓外部瀏覽器" name="home_item"/>
+ </flyout_button>
+ <button name="web_profile_popout_btn" tool_tip="彈出式個人檔案網頁"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
index 85e759e445..81bce46876 100644
--- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
+++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml
@@ -10,7 +10,7 @@
<spinner label="地形提升限制" name="terrain_raise_spin"/>
<spinner label="地形降低限制" name="terrain_lower_spin"/>
<text name="detail_texture_text">
- 地形材質(須 512x512,24 位元 .tga 檔格式)
+ 地形材質(須 1024x1024,24 位元 .tga 檔格式)
</text>
<text name="height_text_lbl">
1(低)
diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml
index a8d5fd90bb..bdb16c9bf1 100644
--- a/indra/newview/skins/default/xui/zh/strings.xml
+++ b/indra/newview/skins/default/xui/zh/strings.xml
@@ -353,6 +353,24 @@ http://secondlife.com/viewer-access-faq
<string name="TestingDisconnect">
測試瀏覽器斷線
</string>
+ <string name="SocialFacebookConnecting">
+ 連通臉書中…
+ </string>
+ <string name="SocialFacebookPosting">
+ 發佈中…
+ </string>
+ <string name="SocialFacebookDisconnecting">
+ 臉書連通中斷中…
+ </string>
+ <string name="SocialFacebookErrorConnecting">
+ 連通臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorPosting">
+ 發佈到臉書時出問題
+ </string>
+ <string name="SocialFacebookErrorDisconnecting">
+ 試圖中斷臉書連通時出問題
+ </string>
<string name="SocialFlickrConnecting">
連通 Flickr 中…
</string>
@@ -667,9 +685,6 @@ http://secondlife.com/viewer-access-faq
<string name="GroupNameNone">
(無)
</string>
- <string name="AvalineCaller">
- Avaline 通話者 [ORDER]
- </string>
<string name="AssetErrorNone">
無錯誤
</string>
@@ -2569,9 +2584,21 @@ http://secondlife.com/support 求助解決問題。
<string name="NoPicksClassifiedsText">
你尚未建立任何精選地點或個人廣告。 點按下面的 + 按鈕建立精選地點或個人廣告。
</string>
+ <string name="NoPicksText">
+ 你尚未建立任何精選地點。 點按「新增」按鈕建立精選地點。
+ </string>
+ <string name="NoClassifiedsText">
+ 你尚未建立任何分類廣告。 點按「新增」按鈕建立分類廣告。
+ </string>
<string name="NoAvatarPicksClassifiedsText">
使用者無精選地點或個人廣告
</string>
+ <string name="NoAvatarPicksText">
+ 使用者沒有精選地點
+ </string>
+ <string name="NoAvatarClassifiedsText">
+ 使用者沒有分類廣告
+ </string>
<string name="PicksClassifiedsLoadingText">
載入中...
</string>
@@ -4549,6 +4576,9 @@ http://secondlife.com/support 求助解決問題。
<string name="share_alert">
將收納區物品拖曳到這裡
</string>
+ <string name="facebook_post_success">
+ 成功發佈到臉書。
+ </string>
<string name="flickr_post_success">
成功發佈到 Flickr。
</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index de5ac5ed3d..59eb18b734 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -568,6 +568,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
@@ -954,6 +955,7 @@ class DarwinManifest(ViewerManifest):
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
+ self.path("cube.dae")
self.path("SecondLife.nib")
with self.prefix(src=pkgdir,dst=""):
@@ -1427,6 +1429,7 @@ class LinuxManifest(ViewerManifest):
print("Skipping llcommon.so (assuming llcommon was linked statically)")
self.path("featuretable_linux.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")