summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.hgtags4
-rwxr-xr-xBuildParams48
-rwxr-xr-xautobuild.xml24
-rwxr-xr-xdoc/contributions.txt14
-rwxr-xr-xindra/cmake/Copy3rdPartyLibs.cmake4
-rw-r--r--indra/cmake/FMODEX.cmake2
-rwxr-xr-xindra/cmake/GoogleBreakpad.cmake2
-rwxr-xr-xindra/edit-me-to-trigger-new-build.txt2
-rwxr-xr-xindra/linux_crash_logger/linux_crash_logger.cpp11
-rwxr-xr-xindra/linux_crash_logger/llcrashloggerlinux.cpp1
-rw-r--r--indra/llappearance/llavatarappearance.cpp18
-rw-r--r--indra/llappearance/lltexglobalcolor.cpp1
-rw-r--r--indra/llappearance/lltexlayer.cpp6
-rw-r--r--indra/llaudio/llaudioengine_fmodex.cpp25
-rw-r--r--indra/llaudio/llaudioengine_fmodex.h4
-rw-r--r--indra/llaudio/lllistener_fmodex.cpp5
-rwxr-xr-xindra/llcharacter/llbvhloader.cpp1
-rwxr-xr-xindra/llcharacter/llkeyframemotion.cpp3
-rwxr-xr-xindra/llcharacter/llmultigesture.cpp1
-rwxr-xr-xindra/llcharacter/llpose.cpp1
-rwxr-xr-xindra/llcommon/llapp.cpp258
-rwxr-xr-xindra/llcommon/llapp.h52
-rwxr-xr-xindra/llcommon/llavatarname.cpp17
-rwxr-xr-xindra/llcommon/llavatarname.h6
-rwxr-xr-xindra/llcommon/llerror.cpp4
-rwxr-xr-xindra/llcommon/llerrorthread.cpp71
-rwxr-xr-xindra/llcommon/llfasttimer.cpp1
-rwxr-xr-xindra/llcommon/llfile.cpp31
-rwxr-xr-xindra/llcommon/llfile.h2
-rwxr-xr-xindra/llcommon/llfoldertype.cpp5
-rwxr-xr-xindra/llcommon/llstl.h1
-rwxr-xr-xindra/llcommon/llstring.h5
-rwxr-xr-xindra/llcommon/stringize.h51
-rwxr-xr-xindra/llcommon/tests/stringize_test.cpp20
-rwxr-xr-xindra/llcrashlogger/CMakeLists.txt2
-rw-r--r--indra/llcrashlogger/llcrashlock.cpp209
-rw-r--r--indra/llcrashlogger/llcrashlock.h73
-rwxr-xr-xindra/llcrashlogger/llcrashlogger.cpp299
-rwxr-xr-xindra/llcrashlogger/llcrashlogger.h8
-rwxr-xr-xindra/llmath/llmath.h1
-rwxr-xr-xindra/llmath/v3dmath.h150
-rwxr-xr-xindra/llmath/v3math.h13
-rwxr-xr-xindra/llmessage/llavatarnamecache.cpp9
-rwxr-xr-xindra/llmessage/llavatarnamecache.h2
-rwxr-xr-xindra/llmessage/llbuffer.cpp2
-rwxr-xr-xindra/llmessage/llcachename.cpp2
-rwxr-xr-xindra/llmessage/llcurl.cpp1
-rwxr-xr-xindra/llmessage/llhttpnode.cpp4
-rwxr-xr-xindra/llmessage/llhttpsender.cpp3
-rwxr-xr-xindra/llmessage/llhttpsender.h2
-rwxr-xr-xindra/llmessage/llmessagetemplate.h1
-rwxr-xr-xindra/llmessage/lltemplatemessagereader.cpp6
-rwxr-xr-xindra/llmessage/message.cpp19
-rwxr-xr-xindra/llrender/llfontfreetype.cpp1
-rwxr-xr-xindra/llrender/llrender.cpp10
-rwxr-xr-xindra/llui/lldraghandle.cpp5
-rwxr-xr-xindra/llui/llfloater.cpp74
-rwxr-xr-xindra/llui/llfloater.h8
-rwxr-xr-xindra/llui/llfolderview.cpp30
-rwxr-xr-xindra/llui/llfolderview.h7
-rwxr-xr-xindra/llui/llkeywords.cpp3
-rwxr-xr-xindra/llui/llmenugl.cpp99
-rwxr-xr-xindra/llui/llpanel.h9
-rwxr-xr-xindra/llui/llscrolllistctrl.cpp4
-rwxr-xr-xindra/llui/llscrolllistitem.cpp1
-rwxr-xr-xindra/llui/lltabcontainer.cpp1
-rwxr-xr-xindra/llui/lltextbase.cpp4
-rwxr-xr-xindra/llui/lltextbase.h5
-rwxr-xr-xindra/llui/lltexteditor.cpp4
-rwxr-xr-xindra/llui/lltoolbar.cpp26
-rwxr-xr-xindra/llui/lltoolbar.h39
-rwxr-xr-xindra/llui/llurlaction.cpp6
-rwxr-xr-xindra/llui/llurlaction.h4
-rwxr-xr-xindra/llui/llurlentry.cpp3
-rwxr-xr-xindra/llui/llview.cpp109
-rw-r--r--indra/llui/llviewereventrecorder.cpp2
-rw-r--r--indra/llui/llviewereventrecorder.h2
-rwxr-xr-xindra/llvfs/lldir.cpp88
-rwxr-xr-xindra/llvfs/lldir.h8
-rwxr-xr-xindra/llvfs/lldir_mac.cpp2
-rwxr-xr-xindra/llvfs/lldiriterator.cpp23
-rwxr-xr-xindra/llvfs/llpidlock.cpp5
-rwxr-xr-xindra/llvfs/llpidlock.h31
-rwxr-xr-xindra/llvfs/llvfile.cpp2
-rwxr-xr-xindra/llvfs/llvfs.cpp2
-rwxr-xr-xindra/llvfs/tests/lldiriterator_test.cpp6
-rwxr-xr-xindra/llwindow/lldxhardware.cpp2
-rwxr-xr-xindra/llwindow/llwindow.cpp4
-rwxr-xr-xindra/llwindow/llwindowmacosx.cpp27
-rwxr-xr-xindra/llwindow/llwindowsdl.cpp4
-rwxr-xr-xindra/mac_crash_logger/llcrashloggermac.cpp1
-rwxr-xr-xindra/mac_crash_logger/mac_crash_logger.cpp11
-rwxr-xr-xindra/media_plugins/winmmshim/winmm_shim.cpp81
-rwxr-xr-xindra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rwxr-xr-xindra/newview/app_settings/settings.xml490
-rwxr-xr-xindra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl38
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl7
-rwxr-xr-xindra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl3
-rwxr-xr-xindra/newview/featuretable_mac.txt5
-rwxr-xr-xindra/newview/installers/windows/installer_template.nsi187
-rwxr-xr-xindra/newview/installers/windows/lang_da.nsibin7108 -> 8026 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_de.nsibin8260 -> 9346 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_en-us.nsibin7542 -> 8120 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_es.nsibin7846 -> 8764 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_fr.nsibin8114 -> 9030 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_it.nsibin7438 -> 8372 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ja.nsibin6302 -> 7288 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pl.nsibin7450 -> 8426 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_pt-br.nsibin7832 -> 8788 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_ru.nsibin7598 -> 8144 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_tr.nsibin7722 -> 8266 bytes
-rwxr-xr-xindra/newview/installers/windows/lang_zh.nsibin5824 -> 6798 bytes
-rwxr-xr-xindra/newview/llagent.cpp1
-rwxr-xr-xindra/newview/llagentwearables.cpp61
-rw-r--r--indra/newview/llappdelegate-objc.mm7
-rwxr-xr-xindra/newview/llappearancemgr.cpp13
-rwxr-xr-xindra/newview/llappviewer.cpp536
-rwxr-xr-xindra/newview/llappviewer.h15
-rwxr-xr-xindra/newview/llappviewerlinux.cpp114
-rwxr-xr-xindra/newview/llappviewerlinux.h2
-rw-r--r--indra/newview/llappviewermacosx-objc.h36
-rw-r--r--indra/newview/llappviewermacosx-objc.mm73
-rwxr-xr-xindra/newview/llappviewermacosx.cpp183
-rwxr-xr-xindra/newview/llappviewermacosx.h2
-rw-r--r--[-rwxr-xr-x]indra/newview/llappviewerwin32.cpp110
-rw-r--r--[-rwxr-xr-x]indra/newview/llappviewerwin32.h2
-rwxr-xr-xindra/newview/llavataractions.cpp4
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp2
-rwxr-xr-xindra/newview/llcallingcard.cpp2
-rwxr-xr-xindra/newview/llchannelmanager.cpp50
-rwxr-xr-xindra/newview/llchathistory.cpp10
-rwxr-xr-xindra/newview/llcofwearables.cpp2
-rw-r--r--indra/newview/llconversationview.cpp2
-rwxr-xr-xindra/newview/lldrawpoolsimple.cpp21
-rwxr-xr-xindra/newview/llfeaturemanager.cpp8
-rwxr-xr-xindra/newview/llfloaterabout.cpp181
-rwxr-xr-xindra/newview/llfloaterbulkpermission.cpp5
-rwxr-xr-xindra/newview/llfloaterbvhpreview.cpp2
-rwxr-xr-xindra/newview/llfloatercamera.cpp2
-rwxr-xr-xindra/newview/llfloatergesture.cpp26
-rwxr-xr-xindra/newview/llfloaterimcontainer.cpp4
-rwxr-xr-xindra/newview/llfloaterimsessiontab.cpp7
-rwxr-xr-xindra/newview/llfloaternamedesc.cpp6
-rwxr-xr-xindra/newview/llfloateroutbox.cpp252
-rwxr-xr-xindra/newview/llfloateroutbox.h6
-rwxr-xr-xindra/newview/llfloaterpay.cpp1
-rwxr-xr-xindra/newview/llfloaterperms.cpp229
-rwxr-xr-xindra/newview/llfloaterperms.h55
-rwxr-xr-xindra/newview/llfloaterpreference.cpp16
-rwxr-xr-xindra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloatersocial.cpp30
-rw-r--r--indra/newview/llfloatersocial.h1
-rwxr-xr-xindra/newview/llfloaterspellchecksettings.cpp35
-rwxr-xr-xindra/newview/llfloaterspellchecksettings.h1
-rwxr-xr-xindra/newview/llfloatertoybox.cpp8
-rwxr-xr-xindra/newview/llfolderviewmodelinventory.cpp20
-rwxr-xr-xindra/newview/llglsandbox.cpp133
-rwxr-xr-xindra/newview/llgroupmgr.cpp1
-rwxr-xr-xindra/newview/llimview.cpp6
-rwxr-xr-xindra/newview/llinventoryfilter.cpp9
-rwxr-xr-xindra/newview/llinventorymodel.cpp79
-rwxr-xr-xindra/newview/llinventorymodel.h5
-rwxr-xr-xindra/newview/llinventoryobserver.cpp19
-rwxr-xr-xindra/newview/llinventorypanel.cpp194
-rwxr-xr-xindra/newview/llinventorypanel.h11
-rwxr-xr-xindra/newview/lllandmarklist.cpp1
-rwxr-xr-xindra/newview/llmaniprotate.cpp29
-rwxr-xr-xindra/newview/llmanipscale.cpp698
-rwxr-xr-xindra/newview/llmanipscale.h47
-rwxr-xr-xindra/newview/llmaniptranslate.cpp11
-rwxr-xr-xindra/newview/llmaniptranslate.h2
-rwxr-xr-xindra/newview/llmarketplacefunctions.cpp88
-rwxr-xr-xindra/newview/llmarketplacefunctions.h20
-rwxr-xr-xindra/newview/llmeshrepository.cpp6
-rwxr-xr-xindra/newview/llmoveview.cpp4
-rwxr-xr-xindra/newview/llnamelistctrl.cpp33
-rwxr-xr-xindra/newview/llnamelistctrl.h13
-rwxr-xr-xindra/newview/lloutfitslist.cpp2
-rwxr-xr-xindra/newview/llpanelblockedlist.cpp2
-rwxr-xr-xindra/newview/llpanelcontents.cpp11
-rwxr-xr-xindra/newview/llpaneleditwearable.cpp2
-rwxr-xr-xindra/newview/llpanelgroup.cpp2
-rwxr-xr-xindra/newview/llpanelgroupgeneral.cpp194
-rwxr-xr-xindra/newview/llpanelgroupgeneral.h13
-rwxr-xr-xindra/newview/llpanelgrouplandmoney.cpp2
-rwxr-xr-xindra/newview/llpanelgroupnotices.cpp2
-rwxr-xr-xindra/newview/llpanelgrouproles.cpp48
-rwxr-xr-xindra/newview/llpanelgrouproles.h5
-rwxr-xr-xindra/newview/llpanelhome.cpp2
-rwxr-xr-xindra/newview/llpanellandmarkinfo.cpp2
-rwxr-xr-xindra/newview/llpanelmaininventory.cpp15
-rwxr-xr-xindra/newview/llpanelmaininventory.h2
-rwxr-xr-xindra/newview/llpanelmarketplaceinbox.cpp2
-rwxr-xr-xindra/newview/llpanelmarketplaceinboxinventory.cpp4
-rwxr-xr-xindra/newview/llpanelme.cpp2
-rwxr-xr-xindra/newview/llpaneloutfitedit.cpp2
-rwxr-xr-xindra/newview/llpaneloutfitsinventory.cpp2
-rwxr-xr-xindra/newview/llpanelpeople.cpp2
-rwxr-xr-xindra/newview/llpanelpicks.cpp2
-rwxr-xr-xindra/newview/llpanelplaceprofile.cpp2
-rwxr-xr-xindra/newview/llpanelplaces.cpp2
-rwxr-xr-xindra/newview/llpanelsnapshotinventory.cpp2
-rwxr-xr-xindra/newview/llpanelsnapshotlocal.cpp2
-rwxr-xr-xindra/newview/llpanelsnapshotoptions.cpp2
-rwxr-xr-xindra/newview/llpanelsnapshotpostcard.cpp2
-rwxr-xr-xindra/newview/llpanelsnapshotprofile.cpp2
-rwxr-xr-xindra/newview/llpanelvoicedevicesettings.cpp2
-rwxr-xr-xindra/newview/llpanelvoiceeffect.cpp2
-rwxr-xr-xindra/newview/llpanelwearing.cpp2
-rwxr-xr-xindra/newview/llplacesinventorypanel.cpp12
-rwxr-xr-xindra/newview/llpopupview.cpp2
-rwxr-xr-xindra/newview/llprogressview.cpp2
-rwxr-xr-xindra/newview/llselectmgr.cpp7
-rwxr-xr-xindra/newview/llsidepanelappearance.cpp2
-rwxr-xr-xindra/newview/llsidepanelinventory.cpp34
-rwxr-xr-xindra/newview/llsidepanelinventory.h4
-rwxr-xr-xindra/newview/llsidepaneliteminfo.cpp2
-rwxr-xr-xindra/newview/llsidepaneltaskinfo.cpp2
-rwxr-xr-xindra/newview/llstartup.cpp21
-rwxr-xr-xindra/newview/lltexturectrl.cpp2
-rwxr-xr-xindra/newview/lltoastnotifypanel.cpp5
-rwxr-xr-xindra/newview/lltool.h2
-rwxr-xr-xindra/newview/lltoolbarview.cpp82
-rwxr-xr-xindra/newview/lltoolbarview.h21
-rwxr-xr-xindra/newview/lltoolcomp.cpp2
-rwxr-xr-xindra/newview/llurldispatcher.cpp6
-rwxr-xr-xindra/newview/llurldispatcher.h2
-rwxr-xr-xindra/newview/llurldispatcherlistener.cpp2
-rwxr-xr-xindra/newview/llviewerfloaterreg.cpp2
-rw-r--r--indra/newview/llviewerfoldertype.cpp8
-rwxr-xr-xindra/newview/llviewerinventory.cpp129
-rwxr-xr-xindra/newview/llviewerinventory.h2
-rwxr-xr-xindra/newview/llviewermedia.cpp2
-rwxr-xr-xindra/newview/llviewermenu.cpp29
-rwxr-xr-xindra/newview/llviewermenufile.cpp12
-rwxr-xr-xindra/newview/llviewermessage.cpp79
-rwxr-xr-xindra/newview/llviewerobject.cpp38
-rwxr-xr-xindra/newview/llviewerobject.h5
-rwxr-xr-xindra/newview/llviewerobjectlist.cpp17
-rwxr-xr-xindra/newview/llviewerobjectlist.h2
-rwxr-xr-xindra/newview/llviewerregion.cpp17
-rwxr-xr-xindra/newview/llviewershadermgr.cpp23
-rwxr-xr-xindra/newview/llviewershadermgr.h1
-rwxr-xr-xindra/newview/llviewertexteditor.cpp5
-rwxr-xr-xindra/newview/llviewertexteditor.h2
-rwxr-xr-xindra/newview/llviewertexture.cpp2
-rwxr-xr-xindra/newview/llviewerwindow.cpp13
-rwxr-xr-xindra/newview/llvoavatar.cpp249
-rwxr-xr-xindra/newview/llvoavatar.h32
-rwxr-xr-xindra/newview/llvoavatarself.cpp68
-rwxr-xr-xindra/newview/llvoavatarself.h2
-rwxr-xr-xindra/newview/llvograss.cpp3
-rwxr-xr-xindra/newview/llvograss.h2
-rwxr-xr-xindra/newview/llvoground.cpp2
-rwxr-xr-xindra/newview/llvoground.h2
-rwxr-xr-xindra/newview/llvoicevivox.cpp11
-rwxr-xr-xindra/newview/llvoicevivox.h2
-rwxr-xr-xindra/newview/llvopartgroup.cpp2
-rwxr-xr-xindra/newview/llvopartgroup.h2
-rwxr-xr-xindra/newview/llvosky.cpp2
-rwxr-xr-xindra/newview/llvosky.h2
-rwxr-xr-xindra/newview/llvotree.cpp3
-rwxr-xr-xindra/newview/llvotree.h2
-rwxr-xr-xindra/newview/llvowater.cpp2
-rwxr-xr-xindra/newview/llvowater.h2
-rwxr-xr-xindra/newview/llvowlsky.cpp2
-rwxr-xr-xindra/newview/llvowlsky.h2
-rwxr-xr-xindra/newview/llworld.cpp15
-rwxr-xr-xindra/newview/llworldmapview.cpp12
-rwxr-xr-xindra/newview/pipeline.cpp61
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_about.xml58
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_buy_object.xml4
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_perm_prefs.xml108
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml503
-rwxr-xr-xindra/newview/skins/default/xui/en/floater_region_debug_console.xml55
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_avatar_icon.xml6
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_inventory_add.xml7
-rwxr-xr-xindra/newview/skins/default/xui/en/menu_viewer.xml36
-rwxr-xr-xindra/newview/skins/default/xui/en/notifications.xml57
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_general.xml28
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_info_sidetray.xml2
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_group_roles.xml8
-rwxr-xr-xindra/newview/skins/default/xui/en/panel_preferences_advanced.xml11
-rw-r--r--indra/newview/skins/default/xui/en/panel_social_photo.xml8
-rwxr-xr-xindra/newview/skins/default/xui/en/strings.xml51
-rwxr-xr-xindra/newview/viewer_manifest.py17
-rwxr-xr-xindra/win_crash_logger/CMakeLists.txt3
-rw-r--r--[-rwxr-xr-x]indra/win_crash_logger/llcrashloggerwindows.cpp186
-rw-r--r--[-rwxr-xr-x]indra/win_crash_logger/llcrashloggerwindows.h34
-rwxr-xr-xindra/win_crash_logger/win_crash_logger.cpp12
293 files changed, 6011 insertions, 3195 deletions
diff --git a/.hgtags b/.hgtags
index 30e96d4a18..08f079a3a1 100755
--- a/.hgtags
+++ b/.hgtags
@@ -475,3 +475,7 @@ d40c66e410741de7e90b1ed6dac28dd8a2d7e1f6 3.6.8-release
5d746de933a98ca17887cde2fece80e9c7ab0b98 3.7.0-release
dcb4981ce255841b6083d8f65444b65d5a733a17 3.7.1-release
b842534cb4d76c9ef87676a62b1d2d19e79c015f 3.7.2-release
+962d3f98955bfc7310a7867c8cbc3df075e54aa9 3.7.3-release
+d076568ff7883b41c149e6afb421f39c29dbfe2b 3.7.4-release
+fc066b82343fca51f9c1b8eda0abc6bee9bb4503 3.7.5-release
+d029faf69f20a23007f32420a1ac6a3b89a6d441 3.7.6-release
diff --git a/BuildParams b/BuildParams
index ede2595cd3..3e04d1ce29 100755
--- a/BuildParams
+++ b/BuildParams
@@ -49,33 +49,15 @@ viewer_channel = "Second Life Test"
# Setup default packaging parameters.
sourceid = ""
-additional_packages = "Amazon Desura A B C"
+additional_packages = "Amazon Desura"
Amazon_sourceid = "1207v_Amazon"
Amazon_viewer_channel_suffix = "Amazon"
Desura_sourceid = "1208_desura"
Desura_viewer_channel_suffix = "Desura"
-A_sourceid = "1300_A"
-A_viewer_channel_suffix = "A"
-B_sourceid = "1301_B"
-B_viewer_channel_suffix = "B"
-C_sourceid = "1302_C"
-C_viewer_channel_suffix = "C"
-
-# Report changes since...
-viewer-development.show_changes_since = last_sprint
-
-# Build Settings
-viewer-development.build_debug_release_separately = true
# Notifications - to configure email notices, add a setting like this:
# <username>_<reponame>.email = <email-address>
-viewer-release.viewer_channel = "Second Life Release"
-viewer-release.build_debug_release_separately = true
-viewer-release.build_viewer_update_version_manager = true
-viewer-release.codeticket_add_context = false
-
-
# ========================================
# mesh-development
# ========================================
@@ -127,25 +109,6 @@ viewer-mesh.viewer_channel = "Project Viewer - Mesh"
viewer-mesh.viewer_grid = aditi
viewer-mesh.email = shining@lists.lindenlab.com
-# ========================================
-# viewer-pathfinding
-# ========================================
-
-viewer-pathfinding.viewer_channel = "Project Viewer - Pathfinding"
-viewer-pathfinding.viewer_grid = agni
-viewer-pathfinding.build_debug_release_separately = true
-viewer-pathfinding.build_CYGWIN_Debug = false
-viewer-pathfinding.build_viewer_update_version_manager = false
-
-# ========================================
-# viewer-materials
-# ========================================
-
-viewer-materials.viewer_channel = "Second Life Beta Materials"
-viewer-materials.build_debug_release_separately = true
-viewer-materials.build_CYGWIN_Debug = false
-viewer-materials.build_viewer_update_version_manager = false
-
# =================================================================
# asset delivery 2010 projects
# =================================================================
@@ -174,6 +137,14 @@ simon_viewer-dev-private.email_status_this_is_os = false
vir-project-1.viewer_channel = "Second Life Release"
# ========================================
+# Merov
+# ========================================
+merov-viewer-maint-2287.viewer_channel = "Second Life Project Merchant Outbox"
+merov-viewer-maint-2287.login_channel = "Second Life Project Merchant Outbox"
+merov-viewer-maint-2287.build_viewer_update_version_manager = false
+merov-viewer-maint-2287.codeticket_add_context = false
+
+# ========================================
# THX-1138 / Runway projects
# ========================================
viewer-thx1138-runway-shared.viewer_channel = "Project Viewer - THX-1138 Runway"
@@ -200,7 +171,6 @@ runway.build_debug_release_separately = true
runway.build_CYGWIN_Debug = false
runway.build_viewer_update_version_manager = false
-
# eof
diff --git a/autobuild.xml b/autobuild.xml
index 6226c2137b..468a7c6182 100755
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -498,9 +498,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>10352aab979c333a52dbad21b6e6fba9</string>
+ <string>862b9244ed8a27bec16b62883fe3580a</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274403/arch/Darwin/installer/fmodex-4.44-darwin-20130419.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/288122/arch/Darwin/installer/fmodex-4.44.31-darwin-20140314.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -510,9 +510,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>79e45527aa9fb90b813599dff5ce01a7</string>
+ <string>180f4d703deec104469e6a9044243110</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/274378/arch/Linux/installer/fmodex-4.44-linux-20130419.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/288122/arch/Linux/installer/fmodex-4.44.31-linux-20140315.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -522,9 +522,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>91752db72202807cffb33c1ec3fd90fc</string>
+ <string>6c859cd17fb8c9cdd96b188c2a2c2838</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/276321/arch/CYGWIN/installer/fmodex-4.44-windows-20130521.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-fmodex-private/rev/288122/arch/CYGWIN/installer/fmodex-4.44.31-windows-20140314.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -786,9 +786,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d812a6dfcabe6528198a3191068dac09</string>
+ <string>a1e519d08c507c12f9d412b2ae8328c8</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/273073/arch/CYGWIN/installer/google_breakpad-0.0.0-rev1099-windows-20130329.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-breakpad/rev/279804/arch/CYGWIN/installer/google_breakpad-0.0.0-rev1099-windows-20130813.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1808,9 +1808,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>2994f1e028fb200c454c12b5f7ca9108</string>
+ <string>88181b9f66b7db650e0d571bbb632bdc</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/270464/arch/Darwin/installer/slvoice-4.5.0009.17865-darwin-20130215.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/287264/arch/Darwin/installer/slvoice-4.6.0009.20030-darwin-20140226.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -1832,9 +1832,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>24710eda136bfd42d6333e5609c2c74f</string>
+ <string>ce89b881ee24977641d1ecbf8aff6dc7</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/270464/arch/CYGWIN/installer/slvoice-4.5.0009.17865-windows-20130214.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-slvoice/rev/287264/arch/CYGWIN/installer/slvoice-4.6.0009.20030-windows-20140227.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index bcda595e91..db8d58dbc0 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -180,6 +180,8 @@ Ansariel Hiller
MAINT-2368
STORM-1931
MAINT-2773
+ STORM-2011
+ MAINT-3187
BUG-3764
STORM-1984
STORM-1979
@@ -330,6 +332,9 @@ Cron Stardust
VWR-25120
STORM-1075
STORM-1919
+ STORM-1920
+ OPEN-209
+ STORM-2017
Cypren Christenson
STORM-417
Dante Tucker
@@ -663,6 +668,7 @@ Jonathan Yap
STORM-1809
STORM-1793
STORM-1810
+ STORM-68
STORM-1838
STORM-1892
STORM-1894
@@ -680,6 +686,8 @@ Jonathan Yap
STORM-1953
STORM-1957
STORM-1993
+ STORM-2017
+ STORM-2007
STORM-1980
OPEN-113
STORM-1975
@@ -692,6 +700,8 @@ Jonathan Yap
STORM-1987
STORM-1986
STORM-1981
+ STORM-2015
+ STORM-2018
Kadah Coba
STORM-1060
STORM-1843
@@ -745,6 +755,7 @@ Kunnis Basiat
Lance Corrimal
STORM-1910
VWR-25269
+ STORM-2008
Latif Khalifa
VWR-5370
leliel Mirihi
@@ -961,6 +972,7 @@ Nicky Dasmijn
OPEN-187
STORM-1937
OPEN-187
+ STORM-2010
Nicky Perian
OPEN-1
STORM-1087
@@ -1158,6 +1170,7 @@ snowy Sidran
Sovereign Engineer
MAINT-2334
OPEN-189
+ STORM-1972
OPEN-195
SpacedOut Frye
VWR-34
@@ -1199,6 +1212,7 @@ Takeda Terrawyng
TankMaster Finesmith
OPEN-140
OPEN-142
+ OPEN-154
STORM-1100
STORM-1258
STORM-1602
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 44c2d3ac27..f98e88b697 100755
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -64,6 +64,7 @@ if(WINDOWS)
endif(USE_TCMALLOC)
if (FMODEX)
+ set(debug_files ${debug_files} fmodexL.dll)
set(release_files ${release_files} fmodex.dll)
endif (FMODEX)
@@ -294,7 +295,8 @@ elseif(LINUX)
endif (USE_TCMALLOC)
if (FMODEX)
- set(release_file ${release_files} "libfmodex.so")
+ set(debug_files ${debug_files} "libfmodexL.so")
+ set(release_files ${release_files} "libfmodex.so")
endif (FMODEX)
else(WINDOWS)
diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake
index 65bc1cabeb..163260137b 100644
--- a/indra/cmake/FMODEX.cmake
+++ b/indra/cmake/FMODEX.cmake
@@ -39,7 +39,7 @@ if (FMODEX)
optimized fmodex)
endif (WINDOWS)
set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
- set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex)
+ set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/)
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
endif (STANDALONE)
endif (FMODEX)
diff --git a/indra/cmake/GoogleBreakpad.cmake b/indra/cmake/GoogleBreakpad.cmake
index 96e22791ec..7f9ba4ea8e 100755
--- a/indra/cmake/GoogleBreakpad.cmake
+++ b/indra/cmake/GoogleBreakpad.cmake
@@ -13,7 +13,7 @@ else (STANDALONE)
set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES breakpad_client)
endif (LINUX)
if (WINDOWS)
- set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client common)
+ set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client crash_generation_server common)
endif (WINDOWS)
# yes, this does look dumb, no, it's not incorrect
#
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index beeb570496..86ce564c0d 100755
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -1,4 +1,4 @@
-Wed Nov 7 00:25:19 UTC 2012
+Wed Nov 7 00:25:19 UTC 2012
diff --git a/indra/linux_crash_logger/linux_crash_logger.cpp b/indra/linux_crash_logger/linux_crash_logger.cpp
index 99d0ad7e14..d4e7ad7be3 100755
--- a/indra/linux_crash_logger/linux_crash_logger.cpp
+++ b/indra/linux_crash_logger/linux_crash_logger.cpp
@@ -26,6 +26,7 @@
#include "linden_common.h"
#include "llcrashloggerlinux.h"
+#include "llsdutil.h"
int main(int argc, char **argv)
{
@@ -34,6 +35,16 @@ int main(int argc, char **argv)
LLCrashLoggerLinux app;
app.parseCommandOptions(argc, argv);
+ LLSD options = LLApp::instance()->getOptionData(
+ LLApp::PRIORITY_COMMAND_LINE);
+ //LLApp::PRIORITY_RUNTIME_OVERRIDE);
+
+
+ if (!(options.has("pid") && options.has("dumpdir")))
+ {
+ llwarns << "Insufficient parameters to crash report." << llendl;
+ }
+
if (! app.init())
{
llwarns << "Unable to initialize application." << llendl;
diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp
index 62465f9937..871d6377cb 100755
--- a/indra/linux_crash_logger/llcrashloggerlinux.cpp
+++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp
@@ -136,6 +136,7 @@ bool LLCrashLoggerLinux::mainLoop()
bool LLCrashLoggerLinux::cleanup()
{
commonCleanup();
+ mKeyMaster.releaseMaster();
return true;
}
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 3bb759d458..0f5d729e77 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -81,6 +81,7 @@ public:
~LLAvatarBoneInfo()
{
std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
+ mChildList.clear();
}
BOOL parseXml(LLXmlTreeNode* node);
@@ -108,6 +109,7 @@ public:
~LLAvatarSkeletonInfo()
{
std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
+ mBoneInfoList.clear();
}
BOOL parseXml(LLXmlTreeNode* node);
S32 getNumBones() const { return mNumBones; }
@@ -132,14 +134,26 @@ LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo()
LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
{
std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
+ mMeshInfoList.clear();
+
std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());
+ mSkeletalDistortionInfoList.clear();
+
std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
+ mAttachmentInfoList.clear();
+
deleteAndClear(mTexSkinColorInfo);
deleteAndClear(mTexHairColorInfo);
deleteAndClear(mTexEyeColorInfo);
+
std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
+ mLayerInfoList.clear();
+
std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+ mDriverInfoList.clear();
+
std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
+ mMorphMaskInfoList.clear();
}
@@ -291,10 +305,6 @@ LLAvatarAppearance::~LLAvatarAppearance()
clearSkeleton();
deleteAndClearArray(mCollisionVolumes);
- deleteAndClear(mTexSkinColor);
- deleteAndClear(mTexHairColor);
- deleteAndClear(mTexEyeColor);
-
std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
mPolyMeshes.clear();
diff --git a/indra/llappearance/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp
index f38b982104..16b0260d1a 100644
--- a/indra/llappearance/lltexglobalcolor.cpp
+++ b/indra/llappearance/lltexglobalcolor.cpp
@@ -120,6 +120,7 @@ LLTexGlobalColorInfo::LLTexGlobalColorInfo()
LLTexGlobalColorInfo::~LLTexGlobalColorInfo()
{
for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
+ mParamColorInfoList.clear();
}
BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node)
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index a3a8616864..63d01999f0 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -195,6 +195,7 @@ LLTexLayerSetInfo::LLTexLayerSetInfo() :
LLTexLayerSetInfo::~LLTexLayerSetInfo( )
{
std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());
+ mLayerInfoList.clear();
}
BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
@@ -282,7 +283,10 @@ LLTexLayerSet::~LLTexLayerSet()
{
deleteCaches();
std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer());
+ mLayerList.clear();
+
std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer());
+ mMaskLayerList.clear();
}
//-----------------------------------------------------------------------------
@@ -652,7 +656,9 @@ LLTexLayerInfo::LLTexLayerInfo() :
LLTexLayerInfo::~LLTexLayerInfo( )
{
std::for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer());
+ mParamColorInfoList.clear();
std::for_each(mParamAlphaInfoList.begin(), mParamAlphaInfoList.end(), DeletePointer());
+ mParamAlphaInfoList.clear();
}
BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp
index e9b74b8f41..36e8044a25 100644
--- a/indra/llaudio/llaudioengine_fmodex.cpp
+++ b/indra/llaudio/llaudioengine_fmodex.cpp
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2014, 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
@@ -55,11 +55,13 @@ LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler)
mWindDSP = NULL;
mSystem = NULL;
mEnableProfiler = enable_profiler;
+ mWindDSPDesc = new FMOD_DSP_DESCRIPTION();
}
LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX()
{
+ delete mWindDSPDesc;
}
@@ -320,8 +322,8 @@ void LLAudioEngine_FMODEX::shutdown()
llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
if ( mSystem ) // speculative fix for MAINT-2657
{
- mSystem->close();
- mSystem->release();
+ mSystem->close();
+ mSystem->release();
}
llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
@@ -347,15 +349,14 @@ bool LLAudioEngine_FMODEX::initWind()
if (!mWindDSP)
{
- FMOD_DSP_DESCRIPTION dspdesc;
- memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero
- strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit"
- dspdesc.channels=2;
- dspdesc.read = &windCallback; //Assign callback.
- if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP"))
+ memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero
+ strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name));
+ mWindDSPDesc->channels = 2;
+ mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads
+ if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP"))
return false;
- if(mWindGen)
+ if (mWindGen)
delete mWindGen;
float frequency = 44100;
@@ -364,6 +365,7 @@ bool LLAudioEngine_FMODEX::initWind()
mWindDSP->setUserData((void*)mWindGen);
}
+ // *TODO: Should this guard against multiple plays?
if (mWindDSP)
{
mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
@@ -741,6 +743,9 @@ void LLAudioChannelFMODEX::set3DMode(bool use3d)
}
}
+// *NOTE: This is almost certainly being called on the mixer thread,
+// not the main thread. May have implications for callees or audio
+// engine shutdown.
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels)
{
diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h
index 415a9ed0ef..ca389d489f 100644
--- a/indra/llaudio/llaudioengine_fmodex.h
+++ b/indra/llaudio/llaudioengine_fmodex.h
@@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2014, 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
@@ -41,6 +41,7 @@ namespace FMOD
class Sound;
class DSP;
}
+typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION;
//Interfaces
class LLAudioEngine_FMODEX : public LLAudioEngine
@@ -74,6 +75,7 @@ protected:
LLWindGen<MIXBUFFERFORMAT> *mWindGen;
+ FMOD_DSP_DESCRIPTION *mWindDSPDesc;
FMOD::DSP *mWindDSP;
FMOD::System *mSystem;
bool mEnableProfiler;
diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp
index 2509a7aebc..31ab47a635 100644
--- a/indra/llaudio/lllistener_fmodex.cpp
+++ b/indra/llaudio/lllistener_fmodex.cpp
@@ -94,6 +94,11 @@ void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at)
//-----------------------------------------------------------------------
void LLListener_FMODEX::commitDeferredChanges()
{
+ if(!mSystem)
+ {
+ return;
+ }
+
mSystem->update();
}
diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp
index 2a0df26384..8c02a25367 100755
--- a/indra/llcharacter/llbvhloader.cpp
+++ b/indra/llcharacter/llbvhloader.cpp
@@ -203,6 +203,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
LLBVHLoader::~LLBVHLoader()
{
std::for_each(mJoints.begin(),mJoints.end(),DeletePointer());
+ mJoints.clear();
}
//------------------------------------------------------------------------
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 07ef52228e..2241a59513 100755
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -81,7 +81,9 @@ LLKeyframeMotion::JointMotionList::JointMotionList()
LLKeyframeMotion::JointMotionList::~JointMotionList()
{
for_each(mConstraints.begin(), mConstraints.end(), DeletePointer());
+ mConstraints.clear();
for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer());
+ mJointMotionArray.clear();
}
U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo()
@@ -447,6 +449,7 @@ LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id)
LLKeyframeMotion::~LLKeyframeMotion()
{
for_each(mConstraints.begin(), mConstraints.end(), DeletePointer());
+ mConstraints.clear();
}
//-----------------------------------------------------------------------------
diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp
index e2d284834f..411bb094fd 100755
--- a/indra/llcharacter/llmultigesture.cpp
+++ b/indra/llcharacter/llmultigesture.cpp
@@ -59,6 +59,7 @@ LLMultiGesture::LLMultiGesture()
LLMultiGesture::~LLMultiGesture()
{
std::for_each(mSteps.begin(), mSteps.end(), DeletePointer());
+ mSteps.clear();
}
void LLMultiGesture::reset()
diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp
index 55e1b6e9ea..b1a7ebb159 100755
--- a/indra/llcharacter/llpose.cpp
+++ b/indra/llcharacter/llpose.cpp
@@ -461,6 +461,7 @@ LLPoseBlender::LLPoseBlender()
LLPoseBlender::~LLPoseBlender()
{
for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer());
+ mJointStateBlenderPool.clear();
}
//-----------------------------------------------------------------------------
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 67a98d5fb8..63a38f2884 100755
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -46,8 +46,8 @@
#include "llstl.h" // for DeletePointer()
#include "llstring.h"
#include "lleventtimer.h"
-
#include "google_breakpad/exception_handler.h"
+#include "stringize.h"
//
// Signal handling
@@ -55,6 +55,8 @@
// Windows uses structured exceptions, so it's handled a bit differently.
//
#if LL_WINDOWS
+#include "windows.h"
+
LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop);
BOOL ConsoleCtrlHandler(DWORD fdwCtrlType);
bool windows_post_minidump_callback(const wchar_t* dump_path,
@@ -71,7 +73,9 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *);
#if LL_LINUX
#include "google_breakpad/minidump_descriptor.h"
-bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded);
+static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc,
+ void* context,
+ bool succeeded);
#else
// Called by breakpad exception handler after the minidump has been generated.
bool unix_post_minidump_callback(const char *dump_dir,
@@ -109,11 +113,6 @@ BOOL LLApp::sLogInSignal = FALSE;
LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status
LLAppErrorHandler LLApp::sErrorHandler = NULL;
BOOL LLApp::sErrorThreadRunning = FALSE;
-#if !LL_WINDOWS
-LLApp::child_map LLApp::sChildMap;
-LLAtomicU32* LLApp::sSigChildCount = NULL;
-LLAppChildCallback LLApp::sDefaultChildCallback = NULL;
-#endif
LLApp::LLApp() : mThreadErrorp(NULL)
@@ -128,11 +127,6 @@ void LLApp::commonCtor()
LLCommon::initClass();
-#if !LL_WINDOWS
- // This must be initialized before the error handler.
- sSigChildCount = new LLAtomicU32(0);
-#endif
-
// initialize the options structure. We need to make this an array
// because the structured data will not auto-allocate if we
// reference an invalid location with the [] operator.
@@ -149,12 +143,13 @@ void LLApp::commonCtor()
// Set the application to this instance.
sApplication = this;
-
+
mExceptionHandler = 0;
// initialize the buffer to write the minidump filename to
// (this is used to avoid allocating memory in the crash handler)
- memset(minidump_path, 0, MAX_MINDUMP_PATH_LENGTH);
+ memset(mMinidumpPath, 0, MAX_MINDUMP_PATH_LENGTH);
+ mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
}
LLApp::LLApp(LLErrorThread *error_thread) :
@@ -166,10 +161,6 @@ LLApp::LLApp(LLErrorThread *error_thread) :
LLApp::~LLApp()
{
-#if !LL_WINDOWS
- delete sSigChildCount;
- sSigChildCount = NULL;
-#endif
// reclaim live file memory
std::for_each(mLiveFiles.begin(), mLiveFiles.end(), DeletePointer());
@@ -244,6 +235,20 @@ bool LLApp::parseCommandOptions(int argc, char** argv)
}
++ii;
value.assign(argv[ii]);
+
+#if LL_WINDOWS
+ //Windows changed command line parsing. Deal with it.
+ S32 slen = value.length() - 1;
+ S32 start = 0;
+ S32 end = slen;
+ if (argv[ii][start]=='"')start++;
+ if (argv[ii][end]=='"')end--;
+ if (start!=0 || end!=slen)
+ {
+ value = value.substr (start,end);
+ }
+#endif
+
commands[name] = value;
}
setOptionData(PRIORITY_COMMAND_LINE, commands);
@@ -288,14 +293,43 @@ void LLApp::stepFrame()
mRunner.run();
}
+#if LL_WINDOWS
+//The following code is needed for 32-bit apps on 64-bit windows to keep it from eating
+//crashes. It is a lovely undocumented 'feature' in SP1 of Windows 7. An excellent
+//in-depth article on the issue may be found here: http://randomascii.wordpress.com/2012/07/05/when-even-crashing-doesn-work/
+void EnableCrashingOnCrashes()
+{
+ typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
+ typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
+ const DWORD EXCEPTION_SWALLOWING = 0x1;
+
+ HMODULE kernel32 = LoadLibraryA("kernel32.dll");
+ tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32,
+ "GetProcessUserModeExceptionPolicy");
+ tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32,
+ "SetProcessUserModeExceptionPolicy");
+ if (pGetPolicy && pSetPolicy)
+ {
+ DWORD dwFlags;
+ if (pGetPolicy(&dwFlags))
+ {
+ // Turn off the filter
+ pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
+ }
+ }
+}
+#endif
-void LLApp::setupErrorHandling()
+void LLApp::setupErrorHandling(bool second_instance)
{
// Error handling is done by starting up an error handling thread, which just sleeps and
// occasionally checks to see if the app is in an error state, and sees if it needs to be run.
#if LL_WINDOWS
+
#if LL_SEND_CRASH_REPORTS
+ EnableCrashingOnCrashes();
+
// This sets a callback to handle w32 signals to the console window.
// The viewer shouldn't be affected, sicne its a windowed app.
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE);
@@ -303,9 +337,57 @@ void LLApp::setupErrorHandling()
// Install the Google Breakpad crash handler for Windows
if(mExceptionHandler == 0)
{
- llwarns << "adding breakpad exception handler" << llendl;
- mExceptionHandler = new google_breakpad::ExceptionHandler(
- L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL);
+ if ( second_instance ) //BUG-5707 Firing teleport from a web browser causes second
+ {
+ mExceptionHandler = new google_breakpad::ExceptionHandler(
+ L"C:\\Temp\\",
+ 0, //No filter
+ windows_post_minidump_callback,
+ 0,
+ google_breakpad::ExceptionHandler::HANDLER_ALL); //No custom client info.
+ }
+ else
+ {
+ llwarns << "adding breakpad exception handler" << llendl;
+
+ std::wstring wpipe_name;
+ wpipe_name = mCrashReportPipeStr + wstringize(getPid());
+
+ const std::wstring wdump_path(wstringize(mDumpPath));
+
+ int retries = 30;
+ for (; retries > 0; --retries)
+ {
+ if (mExceptionHandler != 0) delete mExceptionHandler;
+
+ mExceptionHandler = new google_breakpad::ExceptionHandler(
+ wdump_path,
+ NULL, //No filter
+ windows_post_minidump_callback,
+ 0,
+ google_breakpad::ExceptionHandler::HANDLER_ALL,
+ MiniDumpNormal, //Generate a 'normal' minidump.
+ wpipe_name.c_str(),
+ NULL); //No custom client info.
+ if (mExceptionHandler->IsOutOfProcess())
+ {
+ LL_INFOS("CRASHREPORT") << "Successfully attached to Out of Process exception handler." << LL_ENDL;
+ break;
+ }
+ else
+ {
+ LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler. " << retries << " retries remaining." << LL_ENDL;
+ ::Sleep(100); //Wait a tick and try again.
+ }
+ }
+
+ if (retries == 0) LL_WARNS("CRASHREPORT") << "Unable to attach to Out of Process exception handler." << LL_ENDL;
+ }
+
+ if (mExceptionHandler)
+ {
+ mExceptionHandler->set_handle_debug_exceptions(true);
+ }
}
#endif
#else
@@ -355,14 +437,17 @@ void LLApp::setupErrorHandling()
if(installHandler && (mExceptionHandler == 0))
{
- std::string dumpPath = "/tmp/";
- mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true, 0);
+ mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, 0, &unix_post_minidump_callback, 0, true, 0);
}
#elif LL_LINUX
if(installHandler && (mExceptionHandler == 0))
{
- google_breakpad::MinidumpDescriptor desc("/tmp");
- new google_breakpad::ExceptionHandler(desc, 0, &unix_minidump_callback, 0, true, 0);
+ if (mDumpPath.empty())
+ {
+ mDumpPath = "/tmp";
+ }
+ google_breakpad::MinidumpDescriptor desc(mDumpPath);
+ mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1);
}
#endif
@@ -418,19 +503,35 @@ void LLApp::setError()
void LLApp::setMiniDumpDir(const std::string &path)
{
+ if (path.empty())
+ {
+ mDumpPath = "/tmp";
+ }
+ else
+ {
+ mDumpPath = path;
+ }
+
if(mExceptionHandler == 0) return;
#ifdef LL_WINDOWS
wchar_t buffer[MAX_MINDUMP_PATH_LENGTH];
- mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH);
+ mbstowcs(buffer, mDumpPath.c_str(), MAX_MINDUMP_PATH_LENGTH);
mExceptionHandler->set_dump_path(std::wstring(buffer));
#elif LL_LINUX
- google_breakpad::MinidumpDescriptor desc(path);
+ //google_breakpad::MinidumpDescriptor desc("/tmp"); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched.
+ google_breakpad::MinidumpDescriptor desc(mDumpPath); //path works in debug fails in production inside breakpad lib so linux gets a little less stack reporting until it is patched.
mExceptionHandler->set_minidump_descriptor(desc);
#else
- mExceptionHandler->set_dump_path(path);
+ mExceptionHandler->set_dump_path(mDumpPath);
#endif
}
+void LLApp::setDebugFileNames(const std::string &path)
+{
+ mStaticDebugFileName = path + "static_debug_info.log";
+ mDynamicDebugFileName = path + "dynamic_debug_info.log";
+}
+
void LLApp::writeMiniDump()
{
if(mExceptionHandler == 0) return;
@@ -507,34 +608,11 @@ bool LLApp::isCrashloggerDisabled()
return (sDisableCrashlogger == TRUE);
}
-#if !LL_WINDOWS
-// static
-U32 LLApp::getSigChildCount()
-{
- if (sSigChildCount)
- {
- return U32(*sSigChildCount);
- }
- return 0;
-}
-
-// static
-void LLApp::incSigChildCount()
-{
- if (sSigChildCount)
- {
- (*sSigChildCount)++;
- }
-}
-
-#endif
-
-
// static
int LLApp::getPid()
{
#if LL_WINDOWS
- return 0;
+ return GetCurrentProcessId();
#else
return getpid();
#endif
@@ -610,43 +688,6 @@ BOOL ConsoleCtrlHandler(DWORD fdwCtrlType)
}
#else //!LL_WINDOWS
-void LLApp::setChildCallback(pid_t pid, LLAppChildCallback callback)
-{
- LLChildInfo child_info;
- child_info.mCallback = callback;
- LLApp::sChildMap[pid] = child_info;
-}
-
-void LLApp::setDefaultChildCallback(LLAppChildCallback callback)
-{
- LLApp::sDefaultChildCallback = callback;
-}
-
-pid_t LLApp::fork()
-{
- fflush(NULL); // flush all buffers before the child inherits them
- pid_t pid = ::fork();
- if( pid < 0 )
- {
- int system_error = errno;
- llwarns << "Unable to fork! Operating system error code: "
- << system_error << llendl;
- }
- else if (pid == 0)
- {
- // Sleep a bit to allow the parent to set up child callbacks.
- ms_sleep(10);
-
- // We need to disable signal handling, because we don't have a
- // signal handling thread anymore.
- setupErrorHandling();
- }
- else
- {
- llinfos << "Forked child process " << pid << llendl;
- }
- return pid;
-}
void setup_signals()
{
@@ -747,19 +788,6 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
llinfos << "Signal handler - Got SIGCHLD from " << info->si_pid << llendl;
}
- // Check result code for all child procs for which we've
- // registered callbacks THIS WILL NOT WORK IF SIGCHLD IS SENT
- // w/o killing the child (Go, launcher!)
- // TODO: Now that we're using SIGACTION, we can actually
- // implement the launcher behavior to determine who sent the
- // SIGCHLD even if it doesn't result in child termination
- if (LLApp::sChildMap.count(info->si_pid))
- {
- LLApp::sChildMap[info->si_pid].mGotSigChild = TRUE;
- }
-
- LLApp::incSigChildCount();
-
return;
case SIGABRT:
// Abort just results in termination of the app, no funky error handling.
@@ -880,21 +908,26 @@ bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_
// heap allocations in a crash handler.
// path format: <dump_dir>/<minidump_id>.dmp
- int dirPathLength = strlen(minidump_desc.path());
+
+ //HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space
+ //to avoid doing allocation during crash.
+ char * path = LLApp::instance()->getMiniDumpFilename();
+ int dir_path_len = strlen(path);
// The path must not be truncated.
- llassert((dirPathLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH);
+ S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len;
+
+ llassert( (remaining - strlen(minidump_desc.path())) > 5);
- char * path = LLApp::instance()->getMiniDumpFilename();
- S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
- strncpy(path, minidump_desc.path(), remaining);
- remaining -= dirPathLength;
- path += dirPathLength;
- if (remaining > 0 && dirPathLength > 0 && path[-1] != '/')
+ path += dir_path_len;
+
+ if (dir_path_len > 0 && path[-1] != '/')
{
*path++ = '/';
--remaining;
}
+
+ strncpy(path, minidump_desc.path(), remaining);
llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
LLApp::runErrorHandler();
@@ -942,7 +975,7 @@ bool unix_post_minidump_callback(const char *dump_dir,
strncpy(path, ".dmp", remaining);
}
- llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl;
+ llinfos << "generated minidump: " << path << llendl;
LLApp::runErrorHandler();
#ifndef LL_RELEASE_FOR_DOWNLOAD
@@ -966,6 +999,7 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH;
size_t bytesUsed;
+ LL_INFOS("MINIDUMPCALLBACK") << "Dump file was generated." << LL_ENDL;
bytesUsed = wcstombs(path, dump_path, static_cast<size_t>(remaining));
remaining -= bytesUsed;
path += bytesUsed;
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index afa06df23e..3f7bf2ca47 100755
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -31,7 +31,6 @@
#include "llrun.h"
#include "llsd.h"
#include "lloptioninterface.h"
-
// Forward declarations
template <typename Type> class LLAtomic32;
typedef LLAtomic32<U32> LLAtomicU32;
@@ -42,7 +41,6 @@ class LLLiveFile;
#endif
typedef void (*LLAppErrorHandler)();
-typedef void (*LLAppChildCallback)(int pid, bool exited, int status);
#if !LL_WINDOWS
extern S32 LL_SMACKDOWN_SIGNAL;
@@ -51,13 +49,6 @@ extern S32 LL_HEARTBEAT_SIGNAL;
// Clear all of the signal handlers (which we want to do for the child process when we fork
void clear_signals();
-class LLChildInfo
-{
-public:
- LLChildInfo() : mGotSigChild(FALSE), mCallback(NULL) {}
- BOOL mGotSigChild;
- LLAppChildCallback mCallback;
-};
#endif
namespace google_breakpad {
@@ -206,10 +197,6 @@ public:
static bool isQuitting();
static bool isError();
static bool isExiting(); // Either quitting or error (app is exiting, cleanly or not)
-#if !LL_WINDOWS
- static U32 getSigChildCount();
- static void incSigChildCount();
-#endif
static int getPid();
/** @name Error handling methods */
@@ -227,7 +214,7 @@ public:
* DO NOT call this method if your application has specialized
* error handling code.
*/
- void setupErrorHandling();
+ void setupErrorHandling(bool mSecondInstance=false);
void setErrorHandler(LLAppErrorHandler handler);
static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
@@ -238,32 +225,16 @@ public:
// change the directory where Breakpad minidump files are written to
void setMiniDumpDir(const std::string &path);
+ void setDebugFileNames(const std::string &path);
// Return the Google Breakpad minidump filename after a crash.
- char *getMiniDumpFilename() { return minidump_path; }
+ char *getMiniDumpFilename() { return mMinidumpPath; }
+ std::string* getStaticDebugFile() { return &mStaticDebugFileName; }
+ std::string* getDynamicDebugFile() { return &mDynamicDebugFileName; }
// Write out a Google Breakpad minidump file.
void writeMiniDump();
-#if !LL_WINDOWS
- //
- // Child process handling (Unix only for now)
- //
- // Set a callback to be run on exit of a child process
- // WARNING! This callback is run from the signal handler due to
- // Linux threading requiring waitpid() to be called from the thread that spawned the process.
- // At some point I will make this more behaved, but I'm not going to fix this right now - djs
- void setChildCallback(pid_t pid, LLAppChildCallback callback);
-
- // The child callback to run if no specific handler is set
- void setDefaultChildCallback(LLAppChildCallback callback);
-
- // Fork and do the proper signal handling/error handling mojo
- // *NOTE: You need to make sure your signal handling callback is
- // correct after you fork, because not all threads are duplicated
- // when you fork!
- pid_t fork();
-#endif
/**
* @brief Get a reference to the application runner
@@ -286,13 +257,9 @@ protected:
static EAppStatus sStatus; // Reflects current application status
static BOOL sErrorThreadRunning; // Set while the error thread is running
static BOOL sDisableCrashlogger; // Let the OS handle crashes for us.
+ std::wstring mCrashReportPipeStr; //Name of pipe to use for crash reporting.
-#if !LL_WINDOWS
- static LLAtomicU32* sSigChildCount; // Number of SIGCHLDs received.
- typedef std::map<pid_t, LLChildInfo> child_map; // Map key is a PID
- static child_map sChildMap;
- static LLAppChildCallback sDefaultChildCallback;
-#endif
+ std::string mDumpPath; //output path for google breakpad. Dependency workaround.
/**
* @brief This method is called once a frame to do once a frame tasks.
@@ -303,7 +270,10 @@ private:
void startErrorThread();
// Contains the filename of the minidump file after a crash.
- char minidump_path[MAX_MINDUMP_PATH_LENGTH];
+ char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH];
+
+ std::string mStaticDebugFileName;
+ std::string mDynamicDebugFileName;
// *NOTE: On Windows, we need a routine to reset the structured
// exception handler when some evil driver has taken it over for
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 642bd82e90..d12f157910 100755
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -44,6 +44,7 @@ static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
bool LLAvatarName::sUseDisplayNames = true;
+bool LLAvatarName::sUseUsernames = true;
// Minimum time-to-live (in seconds) for a name entry.
// Avatar name should always guarantee to expire reasonably soon by default
@@ -81,6 +82,16 @@ bool LLAvatarName::useDisplayNames()
return sUseDisplayNames;
}
+void LLAvatarName::setUseUsernames(bool use)
+{
+ sUseUsernames = use;
+}
+
+bool LLAvatarName::useUsernames()
+{
+ return sUseUsernames;
+}
+
LLSD LLAvatarName::asLLSD() const
{
LLSD sd;
@@ -168,7 +179,11 @@ std::string LLAvatarName::getCompleteName() const
}
else
{
- name = mDisplayName + " (" + mUsername + ")";
+ name = mDisplayName;
+ if(sUseUsernames)
+ {
+ name += " (" + mUsername + ")";
+ }
}
}
else
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index 5d2fccc5ba..1cb3ae421f 100755
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -54,6 +54,9 @@ public:
static void setUseDisplayNames(bool use);
static bool useDisplayNames();
+ static void setUseUsernames(bool use);
+ static bool useUsernames();
+
// A name object is valid if not temporary and not yet expired (default is expiration not checked)
bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
@@ -128,6 +131,9 @@ private:
// Global flag indicating if display name should be used or not
// This will affect the output of the high level "get" methods
static bool sUseDisplayNames;
+
+ // Flag indicating if username should be shown after display name or not
+ static bool sUseUsernames;
};
#endif
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index d2af004cde..853f279c95 100755
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -429,8 +429,8 @@ namespace LLError
~Settings()
{
- for_each(recorders.begin(), recorders.end(),
- DeletePointer());
+ for_each(recorders.begin(), recorders.end(), DeletePointer());
+ recorders.clear();
}
static Settings*& getPtr();
diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp
index 950fcd6e83..ebfbe19ff7 100755
--- a/indra/llcommon/llerrorthread.cpp
+++ b/indra/llcommon/llerrorthread.cpp
@@ -109,79 +109,8 @@ void LLErrorThread::run()
llinfos << "thread_error - Waiting for an error" << llendl;
S32 counter = 0;
-#if !LL_WINDOWS
- U32 last_sig_child_count = 0;
-#endif
while (! (LLApp::isError() || LLApp::isStopped()))
{
-#if !LL_WINDOWS
- // Check whether or not the main thread had a sig child we haven't handled.
- U32 current_sig_child_count = LLApp::getSigChildCount();
- if (last_sig_child_count != current_sig_child_count)
- {
- int status = 0;
- pid_t child_pid = 0;
- last_sig_child_count = current_sig_child_count;
- if (LLApp::sLogInSignal)
- {
- llinfos << "thread_error handling SIGCHLD #" << current_sig_child_count << llendl;
- }
- for (LLApp::child_map::iterator iter = LLApp::sChildMap.begin(); iter != LLApp::sChildMap.end();)
- {
- child_pid = iter->first;
- LLChildInfo &child_info = iter->second;
- // check the status of *all* children, in case we missed a signal
- if (0 != waitpid(child_pid, &status, WNOHANG))
- {
- bool exited = false;
- int exit_status = -1;
- get_child_status(status, exit_status, exited, LLApp::sLogInSignal);
-
- if (child_info.mCallback)
- {
- if (LLApp::sLogInSignal)
- {
- llinfos << "Signal handler - Running child callback" << llendl;
- }
- child_info.mCallback(child_pid, exited, status);
- }
- LLApp::sChildMap.erase(iter++);
- }
- else
- {
- // Child didn't terminate, yet we got a sigchild somewhere...
- if (child_info.mGotSigChild && child_info.mCallback)
- {
- child_info.mCallback(child_pid, false, 0);
- }
- child_info.mGotSigChild = FALSE;
- iter++;
- }
- }
-
- // check the status of *all* children, in case we missed a signal
- // Same as above, but use the default child callback
- while(0 < (child_pid = waitpid( -1, &status, WNOHANG )))
- {
- if (0 != waitpid(child_pid, &status, WNOHANG))
- {
- bool exited = false;
- int exit_status = -1;
- get_child_status(status, exit_status, exited, LLApp::sLogInSignal);
- if (LLApp::sDefaultChildCallback)
- {
- if (LLApp::sLogInSignal)
- {
- llinfos << "Signal handler - Running default child callback" << llendl;
- }
- LLApp::sDefaultChildCallback(child_pid, true, status);
- }
- }
- }
- }
-
-
-#endif
ms_sleep(10);
counter++;
}
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 01b6e60d2b..58db7d0d17 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -119,6 +119,7 @@ public:
~NamedTimerFactory()
{
std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
+ mTimers.clear();
delete mTimerRoot;
}
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c3a0f0bfe0..761d7f430c 100755
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -265,6 +265,37 @@ int LLFile::rename(const std::string& filename, const std::string& newname)
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc);
}
+bool LLFile::copy(const std::string from, const std::string to)
+{
+ bool copied = false;
+ LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */
+ if (in)
+ {
+ LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */
+ if (out)
+ {
+ char buf[16384]; /* Flawfinder: ignore */
+ size_t readbytes;
+ bool write_ok = true;
+ while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
+ {
+ if (fwrite(buf, 1, readbytes, out) != readbytes)
+ {
+ LL_WARNS("LLFile") << "Short write" << LL_ENDL;
+ write_ok = false;
+ }
+ }
+ if ( write_ok )
+ {
+ copied = true;
+ }
+ fclose(out);
+ }
+ fclose(in);
+ }
+ return copied;
+}
+
int LLFile::stat(const std::string& filename, llstat* filestatus)
{
#if LL_WINDOWS
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index d59e68367e..f56b22bf9a 100755
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -75,6 +75,8 @@ public:
static int rmdir(const std::string& filename);
static int remove(const std::string& filename);
static int rename(const std::string& filename,const std::string& newname);
+ static bool copy(const std::string from, const std::string to);
+
static int stat(const std::string& filename,llstat* file_status);
static bool isdir(const std::string& filename);
static bool isfile(const std::string& filename);
diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp
index f6d0f5bce8..9c38349cf7 100755
--- a/indra/llcommon/llfoldertype.cpp
+++ b/indra/llcommon/llfoldertype.cpp
@@ -92,8 +92,9 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE));
- addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE));
- addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", TRUE));
+ addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", FALSE));
+ addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", FALSE));
+
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index d3941e1bc9..0a39288f5a 100755
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -98,6 +98,7 @@ struct DeletePointerArray
// The general form is:
//
// std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer());
+// somemap.clear(); // Don't leave dangling pointers around
struct DeletePairedPointer
{
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index f9702868c8..16a19e7021 100755
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -518,10 +518,13 @@ LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
-
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
+#if LL_WINDOWS
+inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);}
+#endif
+
// Length of this UTF32 string in bytes when transformed to UTF8
LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr);
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index 72f2e58ce1..acae74b584 100755
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -31,21 +31,64 @@
#include <sstream>
#include <boost/lambda/lambda.hpp>
+#include <llstring.h>
/**
- * stringize(item) encapsulates an idiom we use constantly, using
+ * gstringize(item) encapsulates an idiom we use constantly, using
* operator<<(std::ostringstream&, TYPE) followed by std::ostringstream::str()
+ * or their wstring equivalents
* to render a string expressing some item.
*/
-template <typename T>
-std::string stringize(const T& item)
+template <typename CHARTYPE, typename T>
+std::basic_string<CHARTYPE> gstringize(const T& item)
{
- std::ostringstream out;
+ std::basic_ostringstream<CHARTYPE> out;
out << item;
return out.str();
}
/**
+ *partial specialization of stringize for handling wstring
+ *TODO: we should have similar specializations for wchar_t[] but not until it is needed.
+ */
+inline std::string stringize(const std::wstring& item)
+{
+ llwarns << "WARNING: Possible narrowing" << llendl;
+
+ std::string s;
+
+ s = wstring_to_utf8str(item);
+ return gstringize<char>(s);
+}
+
+/**
+ * Specialization of gstringize for std::string return types
+ */
+template <typename T>
+std::string stringize(const T& item)
+{
+ return gstringize<char>(item);
+}
+
+/**
+ * Specialization for generating wstring from string.
+ * Both a convenience function and saves a miniscule amount of overhead.
+ */
+inline std::wstring wstringize(const std::string& item)
+{
+ return gstringize<wchar_t>(item.c_str());
+}
+
+/**
+ * Specialization of gstringize for std::wstring return types
+ */
+template <typename T>
+std::wstring wstringize(const T& item)
+{
+ return gstringize<wchar_t>(item);
+}
+
+/**
* stringize_f(functor)
*/
template <typename Functor>
diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp
index 3d34f23998..3e4ca548e5 100755
--- a/indra/llcommon/tests/stringize_test.cpp
+++ b/indra/llcommon/tests/stringize_test.cpp
@@ -67,6 +67,8 @@ namespace tut
llsd["i"] = i;
llsd["d"] = d;
llsd["abc"] = abc;
+ def = L"def ghi";
+
}
char c;
@@ -76,6 +78,7 @@ namespace tut
float f;
double d;
std::string abc;
+ std::wstring def;
LLSD llsd;
};
typedef test_group<stringize_data> stringize_group;
@@ -92,6 +95,7 @@ namespace tut
ensure_equals(stringize(f), "3.14159");
ensure_equals(stringize(d), "3.14159");
ensure_equals(stringize(abc), "abc def");
+ ensure_equals(stringize(def), "def ghi"); //Will generate llwarns due to narrowing.
ensure_equals(stringize(llsd), "{'abc':'abc def','d':r3.14159,'i':i34}");
}
@@ -101,4 +105,20 @@ namespace tut
ensure_equals(STRINGIZE("c is " << c), "c is c");
ensure_equals(STRINGIZE(std::setprecision(4) << d), "3.142");
}
+
+ template<> template<>
+ void stringize_object::test<3>()
+ {
+ //Tests rely on validity of wstring_to_utf8str()
+ ensure_equals(wstring_to_utf8str(wstringize(c)), wstring_to_utf8str(L"c"));
+ ensure_equals(wstring_to_utf8str(wstringize(s)), wstring_to_utf8str(L"17"));
+ ensure_equals(wstring_to_utf8str(wstringize(i)), wstring_to_utf8str(L"34"));
+ ensure_equals(wstring_to_utf8str(wstringize(l)), wstring_to_utf8str(L"68"));
+ ensure_equals(wstring_to_utf8str(wstringize(f)), wstring_to_utf8str(L"3.14159"));
+ ensure_equals(wstring_to_utf8str(wstringize(d)), wstring_to_utf8str(L"3.14159"));
+ ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(L"abc def"));
+ ensure_equals(wstring_to_utf8str(wstringize(abc)), wstring_to_utf8str(wstringize(abc.c_str())));
+ ensure_equals(wstring_to_utf8str(wstringize(def)), wstring_to_utf8str(L"def ghi"));
+ // ensure_equals(wstring_to_utf8str(wstringize(llsd)), wstring_to_utf8str(L"{'abc':'abc def','d':r3.14159,'i':i34}"));
+ }
} // namespace tut
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index 12986de8b2..ba4e34d92b 100755
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -23,12 +23,14 @@ include_directories(SYSTEM
set(llcrashlogger_SOURCE_FILES
llcrashlogger.cpp
+ llcrashlock.cpp
)
set(llcrashlogger_HEADER_FILES
CMakeLists.txt
llcrashlogger.h
+ llcrashlock.h
)
set_source_files_properties(${llcrashlogger_HEADER_FILES}
diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp
new file mode 100644
index 0000000000..c3d2f944fc
--- /dev/null
+++ b/indra/llcrashlogger/llcrashlock.cpp
@@ -0,0 +1,209 @@
+/**
+ * @file llformat.cpp
+ * @date January 2007
+ * @brief string formatting utility
+ *
+ * $LicenseInfo:firstyear=2007&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 "linden_common.h"
+
+#include "llcrashlock.h"
+#include "lldir.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llnametable.h"
+#include "llframetimer.h"
+#include <boost/filesystem.hpp>
+#include <string>
+#include <iostream>
+#include <stdio.h>
+
+
+#if LL_WINDOWS //For windows platform.
+#include <windows.h>
+#include <TlHelp32.h>
+
+namespace {
+ inline DWORD getpid() {
+ return GetCurrentProcessId();
+ }
+}
+
+bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
+{
+ std::wstring wpname;
+ wpname = std::wstring(pname.begin(), pname.end());
+
+ HANDLE snapshot;
+ PROCESSENTRY32 pe32;
+
+ bool matched = false;
+
+ snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (snapshot == INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+ else
+ {
+ pe32.dwSize = sizeof(PROCESSENTRY32);
+ if (Process32First(snapshot, &pe32))
+ {
+ do {
+ std::wstring wexecname = pe32.szExeFile;
+ std::string execname = std::string(wexecname.begin(), wexecname.end());
+ if (!wpname.compare(pe32.szExeFile))
+ {
+ if (pid == (U32)pe32.th32ProcessID)
+ {
+ matched = true;
+ break;
+ }
+ }
+ } while (Process32Next(snapshot, &pe32));
+ }
+ }
+
+ CloseHandle(snapshot);
+ return matched;
+}
+
+#else //Everyone Else
+bool LLCrashLock::isProcessAlive(U32 pid, const std::string& pname)
+{
+ //Will boost.process ever become a reality?
+ std::stringstream cmd;
+
+ cmd << "pgrep '" << pname << "' | grep '^" << pid << "$'";
+ return (!system(cmd.str().c_str()));
+}
+#endif //Everyone else.
+
+
+LLCrashLock::LLCrashLock() : mCleanUp(true), mWaitingPID(0)
+{
+}
+
+void LLCrashLock::setCleanUp(bool cleanup)
+{
+ mCleanUp = cleanup; //Allow cleanup to be disabled for debugging.
+}
+
+LLSD LLCrashLock::getLockFile(std::string filename)
+{
+ LLSD lock_sd = LLSD::emptyMap();
+
+ llifstream ifile(filename);
+
+ if (ifile.is_open())
+ {
+ LLSDSerialize::fromXML(lock_sd, ifile);
+ ifile.close();
+ }
+
+ return lock_sd;
+}
+
+bool LLCrashLock::putLockFile(std::string filename, const LLSD& data)
+{
+ bool result = true;
+ llofstream ofile(filename);
+
+ if (!LLSDSerialize::toXML(data,ofile))
+ {
+ result=false;
+ }
+ ofile.close();
+ return result;
+}
+
+bool LLCrashLock::requestMaster( F32 timeout )
+{
+ if (mMaster.empty())
+ {
+ mMaster = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "crash_master.lock");
+ }
+
+ LLSD lock_sd=getLockFile(mMaster);
+
+ if (lock_sd.has("pid"))
+ {
+ mWaitingPID = lock_sd["pid"].asInteger();
+ if ( isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()) )
+ {
+ mTimer.resetWithExpiry(timeout);
+ return false;
+ }
+ }
+
+ U32 pid = getpid();
+ lock_sd["pid"] = (LLSD::Integer)pid;
+ return putLockFile(mMaster,lock_sd);
+}
+
+bool LLCrashLock::checkMaster()
+{
+ if (mWaitingPID)
+ {
+ return (!isProcessAlive(mWaitingPID, gDirUtilp->getExecutableFilename()));
+ }
+ return false;
+}
+
+bool LLCrashLock::isWaiting()
+{
+ return !mTimer.hasExpired();
+}
+
+void LLCrashLock::releaseMaster()
+{
+ //Yeeeeeeehaw
+ unlink(mMaster.c_str());
+}
+
+LLSD LLCrashLock::getProcessList()
+{
+ if (mDumpTable.empty())
+ {
+ mDumpTable= gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "crash_table.lock");
+ }
+ return getLockFile(mDumpTable);
+}
+
+//static
+bool LLCrashLock::fileExists(std::string filename)
+{
+ return boost::filesystem::exists(filename.c_str());
+}
+
+void LLCrashLock::cleanupProcess(std::string proc_dir)
+{
+ boost::filesystem::remove_all(proc_dir);
+}
+
+bool LLCrashLock::putProcessList(const LLSD& proc_sd)
+{
+ return putLockFile(mDumpTable,proc_sd);
+}
diff --git a/indra/llcrashlogger/llcrashlock.h b/indra/llcrashlogger/llcrashlock.h
new file mode 100644
index 0000000000..cde183272f
--- /dev/null
+++ b/indra/llcrashlogger/llcrashlock.h
@@ -0,0 +1,73 @@
+/**
+ * @file llpidlock.h
+ * @brief Maintainence of disk locking files for crash reporting
+ *
+ * $LicenseInfo:firstyear=2001&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_CRASHLOCK_H
+#define LL_CRASHLOCK_H
+
+#include "llframetimer.h"
+
+class LLSD;
+
+#if !LL_WINDOWS //For non-windows platforms.
+#include <signal.h>
+#endif
+
+//Crash reporter will now be kicked off by the viewer but otherwise
+//run independent of the viewer.
+
+class LLCrashLock
+{
+public:
+ LLCrashLock();
+ bool requestMaster( F32 timeout=300.0); //Wait until timeout for master lock.
+ bool checkMaster(); //True if available. False if not.
+ void releaseMaster( ); //Release master lockfile.
+ bool isLockPresent(std::string filename); //Check if lockfile exists.
+ bool isProcessAlive(U32 pid, const std::string& pname); //Check if pid is alive.
+ bool isWaiting(); //Waiting for master lock to be released.
+ LLSD getProcessList(); //Get next process pid/dir pairs
+ void cleanupProcess(std::string proc_dir); //Remove from list, clean up working dir.
+ bool putProcessList(const LLSD& processlist); //Write pid/dir pairs back to disk.
+ static bool fileExists(std::string filename);
+
+
+ //getters
+ S32 getPID();
+
+ //setters
+ void setCleanUp(bool cleanup=true);
+ void setSaveName(std::string savename);
+private:
+ LLSD getLockFile(std::string filename);
+ bool putLockFile(std::string filename, const LLSD& data);
+ bool mCleanUp;
+ std::string mMaster;
+ std::string mDumpTable;
+ U32 mWaitingPID; //The process we're waiting on if any.
+ LLFrameTimer mTimer;
+};
+
+#endif // LL_CRASHLOCK_H
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index fb2d43e3b0..38858a1a91 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -23,12 +23,14 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <map>
#include "llcrashlogger.h"
+#include "llcrashlock.h"
#include "linden_common.h"
#include "llstring.h"
#include "indra_constants.h" // CRASH_BEHAVIOR_...
@@ -43,8 +45,8 @@
#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llproxy.h"
-
-LLPumpIO* gServicePump;
+
+LLPumpIO* gServicePump = NULL;
BOOL gBreak = false;
BOOL gSent = false;
@@ -61,7 +63,7 @@ public:
}
virtual void result(const LLSD& content)
- {
+ {
gBreak = true;
gSent = true;
}
@@ -74,8 +76,6 @@ LLCrashLogger::LLCrashLogger() :
mSentCrashLogs(false),
mCrashHost("")
{
- // Set up generic error handling
- setupErrorHandling();
}
LLCrashLogger::~LLCrashLogger()
@@ -137,19 +137,67 @@ std::string getStartupStateFromLog(std::string& sllog)
return startup_state;
}
-void LLCrashLogger::gatherFiles()
+bool LLCrashLogger::readDebugFromXML(LLSD& dest, const std::string& filename )
{
- updateApplication("Gathering logs...");
-
- // Figure out the filename of the debug log
- std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
- std::ifstream debug_log_file(db_file_name.c_str());
-
+ std::string db_file_name = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,filename);
+ std::ifstream debug_log_file(db_file_name.c_str());
+
// Look for it in the debug_info.log file
if (debug_log_file.is_open())
{
- LLSDSerialize::fromXML(mDebugLog, debug_log_file);
+ LLSDSerialize::fromXML(dest, debug_log_file);
+ debug_log_file.close();
+ return true;
+ }
+ return false;
+}
+
+void LLCrashLogger::mergeLogs( LLSD src_sd )
+{
+ LLSD::map_iterator iter = src_sd.beginMap();
+ LLSD::map_iterator end = src_sd.endMap();
+ for( ; iter != end; ++iter)
+ {
+ mDebugLog[iter->first] = iter->second;
+ }
+}
+
+bool LLCrashLogger::readMinidump(std::string minidump_path)
+{
+ size_t length=0;
+
+ std::ifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary);
+ if(minidump_stream.is_open())
+ {
+ minidump_stream.seekg(0, std::ios::end);
+ length = (size_t)minidump_stream.tellg();
+ minidump_stream.seekg(0, std::ios::beg);
+
+ LLSD::Binary data;
+ data.resize(length);
+
+ minidump_stream.read(reinterpret_cast<char *>(&(data[0])),length);
+ minidump_stream.close();
+
+ mCrashInfo["Minidump"] = data;
+ }
+ return (length>0?true:false);
+}
+void LLCrashLogger::gatherFiles()
+{
+ updateApplication("Gathering logs...");
+
+ LLSD static_sd;
+ LLSD dynamic_sd;
+
+ bool has_logs = readDebugFromXML( static_sd, "static_debug_info.log" );
+ has_logs |= readDebugFromXML( dynamic_sd, "dynamic_debug_info.log" );
+
+ if ( has_logs )
+ {
+ mDebugLog = static_sd;
+ mergeLogs(dynamic_sd);
mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean();
mFileMap["SecondLifeLog"] = mDebugLog["SLLog"].asString();
@@ -170,20 +218,15 @@ void LLCrashLogger::gatherFiles()
{
// Figure out the filename of the second life log
LLCurl::setCAFile(gDirUtilp->getCAFile());
- mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
- mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
+
+ mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
+ mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");
}
- if(mCrashInPreviousExec)
- {
- // Restarting after freeze.
- // Replace the log file ext with .old, since the
- // instance that launched this process has overwritten
- // SecondLife.log
- std::string log_filename = mFileMap["SecondLifeLog"];
- log_filename.replace(log_filename.size() - 4, 4, ".old");
- mFileMap["SecondLifeLog"] = log_filename;
- }
+ if (!gDirUtilp->fileExists(mFileMap["SecondLifeLog"]) ) //We would prefer to get this from the per-run but here's our fallback.
+ {
+ mFileMap["SecondLifeLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old");
+ }
gatherPlatformSpecificFiles();
@@ -214,7 +257,7 @@ void LLCrashLogger::gatherFiles()
mAltCrashHost = "https://login.agni.lindenlab.com:12043/crash/report";
mCrashInfo["DebugLog"] = mDebugLog;
- mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log");
+ mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"stats.log");
updateApplication("Encoding files...");
@@ -223,7 +266,7 @@ void LLCrashLogger::gatherFiles()
std::ifstream f((*itr).second.c_str());
if(!f.is_open())
{
- std::cout << "Can't find file " << (*itr).second << std::endl;
+ LL_INFOS("CRASHREPORT") << "Can't find file " << (*itr).second << LL_ENDL;
continue;
}
std::stringstream s;
@@ -242,32 +285,55 @@ void LLCrashLogger::gatherFiles()
mCrashInfo[(*itr).first] = LLStringFn::strip_invalid_xml(rawstr_to_utf8(crash_info));
}
+ std::string minidump_path;
// Add minidump as binary.
- std::string minidump_path = mDebugLog["MinidumpPath"];
- if(minidump_path != "")
+ bool has_minidump = mDebugLog.has("MinidumpPath");
+
+ if (has_minidump)
{
- std::ifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary);
- if(minidump_stream.is_open())
- {
- minidump_stream.seekg(0, std::ios::end);
- size_t length = (size_t)minidump_stream.tellg();
- minidump_stream.seekg(0, std::ios::beg);
-
- LLSD::Binary data;
- data.resize(length);
-
- minidump_stream.read(reinterpret_cast<char *>(&(data[0])),length);
- minidump_stream.close();
-
- mCrashInfo["Minidump"] = data;
- }
+ minidump_path = mDebugLog["MinidumpPath"].asString();
+ }
+
+ if (has_minidump)
+ {
+ has_minidump = readMinidump(minidump_path);
}
- mCrashInfo["DebugLog"].erase("MinidumpPath");
+
+ if (!has_minidump) //Viewer was probably so hosed it couldn't write remaining data. Try brute force.
+ {
+ //Look for a filename at least 30 characters long in the dump dir which contains the characters MDMP as the first 4 characters in the file.
+ typedef std::vector<std::string> vec;
+ std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
+ vec file_vec = gDirUtilp->getFilesInDir(pathname);
+ for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter)
+ {
+ if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
+ {
+ std::string fullname = pathname + *iter;
+ std::ifstream fdat( fullname.c_str(), std::ifstream::binary);
+ if (fdat)
+ {
+ char buf[5];
+ fdat.read(buf,4);
+ fdat.close();
+ if (!strncmp(buf,"MDMP",4))
+ {
+ minidump_path = *iter;
+ has_minidump = readMinidump(fullname);
+ mDebugLog["MinidumpPath"] = fullname;
+ if (has_minidump)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
}
LLSD LLCrashLogger::constructPostData()
{
- LLSD ret;
return mCrashInfo;
}
@@ -337,39 +403,106 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg
return gSent;
}
-bool LLCrashLogger::sendCrashLogs()
+bool LLCrashLogger::sendCrashLog(std::string dump_dir)
{
+ gDirUtilp->setDumpDir( dump_dir );
+
+ std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
+ "SecondLifeCrashReport");
+ std::string report_file = dump_path + ".log";
+
gatherFiles();
-
+
LLSD post_data;
post_data = constructPostData();
-
+
updateApplication("Sending reports...");
- std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "SecondLifeCrashReport");
- std::string report_file = dump_path + ".log";
-
std::ofstream out_file(report_file.c_str());
LLSDSerialize::toPrettyXML(post_data, out_file);
out_file.close();
-
+
bool sent = false;
-
+
//*TODO: Translate
if(mCrashHost != "")
{
sent = runCrashLogPost(mCrashHost, post_data, std::string("Sending to server"), 3, 5);
}
-
+
if(!sent)
{
sent = runCrashLogPost(mAltCrashHost, post_data, std::string("Sending to alternate server"), 3, 5);
}
-
+
mSentCrashLogs = sent;
+
+ return sent;
+}
- return true;
+bool LLCrashLogger::sendCrashLogs()
+{
+
+ //pertinent code from below moved into a subroutine.
+ LLSD locks = mKeyMaster.getProcessList();
+ LLSD newlocks = LLSD::emptyArray();
+
+ LLSD opts = getOptionData(PRIORITY_COMMAND_LINE);
+ LLSD rec;
+
+ if ( opts.has("pid") && opts.has("dumpdir") && opts.has("procname") )
+ {
+ rec["pid"]=opts["pid"];
+ rec["dumpdir"]=opts["dumpdir"];
+ rec["procname"]=opts["procname"];
+ }
+
+ if (locks.isArray())
+ {
+ for (LLSD::array_iterator lock=locks.beginArray();
+ lock !=locks.endArray();
+ ++lock)
+ {
+ if ( (*lock).has("pid") && (*lock).has("dumpdir") && (*lock).has("procname") )
+ {
+ if ( mKeyMaster.isProcessAlive( (*lock)["pid"].asInteger(), (*lock)["procname"].asString() ) )
+ {
+ newlocks.append(*lock);
+ }
+ else
+ {
+ //TODO: This is a hack but I didn't want to include boost in another file or retest everything related to lldir
+ if (LLCrashLock::fileExists((*lock)["dumpdir"].asString()))
+ {
+ //the viewer cleans up the log directory on clean shutdown
+ //but is ignorant of the locking table.
+ if (!sendCrashLog((*lock)["dumpdir"].asString()))
+ {
+ newlocks.append(*lock); //Failed to send log so don't delete it.
+ }
+ else
+ {
+ //mCrashInfo["DebugLog"].erase("MinidumpPath");
+
+ mKeyMaster.cleanupProcess((*lock)["dumpdir"].asString());
+ }
+ }
+ }
+ }
+ else
+ {
+ llwarns << "Discarding corrupted entry from lock table." << llendl;
+ }
+ }
+ }
+
+ if (rec)
+ {
+ newlocks.append(rec);
+ }
+
+ mKeyMaster.putProcessList(newlocks);
+ return true;
}
void LLCrashLogger::updateApplication(const std::string& message)
@@ -394,44 +527,62 @@ bool LLCrashLogger::init()
// Rename current log file to ".old"
std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log.old");
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "crashreport.log");
- LLFile::rename(log_file.c_str(), old_log_file.c_str());
+#if LL_WINDOWS
+ LLAPRFile::remove(old_log_file);
+#endif
+
+ LLFile::rename(log_file.c_str(), old_log_file.c_str());
+
// Set the log file to crashreport.log
- LLError::logToFile(log_file);
-
- mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
+ LLError::logToFile(log_file); //NOTE: Until this line, LL_INFOS LL_WARNS, etc are blown to the ether.
+
+ // Handle locking
+ bool locked = mKeyMaster.requestMaster(); //Request master locking file. wait time is defaulted to 300S
+
+ while (!locked && mKeyMaster.isWaiting())
+ {
+ LL_INFOS("CRASHREPORT") << "Waiting for lock." << LL_ENDL;
+#if LL_WINDOWS
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ locked = mKeyMaster.checkMaster();
+ }
+
+ if (!locked)
+ {
+ LL_WARNS("CRASHREPORT") << "Unable to get master lock. Another crash reporter may be hung." << LL_ENDL;
+ return false;
+ }
+
+ mCrashSettings.declareS32("CrashSubmitBehavior", CRASH_BEHAVIOR_ALWAYS_SEND,
"Controls behavior when viewer crashes "
"(0 = ask before sending crash report, "
"1 = always send crash report, "
"2 = never send crash report)");
-
+
// llinfos << "Loading crash behavior setting" << llendl;
// mCrashBehavior = loadCrashBehaviorSetting();
-
+
// If user doesn't want to send, bail out
if (mCrashBehavior == CRASH_BEHAVIOR_NEVER_SEND)
{
llinfos << "Crash behavior is never_send, quitting" << llendl;
return false;
}
-
+
gServicePump = new LLPumpIO(gAPRPoolp);
gServicePump->prime(gAPRPoolp);
LLHTTPClient::setPump(*gServicePump);
-
- //If we've opened the crash logger, assume we can delete the marker file if it exists
- if( gDirUtilp )
- {
- std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- "SecondLife.exec_marker");
- LLAPRFile::remove( marker_file );
- }
-
+
return true;
}
// For cleanup code common to all platforms.
void LLCrashLogger::commonCleanup()
{
+ LLError::logToFile(""); //close crashreport.log
LLProxy::cleanupClass();
}
diff --git a/indra/llcrashlogger/llcrashlogger.h b/indra/llcrashlogger/llcrashlogger.h
index 1510d7e0b3..78acc63b6a 100755
--- a/indra/llcrashlogger/llcrashlogger.h
+++ b/indra/llcrashlogger/llcrashlogger.h
@@ -33,6 +33,7 @@
#include "llapp.h"
#include "llsd.h"
#include "llcontrol.h"
+#include "llcrashlock.h"
class LLCrashLogger : public LLApp
{
@@ -40,9 +41,13 @@ public:
LLCrashLogger();
virtual ~LLCrashLogger();
S32 loadCrashBehaviorSetting();
+ bool readDebugFromXML(LLSD& dest, const std::string& filename );
void gatherFiles();
+ void mergeLogs( LLSD src_sd );
+
virtual void gatherPlatformSpecificFiles() {}
bool saveCrashBehaviorSetting(S32 crash_behavior);
+ bool sendCrashLog(std::string dump_dir);
bool sendCrashLogs();
LLSD constructPostData();
virtual void updateApplication(const std::string& message = LLStringUtil::null);
@@ -53,6 +58,8 @@ public:
void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; }
S32 getCrashBehavior() { return mCrashBehavior; }
bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout);
+ bool readMinidump(std::string minidump_path);
+
protected:
S32 mCrashBehavior;
BOOL mCrashInPreviousExec;
@@ -65,6 +72,7 @@ protected:
std::string mAltCrashHost;
LLSD mDebugLog;
bool mSentCrashLogs;
+ LLCrashLock mKeyMaster;
};
#endif //LLCRASHLOGGER_H
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 95e6f68895..9cf6903197 100755
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -72,6 +72,7 @@ const F32 F_E = 2.71828182845904523536f;
const F32 F_SQRT2 = 1.4142135623730950488016887242097f;
const F32 F_SQRT3 = 1.73205080756888288657986402541f;
const F32 OO_SQRT2 = 0.7071067811865475244008443621049f;
+const F32 OO_SQRT3 = 0.577350269189625764509f;
const F32 DEG_TO_RAD = 0.017453292519943295769236907684886f;
const F32 RAD_TO_DEG = 57.295779513082320876798154814105f;
const F32 F_APPROXIMATELY_ZERO = 0.00001f;
diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h
index 578dcdc8ea..4938273d5b 100755
--- a/indra/llmath/v3dmath.h
+++ b/indra/llmath/v3dmath.h
@@ -72,17 +72,22 @@ class LLVector3d
BOOL clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns TRUE if data changed
BOOL abs(); // sets all values to absolute value of original value (first octant), returns TRUE if changed
- inline const LLVector3d& clearVec(); // Clears LLVector3d to (0, 0, 0, 1)
+ inline const LLVector3d& clear(); // Clears LLVector3d to (0, 0, 0, 1)
+ inline const LLVector3d& clearVec(); // deprecated
inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0)
inline const LLVector3d& zeroVec(); // deprecated
- inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
- inline const LLVector3d& setVec(const LLVector3d &vec); // Sets LLVector3d to vec
- inline const LLVector3d& setVec(const F64 *vec); // Sets LLVector3d to vec
- inline const LLVector3d& setVec(const LLVector3 &vec);
-
- F64 magVec() const; // Returns magnitude of LLVector3d
- F64 magVecSquared() const; // Returns magnitude squared of LLVector3d
- inline F64 normVec(); // Normalizes and returns the magnitude of LLVector3d
+ inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
+ inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec
+ inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec
+ inline const LLVector3d& set(const LLVector3 &vec);
+ inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // deprecated
+ inline const LLVector3d& setVec(const LLVector3d &vec); // deprecated
+ inline const LLVector3d& setVec(const F64 *vec); // deprecated
+ inline const LLVector3d& setVec(const LLVector3 &vec); // deprecated
+
+ F64 magVec() const; // deprecated
+ F64 magVecSquared() const; // deprecated
+ inline F64 normVec(); // deprecated
F64 length() const; // Returns magnitude of LLVector3d
F64 lengthSquared() const; // Returns magnitude squared of LLVector3d
@@ -101,25 +106,25 @@ class LLVector3d
F64 operator[](int idx) const { return mdV[idx]; }
F64 &operator[](int idx) { return mdV[idx]; }
- friend LLVector3d operator+(const LLVector3d &a, const LLVector3d &b); // Return vector a + b
- friend LLVector3d operator-(const LLVector3d &a, const LLVector3d &b); // Return vector a minus b
- friend F64 operator*(const LLVector3d &a, const LLVector3d &b); // Return a dot b
- friend LLVector3d operator%(const LLVector3d &a, const LLVector3d &b); // Return a cross b
- friend LLVector3d operator*(const LLVector3d &a, const F64 k); // Return a times scaler k
- friend LLVector3d operator/(const LLVector3d &a, const F64 k); // Return a divided by scaler k
- friend LLVector3d operator*(const F64 k, const LLVector3d &a); // Return a times scaler k
- friend bool operator==(const LLVector3d &a, const LLVector3d &b); // Return a == b
- friend bool operator!=(const LLVector3d &a, const LLVector3d &b); // Return a != b
+ friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b); // Return vector a + b
+ friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b); // Return vector a minus b
+ friend F64 operator*(const LLVector3d& a, const LLVector3d& b); // Return a dot b
+ friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b); // Return a cross b
+ friend LLVector3d operator*(const LLVector3d& a, const F64 k); // Return a times scaler k
+ friend LLVector3d operator/(const LLVector3d& a, const F64 k); // Return a divided by scaler k
+ friend LLVector3d operator*(const F64 k, const LLVector3d& a); // Return a times scaler k
+ friend bool operator==(const LLVector3d& a, const LLVector3d& b); // Return a == b
+ friend bool operator!=(const LLVector3d& a, const LLVector3d& b); // Return a != b
- friend const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b); // Return vector a + b
- friend const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b); // Return vector a minus b
- friend const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b); // Return a cross b
- friend const LLVector3d& operator*=(LLVector3d &a, const F64 k); // Return a times scaler k
- friend const LLVector3d& operator/=(LLVector3d &a, const F64 k); // Return a divided by scaler k
+ friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b); // Return vector a + b
+ friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b); // Return vector a minus b
+ friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b); // Return a cross b
+ friend const LLVector3d& operator*=(LLVector3d& a, const F64 k); // Return a times scaler k
+ friend const LLVector3d& operator/=(LLVector3d& a, const F64 k); // Return a divided by scaler k
- friend LLVector3d operator-(const LLVector3d &a); // Return vector -a
+ friend LLVector3d operator-(const LLVector3d& a); // Return vector -a
- friend std::ostream& operator<<(std::ostream& s, const LLVector3d &a); // Stream a
+ friend std::ostream& operator<<(std::ostream& s, const LLVector3d& a); // Stream a
static BOOL parseVector3d(const std::string& buf, LLVector3d* value);
@@ -127,7 +132,15 @@ class LLVector3d
typedef LLVector3d LLGlobalVec;
-const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
+inline const LLVector3d &LLVector3d::set(const LLVector3 &vec)
+{
+ mdV[0] = vec.mV[0];
+ mdV[1] = vec.mV[1];
+ mdV[2] = vec.mV[2];
+ return *this;
+}
+
+inline const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
{
mdV[0] = vec.mV[0];
mdV[1] = vec.mV[1];
@@ -184,6 +197,14 @@ inline BOOL LLVector3d::isFinite() const
// Clear and Assignment Functions
+inline const LLVector3d& LLVector3d::clear(void)
+{
+ mdV[0] = 0.f;
+ mdV[1] = 0.f;
+ mdV[2]= 0.f;
+ return (*this);
+}
+
inline const LLVector3d& LLVector3d::clearVec(void)
{
mdV[0] = 0.f;
@@ -208,6 +229,30 @@ inline const LLVector3d& LLVector3d::zeroVec(void)
return (*this);
}
+inline const LLVector3d& LLVector3d::set(const F64 x, const F64 y, const F64 z)
+{
+ mdV[VX] = x;
+ mdV[VY] = y;
+ mdV[VZ] = z;
+ return (*this);
+}
+
+inline const LLVector3d& LLVector3d::set(const LLVector3d &vec)
+{
+ mdV[0] = vec.mdV[0];
+ mdV[1] = vec.mdV[1];
+ mdV[2] = vec.mdV[2];
+ return (*this);
+}
+
+inline const LLVector3d& LLVector3d::set(const F64 *vec)
+{
+ mdV[0] = vec[0];
+ mdV[1] = vec[1];
+ mdV[2] = vec[2];
+ return (*this);
+}
+
inline const LLVector3d& LLVector3d::setVec(const F64 x, const F64 y, const F64 z)
{
mdV[VX] = x;
@@ -298,59 +343,59 @@ inline F64 LLVector3d::lengthSquared(void) const
return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
}
-inline LLVector3d operator+(const LLVector3d &a, const LLVector3d &b)
+inline LLVector3d operator+(const LLVector3d& a, const LLVector3d& b)
{
LLVector3d c(a);
return c += b;
}
-inline LLVector3d operator-(const LLVector3d &a, const LLVector3d &b)
+inline LLVector3d operator-(const LLVector3d& a, const LLVector3d& b)
{
LLVector3d c(a);
return c -= b;
}
-inline F64 operator*(const LLVector3d &a, const LLVector3d &b)
+inline F64 operator*(const LLVector3d& a, const LLVector3d& b)
{
return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]);
}
-inline LLVector3d operator%(const LLVector3d &a, const LLVector3d &b)
+inline LLVector3d operator%(const LLVector3d& a, const LLVector3d& b)
{
return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] );
}
-inline LLVector3d operator/(const LLVector3d &a, const F64 k)
+inline LLVector3d operator/(const LLVector3d& a, const F64 k)
{
F64 t = 1.f / k;
return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t );
}
-inline LLVector3d operator*(const LLVector3d &a, const F64 k)
+inline LLVector3d operator*(const LLVector3d& a, const F64 k)
{
return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
}
-inline LLVector3d operator*(F64 k, const LLVector3d &a)
+inline LLVector3d operator*(F64 k, const LLVector3d& a)
{
return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
}
-inline bool operator==(const LLVector3d &a, const LLVector3d &b)
+inline bool operator==(const LLVector3d& a, const LLVector3d& b)
{
return ( (a.mdV[0] == b.mdV[0])
&&(a.mdV[1] == b.mdV[1])
&&(a.mdV[2] == b.mdV[2]));
}
-inline bool operator!=(const LLVector3d &a, const LLVector3d &b)
+inline bool operator!=(const LLVector3d& a, const LLVector3d& b)
{
return ( (a.mdV[0] != b.mdV[0])
||(a.mdV[1] != b.mdV[1])
||(a.mdV[2] != b.mdV[2]));
}
-inline const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b)
+inline const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b)
{
a.mdV[0] += b.mdV[0];
a.mdV[1] += b.mdV[1];
@@ -358,7 +403,7 @@ inline const LLVector3d& operator+=(LLVector3d &a, const LLVector3d &b)
return a;
}
-inline const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b)
+inline const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b)
{
a.mdV[0] -= b.mdV[0];
a.mdV[1] -= b.mdV[1];
@@ -366,14 +411,14 @@ inline const LLVector3d& operator-=(LLVector3d &a, const LLVector3d &b)
return a;
}
-inline const LLVector3d& operator%=(LLVector3d &a, const LLVector3d &b)
+inline const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b)
{
LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]);
a = ret;
return a;
}
-inline const LLVector3d& operator*=(LLVector3d &a, const F64 k)
+inline const LLVector3d& operator*=(LLVector3d& a, const F64 k)
{
a.mdV[0] *= k;
a.mdV[1] *= k;
@@ -381,7 +426,7 @@ inline const LLVector3d& operator*=(LLVector3d &a, const F64 k)
return a;
}
-inline const LLVector3d& operator/=(LLVector3d &a, const F64 k)
+inline const LLVector3d& operator/=(LLVector3d& a, const F64 k)
{
F64 t = 1.f / k;
a.mdV[0] *= t;
@@ -390,12 +435,12 @@ inline const LLVector3d& operator/=(LLVector3d &a, const F64 k)
return a;
}
-inline LLVector3d operator-(const LLVector3d &a)
+inline LLVector3d operator-(const LLVector3d& a)
{
return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] );
}
-inline F64 dist_vec(const LLVector3d &a, const LLVector3d &b)
+inline F64 dist_vec(const LLVector3d& a, const LLVector3d& b)
{
F64 x = a.mdV[0] - b.mdV[0];
F64 y = a.mdV[1] - b.mdV[1];
@@ -403,7 +448,7 @@ inline F64 dist_vec(const LLVector3d &a, const LLVector3d &b)
return (F32) sqrt( x*x + y*y + z*z );
}
-inline F64 dist_vec_squared(const LLVector3d &a, const LLVector3d &b)
+inline F64 dist_vec_squared(const LLVector3d& a, const LLVector3d& b)
{
F64 x = a.mdV[0] - b.mdV[0];
F64 y = a.mdV[1] - b.mdV[1];
@@ -411,14 +456,14 @@ inline F64 dist_vec_squared(const LLVector3d &a, const LLVector3d &b)
return x*x + y*y + z*z;
}
-inline F64 dist_vec_squared2D(const LLVector3d &a, const LLVector3d &b)
+inline F64 dist_vec_squared2D(const LLVector3d& a, const LLVector3d& b)
{
F64 x = a.mdV[0] - b.mdV[0];
F64 y = a.mdV[1] - b.mdV[1];
return x*x + y*y;
}
-inline LLVector3d lerp(const LLVector3d &a, const LLVector3d &b, const F64 u)
+inline LLVector3d lerp(const LLVector3d& a, const LLVector3d& b, const F64 u)
{
return LLVector3d(
a.mdV[VX] + (b.mdV[VX] - a.mdV[VX]) * u,
@@ -450,7 +495,7 @@ inline F64 angle_between(const LLVector3d& a, const LLVector3d& b)
return angle;
}
-inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 epsilon)
+inline BOOL are_parallel(const LLVector3d& a, const LLVector3d& b, const F64 epsilon)
{
LLVector3d an = a;
LLVector3d bn = b;
@@ -465,11 +510,22 @@ inline BOOL are_parallel(const LLVector3d &a, const LLVector3d &b, const F64 eps
}
-inline LLVector3d projected_vec(const LLVector3d &a, const LLVector3d &b)
+inline LLVector3d projected_vec(const LLVector3d& a, const LLVector3d& b)
{
LLVector3d project_axis = b;
project_axis.normalize();
return project_axis * (a * project_axis);
}
+inline LLVector3d inverse_projected_vec(const LLVector3d& a, const LLVector3d& b)
+{
+ LLVector3d normalized_a = a;
+ normalized_a.normalize();
+ LLVector3d normalized_b = b;
+ F64 b_length = normalized_b.normalize();
+
+ F64 dot_product = normalized_a * normalized_b;
+ return normalized_a * (b_length / dot_product);
+}
+
#endif // LL_V3DMATH_H
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index a269ed1b79..f3fbce4843 100755
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -159,6 +159,7 @@ F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance betwe
F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b
F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component
LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
+LLVector3 inverse_projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a scaled such that projected_vec(inverse_projected_vec(a, b), b) == b;
LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
@@ -501,6 +502,18 @@ inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
}
}
+inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b)
+{
+ LLVector3 normalized_a = a;
+ normalized_a.normalize();
+ LLVector3 normalized_b = b;
+ F32 b_length = normalized_b.normalize();
+
+ F32 dot_product = normalized_a * normalized_b;
+ //NB: if a _|_ b, then returns an infinite vector
+ return normalized_a * (b_length / dot_product);
+}
+
inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
{
return projected_vec(a, b);
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 9a68093427..31dd264021 100755
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -680,6 +680,15 @@ void LLAvatarNameCache::setUseDisplayNames(bool use)
}
}
+void LLAvatarNameCache::setUseUsernames(bool use)
+{
+ if (use != LLAvatarName::useUsernames())
+ {
+ LLAvatarName::setUseUsernames(use);
+ mUseDisplayNamesSignal();
+ }
+}
+
void LLAvatarNameCache::erase(const LLUUID& agent_id)
{
sCache.erase(agent_id);
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 2a8eb46187..3a19cee3ed 100755
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -80,6 +80,8 @@ namespace LLAvatarNameCache
// Set display name: flips the switch and triggers the callbacks.
void setUseDisplayNames(bool use);
+ void setUseUsernames(bool use);
+
void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
void erase(const LLUUID& agent_id);
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index 01da20f060..aaa49d2ed6 100755
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -225,7 +225,7 @@ LLBufferArray::LLBufferArray() :
LLBufferArray::~LLBufferArray()
{
std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer());
-
+ mBuffers.clear();
delete mMutexp;
}
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 267c48e1d2..13d779ff83 100755
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -278,7 +278,9 @@ LLCacheName::Impl::Impl(LLMessageSystem* msg)
LLCacheName::Impl::~Impl()
{
for_each(mCache.begin(), mCache.end(), DeletePairedPointer());
+ mCache.clear();
for_each(mReplyQueue.begin(), mReplyQueue.end(), DeletePointer());
+ mReplyQueue.clear();
}
boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback)
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 25e175f2cc..9e68c68858 100755
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -1741,6 +1741,7 @@ void LLCurl::cleanupClass()
#if SAFE_SSL
CRYPTO_set_locking_callback(NULL);
for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());
+ sSSLMutex.clear();
#endif
LL_CHECK_MEMORY
diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp
index 5c2f73eccb..f6ccb5bdda 100755
--- a/indra/llmessage/llhttpnode.cpp
+++ b/indra/llmessage/llhttpnode.cpp
@@ -76,8 +76,8 @@ LLHTTPNode::LLHTTPNode()
// virtual
LLHTTPNode::~LLHTTPNode()
{
- std::for_each(impl.mNamedChildren.begin(), impl.mNamedChildren.end(),
- DeletePairedPointer());
+ std::for_each(impl.mNamedChildren.begin(), impl.mNamedChildren.end(), DeletePairedPointer());
+ impl.mNamedChildren.clear();
delete impl.mWildcardChild;
diff --git a/indra/llmessage/llhttpsender.cpp b/indra/llmessage/llhttpsender.cpp
index c48cbc42a6..d0bd343db6 100755
--- a/indra/llmessage/llhttpsender.cpp
+++ b/indra/llmessage/llhttpsender.cpp
@@ -38,7 +38,7 @@ namespace
{
typedef std::map<LLHost, LLHTTPSender*> SenderMap;
static SenderMap senderMap;
- static LLHTTPSender* defaultSender = new LLHTTPSender();
+ static LLPointer<LLHTTPSender> defaultSender(new LLHTTPSender());
}
//virtual
@@ -90,6 +90,5 @@ void LLHTTPSender::clearSender(const LLHost& host)
//static
void LLHTTPSender::setDefaultSender(LLHTTPSender* sender)
{
- delete defaultSender;
defaultSender = sender;
}
diff --git a/indra/llmessage/llhttpsender.h b/indra/llmessage/llhttpsender.h
index 88920db24d..ff8fa2f95b 100755
--- a/indra/llmessage/llhttpsender.h
+++ b/indra/llmessage/llhttpsender.h
@@ -32,7 +32,7 @@
class LLHost;
class LLSD;
-class LLHTTPSender
+class LLHTTPSender : public LLThreadSafeRefCount
{
public:
diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h
index ae8e0087c1..005a49cedf 100755
--- a/indra/llmessage/llmessagetemplate.h
+++ b/indra/llmessage/llmessagetemplate.h
@@ -118,6 +118,7 @@ public:
~LLMsgData()
{
for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
+ mMemberBlocks.clear();
}
void addBlock(LLMsgBlkData *blockp)
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index ab91f74abe..94bc7cb045 100755
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -91,15 +91,17 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname
}
LLMsgBlkData *msg_block_data = iter->second;
- LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
+ LLMsgBlkData::msg_var_data_map_t &var_data_map = msg_block_data->mMemberVarData;
- if (!vardata.getName())
+ if (var_data_map.find(vnamep) == var_data_map.end())
{
llerrs << "Variable "<< vnamep << " not in message "
<< mCurrentRMessageData->mName<< " block " << bnamep << llendl;
return;
}
+ LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
+
if (size && size != vardata.getSize())
{
llerrs << "Msg " << mCurrentRMessageData->mName
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index ae95087377..c3642ccbe8 100755
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -3032,12 +3032,23 @@ void LLMessageSystem::setExceptionFunc(EMessageException e,
BOOL LLMessageSystem::callExceptionFunc(EMessageException exception)
{
callbacks_t::iterator it = mExceptionCallbacks.find(exception);
- if(it != mExceptionCallbacks.end())
+ if(it == mExceptionCallbacks.end())
{
- ((*it).second.first)(this, (*it).second.second,exception);
- return TRUE;
+ return FALSE;
}
- return FALSE;
+
+ exception_t& ex = it->second;
+ msg_exception_callback ex_cb = ex.first;
+
+ if (!ex_cb)
+ {
+ LL_WARNS("Messaging") << "LLMessageSystem::callExceptionFunc: bad message exception callback." << llendl;
+ return FALSE;
+ }
+
+ (ex_cb)(this, ex.second, exception);
+
+ return TRUE;
}
void LLMessageSystem::setTimingFunc(msg_timing_callback func, void* data)
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 058bef43a5..84c782e958 100755
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -125,6 +125,7 @@ LLFontFreetype::~LLFontFreetype()
// Delete glyph info
std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
+ mCharGlyphInfoMap.clear();
// mFontBitmapCachep will be cleaned up by LLPointer destructor.
// mFallbackFonts cleaned up by LLPointer destructor
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 0ac30b4d63..b481cf7095 100755
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -2196,7 +2196,15 @@ void LLRender::texCoord2fv(const GLfloat* tc)
void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
{
- mColorsp[mCount] = LLColor4U(r,g,b,a);
+ if (!LLGLSLShader::sCurBoundShaderPtr ||
+ LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR)
+ {
+ mColorsp[mCount] = LLColor4U(r,g,b,a);
+ }
+ else
+ { //not using shaders or shader reads color from a uniform
+ diffuseColor4ub(r,g,b,a);
+ }
}
void LLRender::color4ubv(const GLubyte* c)
{
diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp
index 5f69c6af31..304d21d0df 100755
--- a/indra/llui/lldraghandle.cpp
+++ b/indra/llui/lldraghandle.cpp
@@ -315,14 +315,15 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask)
S32 delta_y = screen_y - mDragLastScreenY;
// if dragging a docked floater we want to undock
- if (((LLFloater*)getParent())->isDocked())
+ LLFloater * parent = dynamic_cast<LLFloater *>(getParent());
+ if (parent && parent->isDocked())
{
const S32 SLOP = 12;
if (delta_y <= -SLOP ||
delta_y >= SLOP)
{
- ((LLFloater*)getParent())->setDocked(false, false);
+ parent->setDocked(false, false);
return TRUE;
}
else
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 6e6bcd6ab5..c462b2aa52 100755
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -509,8 +509,8 @@ LLFloater::~LLFloater()
if( gFocusMgr.childHasKeyboardFocus(this))
{
- // Just in case we might still have focus here, release it.
- releaseFocus();
+ // Just in case we might still have focus here, release it.
+ releaseFocus();
}
// This is important so that floaters with persistent rects (i.e., those
@@ -528,7 +528,6 @@ LLFloater::~LLFloater()
setVisible(false); // We're not visible if we're destroyed
storeVisibilityControl();
storeDockStateControl();
-
delete mMinimizeSignal;
}
@@ -1138,7 +1137,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
if (by_user && !getHost())
{
- static_cast<LLFloaterView*>(getParent())->adjustToFitScreen(this, !isMinimized());
+ LLFloaterView * floaterVp = dynamic_cast<LLFloaterView*>(getParent());
+ if (floaterVp)
+ {
+ floaterVp->adjustToFitScreen(this, !isMinimized());
+ }
}
// if not minimized, adjust all snapped dependents to new shape
@@ -1349,7 +1352,8 @@ void LLFloater::setFocus( BOOL b )
if (b)
{
// only push focused floaters to front of stack if not in midst of ctrl-tab cycle
- if (!getHost() && !((LLFloaterView*)getParent())->getCycleMode())
+ LLFloaterView * parent = dynamic_cast<LLFloaterView *>(getParent());
+ if (!getHost() && parent && !parent->getCycleMode())
{
if (!isFrontmost())
{
@@ -1619,7 +1623,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
}
else
{
- LLFloaterView* parent = (LLFloaterView*) getParent();
+ LLFloaterView* parent = dynamic_cast<LLFloaterView*>( getParent() );
if (parent)
{
parent->bringToFront( this );
@@ -1658,7 +1662,11 @@ void LLFloater::setFrontmost(BOOL take_focus)
{
// there are more than one floater view
// so we need to query our parent directly
- ((LLFloaterView*)getParent())->bringToFront(this, take_focus);
+ LLFloaterView * parent = dynamic_cast<LLFloaterView*>( getParent() );
+ if (parent)
+ {
+ parent->bringToFront(this, take_focus);
+ }
// Make sure to set the appropriate transparency type (STORM-732).
updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE);
@@ -1951,6 +1959,7 @@ void LLFloater::drawShadow(LLPanel* panel)
void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type)
{
+ if (!view) return;
child_list_t children = *view->getChildList();
child_list_t::iterator it = children.begin();
@@ -2387,6 +2396,9 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
{
+ if (!child)
+ return;
+
if (mFrontChild == child)
{
if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
@@ -2742,8 +2754,6 @@ void LLFloaterView::refresh()
}
}
-const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
-
void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars/* = false*/)
{
if (floater->getParent() != this)
@@ -2796,11 +2806,29 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
}
}
+ const LLRect& floater_rect = floater->getRect();
+
+ S32 delta_left = mToolbarLeftRect.notEmpty() ? mToolbarLeftRect.mRight - floater_rect.mRight : 0;
+ S32 delta_bottom = mToolbarBottomRect.notEmpty() ? mToolbarBottomRect.mTop - floater_rect.mTop : 0;
+ S32 delta_right = mToolbarRightRect.notEmpty() ? mToolbarRightRect.mLeft - floater_rect.mLeft : 0;
+
// move window fully onscreen
if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
{
floater->clearSnapTarget();
}
+ else if (delta_left > 0 && floater_rect.mTop < mToolbarLeftRect.mTop && floater_rect.mBottom > mToolbarLeftRect.mBottom)
+ {
+ floater->translate(delta_left, 0);
+ }
+ else if (delta_bottom > 0 && floater_rect.mLeft > mToolbarBottomRect.mLeft && floater_rect.mRight < mToolbarBottomRect.mRight)
+ {
+ floater->translate(0, delta_bottom);
+ }
+ else if (delta_right < 0 && floater_rect.mTop < mToolbarRightRect.mTop && floater_rect.mBottom > mToolbarRightRect.mBottom)
+ {
+ floater->translate(delta_right, 0);
+ }
}
void LLFloaterView::draw()
@@ -2846,10 +2874,13 @@ LLFloater *LLFloaterView::getFocusedFloater() const
{
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
- LLUICtrl* ctrlp = (*child_it)->isCtrl() ? static_cast<LLUICtrl*>(*child_it) : NULL;
- if ( ctrlp && ctrlp->hasFocus() )
+ if ((*child_it)->isCtrl())
{
- return static_cast<LLFloater *>(ctrlp);
+ LLFloater* ctrlp = dynamic_cast<LLFloater*>(*child_it);
+ if ( ctrlp && ctrlp->hasFocus() )
+ {
+ return ctrlp;
+ }
}
}
return NULL;
@@ -3000,6 +3031,25 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
LLFloaterReg::blockShowFloaters(false);
}
+void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect)
+{
+ switch (tb)
+ {
+ case LLToolBarEnums::TOOLBAR_LEFT:
+ mToolbarLeftRect = toolbar_rect;
+ break;
+ case LLToolBarEnums::TOOLBAR_BOTTOM:
+ mToolbarBottomRect = toolbar_rect;
+ break;
+ case LLToolBarEnums::TOOLBAR_RIGHT:
+ mToolbarRightRect = toolbar_rect;
+ break;
+ default:
+ llwarns << "setToolbarRect() passed odd toolbar number " << (S32) tb << llendl;
+ break;
+ }
+}
+
void LLFloater::setInstanceName(const std::string& name)
{
if (name != mInstanceName)
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 75715ef296..12eb3cdbfa 100755
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -32,6 +32,7 @@
#define LL_FLOATER_H
#include "llpanel.h"
+#include "lltoolbar.h"
#include "lluuid.h"
//#include "llnotificationsutil.h"
#include <set>
@@ -514,6 +515,8 @@ private:
// LLFloaterView
// Parent of all floating panels
+const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
+
class LLFloaterView : public LLUICtrl
{
public:
@@ -572,10 +575,15 @@ public:
void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; }
LLFloater* getFrontmostClosableFloater();
+ void setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect);
+
private:
void hiddenFloaterClosed(LLFloater* floater);
LLRect mLastSnapRect;
+ LLRect mToolbarLeftRect;
+ LLRect mToolbarBottomRect;
+ LLRect mToolbarRightRect;
LLHandle<LLView> mSnapView;
BOOL mFocusCycleMode;
S32 mSnapOffsetBottom;
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index f32a52e6c6..704e03a605 100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -167,13 +167,14 @@ LLFolderView::LLFolderView(const Params& p)
mMinWidth(0),
mDragAndDropThisFrame(FALSE),
mCallbackRegistrar(NULL),
- mParentPanel(p.parent_panel),
mUseEllipses(p.use_ellipses),
mDraggingOverItem(NULL),
mStatusTextBox(NULL),
mShowItemLinkOverlays(p.show_item_link_overlays),
mViewModel(p.view_model)
{
+ LLPanel* panel = p.parent_panel;
+ mParentPanel = panel->getHandle();
mViewModel->setFolderView(this);
mRoot = this;
@@ -264,6 +265,7 @@ LLFolderView::~LLFolderView( void )
mItems.clear();
mFolders.clear();
+ //mViewModel->setFolderView(NULL);
mViewModel = NULL;
}
@@ -325,7 +327,7 @@ void LLFolderView::filter( LLFolderViewFilter& filter )
{
// Entry point of inventory filtering (CHUI-849)
LLFastTimer t2(FTM_FILTER);
- filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
+ filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
// Note: we filter the model, not the view
getViewModelItem()->filter(filter);
@@ -419,7 +421,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
if( selection && take_keyboard_focus)
{
- mParentPanel->setFocus(TRUE);
+ mParentPanel.get()->setFocus(TRUE);
}
// clear selection down here because change of keyboard focus can potentially
@@ -757,7 +759,7 @@ void LLFolderView::removeSelectedItems()
if (item_to_delete->remove())
{
// change selection on successful delete
- setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
}
}
arrangeAll();
@@ -767,7 +769,7 @@ void LLFolderView::removeSelectedItems()
LLDynamicArray<LLFolderViewModelItem*> listeners;
LLFolderViewModelItem* listener;
- setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
for(S32 i = 0; i < count; ++i)
{
@@ -947,7 +949,7 @@ void LLFolderView::cut()
}
// Update the selection
- setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
}
mSearchString.clear();
}
@@ -1289,7 +1291,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
}
BOOL handled = FALSE;
- if (mParentPanel->hasFocus())
+ if (mParentPanel.get()->hasFocus())
{
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
@@ -1323,7 +1325,7 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
mKeyboardSelection = FALSE;
mSearchString.clear();
- mParentPanel->setFocus(TRUE);
+ mParentPanel.get()->setFocus(TRUE);
LLEditMenuHandler::gEditMenuHandler = this;
@@ -1406,7 +1408,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
// all user operations move keyboard focus to inventory
// this way, we know when to stop auto-updating a search
- mParentPanel->setFocus(TRUE);
+ mParentPanel.get()->setFocus(TRUE);
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size();
@@ -1598,6 +1600,12 @@ void LLFolderView::update()
// If this is associated with the user's inventory, don't do anything
// until that inventory is loaded up.
LLFastTimer t2(FTM_INVENTORY);
+
+ // If there's no model, the view is in suspended state (being deleted) and shouldn't be updated
+ if (getFolderViewModel() == NULL)
+ {
+ return;
+ }
if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
{
@@ -1644,8 +1652,8 @@ void LLFolderView::update()
BOOL filter_finished = getViewModelItem()->passedFilter()
&& mViewModel->contentsReady();
if (filter_finished
- || gFocusMgr.childHasKeyboardFocus(mParentPanel)
- || gFocusMgr.childHasMouseCapture(mParentPanel))
+ || gFocusMgr.childHasKeyboardFocus(mParentPanel.get())
+ || gFocusMgr.childHasMouseCapture(mParentPanel.get()))
{
// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
mNeedsAutoSelect = FALSE;
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 11fccdace4..5b83049e5c 100755
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -229,7 +229,7 @@ public:
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
- LLPanel* getParentPanel() { return mParentPanel; }
+ LLPanel* getParentPanel() { return mParentPanel.get(); }
// DEBUG only
void dumpSelectionInformation();
@@ -238,6 +238,9 @@ public:
bool useLabelSuffix() { return mUseLabelSuffix; }
void updateMenu();
+ // Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem.
+ LLHandle<LLFolderView> getHandle() const { return getDerivedHandle<LLFolderView>(); }
+
private:
void updateMenuOptions(LLMenuGL* menu);
void updateRenamerPosition();
@@ -295,7 +298,7 @@ protected:
S32 mMinWidth;
BOOL mDragAndDropThisFrame;
- LLPanel* mParentPanel;
+ LLHandle<LLPanel> mParentPanel;
LLFolderViewModelInterface* mViewModel;
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 26d27d1f34..39153977bf 100755
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -76,8 +76,11 @@ inline BOOL LLKeywordToken::isTail(const llwchar* s) const
LLKeywords::~LLKeywords()
{
std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer());
+ mWordTokenMap.clear();
std::for_each(mLineTokenList.begin(), mLineTokenList.end(), DeletePointer());
+ mLineTokenList.clear();
std::for_each(mDelimiterTokenList.begin(), mDelimiterTokenList.end(), DeletePointer());
+ mDelimiterTokenList.clear();
}
BOOL LLKeywords::loadFromFile( const std::string& filename )
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index f854e1785d..6a57158eaa 100755
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -693,8 +693,11 @@ void LLMenuItemTearOffGL::onCommit()
{
if (getMenu()->getTornOff())
{
- LLTearOffMenu* torn_off_menu = (LLTearOffMenu*)(getMenu()->getParent());
- torn_off_menu->closeFloater();
+ LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getMenu()->getParent());
+ if (torn_off_menu)
+ {
+ torn_off_menu->closeFloater();
+ }
}
else
{
@@ -1097,7 +1100,8 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )
BOOL auto_open = getEnabled() && (!branch->getVisible() || branch->getTornOff());
// torn off menus don't open sub menus on hover unless they have focus
- if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus())
+ LLFloater * menu_parent = dynamic_cast<LLFloater *>(getMenu()->getParent());
+ if (getMenu()->getTornOff() && menu_parent && !menu_parent->hasFocus())
{
auto_open = FALSE;
}
@@ -1118,7 +1122,11 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight )
{
if (branch->getTornOff())
{
- ((LLFloater*)branch->getParent())->setFocus(FALSE);
+ LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
+ if (branch_parent)
+ {
+ branch_parent->setFocus(FALSE);
+ }
branch->clearHoverItem();
}
else
@@ -1175,11 +1183,19 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask )
BOOL handled = branch->clearHoverItem();
if (branch->getTornOff())
{
- ((LLFloater*)branch->getParent())->setFocus(FALSE);
+ LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
+ if (branch_parent)
+ {
+ branch_parent->setFocus(FALSE);
+ }
}
if (handled && getMenu()->getTornOff())
{
- ((LLFloater*)getMenu()->getParent())->setFocus(TRUE);
+ LLFloater * menu_parent = dynamic_cast<LLFloater *>(getMenu()->getParent());
+ if (menu_parent)
+ {
+ menu_parent->setFocus(TRUE);
+ }
}
return handled;
}
@@ -1219,9 +1235,13 @@ void LLMenuItemBranchGL::openMenu()
if (branch->getTornOff())
{
- gFloaterView->bringToFront((LLFloater*)branch->getParent());
- // this might not be necessary, as torn off branches don't get focus and hence no highligth
- branch->highlightNextItem(NULL);
+ LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
+ if (branch_parent)
+ {
+ gFloaterView->bringToFront(branch_parent);
+ // this might not be necessary, as torn off branches don't get focus and hence no highligth
+ branch->highlightNextItem(NULL);
+ }
}
else if( !branch->getVisible() )
{
@@ -1348,7 +1368,11 @@ void LLMenuItemBranchDownGL::openMenu( void )
{
if (branch->getTornOff())
{
- gFloaterView->bringToFront((LLFloater*)branch->getParent());
+ LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
+ if (branch_parent)
+ {
+ gFloaterView->bringToFront(branch_parent);
+ }
}
else
{
@@ -1403,7 +1427,11 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight )
{
if (branch->getTornOff())
{
- ((LLFloater*)branch->getParent())->setFocus(FALSE);
+ LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
+ if (branch_parent)
+ {
+ branch_parent->setFocus(FALSE);
+ }
branch->clearHoverItem();
}
else
@@ -1826,20 +1854,28 @@ BOOL LLMenuGL::jumpKeysActive()
{
LLMenuItemGL* highlighted_item = getHighlightedItem();
BOOL active = getVisible() && getEnabled();
- if (getTornOff())
- {
- // activation of jump keys on torn off menus controlled by keyboard focus
- active = active && ((LLFloater*)getParent())->hasFocus();
- }
- else
+ if (active)
{
- // Are we the terminal active menu?
- // Yes, if parent menu item deems us to be active (just being visible is sufficient for top-level menus)
- // and we don't have a highlighted menu item pointing to an active sub-menu
- active = active && (!getParentMenuItem() || getParentMenuItem()->isActive()) // I have a parent that is active...
- && (!highlighted_item || !highlighted_item->isActive()); //... but no child that is active
+ if (getTornOff())
+ {
+ // activation of jump keys on torn off menus controlled by keyboard focus
+ LLFloater * parent = dynamic_cast<LLFloater *>(getParent());
+ if (parent)
+ {
+ active = parent->hasFocus();
+ }
+ }
+ else
+ {
+ // Are we the terminal active menu?
+ // Yes, if parent menu item deems us to be active (just being visible is sufficient for top-level menus)
+ // and we don't have a highlighted menu item pointing to an active sub-menu
+ active = (!getParentMenuItem() || getParentMenuItem()->isActive()) // I have a parent that is active...
+ && (!highlighted_item || !highlighted_item->isActive()); //... but no child that is active
+ }
}
+
return active;
}
@@ -1855,7 +1891,12 @@ BOOL LLMenuGL::isOpen()
return TRUE;
}
// otherwise we are only active if we have keyboard focus
- return ((LLFloater*)getParent())->hasFocus();
+ LLFloater * parent = dynamic_cast<LLFloater *>(getParent());
+ if (parent)
+ {
+ return parent->hasFocus();
+ }
+ return FALSE;
}
else
{
@@ -2714,7 +2755,11 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa
// same as giving focus to it
if (!cur_item && getTornOff())
{
- ((LLFloater*)getParent())->setFocus(TRUE);
+ LLFloater * parent = dynamic_cast<LLFloater *>(getParent());
+ if (parent)
+ {
+ parent->setFocus(TRUE);
+ }
}
// Current item position in the items list
@@ -2816,7 +2861,11 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa
// same as giving focus to it
if (!cur_item && getTornOff())
{
- ((LLFloater*)getParent())->setFocus(TRUE);
+ LLFloater * parent = dynamic_cast<LLFloater *>(getParent());
+ if (parent)
+ {
+ parent->setFocus(TRUE);
+ }
}
// Current item reverse position from the end of the list
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index e63b41f97c..17b9b91ba7 100755
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -330,17 +330,16 @@ private:
// local static instance for registering a particular panel class
template<typename T>
-class LLRegisterPanelClassWrapper
-: public LLRegisterPanelClass
+ class LLPanelInjector
{
public:
- // reigister with either the provided builder, or the generic templated builder
- LLRegisterPanelClassWrapper(const std::string& tag);
+ // register with either the provided builder, or the generic templated builder
+ LLPanelInjector(const std::string& tag);
};
template<typename T>
-LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag)
+ LLPanelInjector<T>::LLPanelInjector(const std::string& tag)
{
LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>);
}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 6e03f604a2..d4bbea0f8e 100755
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -320,7 +320,9 @@ LLScrollListCtrl::~LLScrollListCtrl()
delete mSortCallback;
std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
+ mItemList.clear();
std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer());
+ mColumns.clear();
}
@@ -1855,7 +1857,7 @@ void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
// open the resident's details or the group details
std::string sltype = is_group ? "group" : "agent";
std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
- LLUrlAction::clickAction(slurl);
+ LLUrlAction::clickAction(slurl, true);
}
void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp
index 5a1e96ab03..cc7f42e49a 100755
--- a/indra/llui/llscrolllistitem.cpp
+++ b/indra/llui/llscrolllistitem.cpp
@@ -50,6 +50,7 @@ LLScrollListItem::LLScrollListItem( const Params& p )
LLScrollListItem::~LLScrollListItem()
{
std::for_each(mColumns.begin(), mColumns.end(), DeletePointer());
+ mColumns.clear();
}
void LLScrollListItem::addColumn(const LLScrollListCell::Params& p)
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 76ba53ec32..2b9286f663 100755
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -281,6 +281,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
LLTabContainer::~LLTabContainer()
{
std::for_each(mTabList.begin(), mTabList.end(), DeletePointer());
+ mTabList.clear();
}
//virtual
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 5ec4cf4fe5..4144a42fd6 100755
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -167,6 +167,7 @@ LLTextBase::Params::Params()
max_text_length("max_length", 255),
font_shadow("font_shadow"),
wrap("wrap"),
+ trusted_content("trusted_content", true),
use_ellipses("use_ellipses", false),
parse_urls("parse_urls", false),
parse_highlights("parse_highlights", false)
@@ -211,6 +212,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
mLineSpacingPixels(p.line_spacing.pixels),
mClip(p.clip),
mClipPartial(p.clip_partial && !p.allow_scroll),
+ mTrustedContent(p.trusted_content),
mTrackEnd( p.track_end ),
mScrollIndex(-1),
mSelectionStart( 0 ),
@@ -3164,7 +3166,7 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask)
// Only process the click if it's actually in this segment, not to the right of the end-of-line.
if(mEditor.getSegmentAtLocalPos(x, y, false) == this)
{
- LLUrlAction::clickAction(getStyle()->getLinkHREF());
+ LLUrlAction::clickAction(getStyle()->getLinkHREF(), mEditor.isContentTrusted());
return TRUE;
}
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index a74e97cac8..3603f55c3f 100755
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -291,7 +291,8 @@ public:
parse_urls,
parse_highlights,
clip,
- clip_partial;
+ clip_partial,
+ trusted_content;
Optional<S32> v_pad,
h_pad;
@@ -361,6 +362,7 @@ public:
bool getWordWrap() { return mWordWrap; }
bool getUseEllipses() { return mUseEllipses; }
bool truncate(); // returns true of truncation occurred
+ bool isContentTrusted() {return mTrustedContent;}
// TODO: move into LLTextSegment?
void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url
@@ -634,6 +636,7 @@ protected:
bool mBGVisible; // render background?
bool mClip; // clip text to widget rect
bool mClipPartial; // false if we show lines that are partially inside bounding rect
+ bool mTrustedContent; // if false, does not allow to execute SURL links from this editor
bool mPlainText; // didn't use Image or Icon segments
bool mAutoIndent;
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 62140dd9d6..02c81c0744 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -310,7 +310,7 @@ LLTextEditor::~LLTextEditor()
// Scrollbar is deleted by LLView
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
-
+ mUndoStack.clear();
// context menu is owned by menu holder, not us
//delete mContextMenu;
}
@@ -1620,7 +1620,7 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask)
}
}
- if (handled)
+ if (handled && !gFocusMgr.getMouseCapture())
{
updatePrimary();
}
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 928e82cb8c..ee82e0403b 100755
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -118,7 +118,8 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
mButtonLeaveSignal(NULL),
mButtonRemoveSignal(NULL),
mDragAndDropTarget(false),
- mCaretIcon(NULL)
+ mCaretIcon(NULL),
+ mCenterPanel(NULL)
{
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon;
@@ -200,14 +201,15 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)
center_panel_p.auto_resize = false;
center_panel_p.user_resize = false;
center_panel_p.mouse_opaque = false;
- LLLayoutPanel* center_panel = LLUICtrlFactory::create<LLLayoutPanel>(center_panel_p);
- mCenteringStack->addChild(center_panel);
+ mCenterPanel = LLUICtrlFactory::create<LLCenterLayoutPanel>(center_panel_p);
+ mCenteringStack->addChild(mCenterPanel);
LLPanel::Params button_panel_p(p.button_panel);
- button_panel_p.rect = center_panel->getLocalRect();
- button_panel_p.follows.flags = FOLLOWS_BOTTOM|FOLLOWS_LEFT;
+ button_panel_p.rect = mCenterPanel->getLocalRect();
+ button_panel_p.follows.flags = FOLLOWS_BOTTOM|FOLLOWS_LEFT;
mButtonPanel = LLUICtrlFactory::create<LLPanel>(button_panel_p);
- center_panel->addChild(mButtonPanel);
+ mCenterPanel->setButtonPanel(mButtonPanel);
+ mCenterPanel->addChild(mButtonPanel);
mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p));
@@ -1242,3 +1244,15 @@ const std::string LLToolBarButton::getToolTip() const
return tooltip;
}
+void LLToolBar::LLCenterLayoutPanel::handleReshape(const LLRect& rect, bool by_user)
+{
+ LLLayoutPanel::handleReshape(rect, by_user);
+
+ if (!mReshapeCallback.empty())
+ {
+ LLRect r;
+ localRectToOtherView(mButtonPanel->getRect(), &r, gFloaterView);
+ r.stretch(FLOATER_MIN_VISIBLE_PIXELS);
+ mReshapeCallback(mLocationId, r);
+ }
+}
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 743951a41f..9e17eaed8b 100755
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -125,6 +125,19 @@ namespace LLToolBarEnums
SIDE_TOP,
};
+ enum EToolBarLocation
+ {
+ TOOLBAR_NONE = 0,
+ TOOLBAR_LEFT,
+ TOOLBAR_RIGHT,
+ TOOLBAR_BOTTOM,
+
+ TOOLBAR_COUNT,
+
+ TOOLBAR_FIRST = TOOLBAR_LEFT,
+ TOOLBAR_LAST = TOOLBAR_BOTTOM,
+ };
+
LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType);
}
@@ -150,6 +163,30 @@ class LLToolBar
{
friend class LLToolBarButton;
public:
+
+ class LLCenterLayoutPanel : public LLLayoutPanel
+ {
+ public:
+ typedef struct LLLayoutPanel::Params Params;
+ typedef boost::function<void(LLToolBarEnums::EToolBarLocation tb, const LLRect& rect)> reshape_callback_t;
+
+ virtual ~LLCenterLayoutPanel() {}
+ /*virtual*/ void handleReshape(const LLRect& rect, bool by_user);
+
+ void setLocationId(LLToolBarEnums::EToolBarLocation id) { mLocationId = id; }
+ void setReshapeCallback(reshape_callback_t cb) { mReshapeCallback = cb; }
+ void setButtonPanel(LLPanel * panel) { mButtonPanel = panel; }
+
+ protected:
+ friend class LLUICtrlFactory;
+ LLCenterLayoutPanel(const Params& params) : LLLayoutPanel(params), mButtonPanel(NULL) {}
+
+ private:
+ reshape_callback_t mReshapeCallback;
+ LLToolBarEnums::EToolBarLocation mLocationId;
+ LLPanel * mButtonPanel;
+ };
+
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Mandatory<LLToolBarEnums::ButtonType> button_display_mode;
@@ -198,6 +235,7 @@ public:
void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
void setHandleDropCallback(tool_handledrop_callback_t cb) { mHandleDropCallback = cb; }
bool isReadOnly() const { return mReadOnly; }
+ LLCenterLayoutPanel * getCenterLayoutPanel() const { return mCenterPanel; }
LLToolBarButton* createButton(const LLCommandId& id);
@@ -270,6 +308,7 @@ private:
// related widgets
LLLayoutStack* mCenteringStack;
+ LLCenterLayoutPanel* mCenterPanel;
LLPanel* mButtonPanel;
LLHandle<class LLContextMenu> mPopupMenuHandle;
LLHandle<class LLView> mRemoveButtonHandle;
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index 23e574cb74..12537d9dd1 100755
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -87,14 +87,14 @@ void LLUrlAction::executeSLURL(std::string url)
{
if (sExecuteSLURLCallback)
{
- sExecuteSLURLCallback(url);
+ sExecuteSLURLCallback(url ,true);
}
}
-void LLUrlAction::clickAction(std::string url)
+void LLUrlAction::clickAction(std::string url, bool trusted_content)
{
// Try to handle as SLURL first, then http Url
- if ( (sExecuteSLURLCallback) && !sExecuteSLURLCallback(url) )
+ if ( (sExecuteSLURLCallback) && !sExecuteSLURLCallback(url, trusted_content) )
{
if (sOpenURLCallback)
{
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index e731376b95..5f3626490c 100755
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -66,7 +66,7 @@ public:
static void showLocationOnMap(std::string url);
/// perform the appropriate action for left-clicking on a Url
- static void clickAction(std::string url);
+ static void clickAction(std::string url, bool trusted_content);
/// copy the label for a Url to the clipboard
static void copyLabelToClipboard(std::string url);
@@ -86,7 +86,7 @@ public:
/// specify the callbacks to enable this class's functionality
typedef boost::function<void (const std::string&)> url_callback_t;
- typedef boost::function<bool(const std::string& url)> execute_url_callback_t;
+ typedef boost::function<bool(const std::string& url, bool trusted_content)> execute_url_callback_t;
static void setOpenURLCallback(url_callback_t cb);
static void setOpenURLInternalCallback(url_callback_t cb);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index b1cc502c4b..840f67968d 100755
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -1067,7 +1067,8 @@ LLUrlEntrySLLabel::LLUrlEntrySLLabel()
std::string LLUrlEntrySLLabel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
- return getLabelFromWikiLink(url);
+ std::string label = getLabelFromWikiLink(url);
+ return (!LLUrlRegistry::instance().hasUrl(label)) ? label : getUrl(url);
}
std::string LLUrlEntrySLLabel::getUrl(const std::string &string) const
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 20015dca1a..5ee2169b66 100755
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -645,14 +645,18 @@ void LLView::setVisible(BOOL visible)
void LLView::handleVisibilityChange ( BOOL new_visibility )
{
BOOL old_visibility;
+ BOOL log_visibility_change = LLViewerEventRecorder::instance().getLoggingStatus();
BOOST_FOREACH(LLView* viewp, mChildList)
{
// only views that are themselves visible will have their overall visibility affected by their ancestors
old_visibility=viewp->getVisible();
- if (old_visibility!=new_visibility)
+ if(log_visibility_change)
{
- LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget");
+ if (old_visibility!=new_visibility)
+ {
+ LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget");
+ }
}
if (old_visibility)
@@ -660,11 +664,13 @@ void LLView::handleVisibilityChange ( BOOL new_visibility )
viewp->handleVisibilityChange ( new_visibility );
}
- // Consider changing returns to confirm success and know which widget grabbed it
- // For now assume success and log at highest xui possible
- // NOTE we log actual state - which may differ if it somehow failed to set visibility
- lldebugs << "LLView::handleVisibilityChange - now: " << getVisible() << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl;
-
+ if(log_visibility_change)
+ {
+ // Consider changing returns to confirm success and know which widget grabbed it
+ // For now assume success and log at highest xui possible
+ // NOTE we log actual state - which may differ if it somehow failed to set visibility
+ lldebugs << "LLView::handleVisibilityChange - now: " << getVisible() << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl;
+ }
}
}
@@ -1308,52 +1314,55 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
// move child views according to reshape flags
BOOST_FOREACH(LLView* viewp, mChildList)
{
- LLRect child_rect( viewp->mRect );
-
- if (viewp->followsRight() && viewp->followsLeft())
- {
- child_rect.mRight += delta_width;
- }
- else if (viewp->followsRight())
- {
- child_rect.mLeft += delta_width;
- child_rect.mRight += delta_width;
- }
- else if (viewp->followsLeft())
- {
- // left is 0, don't need to adjust coords
- }
- else
+ if (viewp != NULL)
{
- // BUG what to do when we don't follow anyone?
- // for now, same as followsLeft
- }
+ LLRect child_rect( viewp->mRect );
- if (viewp->followsTop() && viewp->followsBottom())
- {
- child_rect.mTop += delta_height;
- }
- else if (viewp->followsTop())
- {
- child_rect.mTop += delta_height;
- child_rect.mBottom += delta_height;
- }
- else if (viewp->followsBottom())
- {
- // bottom is 0, so don't need to adjust coords
- }
- else
- {
- // BUG what to do when we don't follow?
- // for now, same as bottom
- }
+ if (viewp->followsRight() && viewp->followsLeft())
+ {
+ child_rect.mRight += delta_width;
+ }
+ else if (viewp->followsRight())
+ {
+ child_rect.mLeft += delta_width;
+ child_rect.mRight += delta_width;
+ }
+ else if (viewp->followsLeft())
+ {
+ // left is 0, don't need to adjust coords
+ }
+ else
+ {
+ // BUG what to do when we don't follow anyone?
+ // for now, same as followsLeft
+ }
- S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;
- S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;
- viewp->translate( delta_x, delta_y );
- if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight())
- {
- viewp->reshape(child_rect.getWidth(), child_rect.getHeight());
+ if (viewp->followsTop() && viewp->followsBottom())
+ {
+ child_rect.mTop += delta_height;
+ }
+ else if (viewp->followsTop())
+ {
+ child_rect.mTop += delta_height;
+ child_rect.mBottom += delta_height;
+ }
+ else if (viewp->followsBottom())
+ {
+ // bottom is 0, so don't need to adjust coords
+ }
+ else
+ {
+ // BUG what to do when we don't follow?
+ // for now, same as bottom
+ }
+
+ S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;
+ S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;
+ viewp->translate( delta_x, delta_y );
+ if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight())
+ {
+ viewp->reshape(child_rect.getWidth(), child_rect.getHeight());
+ }
}
}
}
diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp
index a352f621eb..546a0f5866 100644
--- a/indra/llui/llviewereventrecorder.cpp
+++ b/indra/llui/llviewereventrecorder.cpp
@@ -31,7 +31,7 @@
LLViewerEventRecorder::LLViewerEventRecorder() {
clear(UNDEFINED);
-
+ logEvents = false;
// Remove any previous event log file
std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old");
LLFile::remove(old_log_ui_events_to_llsd_file);
diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h
index 72ca643ced..375efcc3de 100644
--- a/indra/llui/llviewereventrecorder.h
+++ b/indra/llui/llviewereventrecorder.h
@@ -65,7 +65,7 @@ class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
std::string get_xui();
void update_xui(std::string xui);
- bool getLoggingStatus();
+ bool getLoggingStatus(){return logEvents;};
void setEventLoggingOn();
void setEventLoggingOff();
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 6899e9a44a..0d65c3f8c3 100755
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -42,6 +42,7 @@
#include "lldiriterator.h"
#include "stringize.h"
+#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -76,6 +77,7 @@ const char
*LLDir::SKINBASE = "";
static const char* const empty = "";
+std::string LLDir::sDumpDir = "";
LLDir::LLDir()
: mAppName(""),
@@ -99,7 +101,32 @@ LLDir::~LLDir()
{
}
-
+std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
+{
+ //Returns a vector of fullpath filenames.
+
+ boost::filesystem::path p (dirname);
+ std::vector<std::string> v;
+
+ if (exists(p))
+ {
+ if (is_directory(p))
+ {
+ boost::filesystem::directory_iterator end_iter;
+ for (boost::filesystem::directory_iterator dir_itr(p);
+ dir_itr != end_iter;
+ ++dir_itr)
+ {
+ if (boost::filesystem::is_regular_file(dir_itr->status()))
+ {
+ v.push_back(dir_itr->path().filename().string());
+ }
+ }
+ }
+ }
+ return v;
+}
+
S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
{
S32 count = 0;
@@ -158,6 +185,34 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
return count;
}
+U32 LLDir::deleteDirAndContents(const std::string& dir_name)
+{
+ //Removes the directory and its contents. Returns number of files deleted.
+
+ U32 num_deleted = 0;
+
+ try
+ {
+ boost::filesystem::path dir_path(dir_name);
+ if (boost::filesystem::exists (dir_path))
+ {
+ if (!boost::filesystem::is_empty (dir_path))
+ { // Directory has content
+ num_deleted = boost::filesystem::remove_all (dir_path);
+ }
+ else
+ { // Directory is empty
+ boost::filesystem::remove (dir_path);
+ }
+ }
+ }
+ catch (boost::filesystem::filesystem_error &er)
+ {
+ llwarns << "Failed to delete " << dir_name << " with error " << er.code().message() << llendl;
+ }
+ return num_deleted;
+}
+
const std::string LLDir::findFile(const std::string &filename,
const std::string& searchPath1,
const std::string& searchPath2,
@@ -244,11 +299,36 @@ const std::string &LLDir::getLindenUserDir() const
return mLindenUserDir;
}
-const std::string &LLDir::getChatLogsDir() const
+const std::string& LLDir::getChatLogsDir() const
{
return mChatLogsDir;
}
+void LLDir::setDumpDir( const std::string& path )
+{
+ LLDir::sDumpDir = path;
+ if (! sDumpDir.empty() && sDumpDir.rbegin() == mDirDelimiter.rbegin() )
+ {
+ sDumpDir.erase(sDumpDir.size() -1);
+ }
+}
+
+const std::string &LLDir::getDumpDir() const
+{
+ if (sDumpDir.empty() )
+ {
+ LLUUID uid;
+ uid.generate();
+
+ sDumpDir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "")
+ + "dump-" + uid.asString();
+
+ dir_exists_or_crash(sDumpDir);
+ }
+
+ return LLDir::sDumpDir;
+}
+
const std::string &LLDir::getPerAccountChatLogsDir() const
{
return mPerAccountChatLogsDir;
@@ -420,6 +500,10 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
prefix = getCacheDir();
break;
+ case LL_PATH_DUMP:
+ prefix=getDumpDir();
+ break;
+
case LL_PATH_USER_SETTINGS:
prefix = add(getOSUserAppDir(), "user_settings");
break;
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index e02bf552aa..b219c6e29f 100755
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -53,6 +53,7 @@ typedef enum ELLPath
LL_PATH_EXECUTABLE = 16,
LL_PATH_DEFAULT_SKIN = 17,
LL_PATH_FONTS = 18,
+ LL_PATH_DUMP = 19,
LL_PATH_LAST
} ELLPath;
@@ -71,7 +72,8 @@ class LLDir
const std::string& app_read_only_data_dir = "") = 0;
virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
-
+ U32 deleteDirAndContents(const std::string& dir_name);
+ std::vector<std::string> getFilesInDir(const std::string &dirname);
// pure virtual functions
virtual std::string getCurPath() = 0;
virtual bool fileExists(const std::string &filename) const = 0;
@@ -92,6 +94,7 @@ class LLDir
const std::string &getOSUserAppDir() const; // Location of the os-specific user app dir
const std::string &getLindenUserDir() const; // Location of the Linden user dir.
const std::string &getChatLogsDir() const; // Location of the chat logs dir.
+ const std::string &getDumpDir() const; // Location of the per-run dump dir.
const std::string &getPerAccountChatLogsDir() const; // Location of the per account chat logs dir.
const std::string &getTempDir() const; // Common temporary directory
const std::string getCacheDir(bool get_default = false) const; // Location of the cache.
@@ -179,6 +182,8 @@ class LLDir
// For producing safe download file names from potentially unsafe ones
static std::string getScrubbedFileName(const std::string uncleanFileName);
static std::string getForbiddenFileChars();
+ void setDumpDir( const std::string& path );
+
virtual void setChatLogsDir(const std::string &path); // Set the chat logs dir to this user's dir
virtual void setPerAccountChatLogsDir(const std::string &username); // Set the per user chat log directory.
@@ -245,6 +250,7 @@ protected:
std::vector<std::string> mSearchSkinDirs;
std::string mLanguage; // Current viewer language
std::string mLLPluginDir; // Location for plugins and plugin shell
+ static std::string sDumpDir; // Per-run crash report subdir of log directory.
std::string mUserName; // Current user name
};
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index e00596cdb5..2f47ab3507 100755
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -134,7 +134,7 @@ LLDir_Mac::LLDir_Mac()
{
mOSCacheDir = *cachedir;
- //Aura TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
+ //TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away.
CreateDirectory(mOSCacheDir, secondLifeString, NULL);
}
diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp
index 460d2a8b4f..229608231c 100755
--- a/indra/llvfs/lldiriterator.cpp
+++ b/indra/llvfs/lldiriterator.cpp
@@ -119,16 +119,25 @@ bool LLDirIterator::Impl::next(std::string &fname)
fs::directory_iterator end_itr; // default construction yields past-the-end
bool found = false;
- while (mIter != end_itr && !found)
+
+ // Check if path is a directory.
+ try
{
- boost::smatch match;
- std::string name = mIter->path().filename().string();
- if (found = boost::regex_match(name, match, mFilterExp))
+ while (mIter != end_itr && !found)
{
- fname = name;
+ boost::smatch match;
+ std::string name = mIter->path().filename().string();
+ if (found = boost::regex_match(name, match, mFilterExp))
+ {
+ fname = name;
+ }
+
+ ++mIter;
}
-
- ++mIter;
+ }
+ catch (const fs::filesystem_error& e)
+ {
+ llwarns << e.what() << llendl;
}
return found;
diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp
index 0424f2379e..b5fd3673a6 100755
--- a/indra/llvfs/llpidlock.cpp
+++ b/indra/llvfs/llpidlock.cpp
@@ -274,3 +274,8 @@ void LLPidLock::setSaveName(std::string savename)
{
LLPidLockFile::instance().mSaveName=savename;
}
+
+S32 LLPidLock::getPID()
+{
+ return (S32)getpid();
+}
diff --git a/indra/llvfs/llpidlock.h b/indra/llvfs/llpidlock.h
index d3295f4911..334f26bb29 100755
--- a/indra/llvfs/llpidlock.h
+++ b/indra/llvfs/llpidlock.h
@@ -39,21 +39,22 @@ namespace LLPidLock
{
void initClass(); // { (void) LLPidLockFile::instance(); }
- bool requestLock( LLNameTable<void *> *name_table=NULL, bool autosave=TRUE,
- bool force_immediate=FALSE, F32 timeout=300.0);
- bool checkLock();
- void releaseLock();
- bool isClean();
-
- //getters
- LLNameTable<void *> * getNameTable();
- bool getAutosave();
- bool getClean();
- std::string getSaveName();
-
- //setters
- void setClean(bool clean);
- void setSaveName(std::string savename);
+ bool requestLock( LLNameTable<void *> *name_table=NULL, bool autosave=TRUE,
+ bool force_immediate=FALSE, F32 timeout=300.0);
+ bool checkLock();
+ void releaseLock();
+ bool isClean();
+
+ //getters
+ LLNameTable<void *> * getNameTable();
+ bool getAutosave();
+ bool getClean();
+ std::string getSaveName();
+ S32 getPID();
+
+ //setters
+ void setClean(bool clean);
+ void setSaveName(std::string savename);
};
#endif // LL_PIDLOCK_H
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index 306d7d8ec7..983e7c3b59 100755
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -104,7 +104,7 @@ BOOL LLVFile::read(U8 *buffer, S32 bytes, BOOL async, F32 priority)
// We can't do a read while there are pending async writes
waitForLock(VFSLOCK_APPEND);
- // *FIX: (???)
+ // *FIX: (?)
if (async)
{
mHandle = sVFSThread->read(mVFS, mFileID, mFileType, buffer, mPosition, bytes, threadPri());
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 82c926620a..7b589f5b96 100755
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -578,6 +578,7 @@ LLVFS::~LLVFS()
mFreeBlocksByLength.clear();
for_each(mFreeBlocksByLocation.begin(), mFreeBlocksByLocation.end(), DeletePairedPointer());
+ mFreeBlocksByLocation.clear();
unlockAndClose(mDataFP);
mDataFP = NULL;
@@ -1835,6 +1836,7 @@ void LLVFS::audit()
}
for_each(audit_blocks.begin(), audit_blocks.end(), DeletePointer());
+ audit_blocks.clear();
}
diff --git a/indra/llvfs/tests/lldiriterator_test.cpp b/indra/llvfs/tests/lldiriterator_test.cpp
index 505d86faa7..a65e3dada5 100755
--- a/indra/llvfs/tests/lldiriterator_test.cpp
+++ b/indra/llvfs/tests/lldiriterator_test.cpp
@@ -51,9 +51,9 @@ namespace tut
void test_chop_662(void)
{
// Check a selection of bad group names from the crash reports
- LLDirIterator iter(".","+bad-group-name]+??-??.*");
- LLDirIterator iter1(".","))--@---bad-group-name2((??-??.*\\.txt");
- LLDirIterator iter2(".","__^v--x)Cuide d sua vida(x--v^__??-??.*");
+ LLDirIterator iter(".","+bad-group-name]+?\?-??.*");
+ LLDirIterator iter1(".","))--@---bad-group-name2((?\?-??.*\\.txt");
+ LLDirIterator iter2(".","__^v--x)Cuide d sua vida(x--v^__?\?-??.*");
}
template<> template<>
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index 3579b5d42f..b0f4bc5503 100755
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -171,6 +171,7 @@ std::string LLDXDriverFile::dump()
LLDXDevice::~LLDXDevice()
{
for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer());
+ mDriverFiles.clear();
}
std::string LLDXDevice::dump()
@@ -230,6 +231,7 @@ LLDXHardware::LLDXHardware()
void LLDXHardware::cleanup()
{
// for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer());
+ // mDevices.clear();
}
/*
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 93b9d36939..a2824db70a 100755
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -72,7 +72,7 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)
}
S32 result = 0;
-#if LL_MESA_HEADLESS // !!! *FIX: (???)
+#if LL_MESA_HEADLESS // !!! *FIX: (?)
llwarns << "OSMessageBox: " << text << llendl;
return OSBTN_OK;
#elif LL_WINDOWS
@@ -324,7 +324,7 @@ bool LLSplashScreen::isVisible()
// static
LLSplashScreen *LLSplashScreen::create()
{
-#if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (???)
+#if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (?)
return 0;
#elif LL_WINDOWS
return new LLSplashScreenWin32;
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 11c0b51086..ed0348e10e 100755
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -39,6 +39,7 @@
#include "indra_constants.h"
#include <OpenGL/OpenGL.h>
+#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>
extern BOOL gDebugWindowProc;
@@ -1743,16 +1744,34 @@ LLSD LLWindowMacOSX::getNativeKeyData()
return result;
}
-
BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)
{
- // Is this even used anywhere? Do we really need an OS color picker?
BOOL retval = FALSE;
- //S32 error = 0;
+ OSErr error = noErr;
+ NColorPickerInfo info;
+
+ memset(&info, 0, sizeof(info));
+ info.theColor.color.rgb.red = (UInt16)(*r * 65535.f);
+ info.theColor.color.rgb.green = (UInt16)(*g * 65535.f);
+ info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f);
+ info.placeWhere = kCenterOnMainScreen;
+
+ error = NPickColor(&info);
+
+ if (error == noErr)
+ {
+ retval = info.newColorChosen;
+ if (info.newColorChosen)
+ {
+ *r = ((float) info.theColor.color.rgb.red) / 65535.0;
+ *g = ((float) info.theColor.color.rgb.green) / 65535.0;
+ *b = ((float) info.theColor.color.rgb.blue) / 65535.0;
+ }
+ }
+
return (retval);
}
-
void *LLWindowMacOSX::getPlatformWindow()
{
// NOTE: this will be NULL in fullscreen mode. Plan accordingly.
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 205466e936..18e9eb0ee9 100755
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -223,7 +223,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
mOriginalAspectRatio = 1024.0 / 768.0;
if (title.empty())
- mWindowTitle = "SDL Window"; // *FIX: (???)
+ mWindowTitle = "SDL Window"; // *FIX: (?)
else
mWindowTitle = title;
@@ -956,7 +956,7 @@ BOOL LLWindowSDL::setPosition(const LLCoordScreen position)
{
if(mWindow)
{
- // *FIX: (???)
+ // *FIX: (?)
//MacMoveWindow(mWindow, position.mX, position.mY, false);
}
diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp
index c5f660ca6e..351009814d 100755
--- a/indra/mac_crash_logger/llcrashloggermac.cpp
+++ b/indra/mac_crash_logger/llcrashloggermac.cpp
@@ -89,5 +89,6 @@ bool LLCrashLoggerMac::mainLoop()
bool LLCrashLoggerMac::cleanup()
{
commonCleanup();
+ mKeyMaster.releaseMaster();
return true;
}
diff --git a/indra/mac_crash_logger/mac_crash_logger.cpp b/indra/mac_crash_logger/mac_crash_logger.cpp
index 6add74556f..2c83f3439d 100755
--- a/indra/mac_crash_logger/mac_crash_logger.cpp
+++ b/indra/mac_crash_logger/mac_crash_logger.cpp
@@ -27,6 +27,7 @@
#include "linden_common.h"
#include "llcrashloggermac.h"
#include "indra_constants.h"
+#include "llpidlock.h"
#include <iostream>
@@ -35,6 +36,14 @@ int main(int argc, char **argv)
LLCrashLoggerMac app;
app.parseCommandOptions(argc, argv);
+ LLSD options = LLApp::instance()->getOptionData(
+ LLApp::PRIORITY_COMMAND_LINE);
+
+ if (!(options.has("pid") && options.has("dumpdir")))
+ {
+ llwarns << "Insufficient parameters to crash report." << llendl;
+ }
+
if (! app.init())
{
llwarns << "Unable to initialize application." << llendl;
@@ -44,9 +53,7 @@ int main(int argc, char **argv)
{
// return NSApplicationMain(argc, (const char **)argv);
}
-
app.mainLoop();
-
app.cleanup();
llinfos << "Crash reporter finished normally." << llendl;
diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp
index aac349bf57..49a1c9dba3 100755
--- a/indra/media_plugins/winmmshim/winmm_shim.cpp
+++ b/indra/media_plugins/winmmshim/winmm_shim.cpp
@@ -4,7 +4,7 @@
*
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2010-2014, 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
@@ -30,8 +30,8 @@
using std::wstring;
-static float sVolumeLevel = 1.f;
-static bool sMute = false;
+static float sVolumeLevel = 1.f; // Could be covered by critical section,
+static bool sMute = false; // not needed with atomicity and alignment.
static CRITICAL_SECTION sCriticalSection;
BOOL APIENTRY DllMain( HMODULE hModule,
@@ -39,37 +39,44 @@ BOOL APIENTRY DllMain( HMODULE hModule,
LPVOID lpReserved
)
{
- InitializeCriticalSection(&sCriticalSection);
+ if (DLL_PROCESS_ATTACH == ul_reason_for_call)
+ {
+ InitializeCriticalSection(&sCriticalSection);
+ }
return TRUE;
}
void ll_winmm_shim_initialize(){
- static bool initialized = false;
- // do this only once
- EnterCriticalSection(&sCriticalSection);
+ static volatile bool initialized = false;
+
+ // do this only once using double-check locking
if (!initialized)
- { // bind to original winmm.dll
- TCHAR system_path[MAX_PATH];
- TCHAR dll_path[MAX_PATH];
- ::GetSystemDirectory(system_path, MAX_PATH);
-
- // grab winmm.dll from system path, where it should live
- wsprintf(dll_path, "%s\\winmm.dll", system_path);
- HMODULE winmm_handle = ::LoadLibrary(dll_path);
-
- if (winmm_handle != NULL)
- { // we have a dll, let's get out pointers!
- initialized = true;
- init_function_pointers(winmm_handle);
- ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n");
- }
- else
- {
- // failed to initialize real winmm.dll
- ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n");
+ {
+ EnterCriticalSection(&sCriticalSection);
+ if (!initialized)
+ { // bind to original winmm.dll
+ TCHAR system_path[MAX_PATH];
+ TCHAR dll_path[MAX_PATH];
+ ::GetSystemDirectory(system_path, MAX_PATH);
+
+ // grab winmm.dll from system path, where it should live
+ wsprintf(dll_path, "%s\\winmm.dll", system_path);
+ HMODULE winmm_handle = ::LoadLibrary(dll_path);
+
+ if (winmm_handle != NULL)
+ { // we have a dll, let's get out pointers!
+ init_function_pointers(winmm_handle);
+ ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n");
+ initialized = true; // Last thing after completing setup
+ }
+ else
+ {
+ // failed to initialize real winmm.dll
+ ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n");
+ }
}
+ LeaveCriticalSection(&sCriticalSection);
}
- LeaveCriticalSection(&sCriticalSection);
}
@@ -84,7 +91,7 @@ extern "C"
int mBitsPerSample;
};
typedef std::map<HWAVEOUT, WaveOutFormat*> wave_out_map_t;
- static wave_out_map_t sWaveOuts;
+ static wave_out_map_t sWaveOuts; // Covered by sCriticalSection
MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
{
@@ -100,7 +107,9 @@ extern "C"
&& ((fdwOpen & WAVE_FORMAT_QUERY) == 0)) // not just querying for format support
{ // remember the requested bits per sample, and associate with the given handle
WaveOutFormat* wave_outp = new WaveOutFormat(pwfx->wBitsPerSample);
+ EnterCriticalSection(&sCriticalSection);
sWaveOuts.insert(std::make_pair(*phwo, wave_outp));
+ LeaveCriticalSection(&sCriticalSection);
}
return result;
}
@@ -108,13 +117,15 @@ extern "C"
MMRESULT WINAPI waveOutClose( HWAVEOUT hwo)
{
ll_winmm_shim_initialize();
+ EnterCriticalSection(&sCriticalSection);
wave_out_map_t::iterator found_it = sWaveOuts.find(hwo);
if (found_it != sWaveOuts.end())
{ // forget what we know about this handle
delete found_it->second;
sWaveOuts.erase(found_it);
}
- return waveOutClose_orig( hwo);
+ LeaveCriticalSection(&sCriticalSection);
+ return waveOutClose_orig(hwo);
}
MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
@@ -128,11 +139,19 @@ extern "C"
}
else if (sVolumeLevel != 1.f)
{ // need to apply volume level
+ int bits_per_sample(0);
+
+ EnterCriticalSection(&sCriticalSection);
wave_out_map_t::iterator found_it = sWaveOuts.find(hwo);
if (found_it != sWaveOuts.end())
{
- WaveOutFormat* formatp = found_it->second;
- switch (formatp->mBitsPerSample){
+ bits_per_sample = found_it->second->mBitsPerSample;
+ }
+ LeaveCriticalSection(&sCriticalSection);
+ if (bits_per_sample)
+ {
+ switch (bits_per_sample)
+ {
case 8:
{
char volume = (char)(sVolumeLevel * 127.f);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 17e340d136..0bf0152b30 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1282,6 +1282,8 @@ set_source_files_properties(
if (DARWIN)
LIST(APPEND viewer_SOURCE_FILES llappviewermacosx.cpp)
+ LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-objc.mm)
+ LIST(APPEND viewer_SOURCE_FILES llappviewermacosx-objc.h)
LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm)
LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index c1e43e6d45..d2577d9756 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.7.3
+3.7.7
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4c7b192ae5..778ab4983a 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1203,7 +1203,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>BulkChangeShareWithGroup</key>
<map>
@@ -3533,17 +3533,6 @@
<key>Value</key>
<string>http://events.secondlife.com/viewer/embed/event/</string>
</map>
- <key>EveryoneCopy</key>
- <map>
- <key>Comment</key>
- <string>Everyone can copy the newly created objects</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FastCacheFetchEnabled</key>
<map>
<key>Comment</key>
@@ -3569,13 +3558,13 @@
<key>FPSLogFrequency</key>
<map>
<key>Comment</key>
- <string>Seconds between display of FPS in log (0 for never)</string>
+ <string>Seconds between display of FPS in log (0 for never)</string>
<key>Persist</key>
- <integer>1</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>F32</string>
+ <string>F32</string>
<key>Value</key>
- <real>10.0</real>
+ <real>10.0</real>
</map>
<key>FilterItemsMaxTimePerFrameVisible</key>
<map>
@@ -4655,6 +4644,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>InventoryOutboxMakeVisible</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable making the Merchant Outbox and Inbox visible in the inventory for debug purposes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>InventoryOutboxMaxFolderCount</key>
<map>
<key>Comment</key>
@@ -6426,39 +6426,6 @@
<key>Value</key>
<integer>130</integer>
</map>
- <key>NextOwnerCopy</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects can be copied by next owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>NextOwnerModify</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects can be modified by next owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>NextOwnerTransfer</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects can be resold or given away by next owner</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>NewCacheLocation</key>
<map>
<key>Comment</key>
@@ -8696,7 +8663,7 @@
<key>RenderDepthOfField</key>
<map>
<key>Comment</key>
- <string>Whether to use depth of field effect when lighting and shadows are enabled</string>
+ <string>Whether to use depth of field effect when Advanced Lighting Model is enabled</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -8908,7 +8875,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>384</real>
+ <real>368.0</real>
</map>
<key>RenderDeferred</key>
@@ -9991,7 +9958,18 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RevokePermsOnStopAnimation</key>
+ <key>ReportBugURL</key>
+ <map>
+ <key>Comment</key>
+ <string>URL used for filing bugs from viewer</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>https://jira.secondlife.com/secure/CreateIssueDetails!init.jspa?pid=10610&amp;issuetype=1&amp;environment=[ENVIRONMENT]&amp;customfield_10253=[LOCATION]</string>
+ </map>
+ <key>RevokePermsOnStopAnimation</key>
<map>
<key>Comment</key>
<string>Clear animation permssions when choosing "Stop Animating Me"</string>
@@ -10321,17 +10299,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShareWithGroup</key>
- <map>
- <key>Comment</key>
- <string>Newly created objects are shared with the currently active group</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowAdvancedGraphicsSettings</key>
<map>
<key>Comment</key>
@@ -14583,6 +14550,347 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>ObjectsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ObjectsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ObjectsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ObjectsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created object</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ObjectsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created objects are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>UploadsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly uploaded item</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>UploadsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly uploaded items are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ScriptsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created script</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>ScriptsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created scripts are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NotecardsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotecardsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotecardsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>NotecardsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created notecard</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NotecardsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created notecards are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>GesturesNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>GesturesNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>GesturesNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>GesturesEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created gesture</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>GesturesShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created gestures are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>WearablesEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created clothing or body part</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>WearablesShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created clothing or body part is shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DefaultUploadPermissionsConverted</key>
+ <map>
+ <key>Comment</key>
+ <string>Default upload permissions have been converted to default creation permissions</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>PathfindingRetrieveNeighboringRegion</key>
<map>
<key>Comment</key>
@@ -14970,6 +15278,62 @@
<key>Value</key>
<string />
</map>
+ <key>EveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Everyone can copy the newly created objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>NextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>ShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>(obsolete) Newly created objects are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index c98e7d1cd3..bc63d07d72 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -33,8 +33,8 @@ mat4 getSkinnedTransform()
mat4 ret;
int i = int(floor(weight.x));
float x = fract(weight.x);
-
- ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
+
+ ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x);
ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x);
ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x);
ret[3] = vec4(0,0,0,1);
diff --git a/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl b/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl
new file mode 100644
index 0000000000..1936e0dcaa
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl
@@ -0,0 +1,39 @@
+/**
+ * @file benchmarkF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform sampler2D diffuseMap;
+
+VARYING vec2 tc0;
+
+void main()
+{
+ frag_color = texture2D(diffuseMap, tc0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl b/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl
new file mode 100644
index 0000000000..7beb20ede4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file benchmarkV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec2 tc0;
+
+void main()
+{
+ gl_Position = vec4(position, 1.0);
+
+ tc0 = (position.xy*0.5+0.5);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
index 67dc500493..da02534dbb 100755
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
@@ -31,12 +31,13 @@ out vec4 frag_color;
uniform sampler2D tex0;
-VARYING vec4 vertex_color;
+uniform vec4 color;
+
VARYING vec2 vary_texcoord0;
void main()
{
- float alpha = texture2D(tex0, vary_texcoord0.xy).a * vertex_color.a;
+ float alpha = texture2D(tex0, vary_texcoord0.xy).a * color.a;
- frag_color = vec4(vertex_color.rgb, alpha);
+ frag_color = vec4(color.rgb, alpha);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
index c58f9dfdaf..f33115d78d 100755
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
@@ -26,16 +26,13 @@
uniform mat4 modelview_projection_matrix;
ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
ATTRIBUTE vec2 texcoord0;
-VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
void main()
{
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vertex_color = diffuse_color;
vary_texcoord0 = texcoord0;
}
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 0bdd425504..a2d68eb550 100755
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 35
+version 36
// The version number above should be implemented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -628,3 +628,6 @@ Disregard128DefaultDrawDistance 1 0
list NVIDIA_GeForce_Go_7400
Disregard128DefaultDrawDistance 1 0
+list OSX_10_6_8
+RenderDeferred 0 0
+
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index c4f503ef4e..8b3a9a8372 100755
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -116,11 +116,14 @@ Var DO_UNINSTALL_V2 ; If non-null, path to a previous Viewer 2 installation
!include "FileFunc.nsh" ; For GetParameters, GetOptions
!insertmacro GetParameters
!insertmacro GetOptions
+!include WinVer.nsh ; For OS and SP detection
+!include x64.nsh ; For 64bit OS detection
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; After install completes, launch app
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function .onInstSuccess
+Call CheckWindowsServPack ; Warn if not on the latest SP before asking to launch.
Push $R0 # Option value, unused
StrCmp $SKIP_DIALOGS "true" label_launch
@@ -152,26 +155,67 @@ Function dirPre
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Make sure we're not on Windows 98 / ME
+; Make sure this computer meets the minimum system requirements.
+; Currently: Windows 32bit XP SP3, 64bit XP SP2 and Server 2003 SP2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CheckWindowsVersion
- DetailPrint "Checking Windows version..."
- Call GetWindowsVersion
- Pop $R0
- ; Just get first two characters, ignore 4.0 part of "NT 4.0"
- StrCpy $R0 $R0 2
- ; Blacklist certain OS versions
- StrCmp $R0 "95" win_ver_bad
- StrCmp $R0 "98" win_ver_bad
- StrCmp $R0 "ME" win_ver_bad
- StrCmp $R0 "NT" win_ver_bad
- Return
-win_ver_bad:
- StrCmp $SKIP_DIALOGS "true" +2 ; If skip_dialogs is set just install
- MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort
- Return
-win_ver_abort:
- Quit
+ ${If} ${AtMostWin2000}
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+
+ ${If} ${IsWinXP}
+ ${AndIfNot} ${RunningX64}
+ ${AndIfNot} ${IsServicePack} 3
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+
+ ${If} ${IsWinXP}
+ ${AndIf} ${RunningX64}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+
+ ${If} ${IsWin2003}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsVersionMB)
+ Quit
+ ${EndIf}
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;Recommend Upgrading Service Pack
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function CheckWindowsServPack
+ ${If} ${IsWinVista}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
+
+ ${If} ${IsWin2008}
+ ${AndIfNot} ${IsServicePack} 2
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
+
+ ${If} ${IsWin7}
+ ${AndIfNot} ${IsServicePack} 1
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
+
+ ${If} ${IsWin2008R2}
+ ${AndIfNot} ${IsServicePack} 1
+ MessageBox MB_OK $(CheckWindowsServPackMB)
+ DetailPrint $(UseLatestServPackDP)
+ Return
+ ${EndIf}
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -222,17 +266,13 @@ FunctionEnd
; Checks for CPU valid (must have SSE2 support)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function CheckCPUFlags
- Call GetWindowsVersion
- Pop $R0
- StrCmp $R0 "2000" OK_SSE ; sse check not available on win2k.
-
Push $1
System::Call 'kernel32::IsProcessorFeaturePresent(i) i(10) .r1'
- IntCmp $1 1 OK_SSE
- MessageBox MB_OKCANCEL $(MissingSSE2) /SD IDOK IDOK OK_SSE
+ IntCmp $1 1 OK_SSE2
+ MessageBox MB_OKCANCEL $(MissingSSE2) /SD IDOK IDOK OK_SSE2
Quit
- OK_SSE:
+ OK_SSE2:
Pop $1
Return
FunctionEnd
@@ -768,103 +808,13 @@ Call un.ProgramFiles
SectionEnd ; end of uninstall section
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; (From the NSIS documentation, JC)
-; GetWindowsVersion
-;
-; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/
-; Updated by Joost Verburg
-;
-; Returns on top of stack
-;
-; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003)
-; or
-; '' (Unknown Windows Version)
-;
-; Usage:
-; Call GetWindowsVersion
-; Pop $R0
-; ; at this point $R0 is "NT 4.0" or whatnot
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-Function GetWindowsVersion
-
- Push $R0
- Push $R1
-
- ReadRegStr $R0 HKLM \
- "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
-
- IfErrors 0 lbl_winnt
-
- ; we are not NT
- ReadRegStr $R0 HKLM \
- "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber
-
- StrCpy $R1 $R0 1
- StrCmp $R1 '4' 0 lbl_error
-
- StrCpy $R1 $R0 3
-
- StrCmp $R1 '4.0' lbl_win32_95
- StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98
-
- lbl_win32_95:
- StrCpy $R0 '95'
- Goto lbl_done
-
- lbl_win32_98:
- StrCpy $R0 '98'
- Goto lbl_done
-
- lbl_win32_ME:
- StrCpy $R0 'ME'
- Goto lbl_done
-
- lbl_winnt:
-
- StrCpy $R1 $R0 1
-
- StrCmp $R1 '3' lbl_winnt_x
- StrCmp $R1 '4' lbl_winnt_x
-
- StrCpy $R1 $R0 3
-
- StrCmp $R1 '5.0' lbl_winnt_2000
- StrCmp $R1 '5.1' lbl_winnt_XP
- StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error
-
- lbl_winnt_x:
- StrCpy $R0 "NT $R0" 6
- Goto lbl_done
-
- lbl_winnt_2000:
- Strcpy $R0 '2000'
- Goto lbl_done
-
- lbl_winnt_XP:
- Strcpy $R0 'XP'
- Goto lbl_done
-
- lbl_winnt_2003:
- Strcpy $R0 '2003'
- Goto lbl_done
-
- lbl_error:
- Strcpy $R0 ''
- lbl_done:
-
- Pop $R1
- Exch $R0
-
-FunctionEnd
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Note: to add new languages, add a language file include to the list
;; at the top of this file, add an entry to the menu and then add an
;; entry to the language ID selector below
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function .onInit
+Call CheckWindowsVersion ; Don't install On unsupported systems
Push $0
${GetParameters} $COMMANDLINE ; get our command line
@@ -933,13 +883,12 @@ StrCpy $INSTPROG "${INSTNAME}"
StrCpy $INSTEXE "${INSTEXE}"
StrCpy $INSTSHORTCUT "${SHORTCUT}"
-Call CheckWindowsVersion ; warn if on Windows 98/ME
-Call CheckCPUFlags ; Make sure we have SSE2 support
+Call CheckCPUFlags ; Make sure we have SSE2 support
Call CheckIfAdministrator ; Make sure the user can install/uninstall
Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this version
Call CloseSecondLife ; Make sure we're not running
Call CheckNetworkConnection ; ping secondlife.com
-Call CheckWillUninstallV2 ; See if a V2 install exists and will be removed.
+Call CheckWillUninstallV2 ; See if a V2 install exists and will be removed.
Call CheckOldExeName ; Clean up a previous version of the exe
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi
index 0c832e8ba9..2352649b4b 100755
--- a/indra/newview/installers/windows/lang_da.nsi
+++ b/indra/newview/installers/windows/lang_da.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi
index b717a4d3a5..397262afe1 100755
--- a/indra/newview/installers/windows/lang_de.nsi
+++ b/indra/newview/installers/windows/lang_de.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index da0d7f54d2..df0d55d9e0 100755
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi
index c6a7f38f3f..32967a0dfa 100755
--- a/indra/newview/installers/windows/lang_es.nsi
+++ b/indra/newview/installers/windows/lang_es.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index 008c240ed7..7c75e25360 100755
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi
index eccd965a92..ce66b61f9f 100755
--- a/indra/newview/installers/windows/lang_it.nsi
+++ b/indra/newview/installers/windows/lang_it.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi
index f564291f7d..e68830123a 100755
--- a/indra/newview/installers/windows/lang_ja.nsi
+++ b/indra/newview/installers/windows/lang_ja.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi
index 191bae4755..7883819190 100755
--- a/indra/newview/installers/windows/lang_pl.nsi
+++ b/indra/newview/installers/windows/lang_pl.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi
index da56a3c336..eb3fb2386c 100755
--- a/indra/newview/installers/windows/lang_pt-br.nsi
+++ b/indra/newview/installers/windows/lang_pt-br.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi
index de7affe08a..3b0042fbf5 100755
--- a/indra/newview/installers/windows/lang_ru.nsi
+++ b/indra/newview/installers/windows/lang_ru.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi
index 5e7e3d797b..b9be1eab08 100755
--- a/indra/newview/installers/windows/lang_tr.nsi
+++ b/indra/newview/installers/windows/lang_tr.nsi
Binary files differ
diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi
index ecf1185fbb..3c6f6fd289 100755
--- a/indra/newview/installers/windows/lang_zh.nsi
+++ b/indra/newview/installers/windows/lang_zh.nsi
Binary files differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f150ceda67..54e0375a2b 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -47,6 +47,7 @@
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterimcontainer.h"
+#include "llfloaterperms.h"
#include "llfloaterreg.h"
#include "llfloatertools.h"
#include "llgroupactions.h"
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index fa810aac76..9c36e54928 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -49,6 +49,7 @@
#include "llvoavatarself.h"
#include "llviewerwearable.h"
#include "llwearablelist.h"
+#include "llfloaterperms.h"
#include <boost/scoped_ptr.hpp>
@@ -65,6 +66,19 @@ void wear_and_edit_cb(const LLUUID& inv_item)
{
if (inv_item.isNull()) return;
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (!item) return;
+
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+
// Request editing the item after it gets worn.
gAgentWearables.requestEditingWearable(inv_item);
@@ -72,6 +86,26 @@ void wear_and_edit_cb(const LLUUID& inv_item)
LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
}
+void wear_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
// HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look"
@@ -204,7 +238,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
*
* Would like to pass the agent in here, but we can't safely
* count on it being around later. Just use gAgent directly.
- * @param cb callback to execute on completion (??? unused ???)
+ * @param cb callback to execute on completion (? unused ?)
* @param type Type for the wearable in the agent
* @param wearable The wearable data.
* @param todo Bitmask of actions to take on completion.
@@ -482,6 +516,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(
old_wearable,
trunc_name);
+
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
@@ -1804,7 +1839,16 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
LLAssetType::EType asset_type = wearable->getAssetType();
LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
- LLPointer<LLInventoryCallback> cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;
+ LLPointer<LLInventoryCallback> cb;
+ if(wear)
+ {
+ cb = new LLBoostFuncInventoryCallback(wear_and_edit_cb);
+ }
+ else
+ {
+ cb = new LLBoostFuncInventoryCallback(wear_cb);
+ }
+
LLUUID folder_id;
if (parent_id.notNull())
@@ -1817,10 +1861,15 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
folder_id = gInventory.findCategoryUUIDForType(folder_type);
}
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, wearable->getTransactionID(), wearable->getName(),
- wearable->getDescription(), asset_type, inv_type, wearable->getType(),
- wearable->getPermissions().getMaskNextOwner(),
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ folder_id,
+ wearable->getTransactionID(),
+ wearable->getName(),
+ wearable->getDescription(),
+ asset_type, inv_type,
+ wearable->getType(),
+ LLFloaterPerms::getNextOwnerPerms("Wearables"),
cb);
}
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 91251ed7c0..988058aad3 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -40,6 +40,11 @@
[super dealloc];
}
+- (void) applicationWillFinishLaunching:(NSNotification *)notification
+{
+ [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
+}
+
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
frameTimer = nil;
@@ -55,7 +60,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
- [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
+ // [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}
- (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index da1609297e..c5e98915fc 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1431,6 +1431,18 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
uuids_to_remove.push_back(item->getUUID());
}
removeItemsFromAvatar(uuids_to_remove);
+
+ // deactivate all gestures in the outfit folder
+ LLInventoryModel::item_array_t gest_items;
+ getDescendentsOfAssetType(cat_id, gest_items, LLAssetType::AT_GESTURE, false);
+ for(S32 i = 0; i < gest_items.count(); ++i)
+ {
+ LLViewerInventoryItem *gest_item = gest_items.get(i);
+ if ( LLGestureMgr::instance().isGestureActive( gest_item->getLinkedUUID()) )
+ {
+ LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
+ }
+ }
}
// Create a copy of src_id + contents as a subfolder of dst_id.
@@ -3414,6 +3426,7 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
{
llwarns << "called with empty list, nothing to do" << llendl;
}
+
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
const LLUUID& id_to_remove = *it;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 539d186441..11eaa7d684 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -40,6 +40,7 @@
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentlanguage.h"
+#include "llagentui.h"
#include "llagentwearables.h"
#include "llfloaterimcontainer.h"
#include "llwindow.h"
@@ -60,6 +61,7 @@
#include "llcurl.h"
#include "llcalc.h"
#include "llconversationlog.h"
+#include "lldxhardware.h"
#include "lltexturestats.h"
#include "lltexturestats.h"
#include "llviewerwindow.h"
@@ -75,10 +77,10 @@
#include "lluicolortable.h"
#include "llurldispatcher.h"
#include "llurlhistory.h"
-//#include "llfirstuse.h"
#include "llrender.h"
#include "llteleporthistory.h"
#include "lltoast.h"
+#include "llsdutil_math.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
#include "llvector4a.h"
@@ -689,9 +691,26 @@ LLAppViewer::LLAppViewer() :
llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl;
}
- setupErrorHandling();
+ mDumpPath ="";
+
+ // Need to do this initialization before we do anything else, since anything
+ // that touches files should really go through the lldir API
+ gDirUtilp->initAppDirs("SecondLife");
+ //
+ // IMPORTANT! Do NOT put anything that will write
+ // into the log files during normal startup until AFTER
+ // we run the "program crashed last time" error handler below.
+ //
sInstance = this;
+
gLoggedInTime.stop();
+
+ initLoggingAndGetLastDuration();
+
+ processMarkerFiles();
+ //
+ // OK to write stuff to logs now, we've now crash reported if necessary
+ //
LLLoginInstance::instance().setUpdaterService(mUpdater.get());
LLLoginInstance::instance().setPlatformInfo(gPlatform, getOSInfo().getOSVersionString());
@@ -705,9 +724,9 @@ LLAppViewer::~LLAppViewer()
LLLoginInstance::instance().setUpdaterService(0);
destroyMainloopTimeout();
-
+
// If we got to this destructor somehow, the app didn't hang.
- removeMarkerFile();
+ removeMarkerFiles();
}
class LLUITranslationBridge : public LLTranslationBridge
@@ -721,13 +740,11 @@ public:
bool LLAppViewer::init()
{
+ setupErrorHandling(mSecondInstance);
+
//
// Start of the application
//
- // IMPORTANT! Do NOT put anything that will write
- // into the log files during normal startup until AFTER
- // we run the "program crashed last time" error handler below.
- //
LLFastTimer::reset();
@@ -745,21 +762,15 @@ bool LLAppViewer::init()
//initialize particle index pool
LLVOPartGroup::initClass();
- // Need to do this initialization before we do anything else, since anything
- // that touches files should really go through the lldir API
- gDirUtilp->initAppDirs("SecondLife");
// set skin search path to default, will be overridden later
// this allows simple skinned file lookups to work
gDirUtilp->setSkinFolder("default", "en");
- initLoggingAndGetLastDuration();
+// initLoggingAndGetLastDuration();
- processMarkerFiles();
-
//
// OK to write stuff to logs now, we've now crash reported if necessary
//
-
init_default_trans_args();
if (!initConfiguration())
@@ -772,11 +783,13 @@ bool LLAppViewer::init()
LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
LLPrivateMemoryPoolManager::initClass((BOOL)gSavedSettings.getBOOL("MemoryPrivatePoolEnabled"), (U32)gSavedSettings.getU32("MemoryPrivatePoolSize")*1024*1024) ;
-
- // write Google Breakpad minidump files to our log directory
- std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
- logdir += gDirUtilp->getDirDelimiter();
+ // write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ mDumpPath = logdir;
setMiniDumpDir(logdir);
+ logdir += gDirUtilp->getDirDelimiter();
+ setDebugFileNames(logdir);
+
// Although initLoggingAndGetLastDuration() is the right place to mess with
// setFatalFunction(), we can't query gSavedSettings until after
@@ -1230,8 +1243,8 @@ void LLAppViewer::checkMemory()
}
mMemCheckTimer.reset() ;
- //update the availability of memory
- LLMemory::updateMemoryInfo() ;
+ //update the availability of memory
+ LLMemory::updateMemoryInfo() ;
bool is_low = LLMemory::isMemoryPoolLow() ;
@@ -1761,7 +1774,7 @@ bool LLAppViewer::cleanup()
gAudiop->setStreamingAudioImpl(NULL);
// shut down the audio subsystem
- gAudiop->shutdown();
+ gAudiop->shutdown();
delete gAudiop;
gAudiop = NULL;
@@ -1928,8 +1941,6 @@ bool LLAppViewer::cleanup()
llinfos << "Purging all cache files on exit" << llendflush;
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
}
-
- removeMarkerFile(); // Any crashes from here on we'll just have to ignore
writeDebugInfo();
@@ -2086,10 +2097,14 @@ bool LLAppViewer::cleanup()
ll_close_fail_log();
+ removeMarkerFiles();
+
MEM_TRACK_RELEASE
llinfos << "Goodbye!" << llendflush;
+ removeDumpDir();
+
// return 0;
return true;
}
@@ -2179,7 +2194,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
// Get name of the log file
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
"SecondLife.log");
- /*
+ /*
* Before touching any log files, compute the duration of the last run
* by comparing the ctime of the previous start marker file with the ctime
* of the last log file.
@@ -2579,7 +2594,7 @@ bool LLAppViewer::initConfiguration()
}
if (clp.hasOption("logevents")) {
- LLViewerEventRecorder::instance().setEventLoggingOn();
+ LLViewerEventRecorder::instance().setEventLoggingOn();
}
std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
@@ -2661,8 +2676,8 @@ bool LLAppViewer::initConfiguration()
if(start_slurl.getType() == LLSLURL::LOCATION)
{
LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
- }
- }
+ }
+ }
//RN: if we received a URL, hand it off to the existing instance.
// don't call anotherInstanceRunning() when doing URL handoff, as
@@ -2704,38 +2719,6 @@ bool LLAppViewer::initConfiguration()
mYieldTime = gSavedSettings.getS32("YieldTime");
- // Read skin/branding settings if specified.
- //if (! gDirUtilp->getSkinDir().empty() )
- //{
- // std::string skin_def_file = gDirUtilp->findSkinnedFilename("skin.xml");
- // LLXmlTree skin_def_tree;
-
- // if (!skin_def_tree.parseFile(skin_def_file))
- // {
- // llerrs << "Failed to parse skin definition." << llendl;
- // }
-
- //}
-
-#if LL_DARWIN
-
-#if __ppc__
- // If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further.
- // Only test PowerPC - all Intel Macs have SSE.
- if(!gSysCPU.hasAltivec())
- {
- std::ostringstream msg;
- msg << LLTrans::getString("MBRequiresAltiVec");
- OSMessageBox(
- msg.str(),
- LLStringUtil::null,
- OSMB_OK);
- removeMarkerFile();
- return false;
- }
-#endif
-
-#endif // LL_DARWIN
// Display splash screen. Must be after above check for previous
// crash as this dialog is always frontmost.
@@ -2806,10 +2789,6 @@ bool LLAppViewer::initConfiguration()
disable_voice->setValue(LLSD(TRUE), DO_NOT_PERSIST);
}
}
- else
- {
- checkForCrash();
- }
// NextLoginLocation is set from the command line option
std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
@@ -3113,19 +3092,6 @@ void LLAppViewer::initUpdater()
updater_pump.listen("notify_update", &notify_update);
}
-void LLAppViewer::checkForCrash(void)
-{
-#if LL_SEND_CRASH_REPORTS
- if (gLastExecEvent == LAST_EXEC_FROZE)
- {
- llinfos << "Last execution froze, sending a crash report." << llendl;
-
- bool report_freeze = true;
- handleCrashReporting(report_freeze);
- }
-#endif // LL_SEND_CRASH_REPORTS
-}
-
//
// This function decides whether the client machine meets the minimum requirements to
// run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011.
@@ -3252,15 +3218,200 @@ bool LLAppViewer::initWindow()
return true;
}
-void LLAppViewer::writeDebugInfo()
+void LLAppViewer::writeDebugInfo(bool isStatic)
{
- std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
- llinfos << "Opening debug file " << debug_filename << llendl;
- llofstream out_file(debug_filename);
- LLSDSerialize::toPrettyXML(gDebugInfo, out_file);
+ //Try to do the minimum when writing data during a crash.
+ std::string* debug_filename;
+ debug_filename = ( isStatic
+ ? getStaticDebugFile()
+ : getDynamicDebugFile() );
+
+ llinfos << "Opening debug file " << *debug_filename << llendl;
+ llofstream out_file(*debug_filename);
+
+ isStatic ? LLSDSerialize::toPrettyXML(gDebugInfo, out_file)
+ : LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file);
+
+
out_file.close();
}
+LLSD LLAppViewer::getViewerInfo() const
+{
+ // The point of having one method build an LLSD info block and the other
+ // construct the user-visible About string is to ensure that the same info
+ // is available to a getInfo() caller as to the user opening
+ // LLFloaterAbout.
+ LLSD info;
+ LLSD version;
+ version.append(LLVersionInfo::getMajor());
+ version.append(LLVersionInfo::getMinor());
+ version.append(LLVersionInfo::getPatch());
+ version.append(LLVersionInfo::getBuild());
+ info["VIEWER_VERSION"] = version;
+ info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
+ info["BUILD_DATE"] = __DATE__;
+ info["BUILD_TIME"] = __TIME__;
+ info["CHANNEL"] = LLVersionInfo::getChannel();
+
+ // return a URL to the release notes for this viewer, such as:
+ // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
+ std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
+ if (! LLStringUtil::endsWith(url, "/"))
+ url += "/";
+ url += LLURI::escape(LLVersionInfo::getChannel()) + "/";
+ url += LLURI::escape(LLVersionInfo::getVersion());
+
+ info["VIEWER_RELEASE_NOTES_URL"] = url;
+
+#if LL_MSVC
+ info["COMPILER"] = "MSVC";
+ info["COMPILER_VERSION"] = _MSC_VER;
+#elif LL_GNUC
+ info["COMPILER"] = "GCC";
+ info["COMPILER_VERSION"] = GCC_VERSION;
+#endif
+
+ // Position
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ LLVector3d pos = gAgent.getPositionGlobal();
+ info["POSITION"] = ll_sd_from_vector3d(pos);
+ info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
+ info["REGION"] = gAgent.getRegion()->getName();
+ info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
+ info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
+ info["SERVER_VERSION"] = gLastVersionChannel;
+ LLSLURL slurl;
+ LLAgentUI::buildSLURL(slurl);
+ info["SLURL"] = slurl.getSLURLString();
+ }
+
+ // CPU
+ info["CPU"] = gSysCPU.getCPUString();
+ info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB() / 1024);
+ // Moved hack adjustment to Windows memory size into llsys.cpp
+ info["OS_VERSION"] = LLAppViewer::instance()->getOSInfo().getOSString();
+ info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR));
+ info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER));
+
+#if LL_WINDOWS
+ LLSD driver_info = gDXHardware.getDisplayInfo();
+ if (driver_info.has("DriverVersion"))
+ {
+ info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
+ }
+#endif
+
+ info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
+ info["LIBCURL_VERSION"] = LLCurl::getVersionString();
+ info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
+ bool want_fullname = true;
+ info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
+ if(LLVoiceClient::getInstance()->voiceEnabled())
+ {
+ LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
+ std::ostringstream version_string;
+ version_string << version.serverType << " " << version.serverVersion << std::endl;
+ info["VOICE_VERSION"] = version_string.str();
+ }
+ else
+ {
+ info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
+ }
+
+ // TODO: Implement media plugin version query
+ info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)";
+
+ if (gPacketsIn > 0)
+ {
+ info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent();
+ info["PACKETS_IN"] = F32(gPacketsIn);
+ info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
+ }
+
+ if (mServerReleaseNotesURL.empty())
+ {
+ if (gAgent.getRegion())
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData");
+ }
+ }
+ else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]";
+ }
+ else
+ {
+ info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL;
+ }
+
+ return info;
+}
+
+std::string LLAppViewer::getViewerInfoString() const
+{
+ std::ostringstream support;
+
+ LLSD info(getViewerInfo());
+
+ // Render the LLSD from getInfo() as a format_map_t
+ LLStringUtil::format_map_t args;
+
+ // allow the "Release Notes" URL label to be localized
+ args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes");
+
+ for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
+ ii != iend; ++ii)
+ {
+ if (! ii->second.isArray())
+ {
+ // Scalar value
+ if (ii->second.isUndefined())
+ {
+ args[ii->first] = LLTrans::getString("none_text");
+ }
+ else
+ {
+ // don't forget to render value asString()
+ args[ii->first] = ii->second.asString();
+ }
+ }
+ else
+ {
+ // array value: build KEY_0, KEY_1 etc. entries
+ for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n)
+ {
+ args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString();
+ }
+ }
+ }
+
+ // Now build the various pieces
+ support << LLTrans::getString("AboutHeader", args);
+ if (info.has("REGION"))
+ {
+ support << "\n\n" << LLTrans::getString("AboutPosition", args);
+ }
+ support << "\n\n" << LLTrans::getString("AboutSystem", args);
+ support << "\n";
+ if (info.has("GRAPHICS_DRIVER_VERSION"))
+ {
+ support << "\n" << LLTrans::getString("AboutDriver", args);
+ }
+ support << "\n" << LLTrans::getString("AboutLibs", args);
+ if (info.has("COMPILER"))
+ {
+ support << "\n" << LLTrans::getString("AboutCompiler", args);
+ }
+ if (info.has("PACKETS_IN"))
+ {
+ support << '\n' << LLTrans::getString("AboutTraffic", args);
+ }
+ return support.str();
+}
+
void LLAppViewer::cleanupSavedSettings()
{
gSavedSettings.setBOOL("MouseSun", FALSE);
@@ -3309,7 +3460,16 @@ void LLAppViewer::removeCacheFiles(const std::string& file_mask)
void LLAppViewer::writeSystemInfo()
{
- gDebugInfo["SLLog"] = LLError::logFileName();
+
+ if (! gDebugInfo.has("Dynamic") )
+ gDebugInfo["Dynamic"] = LLSD::emptyMap();
+
+#if LL_WINDOWS
+ gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"SecondLife.log");
+#else
+ //Not ideal but sufficient for good reporting.
+ gDebugInfo["SLLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.old"); //LLError::logFileName();
+#endif
gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
@@ -3373,9 +3533,55 @@ void LLAppViewer::writeSystemInfo()
LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL;
LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL;
+ gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
+ gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
+ gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
+ gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
+ gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
+ gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
+
writeDebugInfo(); // Save out debug_info.log early, in case of crash.
}
+#ifdef LL_WINDOWS
+//For whatever reason, in Windows when using OOP server for breakpad, the callback to get the
+//name of the dump file is not getting triggered by the breakpad library. Unfortunately they
+//also didn't see fit to provide a simple query request across the pipe to get this name either.
+//Since we are putting our output in a runtime generated directory and we know the header data in
+//the dump format, we can however use the following hack to identify our file.
+// TODO make this a member function.
+void getFileList()
+{
+ std::stringstream filenames;
+
+ typedef std::vector<std::string> vec;
+ std::string pathname = gDirUtilp->getExpandedFilename(LL_PATH_DUMP,"");
+ vec file_vec = gDirUtilp->getFilesInDir(pathname);
+ for(vec::const_iterator iter=file_vec.begin(); iter!=file_vec.end(); ++iter)
+ {
+ filenames << *iter << " ";
+ if ( ( iter->length() > 30 ) && (iter->rfind(".dmp") == (iter->length()-4) ) )
+ {
+ std::string fullname = pathname + *iter;
+ std::ifstream fdat( fullname.c_str(), std::ifstream::binary);
+ if (fdat)
+ {
+ char buf[5];
+ fdat.read(buf,4);
+ fdat.close();
+ if (!strncmp(buf,"MDMP",4))
+ {
+ gDebugInfo["Dynamic"]["MinidumpPath"] = fullname;
+ break;
+ }
+ }
+ }
+ }
+ filenames << std::endl;
+ gDebugInfo["Dynamic"]["DumpDirContents"] = filenames.str();
+}
+#endif
+
void LLAppViewer::handleViewerCrash()
{
llinfos << "Handle viewer crash entry." << llendl;
@@ -3411,73 +3617,51 @@ void LLAppViewer::handleViewerCrash()
std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
if(crashHostUrl != "")
{
- gDebugInfo["CrashHostUrl"] = crashHostUrl;
+ gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl;
}
- //We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version
- //to check against no matter what
- gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
-
- gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
- gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
- gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
- gDebugInfo["ClientInfo"]["BuildVersion"] = LLVersionInfo::getBuild();
-
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel && parcel->getMusicURL()[0])
{
- gDebugInfo["ParcelMusicURL"] = parcel->getMusicURL();
+ gDebugInfo["Dynamic"]["ParcelMusicURL"] = parcel->getMusicURL();
}
if ( parcel && parcel->getMediaURL()[0])
{
- gDebugInfo["ParcelMediaURL"] = parcel->getMediaURL();
+ gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL();
}
- gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
- gDebugInfo["CAFilename"] = gDirUtilp->getCAFile();
- gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
- gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
- gDebugInfo["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
- gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
- gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
- gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
- gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
-
- char *minidump_file = pApp->getMiniDumpFilename();
- if(minidump_file && minidump_file[0] != 0)
- {
- gDebugInfo["MinidumpPath"] = minidump_file;
- }
+ gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
+ gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
if(gLogoutInProgress)
{
- gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
+ gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
}
else
{
- gDebugInfo["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH;
+ gDebugInfo["Dynamic"]["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH;
}
if(gAgent.getRegion())
{
- gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
- gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
+ gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
const LLVector3& loc = gAgent.getPositionAgent();
- gDebugInfo["CurrentLocationX"] = loc.mV[0];
- gDebugInfo["CurrentLocationY"] = loc.mV[1];
- gDebugInfo["CurrentLocationZ"] = loc.mV[2];
+ gDebugInfo["Dynamic"]["CurrentLocationX"] = loc.mV[0];
+ gDebugInfo["Dynamic"]["CurrentLocationY"] = loc.mV[1];
+ gDebugInfo["Dynamic"]["CurrentLocationZ"] = loc.mV[2];
}
if(LLAppViewer::instance()->mMainloopTimeout)
{
- gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
+ gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
}
// The crash is being handled here so set this value to false.
// Otherwise the crash logger will think this crash was a freeze.
- gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)false;
+ gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false;
//Write out the crash status file
//Use marker file style setup, as that's the simplest, especially since
@@ -3505,10 +3689,28 @@ void LLAppViewer::handleViewerCrash()
LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
}
+#ifdef LL_WINDOWS
+ Sleep(200);
+#endif
+
+ char *minidump_file = pApp->getMiniDumpFilename();
+
+ if(minidump_file && minidump_file[0] != 0)
+ {
+ gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file;
+ }
+#ifdef LL_WINDOWS
+ else
+ {
+ getFileList();
+ }
+#endif
+ gDebugInfo["Dynamic"]["CrashType"]="crash";
+
if (gMessageSystem && gDirUtilp)
{
std::string filename;
- filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "stats.log");
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "stats.log");
llofstream file(filename, llofstream::binary);
if(file.good())
{
@@ -3524,29 +3726,10 @@ void LLAppViewer::handleViewerCrash()
gMessageSystem->stopLogging();
}
- if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo);
+ if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]);
// Close the debug file
- pApp->writeDebugInfo();
-
- LLError::logToFile("");
-
- // Remove the marker file, since otherwise we'll spawn a process that'll keep it locked
- if(gDebugInfo["LastExecEvent"].asInteger() == LAST_EXEC_LOGOUT_CRASH)
- {
- pApp->removeMarkerFile(true);
- }
- else
- {
- pApp->removeMarkerFile(false);
- }
-
-#if LL_SEND_CRASH_REPORTS
- // Call to pure virtual, handled by platform specific llappviewer instance.
- pApp->handleCrashReporting();
-#endif
-
- return;
+ pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead.
}
// static
@@ -3743,33 +3926,30 @@ void LLAppViewer::processMarkerFiles()
}
}
-void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
+void LLAppViewer::removeMarkerFiles()
{
if (!mSecondInstance)
{
- LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL;
if (mMarkerFile.getFileHandle())
{
- LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
mMarkerFile.close() ;
LLAPRFile::remove( mMarkerFileName );
+ LL_DEBUGS("MarkerFile") << "removed exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
}
else
{
LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
- }
- if (!leave_logout_marker)
+ }
+
+ if (mLogoutMarkerFile.getFileHandle())
{
- if (mLogoutMarkerFile.getFileHandle())
- {
- LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
- mLogoutMarkerFile.close();
- }
- else
- {
- LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
- }
+ mLogoutMarkerFile.close();
LLAPRFile::remove( mLogoutMarkerFileName );
+ LL_DEBUGS("MarkerFile") << "removed logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
}
}
else
@@ -3778,6 +3958,14 @@ void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
}
}
+void LLAppViewer::removeDumpDir()
+{
+ //Call this routine only on clean exit. Crash reporter will clean up
+ //its locking table for us.
+ std::string dump_dir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ gDirUtilp->deleteDirAndContents(dump_dir);
+}
+
void LLAppViewer::forceQuit()
{
LLApp::setQuitting();
@@ -3795,7 +3983,7 @@ void LLAppViewer::fastQuit(S32 error_code)
// figure out the error code
S32 final_error_code = error_code ? error_code : (S32)isError();
// this isn't a crash
- removeMarkerFile();
+ removeMarkerFiles();
// get outta here
_exit(final_error_code);
}
@@ -4593,7 +4781,7 @@ void LLAppViewer::idle()
static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD);
// Update session stats every large chunk of time
- // *FIX: (???) SAMANTHA
+ // *FIX: (?) SAMANTHA
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
llinfos << "Transmitting sessions stats" << llendl;
@@ -4713,7 +4901,7 @@ void LLAppViewer::idle()
if (!(logoutRequestSent() && hasSavedFinalSnapshot()))
{
- gObjectList.update(gAgent, *LLWorld::getInstance());
+ gObjectList.update(gAgent);
}
}
@@ -4973,20 +5161,26 @@ void LLAppViewer::sendLogoutRequest()
{
//Set internal status variables and marker files before actually starting the logout process
gLogoutInProgress = TRUE;
- mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
-
- LLAPRFile outfile ;
- mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
- if (mLogoutMarkerFile.getFileHandle())
+ if (!mSecondInstance)
{
- LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
- recordMarkerVersion(outfile);
+ mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
+
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_WB);
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << LL_ENDL;
+ recordMarkerVersion(mLogoutMarkerFile);
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
+ }
}
else
{
- LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
- }
-
+ LL_INFOS("MarkerFile") << "Did not logout marker file because this is a second instance" << LL_ENDL;
+ }
+
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_LogoutRequest);
msg->nextBlockFast(_PREHASH_AgentData);
@@ -5402,7 +5596,7 @@ void LLAppViewer::handleLoginComplete()
void LLAppViewer::launchUpdater()
{
- LLSD query_map = LLSD::emptyMap();
+ LLSD query_map = LLSD::emptyMap();
query_map["os"] = gPlatform;
// *TODO change userserver to be grid on both viewer and sim, since
@@ -5464,7 +5658,7 @@ void LLAppViewer::launchUpdater()
LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
//Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
- LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
+ LLAppViewer::instance()->removeMarkerFiles(); // In case updater fails
// *NOTE:Mani The updater is spawned as the last thing before the WinMain exit.
// see LLAppViewerWin32.cpp
@@ -5599,7 +5793,7 @@ void LLAppViewer::metricsSend(bool enable_reporting)
// Make a copy of the main stats to send into another thread.
// Receiving thread takes ownership.
LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain));
-
+
// Send a report request into 'thread1' to get the rest of the data
// and provide some additional parameters while here.
LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 3ae8a78845..25b5c90bb0 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -46,7 +46,6 @@ class LLViewerJoystick;
extern LLFastTimer::DeclareTimer FTM_FRAME;
-
class LLAppViewer : public LLApp
{
public:
@@ -81,17 +80,22 @@ public:
bool quitRequested() { return mQuitRequested; }
bool logoutRequestSent() { return mLogoutRequestSent; }
+ bool isSecondInstance() { return mSecondInstance; }
- void writeDebugInfo();
+ void writeDebugInfo(bool isStatic=true);
const LLOSInfo& getOSInfo() const { return mSysOSInfo; }
+ void setServerReleaseNotesURL(const std::string& url) { mServerReleaseNotesURL = url; }
+ LLSD getViewerInfo() const;
+ std::string getViewerInfoString() const;
+
// Report true if under the control of a debugger. A null-op default.
virtual bool beingDebugged() { return false; }
virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism.
// return false if the error trap needed restoration.
- virtual void handleCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report?
+ virtual void initCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report?
static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon.
void checkForCrash();
@@ -119,8 +123,9 @@ public:
void loadNameCache();
void saveNameCache();
- void removeMarkerFile(bool leave_logout_marker = false);
+ void removeMarkerFiles();
+ void removeDumpDir();
// LLAppViewer testing helpers.
// *NOTE: These will potentially crash the viewer. Only for debugging.
virtual void forceErrorLLError();
@@ -246,6 +251,8 @@ private:
LLOSInfo mSysOSInfo;
bool mReportedCrash;
+ std::string mServerReleaseNotesURL;
+
// Thread objects.
static LLTextureCache* sTextureCache;
static LLImageDecodeThread* sImageDecodeThread;
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index b16bb573e1..11fcf0018e 100755
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -58,12 +58,15 @@ namespace
void (*gOldTerminateHandler)() = NULL;
}
+
static void exceptionTerminateHandler()
{
// reinstall default terminate() handler in case we re-terminate.
if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);
// treat this like a regular viewer crash, with nice stacktrace etc.
- LLAppViewer::handleViewerCrash();
+ long *null_ptr;
+ null_ptr = 0;
+ *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
// we've probably been killed-off before now, but...
gOldTerminateHandler(); // call old terminate() handler
}
@@ -127,7 +130,17 @@ bool LLAppViewerLinux::init()
// really early in app startup!
if (!g_thread_supported ()) g_thread_init (NULL);
- return LLAppViewer::init();
+ bool success = LLAppViewer::init();
+
+#if LL_SEND_CRASH_REPORTS
+ if (success)
+ {
+ LLAppViewer* pApp = LLAppViewer::instance();
+ pApp->initCrashReporting();
+ }
+#endif
+
+ return success;
}
bool LLAppViewerLinux::restoreErrorTrap()
@@ -319,7 +332,7 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)
}
#endif // LL_DBUS_ENABLED
-void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
+void LLAppViewerLinux::initCrashReporting(bool reportFreeze)
{
std::string cmd =gDirUtilp->getExecutableDir();
cmd += gDirUtilp->getDirDelimiter();
@@ -331,69 +344,52 @@ void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)
# error Unknown platform
#endif
- if(reportFreeze)
- {
- char* const cmdargv[] =
- {(char*)cmd.c_str(),
- (char*)"-previous",
- NULL};
-
- fflush(NULL); // flush all buffers before the child inherits them
- pid_t pid = fork();
- if (pid == 0)
- { // child
- execv(cmd.c_str(), cmdargv); /* Flawfinder: Ignore */
- llwarns << "execv failure when trying to start " << cmd << llendl;
- _exit(1); // avoid atexit()
- } else {
- if (pid > 0)
- {
- // wait for child proc to die
- int childExitStatus;
- waitpid(pid, &childExitStatus, 0);
- } else {
- llwarns << "fork failure." << llendl;
- }
- }
- }
+ std::stringstream pid_str;
+ pid_str << LLApp::getPid();
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ std::string appname = gDirUtilp->getExecutableFilename();
+ // launch the actual crash logger
+ const char * cmdargv[] =
+ {cmd.c_str(),
+ "-user",
+ (char*)LLGridManager::getInstance()->getGridId().c_str(),
+ "-name",
+ LLAppViewer::instance()->getSecondLifeTitle().c_str(),
+ "-pid",
+ pid_str.str().c_str(),
+ "-dumpdir",
+ logdir.c_str(),
+ "-procname",
+ appname.c_str(),
+ NULL};
+ fflush(NULL);
+
+ pid_t pid = fork();
+ if (pid == 0)
+ { // child
+ execv(cmd.c_str(), (char* const*) cmdargv); /* Flawfinder: ignore */
+ llwarns << "execv failure when trying to start " << cmd << llendl;
+ _exit(1); // avoid atexit()
+ }
else
{
- // launch the actual crash logger
- const char * cmdargv[] =
- {cmd.c_str(),
- "-user",
- (char*)LLGridManager::getInstance()->getGridId().c_str(),
- "-name",
- LLAppViewer::instance()->getSecondLifeTitle().c_str(),
- NULL};
- fflush(NULL);
- pid_t pid = fork();
- if (pid == 0)
- { // child
- execv(cmd.c_str(), (char* const*) cmdargv); /* Flawfinder: ignore */
- llwarns << "execv failure when trying to start " << cmd << llendl;
- _exit(1); // avoid atexit()
+ if (pid > 0)
+ {
+ // DO NOT wait for child proc to die; we want
+ // the logger to outlive us while we quit to
+ // free up the screen/keyboard/etc.
+ ////int childExitStatus;
+ ////waitpid(pid, &childExitStatus, 0);
}
else
{
- if (pid > 0)
- {
- // DO NOT wait for child proc to die; we want
- // the logger to outlive us while we quit to
- // free up the screen/keyboard/etc.
- ////int childExitStatus;
- ////waitpid(pid, &childExitStatus, 0);
- }
- else
- {
- llwarns << "fork failure." << llendl;
- }
+ llwarns << "fork failure." << llendl;
}
- // Sometimes signals don't seem to quit the viewer. Also, we may
- // have been called explicitly instead of from a signal handler.
- // Make sure we exit so as to not totally confuse the user.
- _exit(1); // avoid atexit(), else we may re-crash in dtors.
}
+ // Sometimes signals don't seem to quit the viewer. Also, we may
+ // have been called explicitly instead of from a signal handler.
+ // Make sure we exit so as to not totally confuse the user.
+ //_exit(1); // avoid atexit(), else we may re-crash in dtors.
}
bool LLAppViewerLinux::beingDebugged()
diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h
index fb77600c10..0289c43043 100755
--- a/indra/newview/llappviewerlinux.h
+++ b/indra/newview/llappviewerlinux.h
@@ -61,7 +61,7 @@ protected:
virtual bool beingDebugged();
virtual bool restoreErrorTrap();
- virtual void handleCrashReporting(bool reportFreeze);
+ virtual void initCrashReporting(bool reportFreeze);
virtual void initLoggingAndGetLastDuration();
virtual bool initParseCommandLine(LLCommandLineParser& clp);
diff --git a/indra/newview/llappviewermacosx-objc.h b/indra/newview/llappviewermacosx-objc.h
new file mode 100644
index 0000000000..c6dcec8e34
--- /dev/null
+++ b/indra/newview/llappviewermacosx-objc.h
@@ -0,0 +1,36 @@
+/**
+ * @file llappviewermacosx.h
+ * @brief The LLAppViewerMacOSX class declaration
+ *
+ * $LicenseInfo:firstyear=2007&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_LLAPPVIEWERMACOSX_OBJC_H
+#define LL_LLAPPVIEWERMACOSX_OBJC_H
+
+#include <string>
+#include <vector>
+
+//Why? Because BOOL
+void launchApplication(const std::string* app_name, const std::vector<std::string>* args);
+
+#endif // LL_LLAPPVIEWERMACOSX_OBJC_H
diff --git a/indra/newview/llappviewermacosx-objc.mm b/indra/newview/llappviewermacosx-objc.mm
new file mode 100644
index 0000000000..17301847e8
--- /dev/null
+++ b/indra/newview/llappviewermacosx-objc.mm
@@ -0,0 +1,73 @@
+/**
+ * @file llappviewermacosx-objc.mm
+ * @brief Functions related to LLAppViewerMacOSX that must be expressed in obj-c
+ *
+ * $LicenseInfo:firstyear=2007&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$
+ */
+
+#if !defined LL_DARWIN
+ #error "Use only with Mac OS X"
+#endif
+
+#import <Cocoa/Cocoa.h>
+#include <iostream>
+
+#include "llappviewermacosx-objc.h"
+
+void launchApplication(const std::string* app_name, const std::vector<std::string>* args)
+{
+
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if (app_name->empty()) return;
+
+ NSMutableString* app_name_ns = [NSMutableString stringWithString:[[NSBundle mainBundle] resourcePath]]; //Path to resource dir
+ [app_name_ns appendFormat:@"/%@", [NSString stringWithCString:app_name->c_str()
+ encoding:[NSString defaultCStringEncoding]]];
+
+ NSMutableArray *args_ns = nil;
+ args_ns = [[NSMutableArray alloc] init];
+
+ for (int i=0; i < args->size(); ++i)
+ {
+ NSLog(@"Adding string %s", (*args)[i].c_str());
+ [args_ns addObject:
+ [NSString stringWithCString:(*args)[i].c_str()
+ encoding:[NSString defaultCStringEncoding]]];
+ }
+
+ NSTask *task = [[NSTask alloc] init];
+ NSBundle *bundle = [NSBundle bundleWithPath:[[NSWorkspace sharedWorkspace] fullPathForApplication:app_name_ns]];
+ [task setLaunchPath:[bundle executablePath]];
+ [task setArguments:args_ns];
+ [task launch];
+
+// NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+// NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:app_name_ns]];
+//
+// NSError *error = nil;
+// [workspace launchApplicationAtURL:url options:0 configuration:[NSDictionary dictionaryWithObject:args_ns forKey:NSWorkspaceLaunchConfigurationArguments] error:&error];
+ //TODO Handle error
+
+ [pool release];
+ return;
+}
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 2723f0b90d..c6d45cf4d6 100755
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -32,6 +32,9 @@
#define LL_CARBON_CRASH_HANDLER 1
+#include "llwindowmacosx.h"
+#include "llappviewermacosx-objc.h"
+
#include "llappviewermacosx.h"
#include "llwindowmacosx-objc.h"
#include "llcommandlineparser.h"
@@ -45,6 +48,9 @@
#ifdef LL_CARBON_CRASH_HANDLER
#include <Carbon/Carbon.h>
#endif
+#include <vector>
+#include <exception>
+
#include "lldir.h"
#include <signal.h>
#include <CoreAudio/CoreAudio.h> // for systemwide mute
@@ -56,7 +62,6 @@ namespace
// They are not used immediately by the app.
int gArgC;
char** gArgV;
- bool sCrashReporterIsRunning = false;
LLAppViewerMacOSX* gViewerAppPtr;
#ifdef LL_CARBON_CRASH_HANDLER
OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
@@ -68,6 +73,20 @@ namespace
return(result);
}
#endif
+ void (*gOldTerminateHandler)() = NULL;
+}
+
+static void exceptionTerminateHandler()
+{
+ // reinstall default terminate() handler in case we re-terminate.
+ if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);
+ // treat this like a regular viewer crash, with nice stacktrace etc.
+ long *null_ptr;
+ null_ptr = 0;
+ *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
+ //LLAppViewer::handleViewerCrash();
+ // we've probably been killed-off before now, but...
+ gOldTerminateHandler(); // call old terminate() handler
}
bool initViewer()
@@ -83,19 +102,21 @@ bool initViewer()
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
<< llendl;
}
-
+
gViewerAppPtr = new LLAppViewerMacOSX();
-
+
+ // install unexpected exception handler
+ gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
+
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
-
-
+
bool ok = gViewerAppPtr->init();
if(!ok)
{
llwarns << "Application init failed." << llendl;
}
-
+
return ok;
}
@@ -121,7 +142,8 @@ void cleanupViewer()
{
if(!LLApp::isError())
{
- gViewerAppPtr->cleanup();
+ if (gViewerAppPtr)
+ gViewerAppPtr->cleanup();
}
delete gViewerAppPtr;
@@ -146,7 +168,17 @@ LLAppViewerMacOSX::~LLAppViewerMacOSX()
bool LLAppViewerMacOSX::init()
{
- return LLAppViewer::init();
+ bool success = LLAppViewer::init();
+
+#if LL_SEND_CRASH_REPORTS
+ if (success)
+ {
+ LLAppViewer* pApp = LLAppViewer::instance();
+ pApp->initCrashReporting();
+ }
+#endif
+
+ return success;
}
// MacOSX may add and addition command line arguement for the process serial number.
@@ -263,132 +295,17 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
return reset_count == 0;
}
-#ifdef LL_CARBON_CRASH_HANDLER
-static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,
- EventRef inEvent,
- void* inUserData)
+void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)
{
- ProcessSerialNumber psn;
-
- GetEventParameter(inEvent,
- kEventParamProcessID,
- typeProcessSerialNumber,
- NULL,
- sizeof(psn),
- NULL,
- &psn);
-
- if( GetEventKind(inEvent) == kEventAppTerminated )
- {
- Boolean matching_psn = FALSE;
- OSErr os_result = SameProcess(&psn, (ProcessSerialNumber*)inUserData, &matching_psn);
- if(os_result >= 0 && matching_psn)
- {
- sCrashReporterIsRunning = false;
- QuitApplicationEventLoop();
- }
- }
- return noErr;
-}
-#endif
-
-void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)
-{
-#ifdef LL_CARBON_CRASH_HANDLER
- // This used to use fork&exec, but is switched to LSOpenApplication to
- // Make sure the crash reporter launches in front of the SL window.
-
- std::string command_str;
- //command_str = "open Second Life.app/Contents/Resources/mac-crash-logger.app";
- command_str = "mac-crash-logger.app/Contents/MacOS/mac-crash-logger";
-
- CFURLRef urlRef = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)command_str.c_str(), strlen(command_str.c_str()), FALSE);
-
- // FSRef apparently isn't deprecated.
- // There's other funcitonality that depends on it existing as well that isn't deprecated.
- // There doesn't seem to be much to directly verify what the status of FSRef is, outside of some documentation pointing at FSRef being valid, and other documentation pointing to everything in Files.h being deprecated.
- // We'll assume it isn't for now, since all non-deprecated functions that use it seem to assume similar.
-
- FSRef appRef;
- Boolean pathstatus = CFURLGetFSRef(urlRef, &appRef);
-
- OSStatus os_result = noErr;
-
- if(pathstatus == true)
- {
- LSApplicationParameters appParams;
- memset(&appParams, 0, sizeof(appParams));
- appParams.version = 0;
- appParams.flags = kLSLaunchNoParams | kLSLaunchStartClassic;
-
- appParams.application = &appRef;
-
- if(reportFreeze)
- {
- // Make sure freeze reporting launches the crash logger synchronously, lest
- // Log files get changed by SL while the logger is running.
-
- // *NOTE:Mani A better way - make a copy of the data that the crash reporter will send
- // and let SL go about its business. This way makes the mac work like windows and linux
- // and is the smallest patch for the issue.
- sCrashReporterIsRunning = false;
- ProcessSerialNumber o_psn;
-
- static EventHandlerRef sCarbonEventsRef = NULL;
- static const EventTypeSpec kEvents[] =
- {
- { kEventClassApplication, kEventAppTerminated }
- };
-
- // Install the handler to detect crash logger termination
- InstallEventHandler(GetApplicationEventTarget(),
- (EventHandlerUPP) CarbonEventHandler,
- GetEventTypeCount(kEvents),
- kEvents,
- &o_psn,
- &sCarbonEventsRef
- );
-
- // Remove, temporarily the quit handler - which has *crash* behavior before
- // the mainloop gets running!
- AERemoveEventHandler(kCoreEventClass,
- kAEQuitApplication,
- NewAEEventHandlerUPP(AEQuitHandler),
- false);
-
- // Launch the crash reporter.
- os_result = LSOpenApplication(&appParams, &o_psn);
-
- if(os_result >= 0)
- {
- sCrashReporterIsRunning = true;
- }
-
- while(sCrashReporterIsRunning)
- {
- RunApplicationEventLoop();
- }
-
- // Re-install the apps quit handler.
- AEInstallEventHandler(kCoreEventClass,
- kAEQuitApplication,
- NewAEEventHandlerUPP(AEQuitHandler),
- 0,
- false);
-
- // Remove the crash reporter quit handler.
- RemoveEventHandler(sCarbonEventsRef);
- }
- else
- {
- appParams.flags |= kLSLaunchAsync;
- clear_signals();
-
- ProcessSerialNumber o_psn;
- os_result = LSOpenApplication(&appParams, &o_psn);
- }
- }
-#endif
+ std::string command_str = "mac-crash-logger.app";
+
+ std::stringstream pid_str;
+ pid_str << LLApp::getPid();
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ std::string appname = gDirUtilp->getExecutableFilename();
+ std::string str[] = { "-pid", pid_str.str(), "-dumpdir", logdir, "-procname", appname.c_str() };
+ std::vector< std::string > args( str, str + ( sizeof ( str ) / sizeof ( std::string ) ) );
+ launchApplication(&command_str, &args);
}
std::string LLAppViewerMacOSX::generateSerialNumber()
diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h
index 25053da5e8..ebb41a495c 100755
--- a/indra/newview/llappviewermacosx.h
+++ b/indra/newview/llappviewermacosx.h
@@ -48,7 +48,7 @@ public:
protected:
virtual bool restoreErrorTrap();
- virtual void handleCrashReporting(bool reportFreeze);
+ virtual void initCrashReporting(bool reportFreeze);
std::string generateSerialNumber();
virtual bool initParseCommandLine(LLCommandLineParser& clp);
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 80a80f4298..5585bd914c 100755..100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -65,6 +65,33 @@
#include "llwindebug.h"
#endif
+#include "stringize.h"
+
+#include <exception>
+namespace
+{
+ void (*gOldTerminateHandler)() = NULL;
+}
+
+static void exceptionTerminateHandler()
+{
+ // reinstall default terminate() handler in case we re-terminate.
+ if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);
+ // treat this like a regular viewer crash, with nice stacktrace etc.
+ long *null_ptr;
+ null_ptr = 0;
+ *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
+ //LLAppViewer::handleViewerCrash();
+ // we've probably been killed-off before now, but...
+ gOldTerminateHandler(); // call old terminate() handler
+}
+
+LONG WINAPI catchallCrashHandler(EXCEPTION_POINTERS * /*ExceptionInfo*/)
+{
+ llwarns << "Hit last ditch-effort attempt to catch crash." << llendl;
+ exceptionTerminateHandler();
+ return 0;
+}
// *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib
// The lib was compiled under VS2005 - in VS2003 we need to remap assert
@@ -200,14 +227,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
-#ifdef INCLUDE_VLD
- // only works for debug builds (hard coded into vld.h)
- #ifdef _DEBUG
- // start with Visual Leak Detector turned off
- VLDGlobalDisable();
- #endif // _DEBUG
-#endif // INCLUDE_VLD
-
const S32 MAX_HEAPS = 255;
DWORD heap_enable_lfh_error[MAX_HEAPS];
S32 num_heaps = 0;
@@ -244,8 +263,14 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(lpCmdLine);
+ gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
+
viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
+#if LL_SEND_CRASH_REPORTS
+ // ::SetUnhandledExceptionFilter(catchallCrashHandler);
+#endif
+
// Set a debug info flag to indicate if multiple instances are running.
bool found_other_instance = !create_app_mutex();
gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance);
@@ -496,7 +521,19 @@ bool LLAppViewerWin32::init()
LLWinDebug::instance().init();
#endif
- return LLAppViewer::init();
+#if LL_WINDOWS
+#if LL_SEND_CRASH_REPORTS
+
+
+ LLAppViewer* pApp = LLAppViewer::instance();
+ pApp->initCrashReporting();
+
+#endif
+#endif
+
+ bool success = LLAppViewer::init();
+
+ return success;
}
bool LLAppViewerWin32::cleanup()
@@ -635,26 +672,55 @@ bool LLAppViewerWin32::restoreErrorTrap()
//return LLWinDebug::checkExceptionHandler();
}
-void LLAppViewerWin32::handleCrashReporting(bool reportFreeze)
+void LLAppViewerWin32::initCrashReporting(bool reportFreeze)
{
+ if (isSecondInstance()) return; //BUG-5707 do not start another crash reporter for second instance.
+
const char* logger_name = "win_crash_logger.exe";
std::string exe_path = gDirUtilp->getExecutableDir();
exe_path += gDirUtilp->getDirDelimiter();
exe_path += logger_name;
- const char* arg_str = logger_name;
+ std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
+ std::string appname = gDirUtilp->getExecutableFilename();
- // *NOTE:Mani - win_crash_logger.exe no longer parses command line options.
- if(reportFreeze)
- {
- // Spawn crash logger.
- // NEEDS to wait until completion, otherwise log files will get smashed.
- _spawnl(_P_WAIT, exe_path.c_str(), arg_str, NULL);
- }
- else
- {
- _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL);
- }
+ S32 slen = logdir.length() -1;
+ S32 end = slen;
+ while (logdir.at(end) == '/' || logdir.at(end) == '\\') end--;
+
+ if (slen !=end)
+ {
+ logdir = logdir.substr(0,end+1);
+ }
+ //std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid());
+ //_spawnl(_P_NOWAIT, exe_path.c_str(), arg_str.c_str(), NULL);
+ std::string arg_str = "\"" + exe_path + "\" -dumpdir \"" + logdir + "\" -procname \"" + appname + "\" -pid " + stringize(LLApp::getPid());
+
+ STARTUPINFO startInfo={sizeof(startInfo)};
+ PROCESS_INFORMATION processInfo;
+
+ std::wstring exe_wstr;
+ exe_wstr=wstringize(exe_path);
+
+ std::wstring arg_wstr;
+ arg_wstr=wstringize(arg_str);
+
+ LL_INFOS("CrashReport") << "Creating crash reporter process " << exe_path << " with params: " << arg_str << LL_ENDL;
+ if(CreateProcess(exe_wstr.c_str(),
+ &arg_wstr[0], // Application arguments
+ 0,
+ 0,
+ FALSE,
+ CREATE_DEFAULT_ERROR_MODE,
+ 0,
+ 0, // Working directory
+ &startInfo,
+ &processInfo) == FALSE)
+ // Could not start application -> call 'GetLastError()'
+ {
+ LL_WARNS("CrashReport Launch") << "CreateProcess failed " << GetLastError() << LL_ENDL;
+ return;
+ }
}
//virtual
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index 386bddd495..fb37df1a2f 100755..100644
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -50,7 +50,7 @@ protected:
virtual bool initParseCommandLine(LLCommandLineParser& clp);
virtual bool restoreErrorTrap();
- virtual void handleCrashReporting(bool reportFreeze);
+ virtual void initCrashReporting(bool reportFreeze);
virtual bool sendURLToOtherInstance(const std::string& url);
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 70cc48f12b..307e72fe18 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -868,6 +868,10 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
// check selection in the panel
LLFolderView* root_folder = inv_panel->getRootFolder();
+ if (!root_folder)
+ {
+ return false;
+ }
const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
if (inventory_selected.empty()) return false; // nothing selected
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 77d734cbfe..d6a72b0c05 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -256,7 +256,7 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
{
llinfos << "LRI: Sending avatar render info for " << avatar->getID()
<< ": " << info << llendl;
- llinfos << "LRI: geometry " << avatar->getAttachmentGeometryBytes()
+ llinfos << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes()
<< ", area " << avatar->getAttachmentSurfaceArea()
<< llendl;
}
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 14583e402d..91741c2a77 100755
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -115,7 +115,9 @@ LLAvatarTracker::~LLAvatarTracker()
{
deleteTrackingData();
std::for_each(mObservers.begin(), mObservers.end(), DeletePointer());
+ mObservers.clear();
std::for_each(mBuddyInfo.begin(), mBuddyInfo.end(), DeletePairedPointer());
+ mBuddyInfo.clear();
}
void LLAvatarTracker::track(const LLUUID& avatar_id, const std::string& name)
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 8b2d9e639f..fa23251d95 100755
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -113,29 +113,33 @@ void LLChannelManager::onLoginCompleted()
}
else
{
- // create a channel for the StartUp Toast
- LLScreenChannelBase::Params p;
- p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
- p.channel_align = CA_RIGHT;
- mStartUpChannel = createChannel(p);
-
- if(!mStartUpChannel)
- {
- onStartUpToastClose();
- }
- else
- {
- gViewerWindow->getRootView()->addChild(mStartUpChannel);
-
- // init channel's position and size
- S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
- mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
-
- mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
- mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
- }
+ // TODO: Seems this code leads to MAINT-3536 new crash in XML_ParserFree.
+ // Need to investigate this and fix possible problems with notifications in startup time
+ // Viewer can normally receive and show of postponed notifications about purchasing in marketplace on startup time.
+ // Other types of postponed notifications did not tested.
+ //// create a channel for the StartUp Toast
+ //LLScreenChannelBase::Params p;
+ //p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
+ //p.channel_align = CA_RIGHT;
+ //mStartUpChannel = createChannel(p);
+
+ //if(!mStartUpChannel)
+ //{
+ // onStartUpToastClose();
+ //}
+ //else
+ //{
+ // gViewerWindow->getRootView()->addChild(mStartUpChannel);
+
+ // // init channel's position and size
+ // S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ // S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
+ // mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
+ // mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
+
+ // mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
+ // mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
+ //}
}
LLPersistentNotificationStorage::getInstance()->loadNotifications();
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 2eb4074c97..abeaf958eb 100755
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -187,6 +187,10 @@ public:
{
LLAvatarActions::offerTeleport(getAvatarId());
}
+ else if (level == "request_teleport")
+ {
+ LLAvatarActions::teleportRequest(getAvatarId());
+ }
else if (level == "voice_call")
{
LLAvatarActions::startCall(getAvatarId());
@@ -547,7 +551,9 @@ protected:
menu->setItemEnabled("Send IM", false);
menu->setItemEnabled("Remove Friend", false);
menu->setItemEnabled("Offer Teleport",false);
+ menu->setItemEnabled("Request Teleport",false);
menu->setItemEnabled("Voice Call", false);
+ menu->setItemEnabled("Chat History", false);
menu->setItemEnabled("Invite Group", false);
menu->setItemEnabled("Zoom In", false);
menu->setItemEnabled("Share", false);
@@ -563,6 +569,7 @@ protected:
menu->setItemVisible("Send IM", false);
}
menu->setItemEnabled("Offer Teleport", LLAvatarActions::canOfferTeleport(mAvatarID));
+ menu->setItemEnabled("Request Teleport", LLAvatarActions::canOfferTeleport(mAvatarID));
menu->setItemEnabled("Voice Call", LLAvatarActions::canCall());
// We should only show 'Zoom in' item in a nearby chat
@@ -570,9 +577,9 @@ protected:
menu->setItemVisible("Zoom In", should_show_zoom && gObjectList.findObject(mAvatarID));
menu->setItemEnabled("Block Unblock", LLAvatarActions::canBlock(mAvatarID));
menu->setItemEnabled("Mute Text", LLAvatarActions::canBlock(mAvatarID));
+ menu->setItemEnabled("Chat History", LLLogChat::isTranscriptExist(mAvatarID));
}
- menu->setItemEnabled("Chat History", LLLogChat::isTranscriptExist(mAvatarID));
menu->setItemEnabled("Map", (LLAvatarTracker::instance().isBuddyOnline(mAvatarID) && is_agent_mappable(mAvatarID)) || gAgent.isGodlike() );
menu->buildDrawLabels();
menu->updateParent(LLMenuGL::sMenuContainer);
@@ -724,6 +731,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
editor_params.follows.flags = FOLLOWS_ALL;
editor_params.enabled = false; // read only
editor_params.show_context_menu = "true";
+ editor_params.trusted_content = false;
mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
mEditor->setIsFriendCallback(LLAvatarActions::isFriend);
}
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index e86d6930e8..e200e0ee9e 100755
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -43,7 +43,7 @@
#include "llpaneloutfitedit.h"
#include "lltrans.h"
-static LLRegisterPanelClassWrapper<LLCOFWearables> t_cof_wearables("cof_wearables");
+static LLPanelInjector<LLCOFWearables> t_cof_wearables("cof_wearables");
const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 82d3fe74c0..90800fee58 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -267,7 +267,6 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
//This node (conversation) was selected and a child (participant) was not
if(result && getRoot())
{
-
if(getRoot()->getCurSelectedItem() == this)
{
LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
@@ -282,7 +281,6 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
{
im_container->collapseMessagesPane(false);
}
-
}
selectConversationItem();
}
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index 8926f64c64..0bc7ae766c 100755
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -37,8 +37,6 @@
#include "llviewershadermgr.h"
#include "llrender.h"
-#define GE_FORCE_WORKAROUND LL_DARWIN
-
static LLGLSLShader* simple_shader = NULL;
static LLGLSLShader* fullbright_shader = NULL;
@@ -660,14 +658,6 @@ void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
}
else
{
-
-// Work-around until we can figure out why the right shader causes
-// the GeForce driver to go tango uniform on OS X 10.6.8 only
-//
-#if GE_FORCE_WORKAROUND
- gObjectFullbrightAlphaMaskProgram.bind();
- gObjectFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
-#else
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightAlphaMaskWaterProgram.bind();
@@ -678,9 +668,7 @@ void LLDrawPoolFullbrightAlphaMask::beginPostDeferredPass(S32 pass)
gDeferredFullbrightAlphaMaskProgram.bind();
gDeferredFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::TEXTURE_GAMMA, 2.2f);
}
-#endif
}
-
}
void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
@@ -699,13 +687,6 @@ void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
}
else
{
-
-// Work-around until we can figure out why the right shader causes
-// the GeForce driver to go tango uniform on OS X 10.6.8 only
-//
-#if GE_FORCE_WORKAROUND
- gObjectFullbrightAlphaMaskProgram.unbind();
-#else
if (LLPipeline::sUnderWaterRender)
{
gDeferredFullbrightAlphaMaskWaterProgram.unbind();
@@ -714,8 +695,6 @@ void LLDrawPoolFullbrightAlphaMask::endPostDeferredPass(S32 pass)
{
gDeferredFullbrightAlphaMaskProgram.unbind();
}
-#endif
-
}
LLRenderPass::endRenderPass(pass);
}
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 73607e100a..ba6f26d3ef 100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -925,6 +925,14 @@ void LLFeatureManager::applyBaseMasks()
maskFeatures("VRAMGT512");
}
+#if LL_DARWIN
+ const LLOSInfo& osInfo = LLAppViewer::instance()->getOSInfo();
+ if (osInfo.mMajorVer == 10 && osInfo.mMinorVer < 7)
+ {
+ maskFeatures("OSX_10_6_8");
+ }
+#endif
+
// now mask by gpu string
// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
std::string gpustr = mGPUString;
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index fea8e34729..4331a63346 100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -70,8 +70,6 @@
extern LLMemoryInfo gSysMemory;
extern U32 gPacketsIn;
-static std::string get_viewer_release_notes_url();
-
///----------------------------------------------------------------------------
/// Class LLServerReleaseNotesURLFetcher
///----------------------------------------------------------------------------
@@ -108,8 +106,6 @@ public:
static LLSD getInfo();
void onClickCopyToClipboard();
- void updateServerReleaseNotesURL(const std::string& url);
-
private:
void setSupportText(const std::string& server_release_notes_url);
};
@@ -219,107 +215,9 @@ BOOL LLFloaterAbout::postBuild()
return TRUE;
}
-// static
LLSD LLFloaterAbout::getInfo()
{
- // The point of having one method build an LLSD info block and the other
- // construct the user-visible About string is to ensure that the same info
- // is available to a getInfo() caller as to the user opening
- // LLFloaterAbout.
- LLSD info;
- LLSD version;
- version.append(LLVersionInfo::getMajor());
- version.append(LLVersionInfo::getMinor());
- version.append(LLVersionInfo::getPatch());
- version.append(LLVersionInfo::getBuild());
- info["VIEWER_VERSION"] = version;
- info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
- info["BUILD_DATE"] = __DATE__;
- info["BUILD_TIME"] = __TIME__;
- info["CHANNEL"] = LLVersionInfo::getChannel();
-
- info["VIEWER_RELEASE_NOTES_URL"] = get_viewer_release_notes_url();
-
-#if LL_MSVC
- info["COMPILER"] = "MSVC";
- info["COMPILER_VERSION"] = _MSC_VER;
-#elif LL_GNUC
- info["COMPILER"] = "GCC";
- info["COMPILER_VERSION"] = GCC_VERSION;
-#endif
-
- // Position
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- LLVector3d pos = gAgent.getPositionGlobal();
- info["POSITION"] = ll_sd_from_vector3d(pos);
- info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
- info["REGION"] = gAgent.getRegion()->getName();
- info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
- info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
- info["SERVER_VERSION"] = gLastVersionChannel;
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- info["SLURL"] = slurl.getSLURLString();
- }
-
- // CPU
- info["CPU"] = gSysCPU.getCPUString();
- info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB() / 1024);
- // Moved hack adjustment to Windows memory size into llsys.cpp
- info["OS_VERSION"] = LLAppViewer::instance()->getOSInfo().getOSString();
- info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR));
- info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER));
-
-#if LL_WINDOWS
- LLSD driver_info = gDXHardware.getDisplayInfo();
- if (driver_info.has("DriverVersion"))
- {
- info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"];
- }
-#endif
-
- info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION));
- info["LIBCURL_VERSION"] = LLCurl::getVersionString();
- info["J2C_VERSION"] = LLImageJ2C::getEngineInfo();
- bool want_fullname = true;
- info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD();
- if(LLVoiceClient::getInstance()->voiceEnabled())
- {
- LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion();
- std::ostringstream version_string;
- version_string << version.serverType << " " << version.serverVersion << std::endl;
- info["VOICE_VERSION"] = version_string.str();
- }
- else
- {
- info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
- }
-
- // TODO: Implement media plugin version query
- info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)";
-
- if (gPacketsIn > 0)
- {
- info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent();
- info["PACKETS_IN"] = F32(gPacketsIn);
- info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
- }
-
- return info;
-}
-
-static std::string get_viewer_release_notes_url()
-{
- // return a URL to the release notes for this viewer, such as:
- // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
- std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
- if (! LLStringUtil::endsWith(url, "/"))
- url += "/";
- url += LLVersionInfo::getChannel() + "/";
- url += LLVersionInfo::getVersion();
- return LLWeb::escapeURL(url);
+ return LLAppViewer::instance()->getViewerInfo();
}
class LLFloaterAboutListener: public LLEventAPI
@@ -356,93 +254,22 @@ void LLFloaterAbout::onClickCopyToClipboard()
support_widget->deselect();
}
-void LLFloaterAbout::updateServerReleaseNotesURL(const std::string& url)
-{
- setSupportText(url);
-}
-
void LLFloaterAbout::setSupportText(const std::string& server_release_notes_url)
{
#if LL_WINDOWS
getWindow()->incBusyCount();
getWindow()->setCursor(UI_CURSOR_ARROW);
#endif
- LLSD info(getInfo());
#if LL_WINDOWS
getWindow()->decBusyCount();
getWindow()->setCursor(UI_CURSOR_ARROW);
#endif
- if (LLStringUtil::startsWith(server_release_notes_url, "http")) // it's an URL
- {
- info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(server_release_notes_url) + " " + LLTrans::getString("ReleaseNotes") + "]";
- }
- else
- {
- info["SERVER_RELEASE_NOTES_URL"] = server_release_notes_url;
- }
-
LLViewerTextEditor *support_widget =
getChild<LLViewerTextEditor>("support_editor", true);
- std::ostringstream support;
-
- // Render the LLSD from getInfo() as a format_map_t
- LLStringUtil::format_map_t args;
-
- // allow the "Release Notes" URL label to be localized
- args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes");
-
- for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap());
- ii != iend; ++ii)
- {
- if (! ii->second.isArray())
- {
- // Scalar value
- if (ii->second.isUndefined())
- {
- args[ii->first] = getString("none");
- }
- else
- {
- // don't forget to render value asString()
- args[ii->first] = ii->second.asString();
- }
- }
- else
- {
- // array value: build KEY_0, KEY_1 etc. entries
- for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n)
- {
- args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString();
- }
- }
- }
-
- // Now build the various pieces
- support << getString("AboutHeader", args);
- if (info.has("REGION"))
- {
- support << "\n\n" << getString("AboutPosition", args);
- }
- support << "\n\n" << getString("AboutSystem", args);
- support << "\n";
- if (info.has("GRAPHICS_DRIVER_VERSION"))
- {
- support << "\n" << getString("AboutDriver", args);
- }
- support << "\n" << getString("AboutLibs", args);
- if (info.has("COMPILER"))
- {
- support << "\n" << getString("AboutCompiler", args);
- }
- if (info.has("PACKETS_IN"))
- {
- support << '\n' << getString("AboutTraffic", args);
- }
-
support_widget->clear();
- support_widget->appendText(support.str(),
+ support_widget->appendText(LLAppViewer::instance()->getViewerInfoString(),
FALSE,
LLStyle::Params()
.color(LLUIColorTable::instance().getColor("TextFgReadOnlyColor")));
@@ -489,9 +316,9 @@ void LLServerReleaseNotesURLFetcher::completedHeader(U32 status, const std::stri
std::string location = content["location"].asString();
if (location.empty())
{
- location = floater_about->getString("ErrorFetchingServerReleaseNotesURL");
+ location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
}
- floater_about->updateServerReleaseNotesURL(location);
+ LLAppViewer::instance()->setServerReleaseNotesURL(location);
}
}
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index 76f62a7880..07bd262c00 100755
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -82,6 +82,11 @@ BOOL LLFloaterBulkPermission::postBuild()
mBulkChangeNextOwnerCopy = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy");
mBulkChangeNextOwnerTransfer = gSavedSettings.getBOOL("BulkChangeNextOwnerTransfer");
+ // fix invalid permissions case (in case initial settings were generated by a viewer affected by MAINT-3339)
+ if( !mBulkChangeNextOwnerTransfer && !mBulkChangeEveryoneCopy)
+ {
+ mBulkChangeNextOwnerTransfer = true;
+ }
return TRUE;
}
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index f2deb6a805..a992443ce1 100755
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1002,7 +1002,7 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_ANIMATION,
- LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"),
name,
callback, expected_upload_cost, userdata);
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index c85d048c5a..d0939b3eee 100755
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -151,7 +151,7 @@ void LLPanelCameraItem::setValue(const LLSD& value)
getChildView("selected_picture")->setVisible( value["selected"]);
}
-static LLRegisterPanelClassWrapper<LLPanelCameraZoom> t_camera_zoom_panel("camera_zoom_panel");
+static LLPanelInjector<LLPanelCameraZoom> t_camera_zoom_panel("camera_zoom_panel");
//-------------------------------------------------------------------------------
// LLPanelCameraZoom
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index 56051ff684..59f5b2b346 100755
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -48,6 +48,7 @@
#include "llviewermenu.h"
#include "llviewerinventory.h"
#include "llviewercontrol.h"
+#include "llfloaterperms.h"
BOOL item_name_precedes( LLInventoryItem* a, LLInventoryItem* b )
{
@@ -74,6 +75,17 @@ public:
void fire(const LLUUID &inv_item)
{
LLPreviewGesture::show(inv_item, LLUUID::null);
+
+ LLInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Gestures"));
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+ item->setPermissions(perm);
+ item->updateServer(FALSE);
+ }
}
};
@@ -449,9 +461,17 @@ void LLFloaterGesture::onClickPlay()
void LLFloaterGesture::onClickNew()
{
LLPointer<LLInventoryCallback> cb = new GestureShowCallback();
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- LLUUID::null, LLTransactionID::tnull, "New Gesture", "", LLAssetType::AT_GESTURE,
- LLInventoryType::IT_GESTURE, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ LLUUID::null,
+ LLTransactionID::tnull,
+ "New Gesture",
+ "",
+ LLAssetType::AT_GESTURE,
+ LLInventoryType::IT_GESTURE,
+ NOT_WEARABLE,
+ PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Gestures"),
+ cb);
}
void LLFloaterGesture::onActivateBtnClick()
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index b5aa309066..566f9bc9cc 100755
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -88,12 +88,10 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
LLFloaterIMContainer::~LLFloaterIMContainer()
{
mConversationsEventStream.stopListening("ConversationsRefresh");
-
gIdleCallbacks.deleteFunction(idle, this);
-
mNewMessageConnection.disconnect();
LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-
+
if (mMicroChangedSignal.connected())
{
mMicroChangedSignal.disconnect();
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0ccfdb9a7b..29511f56ff 100755
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -825,6 +825,7 @@ void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
{
LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+ bool should_be_expanded = false;
if (host_floater)
{
// Hide the messages pane if a floater is hosted in the Conversations
@@ -835,7 +836,7 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
if (!self->mIsP2PChat)
{
// The state must toggle the collapsed state of the panel
- bool should_be_expanded = self->mParticipantListPanel->isCollapsed();
+ should_be_expanded = self->mParticipantListPanel->isCollapsed();
// Update the expand/collapse flag of the participant list panel and save it
gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
@@ -847,6 +848,10 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
}
self->assignResizeLimits();
+ if (should_be_expanded)
+ {
+ self->forceReshape();
+ }
}
void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 27b1c3b9cd..ee7f413a59 100755
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -45,6 +45,7 @@
#include "lluictrlfactory.h"
#include "llstring.h"
#include "lleconomy.h"
+#include "llpermissions.h"
// linden includes
#include "llassetstorage.h"
@@ -167,11 +168,14 @@ void LLFloaterNameDesc::onBtnOK( )
S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
void *nruserdata = NULL;
std::string display_name = LLStringUtil::null;
+
upload_new_resource(mFilenameAndPath, // file
getChild<LLUICtrl>("name_form")->getValue().asString(),
getChild<LLUICtrl>("description_form")->getValue().asString(),
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
display_name, callback, expected_upload_cost, nruserdata);
closeFloater(false);
}
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 29a3e6ac3a..de96f75602 100755
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -95,7 +95,7 @@ public:
if (added_category_type == LLFolderType::FT_OUTBOX)
{
- mOutboxFloater->setupOutbox(added_category->getUUID());
+ mOutboxFloater->initializeMarketPlace();
}
}
}
@@ -120,7 +120,6 @@ LLFloaterOutbox::LLFloaterOutbox(const LLSD& key)
, mInventoryText(NULL)
, mInventoryTitle(NULL)
, mOutboxId(LLUUID::null)
- , mOutboxInventoryPanel(NULL)
, mOutboxItemCount(0)
, mOutboxTopLevelDropZone(NULL)
, mWindowShade(NULL)
@@ -157,9 +156,24 @@ BOOL LLFloaterOutbox::postBuild()
LLFocusableElement::setFocusReceivedCallback(boost::bind(&LLFloaterOutbox::onFocusReceived, this));
+ // Observe category creation to catch outbox creation (moot if already existing)
+ mCategoryAddedObserver = new LLOutboxAddedObserver(this);
+ gInventory.addObserver(mCategoryAddedObserver);
+
return TRUE;
}
+void LLFloaterOutbox::cleanOutbox()
+{
+ // Note: we cannot delete the mOutboxInventoryPanel as that point
+ // as this is called through callback observers of the panel itself.
+ // Doing so would crash rapidly.
+
+ // Invalidate the outbox data
+ mOutboxId.setNull();
+ mOutboxItemCount = 0;
+}
+
void LLFloaterOutbox::onClose(bool app_quitting)
{
if (mWindowShade)
@@ -173,33 +187,25 @@ void LLFloaterOutbox::onClose(bool app_quitting)
void LLFloaterOutbox::onOpen(const LLSD& key)
{
//
- // Look for an outbox and set up the inventory API
+ // Initialize the Market Place or go update the outbox
//
-
- if (mOutboxId.isNull())
+ if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
{
- const bool do_not_create_folder = false;
-
- const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder);
-
- if (outbox_id.isNull())
- {
- // Observe category creation to catch outbox creation
- mCategoryAddedObserver = new LLOutboxAddedObserver(this);
- gInventory.addObserver(mCategoryAddedObserver);
- }
- else
- {
- setupOutbox(outbox_id);
- }
+ initializeMarketPlace();
+ }
+ else
+ {
+ setupOutbox();
}
+ //
+ // Update the floater view
+ //
updateView();
//
// Trigger fetch of outbox contents
//
-
fetchOutboxContents();
}
@@ -216,14 +222,34 @@ void LLFloaterOutbox::fetchOutboxContents()
}
}
-void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
+void LLFloaterOutbox::setupOutbox()
{
- llassert(outboxId.notNull());
- llassert(mOutboxId.isNull());
- llassert(mCategoriesObserver == NULL);
-
- mOutboxId = outboxId;
-
+ if (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() != MarketplaceStatusCodes::MARKET_PLACE_MERCHANT)
+ {
+ // If we are *not* a merchant or we have no market place connection established yet, do nothing
+ return;
+ }
+
+ // We are a merchant. Get the outbox, create it if needs be.
+ LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, true);
+ if (outbox_id.isNull())
+ {
+ // We should never get there unless the inventory fails badly
+ llerrs << "Inventory problem: failure to create the outbox for a merchant!" << llendl;
+ return;
+ }
+
+ // Consolidate Merchant Outbox
+ // We shouldn't have to do that but with a client/server system relying on a "well known folder" convention, things get messy and conventions get broken down eventually
+ gInventory.consolidateForType(outbox_id, LLFolderType::FT_OUTBOX);
+
+ if (outbox_id == mOutboxId)
+ {
+ llwarns << "Inventory warning: Merchant outbox already set" << llendl;
+ return;
+ }
+ mOutboxId = outbox_id;
+
// No longer need to observe new category creation
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
@@ -231,45 +257,55 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
delete mCategoryAddedObserver;
mCategoryAddedObserver = NULL;
}
+ llassert(!mCategoryAddedObserver);
- // Create observer for outbox modifications
- mCategoriesObserver = new LLInventoryCategoriesObserver();
- gInventory.addObserver(mCategoriesObserver);
-
- mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+ // Create observer for outbox modifications : clear the old one and create a new one
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ gInventory.removeObserver(mCategoriesObserver);
+ delete mCategoriesObserver;
+ }
+ mCategoriesObserver = new LLInventoryCategoriesObserver();
+ gInventory.addObserver(mCategoriesObserver);
+ mCategoriesObserver->addCategory(mOutboxId, boost::bind(&LLFloaterOutbox::onOutboxChanged, this));
+ llassert(mCategoriesObserver);
- //
// Set up the outbox inventory view
- //
-
- mOutboxInventoryPanel =
- LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml",
- mInventoryPlaceholder->getParent(),
- LLInventoryPanel::child_registry_t::instance());
-
- llassert(mOutboxInventoryPanel);
+ LLInventoryPanel* inventory_panel = mOutboxInventoryPanel.get();
+ if (inventory_panel)
+ {
+ delete inventory_panel;
+ }
+ inventory_panel = LLUICtrlFactory::createFromFile<LLInventoryPanel>("panel_outbox_inventory.xml", mInventoryPlaceholder->getParent(), LLInventoryPanel::child_registry_t::instance());
+ mOutboxInventoryPanel = inventory_panel->getInventoryPanelHandle();
+ llassert(mOutboxInventoryPanel.get() != NULL);
// Reshape the inventory to the proper size
LLRect inventory_placeholder_rect = mInventoryPlaceholder->getRect();
- mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
+ inventory_panel->setShape(inventory_placeholder_rect);
// Set the sort order newest to oldest
-
- mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
- mOutboxInventoryPanel->getFilter().markDefault();
-
+ inventory_panel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ inventory_panel->getFilter().markDefault();
+
+ // Get the content of the outbox
fetchOutboxContents();
-
+}
+
+void LLFloaterOutbox::initializeMarketPlace()
+{
//
// Initialize the marketplace import API
//
-
LLMarketplaceInventoryImporter& importer = LLMarketplaceInventoryImporter::instance();
- importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
- importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
- importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
- importer.initialize();
+ if (!importer.isInitialized())
+ {
+ importer.setInitializationErrorCallback(boost::bind(&LLFloaterOutbox::initializationReportError, this, _1, _2));
+ importer.setStatusChangedCallback(boost::bind(&LLFloaterOutbox::importStatusChanged, this, _1));
+ importer.setStatusReportCallback(boost::bind(&LLFloaterOutbox::importReportResults, this, _1, _2));
+ importer.initialize();
+ }
}
void LLFloaterOutbox::setStatusString(const std::string& statusString)
@@ -281,18 +317,26 @@ void LLFloaterOutbox::setStatusString(const std::string& statusString)
void LLFloaterOutbox::updateFolderCount()
{
- S32 item_count = 0;
-
- if (mOutboxId.notNull())
+ if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
{
- LLInventoryModel::cat_array_t * cats;
- LLInventoryModel::item_array_t * items;
- gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+ S32 item_count = 0;
- item_count = cats->count() + items->count();
- }
+ if (mOutboxId.notNull())
+ {
+ LLInventoryModel::cat_array_t * cats;
+ LLInventoryModel::item_array_t * items;
+ gInventory.getDirectDescendentsOf(mOutboxId, cats, items);
+
+ item_count = cats->count() + items->count();
+ }
- mOutboxItemCount = item_count;
+ mOutboxItemCount = item_count;
+ }
+ else
+ {
+ // If there's no outbox, the number of items in it should be set to 0 for consistency
+ mOutboxItemCount = 0;
+ }
if (!mImportBusy)
{
@@ -302,7 +346,7 @@ void LLFloaterOutbox::updateFolderCount()
void LLFloaterOutbox::updateFolderCountStatus()
{
- if (mOutboxInventoryPanel)
+ if (mOutboxInventoryPanel.get() && mOutboxId.notNull())
{
switch (mOutboxItemCount)
{
@@ -327,18 +371,23 @@ void LLFloaterOutbox::updateFolderCountStatus()
void LLFloaterOutbox::updateView()
{
updateFolderCount();
+ LLInventoryPanel* panel = mOutboxInventoryPanel.get();
if (mOutboxItemCount > 0)
{
- mOutboxInventoryPanel->setVisible(TRUE);
+ panel->setVisible(TRUE);
mInventoryPlaceholder->setVisible(FALSE);
+ mOutboxTopLevelDropZone->setVisible(TRUE);
}
else
{
- if (mOutboxInventoryPanel)
+ if (panel)
{
- mOutboxInventoryPanel->setVisible(FALSE);
+ panel->setVisible(FALSE);
}
+
+ // Show the drop zone if there is an outbox folder
+ mOutboxTopLevelDropZone->setVisible(mOutboxId.notNull());
mInventoryPlaceholder->setVisible(TRUE);
@@ -347,19 +396,41 @@ void LLFloaterOutbox::updateView()
std::string outbox_tooltip;
const LLSD& subs = getMarketplaceStringSubstitutions();
+ U32 mkt_status = LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus();
if (mOutboxId.notNull())
{
+ // Does the outbox needs recreation?
+ if ((mOutboxInventoryPanel.get() == NULL) || !gInventory.getCategory(mOutboxId))
+ {
+ setupOutbox();
+ }
+ // "Outbox is empty!" message strings
outbox_text = LLTrans::getString("InventoryOutboxNoItems", subs);
outbox_title = LLTrans::getString("InventoryOutboxNoItemsTitle");
outbox_tooltip = LLTrans::getString("InventoryOutboxNoItemsTooltip");
}
- else
+ else if (mkt_status <= MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING)
+ {
+ // "Initializing!" message strings
+ outbox_text = LLTrans::getString("InventoryOutboxInitializing", subs);
+ outbox_title = LLTrans::getString("InventoryOutboxInitializingTitle");
+ outbox_tooltip = LLTrans::getString("InventoryOutboxInitializingTooltip");
+ }
+ else if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT)
{
+ // "Not a merchant!" message strings
outbox_text = LLTrans::getString("InventoryOutboxNotMerchant", subs);
outbox_title = LLTrans::getString("InventoryOutboxNotMerchantTitle");
outbox_tooltip = LLTrans::getString("InventoryOutboxNotMerchantTooltip");
}
+ else
+ {
+ // "Errors!" message strings
+ outbox_text = LLTrans::getString("InventoryOutboxError", subs);
+ outbox_title = LLTrans::getString("InventoryOutboxErrorTitle");
+ outbox_tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+ }
mInventoryText->setValue(outbox_text);
mInventoryTitle->setValue(outbox_title);
@@ -378,9 +449,10 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EAcceptance* accept,
std::string& tooltip_msg)
{
- if ((mOutboxInventoryPanel == NULL) ||
+ if ((mOutboxInventoryPanel.get() == NULL) ||
(mWindowShade && mWindowShade->isShown()) ||
- LLMarketplaceInventoryImporter::getInstance()->isImportInProgress())
+ LLMarketplaceInventoryImporter::getInstance()->isImportInProgress() ||
+ mOutboxId.isNull())
{
return FALSE;
}
@@ -391,15 +463,16 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// Determine if the mouse is inside the inventory panel itself or just within the floater
bool pointInInventoryPanel = false;
bool pointInInventoryPanelChild = false;
- LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
- if (mOutboxInventoryPanel->getVisible())
+ LLInventoryPanel* panel = mOutboxInventoryPanel.get();
+ LLFolderView* root_folder = panel->getRootFolder();
+ if (panel->getVisible())
{
S32 inv_x, inv_y;
- localPointToOtherView(x, y, &inv_x, &inv_y, mOutboxInventoryPanel);
+ localPointToOtherView(x, y, &inv_x, &inv_y, panel);
- pointInInventoryPanel = mOutboxInventoryPanel->getRect().pointInRect(inv_x, inv_y);
+ pointInInventoryPanel = panel->getRect().pointInRect(inv_x, inv_y);
- LLView * inventory_panel_child_at_point = mOutboxInventoryPanel->childFromPoint(inv_x, inv_y, true);
+ LLView * inventory_panel_child_at_point = panel->childFromPoint(inv_x, inv_y, true);
pointInInventoryPanelChild = (inventory_panel_child_at_point != root_folder);
}
@@ -439,23 +512,26 @@ void LLFloaterOutbox::onMouseLeave(S32 x, S32 y, MASK mask)
void LLFloaterOutbox::onImportButtonClicked()
{
- mOutboxInventoryPanel->clearSelection();
+ if (mOutboxInventoryPanel.get())
+ {
+ mOutboxInventoryPanel.get()->clearSelection();
+ }
mImportBusy = LLMarketplaceInventoryImporter::instance().triggerImport();
}
void LLFloaterOutbox::onOutboxChanged()
{
- llassert(!mOutboxId.isNull());
-
- //if (mOutboxInventoryPanel)
- //{
- // mOutboxInventoryPanel->requestSort();
- //}
-
- fetchOutboxContents();
-
- updateView();
+ LLViewerInventoryCategory* category = gInventory.getCategory(mOutboxId);
+ if (mOutboxId.notNull() && category)
+ {
+ fetchOutboxContents();
+ updateView();
+ }
+ else
+ {
+ cleanOutbox();
+ }
}
void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
@@ -486,6 +562,11 @@ void LLFloaterOutbox::importReportResults(U32 status, const LLSD& content)
void LLFloaterOutbox::importStatusChanged(bool inProgress)
{
+ if (mOutboxId.isNull() && (LLMarketplaceInventoryImporter::getInstance()->getMarketPlaceStatus() == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT))
+ {
+ setupOutbox();
+ }
+
if (inProgress)
{
if (mImportBusy)
@@ -503,6 +584,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
}
else
{
+ setStatusString("");
mImportBusy = false;
mImportButton->setEnabled(mOutboxItemCount > 0);
mInventoryImportInProgress->setVisible(false);
@@ -513,7 +595,7 @@ void LLFloaterOutbox::importStatusChanged(bool inProgress)
void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
{
- if (status != MarketplaceErrorCodes::IMPORT_DONE)
+ if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
{
char status_string[16];
sprintf(status_string, "%d", status);
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index a91d8c1139..40519c8fd2 100755
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -54,7 +54,7 @@ public:
LLFloaterOutbox(const LLSD& key);
~LLFloaterOutbox();
- void setupOutbox(const LLUUID& outboxId);
+ void initializeMarketPlace();
// virtuals
BOOL postBuild();
@@ -70,6 +70,8 @@ public:
void onMouseLeave(S32 x, S32 y, MASK mask);
protected:
+ void setupOutbox();
+ void cleanOutbox();
void fetchOutboxContents();
void importReportResults(U32 status, const LLSD& content);
@@ -104,7 +106,7 @@ private:
LLTextBox * mInventoryTitle;
LLUUID mOutboxId;
- LLInventoryPanel * mOutboxInventoryPanel;
+ LLHandle<LLInventoryPanel> mOutboxInventoryPanel;
U32 mOutboxItemCount;
LLPanel * mOutboxTopLevelDropZone;
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index b0009fd94f..f0c010b545 100755
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -135,6 +135,7 @@ LLFloaterPay::LLFloaterPay(const LLSD& key)
LLFloaterPay::~LLFloaterPay()
{
std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer());
+ mCallbackData.clear();
// Name callbacks will be automatically disconnected since LLFloater is trackable
// In case this floater is currently waiting for a reply.
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 80b55c3cbb..0880a5f35a 100755
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -1,7 +1,7 @@
/**
* @file llfloaterperms.cpp
* @brief Asset creation permission preferences.
- * @author Coco
+ * @author Jonathan Yap
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -32,101 +32,230 @@
#include "llviewerwindow.h"
#include "lluictrlfactory.h"
#include "llpermissions.h"
-
+#include "llagent.h"
+#include "llviewerregion.h"
+#include "llnotificationsutil.h"
LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
: LLFloater(seed)
{
- mCommitCallbackRegistrar.add("Perms.Copy", boost::bind(&LLFloaterPerms::onCommitCopy, this));
- mCommitCallbackRegistrar.add("Perms.OK", boost::bind(&LLFloaterPerms::onClickOK, this));
- mCommitCallbackRegistrar.add("Perms.Cancel", boost::bind(&LLFloaterPerms::onClickCancel, this));
-
}
BOOL LLFloaterPerms::postBuild()
{
- mCloseSignal.connect(boost::bind(&LLFloaterPerms::cancel, this));
-
+ return TRUE;
+}
+
+//static
+U32 LLFloaterPerms::getGroupPerms(std::string prefix)
+{
+ return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY | PERM_MOVE | PERM_MODIFY : PERM_NONE;
+}
+
+//static
+U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
+{
+ return gSavedSettings.getBOOL(prefix+"EveryoneCopy") ? PERM_COPY : PERM_NONE;
+}
+
+//static
+U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
+{
+ U32 flags = PERM_MOVE;
+ if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+ {
+ flags |= PERM_COPY;
+ }
+ if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
+ {
+ flags |= PERM_MODIFY;
+ }
+ if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+ {
+ flags |= PERM_TRANSFER;
+ }
+ return flags;
+}
+
+//static
+U32 LLFloaterPerms::getNextOwnerPermsInverted(std::string prefix)
+{
+ // Sets bits for permissions that are off
+ U32 flags = PERM_MOVE;
+ if ( !gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+ {
+ flags |= PERM_COPY;
+ }
+ if ( !gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
+ {
+ flags |= PERM_MODIFY;
+ }
+ if ( !gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+ {
+ flags |= PERM_TRANSFER;
+ }
+ return flags;
+}
+
+static bool mCapSent = false;
+
+LLFloaterPermsDefault::LLFloaterPermsDefault(const LLSD& seed)
+ : LLFloater(seed)
+{
+ mCommitCallbackRegistrar.add("PermsDefault.Copy", boost::bind(&LLFloaterPermsDefault::onCommitCopy, this, _2));
+ mCommitCallbackRegistrar.add("PermsDefault.OK", boost::bind(&LLFloaterPermsDefault::onClickOK, this));
+ mCommitCallbackRegistrar.add("PermsDefault.Cancel", boost::bind(&LLFloaterPermsDefault::onClickCancel, this));
+}
+
+
+// String equivalents of enum Categories - initialization order must match enum order!
+const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
+{
+ "Objects",
+ "Uploads",
+ "Scripts",
+ "Notecards",
+ "Gestures",
+ "Wearables"
+};
+
+BOOL LLFloaterPermsDefault::postBuild()
+{
+ if(!gSavedSettings.getBOOL("DefaultUploadPermissionsConverted"))
+ {
+ gSavedSettings.setBOOL("UploadsEveryoneCopy", gSavedSettings.getBOOL("EveryoneCopy"));
+ gSavedSettings.setBOOL("UploadsNextOwnerCopy", gSavedSettings.getBOOL("NextOwnerCopy"));
+ gSavedSettings.setBOOL("UploadsNextOwnerModify", gSavedSettings.getBOOL("NextOwnerModify"));
+ gSavedSettings.setBOOL("UploadsNextOwnerTransfer", gSavedSettings.getBOOL("NextOwnerTransfer"));
+ gSavedSettings.setBOOL("UploadsShareWithGroup", gSavedSettings.getBOOL("ShareWithGroup"));
+ gSavedSettings.setBOOL("DefaultUploadPermissionsConverted", true);
+ }
+
+ mCloseSignal.connect(boost::bind(&LLFloaterPermsDefault::cancel, this));
+
refresh();
- return TRUE;
+ return true;
}
-void LLFloaterPerms::onClickOK()
+void LLFloaterPermsDefault::onClickOK()
{
ok();
closeFloater();
}
-void LLFloaterPerms::onClickCancel()
+void LLFloaterPermsDefault::onClickCancel()
{
cancel();
closeFloater();
}
-void LLFloaterPerms::onCommitCopy()
+void LLFloaterPermsDefault::onCommitCopy(const LLSD& user_data)
{
// Implements fair use
- BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy");
+ std::string prefix = user_data.asString();
+
+ BOOL copyable = gSavedSettings.getBOOL(prefix+"NextOwnerCopy");
if(!copyable)
{
- gSavedSettings.setBOOL("NextOwnerTransfer", TRUE);
+ gSavedSettings.setBOOL(prefix+"NextOwnerTransfer", TRUE);
}
- LLCheckBoxCtrl* xfer = getChild<LLCheckBoxCtrl>("next_owner_transfer");
+ LLCheckBoxCtrl* xfer = getChild<LLCheckBoxCtrl>(prefix+"_transfer");
xfer->setEnabled(copyable);
}
-void LLFloaterPerms::ok()
+class LLFloaterPermsResponder : public LLHTTPClient::Responder
{
- refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official.
-}
+public:
+ LLFloaterPermsResponder(): LLHTTPClient::Responder() {}
+private:
+ static std::string sPreviousReason;
+
+ void error(U32 status, const std::string& reason)
+ {
+ // Do not display the same error more than once in a row
+ if (reason != sPreviousReason)
+ {
+ sPreviousReason = reason;
+ LLSD args;
+ args["REASON"] = reason;
+ LLNotificationsUtil::add("DefaultObjectPermissions", args);
+ }
+ }
+ void result(const LLSD& content)
+ {
+ // Since we have had a successful POST call be sure to display the next error message
+ // even if it is the same as a previous one.
+ sPreviousReason = "";
+ LLFloaterPermsDefault::setCapSent(true);
+ LL_INFOS("FloaterPermsResponder") << "Sent default permissions to simulator" << LL_ENDL;
+ }
+};
+
+ std::string LLFloaterPermsResponder::sPreviousReason;
-void LLFloaterPerms::cancel()
+void LLFloaterPermsDefault::sendInitialPerms()
{
- gSavedSettings.setBOOL("ShareWithGroup", mShareWithGroup);
- gSavedSettings.setBOOL("EveryoneCopy", mEveryoneCopy);
- gSavedSettings.setBOOL("NextOwnerCopy", mNextOwnerCopy);
- gSavedSettings.setBOOL("NextOwnerModify", mNextOwnerModify);
- gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer);
+ if(!mCapSent)
+ {
+ updateCap();
+ }
}
-void LLFloaterPerms::refresh()
+void LLFloaterPermsDefault::updateCap()
{
- mShareWithGroup = gSavedSettings.getBOOL("ShareWithGroup");
- mEveryoneCopy = gSavedSettings.getBOOL("EveryoneCopy");
- mNextOwnerCopy = gSavedSettings.getBOOL("NextOwnerCopy");
- mNextOwnerModify = gSavedSettings.getBOOL("NextOwnerModify");
- mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer");
+ std::string object_url = gAgent.getRegion()->getCapability("AgentPreferences");
+
+ if(!object_url.empty())
+ {
+ LLSD report = LLSD::emptyMap();
+ report["default_object_perm_masks"]["Group"] =
+ (LLSD::Integer)LLFloaterPerms::getGroupPerms(sCategoryNames[CAT_OBJECTS]);
+ report["default_object_perm_masks"]["Everyone"] =
+ (LLSD::Integer)LLFloaterPerms::getEveryonePerms(sCategoryNames[CAT_OBJECTS]);
+ report["default_object_perm_masks"]["NextOwner"] =
+ (LLSD::Integer)LLFloaterPerms::getNextOwnerPerms(sCategoryNames[CAT_OBJECTS]);
+
+ LLHTTPClient::post(object_url, report, new LLFloaterPermsResponder());
+ }
}
-//static
-U32 LLFloaterPerms::getGroupPerms(std::string prefix)
-{
- return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE;
+void LLFloaterPermsDefault::setCapSent(bool cap_sent)
+{
+ mCapSent = cap_sent;
}
-//static
-U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
+void LLFloaterPermsDefault::ok()
{
- return gSavedSettings.getBOOL(prefix+"EveryoneCopy") ? PERM_COPY : PERM_NONE;
+// Changes were already applied automatically to saved settings.
+// Refreshing internal values makes it official.
+ refresh();
+
+// We know some setting has changed but not which one. Just in case it was a setting for
+// object permissions tell the server what the values are.
+ updateCap();
}
-//static
-U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
+void LLFloaterPermsDefault::cancel()
{
- U32 flags = PERM_MOVE;
- if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+ for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++)
{
- flags |= PERM_COPY;
- }
- if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
- {
- flags |= PERM_MODIFY;
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerCopy", mNextOwnerCopy[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerModify", mNextOwnerModify[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"NextOwnerTransfer", mNextOwnerTransfer[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"ShareWithGroup", mShareWithGroup[iter]);
+ gSavedSettings.setBOOL(sCategoryNames[iter]+"EveryoneCopy", mEveryoneCopy[iter]);
}
- if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+}
+
+void LLFloaterPermsDefault::refresh()
+{
+ for (U32 iter = CAT_OBJECTS; iter < CAT_LAST; iter++)
{
- flags |= PERM_TRANSFER;
+ mShareWithGroup[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"ShareWithGroup");
+ mEveryoneCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"EveryoneCopy");
+ mNextOwnerCopy[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerCopy");
+ mNextOwnerModify[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerModify");
+ mNextOwnerTransfer[iter] = gSavedSettings.getBOOL(sCategoryNames[iter]+"NextOwnerTransfer");
}
- return flags;
}
-
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 6b65f4b0cd..2bb0a19dc1 100755
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -1,7 +1,7 @@
/**
* @file llfloaterperms.h
* @brief Asset creation permission preferences.
- * @author Coco
+ * @author Jonathan Yap
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -36,26 +36,57 @@ class LLFloaterPerms : public LLFloater
public:
/*virtual*/ BOOL postBuild();
- void ok();
- void cancel();
- void onClickOK();
- void onClickCancel();
- void onCommitCopy();
+
// Convenience methods to get current permission preference bitfields from saved settings:
static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy"
static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup"
static U32 getNextOwnerPerms(std::string prefix=""); // bitfield for prefix + "NextOwner" + "Copy", "Modify", and "Transfer"
+ static U32 getNextOwnerPermsInverted(std::string prefix="");
private:
LLFloaterPerms(const LLSD& seed);
+
+};
+
+class LLFloaterPermsDefault : public LLFloater
+{
+ friend class LLFloaterReg;
+
+public:
+ /*virtual*/ BOOL postBuild();
+ void ok();
+ void cancel();
+ void onClickOK();
+ void onClickCancel();
+ void onCommitCopy(const LLSD& user_data);
+ static void sendInitialPerms();
+ static void updateCap();
+ static void setCapSent(bool cap_sent);
+
+// Update instantiation of sCategoryNames in the .cpp file to match if you change this!
+enum Categories
+{
+ CAT_OBJECTS,
+ CAT_UPLOADS,
+ CAT_SCRIPTS,
+ CAT_NOTECARDS,
+ CAT_GESTURES,
+ CAT_WEARABLES,
+ CAT_LAST
+};
+
+private:
+ LLFloaterPermsDefault(const LLSD& seed);
void refresh();
- BOOL // cached values only for implementing cancel.
- mShareWithGroup,
- mEveryoneCopy,
- mNextOwnerCopy,
- mNextOwnerModify,
- mNextOwnerTransfer;
+ static const std::string sCategoryNames[CAT_LAST];
+
+ // cached values only for implementing cancel.
+ bool mShareWithGroup[CAT_LAST];
+ bool mEveryoneCopy[CAT_LAST];
+ bool mNextOwnerCopy[CAT_LAST];
+ bool mNextOwnerModify[CAT_LAST];
+ bool mNextOwnerTransfer[CAT_LAST];
};
#endif
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 87ae36716d..04b83c0613 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -238,6 +238,7 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response
void handleNameTagOptionChanged(const LLSD& newvalue)
{
+ LLAvatarNameCache::setUseUsernames(gSavedSettings.getBOOL("NameTagShowUsernames"));
LLVOAvatar::invalidateNameTags();
}
@@ -346,6 +347,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
mCommitCallbackRegistrar.add("Pref.TranslationSettings", boost::bind(&LLFloaterPreference::onClickTranslationSettings, this));
mCommitCallbackRegistrar.add("Pref.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+ mCommitCallbackRegistrar.add("Pref.PermsDefault", boost::bind(&LLFloaterPreference::onClickPermsDefault, this));
mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
sSkin = gSavedSettings.getString("SkinCurrent");
@@ -1187,6 +1189,9 @@ void LLFloaterPreference::refreshEnabledState()
disableUnavailableSettings();
getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
+
+ // Cannot have floater active until caps have been received
+ getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
}
void LLFloaterPreference::disableUnavailableSettings()
@@ -1682,6 +1687,11 @@ void LLFloaterPreference::onClickActionChange()
mClickActionDirty = true;
}
+void LLFloaterPreference::onClickPermsDefault()
+{
+ LLFloaterReg::showInstance("perms_default");
+}
+
void LLFloaterPreference::onDeleteTranscripts()
{
LLSD args;
@@ -1822,7 +1832,7 @@ private:
callback_t mCallback;
};
//----------------------------------------------------------------------------
-static LLRegisterPanelClassWrapper<LLPanelPreference> t_places("panel_preference");
+static LLPanelInjector<LLPanelPreference> t_places("panel_preference");
LLPanelPreference::LLPanelPreference()
: LLPanel(),
mBandWidthUpdater(NULL)
@@ -2062,8 +2072,8 @@ private:
std::list<std::string> mAccountIndependentSettings;
};
-static LLRegisterPanelClassWrapper<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics");
-static LLRegisterPanelClassWrapper<LLPanelPreferencePrivacy> t_pref_privacy("panel_preference_privacy");
+static LLPanelInjector<LLPanelPreferenceGraphics> t_pref_graph("panel_preference_graphics");
+static LLPanelInjector<LLPanelPreferencePrivacy> t_pref_privacy("panel_preference_privacy");
BOOL LLPanelPreferenceGraphics::postBuild()
{
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index cb180f6f1e..e287631b1a 100755
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -164,6 +164,7 @@ public:
void onClickBlockList();
void onClickProxySettings();
void onClickTranslationSettings();
+ void onClickPermsDefault();
void onClickAutoReplace();
void onClickSpellChecker();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llfloatersocial.cpp b/indra/newview/llfloatersocial.cpp
index 2a74c8e3ea..e8c6b179cf 100644
--- a/indra/newview/llfloatersocial.cpp
+++ b/indra/newview/llfloatersocial.cpp
@@ -47,10 +47,10 @@
#include "llviewercontrol.h"
#include "llviewermedia.h"
-static LLRegisterPanelClassWrapper<LLSocialStatusPanel> t_panel_status("llsocialstatuspanel");
-static LLRegisterPanelClassWrapper<LLSocialPhotoPanel> t_panel_photo("llsocialphotopanel");
-static LLRegisterPanelClassWrapper<LLSocialCheckinPanel> t_panel_checkin("llsocialcheckinpanel");
-static LLRegisterPanelClassWrapper<LLSocialAccountPanel> t_panel_account("llsocialaccountpanel");
+static LLPanelInjector<LLSocialStatusPanel> t_panel_status("llsocialstatuspanel");
+static LLPanelInjector<LLSocialPhotoPanel> t_panel_photo("llsocialphotopanel");
+static LLPanelInjector<LLSocialCheckinPanel> t_panel_checkin("llsocialcheckinpanel");
+static LLPanelInjector<LLSocialAccountPanel> t_panel_account("llsocialaccountpanel");
const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
const std::string DEFAULT_CHECKIN_LOCATION_URL = "http://maps.secondlife.com/";
@@ -170,7 +170,6 @@ mRefreshBtn(NULL),
mWorkingLabel(NULL),
mThumbnailPlaceholder(NULL),
mCaptionTextBox(NULL),
-mLocationCheckbox(NULL),
mPostButton(NULL)
{
mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLSocialPhotoPanel::onSend, this));
@@ -196,7 +195,6 @@ BOOL LLSocialPhotoPanel::postBuild()
mWorkingLabel = getChild<LLUICtrl>("working_lbl");
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
mCaptionTextBox = getChild<LLUICtrl>("photo_caption");
- mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
mPostButton = getChild<LLUICtrl>("post_photo_btn");
mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
@@ -213,7 +211,6 @@ void LLSocialPhotoPanel::draw()
mCaptionTextBox->setEnabled(no_ongoing_connection);
mResolutionComboBox->setEnabled(no_ongoing_connection);
mRefreshBtn->setEnabled(no_ongoing_connection);
- mLocationCheckbox->setEnabled(no_ongoing_connection);
// Display the preview if one is available
if (previewp && previewp->getThumbnailImage())
@@ -343,25 +340,6 @@ void LLSocialPhotoPanel::sendPhoto()
// Get the caption
std::string caption = mCaptionTextBox->getValue().asString();
- // Add the location if required
- bool add_location = mLocationCheckbox->getValue().asBoolean();
- if (add_location)
- {
- // Get the SLURL for the location
- LLSLURL slurl;
- LLAgentUI::buildSLURL(slurl);
- std::string slurl_string = slurl.getSLURLString();
-
- // Add query parameters so Google Analytics can track incoming clicks!
- slurl_string += DEFAULT_PHOTO_QUERY_PARAMETERS;
-
- // Add it to the caption (pretty crude, but we don't have a better option with photos)
- if (caption.empty())
- caption = slurl_string;
- else
- caption = caption + " " + slurl_string;
- }
-
// Get the image
LLSnapshotLivePreview* previewp = getPreviewView();
diff --git a/indra/newview/llfloatersocial.h b/indra/newview/llfloatersocial.h
index bbe07c9704..309f015ce9 100644
--- a/indra/newview/llfloatersocial.h
+++ b/indra/newview/llfloatersocial.h
@@ -85,7 +85,6 @@ private:
LLUICtrl * mWorkingLabel;
LLUICtrl * mThumbnailPlaceholder;
LLUICtrl * mCaptionTextBox;
- LLUICtrl * mLocationCheckbox;
LLUICtrl * mPostButton;
LLUICtrl* mCancelButton;
};
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index 5ecdd11918..54c7b4c37d 100755
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -307,12 +307,12 @@ void LLFloaterSpellCheckerImport::onBtnOK()
else
{
std::string settings_dic = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".dic";
- if ( copyFile( dict_dic, settings_dic ) )
+ if ( LLFile::copy( dict_dic, settings_dic ) )
{
if (gDirUtilp->fileExists(dict_aff))
{
std::string settings_aff = LLSpellChecker::getDictionaryUserPath() + mDictionaryBasename + ".aff";
- if (copyFile( dict_aff, settings_aff ))
+ if ( LLFile::copy( dict_aff, settings_aff ))
{
imported = true;
}
@@ -385,37 +385,6 @@ void LLFloaterSpellCheckerImport::onBtnOK()
closeFloater(false);
}
-bool LLFloaterSpellCheckerImport::copyFile(const std::string from, const std::string to)
-{
- bool copied = false;
- LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */
- if (in)
- {
- LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */
- if (out)
- {
- char buf[16384]; /* Flawfinder: ignore */
- size_t readbytes;
- bool write_ok = true;
- while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
- {
- if (fwrite(buf, 1, readbytes, out) != readbytes)
- {
- LL_WARNS("SpellCheck") << "Short write" << LL_ENDL;
- write_ok = false;
- }
- }
- if ( write_ok )
- {
- copied = true;
- }
- fclose(out);
- }
- }
- fclose(in);
- return copied;
-}
-
std::string LLFloaterSpellCheckerImport::parseXcuFile(const std::string& file_path) const
{
LLXMLNodePtr xml_root;
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
index eded3a9133..de59d83f24 100755
--- a/indra/newview/llfloaterspellchecksettings.h
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -58,7 +58,6 @@ protected:
void onBtnBrowse();
void onBtnCancel();
void onBtnOK();
- bool copyFile(const std::string from, const std::string to);
std::string parseXcuFile(const std::string& file_path) const;
std::string mDictionaryDir;
diff --git a/indra/newview/llfloatertoybox.cpp b/indra/newview/llfloatertoybox.cpp
index 324afe661f..a025a859e7 100755
--- a/indra/newview/llfloatertoybox.cpp
+++ b/indra/newview/llfloatertoybox.cpp
@@ -107,7 +107,7 @@ void LLFloaterToybox::draw()
{
const LLCommandId& id = *it;
- const bool command_not_present = (gToolBarView->hasCommand(id) == LLToolBarView::TOOLBAR_NONE);
+ const bool command_not_present = (gToolBarView->hasCommand(id) == LLToolBarEnums::TOOLBAR_NONE);
mToolBar->enableCommand(id, command_not_present);
}
@@ -175,9 +175,9 @@ void LLFloaterToybox::onToolBarButtonEnter(LLView* button)
switch(command_loc)
{
- case LLToolBarView::TOOLBAR_BOTTOM: suffix = LLTrans::getString("Toolbar_Bottom_Tooltip"); break;
- case LLToolBarView::TOOLBAR_LEFT: suffix = LLTrans::getString("Toolbar_Left_Tooltip"); break;
- case LLToolBarView::TOOLBAR_RIGHT: suffix = LLTrans::getString("Toolbar_Right_Tooltip"); break;
+ case LLToolBarEnums::TOOLBAR_BOTTOM: suffix = LLTrans::getString("Toolbar_Bottom_Tooltip"); break;
+ case LLToolBarEnums::TOOLBAR_LEFT: suffix = LLTrans::getString("Toolbar_Left_Tooltip"); break;
+ case LLToolBarEnums::TOOLBAR_RIGHT: suffix = LLTrans::getString("Toolbar_Right_Tooltip"); break;
default:
break;
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index c28657dbcd..aac3a41b9e 100755
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -232,16 +232,16 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
return continue_filtering;
}
-LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
-{
- return &mInventoryViewModel;
-}
-
-
-const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
-{
- return &mInventoryViewModel;
-}
+//LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+//{
+// return &mInventoryViewModel;
+//}
+//
+//
+//const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+//{
+// return &mInventoryViewModel;
+//}
bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
{
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 60fa53f491..c4c1827266 100755
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -62,6 +62,7 @@
#include "llresmgr.h"
#include "pipeline.h"
#include "llspatialpartition.h"
+#include "llviewershadermgr.h"
// Height of the yellow selection highlight posts for land
const F32 PARCEL_POST_HEIGHT = 0.666f;
@@ -767,7 +768,6 @@ void draw_line_cube(F32 width, const LLVector3& center)
gGL.vertex3f(center.mV[VX] + width ,center.mV[VY] - width,center.mV[VZ] - width);
}
-
void LLViewerObjectList::renderObjectBeacons()
{
if (mDebugBeacons.empty())
@@ -878,3 +878,134 @@ void LLViewerObjectList::renderObjectBeacons()
}
+void gpu_benchmark()
+{
+ if (!LLGLSLShader::sNoFixedFunction)
+ { //don't bother benchmarking the fixed function
+ return;
+ }
+
+ //measure memory bandwidth by:
+ // - allocating a batch of textures and render targets
+ // - rendering those textures to those render targets
+ // - recording time taken
+ // - taking the median time for a given number of samples
+
+ //resolution of textures/render targets
+ const U32 res = 1024;
+
+ //number of textures
+ const U32 count = 32;
+
+ //number of samples to take
+ const S32 samples = 64;
+
+ LLGLSLShader::initProfile();
+
+ LLRenderTarget dest[count];
+ U32 source[count];
+ LLImageGL::generateTextures(count, source);
+ std::vector<F32> results;
+
+ //build a random texture
+ U8 pixels[res*res*4];
+
+ for (U32 i = 0; i < res*res*4; ++i)
+ {
+ pixels[i] = (U8) ll_rand(255);
+ }
+
+
+ gGL.setColorMask(true, true);
+ LLGLDepthTest depth(GL_FALSE);
+
+ for (U32 i = 0; i < count; ++i)
+ { //allocate render targets and textures
+ dest[i].allocate(res,res,GL_RGBA,false, false, LLTexUnit::TT_TEXTURE, true);
+ dest[i].bindTarget();
+ dest[i].clear();
+ dest[i].flush();
+
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, source[i]);
+ LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ }
+
+ //make a dummy triangle to draw with
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STATIC_DRAW_ARB);
+ buff->allocateBuffer(3, 0, true);
+
+ LLStrider<LLVector3> v;
+ LLStrider<LLVector2> tc;
+
+ buff->getVertexStrider(v);
+
+ v[0].set(-1,1,0);
+ v[1].set(-1,-3,0);
+ v[2].set(3,1,0);
+ buff->flush();
+
+ gBenchmarkProgram.bind();
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ //wait for any previoius GL commands to finish
+ glFinish();
+
+ for (S32 c = -1; c < samples; ++c)
+ {
+ LLTimer timer;
+ timer.start();
+
+ for (U32 i = 0; i < count; ++i)
+ {
+ dest[i].bindTarget();
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, source[i]);
+ buff->drawArrays(LLRender::TRIANGLES, 0, 3);
+ dest[i].flush();
+ }
+
+ //wait for current batch of copies to finish
+ glFinish();
+
+ F32 time = timer.getElapsedTimeF32();
+
+ if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
+ {
+ //store result in gigabytes per second
+ F32 gb = (F32) ((F64) (res*res*8*count))/(1000000000);
+
+ F32 gbps = gb/time;
+
+ results.push_back(gbps);
+ }
+ }
+
+ gBenchmarkProgram.unbind();
+
+ LLGLSLShader::finishProfile();
+
+ LLImageGL::deleteTextures(count, source);
+
+
+ std::sort(results.begin(), results.end());
+
+ F32 gbps = results[results.size()/2];
+
+ llinfos << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << llendl;
+
+ F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
+ F32 seconds = ms/1000.f;
+
+ F64 samples_drawn = res*res*count*samples;
+ F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
+ gbps = samples_sec*8;
+
+ if (gGLManager.mHasTimerQuery)
+ {
+ llinfos << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << llendl;
+ }
+ else
+ {
+ llinfos << "ARB_timer_query unavailable." << llendl;
+ }
+}
+
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index cbd844cdac..7ea08539f9 100755
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -77,6 +77,7 @@ LLRoleActionSet::~LLRoleActionSet()
{
delete mActionSetData;
std::for_each(mActions.begin(), mActions.end(), DeletePointer());
+ mActions.clear();
}
//
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9ffbd1a675..e8ebd21de4 100755
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1352,7 +1352,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
// IM_SESSION_INVITE means that this is an Ad-hoc incoming chat
// (it can be also Group chat but it is checked above)
// In this case mInitialTargetIDs contains Ad-hoc session ID and it should not be added
- // to Recent People to prevent showing of an item with (???)(???). See EXT-8246.
+ // to Recent People to prevent showing of an item with (?? ?)(?? ?), sans the spaces. See EXT-8246.
// Concrete participants will be added into this list once they sent message in chat.
if (IM_SESSION_INVITE == dialog) return;
@@ -1959,11 +1959,11 @@ LLDockControl::DocAt LLCallDialog::getDockControlPos(const std::string& toolbarB
switch (toolbar_loc)
{
- case LLToolBarView::TOOLBAR_LEFT:
+ case LLToolBarEnums::TOOLBAR_LEFT:
doc_at = LLDockControl::RIGHT;
break;
- case LLToolBarView::TOOLBAR_RIGHT:
+ case LLToolBarEnums::TOOLBAR_RIGHT:
doc_at = LLDockControl::LEFT;
break;
}
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 3c6974cf6d..15463e0d33 100755
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -139,7 +139,14 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
{
return passed_clipboard;
}
-
+
+ // show folder links
+ LLViewerInventoryItem* item = gInventory.getItem(folder_id);
+ if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)
+ {
+ return passed_clipboard;
+ }
+
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 935fe2b4d0..ed7fd3cd34 100755
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -369,15 +369,74 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
mItemLock[cat_id] = false;
}
+void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::EType type)
+{
+ // Make a list of folders that are not "main_id" and are of "type"
+ std::vector<LLUUID> folder_ids;
+ for (cat_map_t::iterator cit = mCategoryMap.begin(); cit != mCategoryMap.end(); ++cit)
+ {
+ LLViewerInventoryCategory* cat = cit->second;
+ if ((cat->getPreferredType() == type) && (cat->getUUID() != main_id))
+ {
+ folder_ids.push_back(cat->getUUID());
+ }
+ }
+
+ // Iterate through those folders
+ for (std::vector<LLUUID>::iterator folder_ids_it = folder_ids.begin(); folder_ids_it != folder_ids.end(); ++folder_ids_it)
+ {
+ LLUUID folder_id = (*folder_ids_it);
+
+ // Get the content of this folder
+ cat_array_t* cats;
+ item_array_t* items;
+ getDirectDescendentsOf(folder_id, cats, items);
+
+ // Move all items to the main folder
+ // Note : we get the list of UUIDs and iterate on them instead of iterating directly on item_array_t
+ // elements. This is because moving elements modify the maps and, consequently, invalidate iterators on them.
+ // This "gather and iterate" method is verbose but resilient.
+ std::vector<LLUUID> list_uuids;
+ for (item_array_t::const_iterator it = items->begin(); it != items->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+ {
+ LLViewerInventoryItem* item = getItem(*it);
+ changeItemParent(item, main_id, TRUE);
+ }
+
+ // Move all folders to the main folder
+ list_uuids.clear();
+ for (cat_array_t::const_iterator it = cats->begin(); it != cats->end(); ++it)
+ {
+ list_uuids.push_back((*it)->getUUID());
+ }
+ for (std::vector<LLUUID>::const_iterator it = list_uuids.begin(); it != list_uuids.end(); ++it)
+ {
+ LLViewerInventoryCategory* cat = getCategory(*it);
+ changeCategoryParent(cat, main_id, TRUE);
+ }
+
+ // Purge the emptied folder
+ // Note: we'd like to use purgeObject() but it doesn't cleanly eliminate the folder
+ // which leads to issues further down the road when the folder is found again
+ //purgeObject(folder_id);
+ // We remove the folder and empty the trash instead which seems to work
+ removeCategory(folder_id);
+ gInventory.emptyFolderType("", LLFolderType::FT_TRASH);
+ }
+}
+
// findCategoryUUIDForType() returns the uuid of the category that
// specifies 'type' as what it defaults to containing. The category is
// not necessarily only for that type. *NOTE: This will create a new
// inventory category on the fly if one does not exist.
-const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,
+const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*,
bool find_in_library*/)
{
LLUUID rv = LLUUID::null;
-
const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();
if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
{
@@ -392,9 +451,9 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
S32 count = cats->count();
for(S32 i = 0; i < count; ++i)
{
- if(cats->get(i)->getPreferredType() == preferred_type)
+ if (cats->get(i)->getPreferredType() == preferred_type)
{
- rv = cats->get(i)->getUUID();
+ rv = cats->get(i)->getUUID();
break;
}
}
@@ -587,7 +646,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
return id;
}
-// Starting with the object specified, add it's descendents to the
+// Starting with the object specified, add its descendents to the
// array provided, but do not add the inventory object specified by
// id. There is no guaranteed order. Neither array will be erased
// before adding objects to it. Do not store a copy of the pointers
@@ -1003,7 +1062,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
new_cat->copyViewerCategory(cat);
addCategory(new_cat);
- // make sure this category is correctly referenced by it's parent.
+ // make sure this category is correctly referenced by its parent.
cat_array_t* cat_array;
cat_array = getUnlockedCatArray(cat->getParentUUID());
if(cat_array)
@@ -1209,12 +1268,6 @@ void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
// folders, items, etc in a fairly efficient manner.
void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
{
- EHasChildren children = categoryHasChildren(id);
- if(children == CHILDREN_NO)
- {
- llinfos << "Not purging descendents of " << id << llendl;
- return;
- }
LLPointer<LLViewerInventoryCategory> cat = getCategory(id);
if (cat.notNull())
{
@@ -1225,7 +1278,7 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
<< " iterate and purge non hidden items" << llendl;
cat_array_t* categories;
item_array_t* items;
- // Get the list of direct descendants in tha categoy passed as argument
+ // Get the list of direct descendants in that category passed as argument
getDirectDescendentsOf(id, categories, items);
std::vector<LLUUID> list_uuids;
// Make a unique list with all the UUIDs of the direct descendants (items and categories are not treated differently)
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8aac879a93..544ca5e5dc 100755
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -263,6 +263,11 @@ public:
// Get the inventoryID or item that this item points to, else just return object_id
const LLUUID& getLinkedItemID(const LLUUID& object_id) const;
LLViewerInventoryItem* getLinkedItem(const LLUUID& object_id) const;
+
+ // Copy content of all folders of type "type" into folder "id" and delete/purge the empty folders
+ // Note : This method has been designed for FT_OUTBOX (aka Merchant Outbox) but can be used for other categories
+ void consolidateForType(const LLUUID& id, LLFolderType::EType type);
+
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 9db175ec2e..16427f2016 100755
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -690,15 +690,24 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
if (!mCategoryMap.size())
return;
+ std::vector<LLUUID> deleted_categories_ids;
+
for (category_map_t::iterator iter = mCategoryMap.begin();
iter != mCategoryMap.end();
++iter)
{
const LLUUID& cat_id = (*iter).first;
-
+ LLCategoryData& cat_data = (*iter).second;
+
LLViewerInventoryCategory* category = gInventory.getCategory(cat_id);
if (!category)
+ {
+ llwarns << "Category : Category id = " << cat_id << " disappeared" << llendl;
+ cat_data.mCallback();
+ // Keep track of those deleted categories so we can remove them
+ deleted_categories_ids.push_back(cat_id);
continue;
+ }
const S32 version = category->getVersion();
const S32 expected_num_descendents = category->getDescendentCount();
@@ -726,8 +735,6 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
const S32 current_num_known_descendents = cats->count() + items->count();
- LLCategoryData& cat_data = (*iter).second;
-
bool cat_changed = false;
// If category version or descendents count has changed
@@ -757,6 +764,12 @@ void LLInventoryCategoriesObserver::changed(U32 mask)
if (cat_changed)
cat_data.mCallback();
}
+
+ // Remove deleted categories from the list
+ for (std::vector<LLUUID>::iterator deleted_id = deleted_categories_ids.begin(); deleted_id != deleted_categories_ids.end(); ++deleted_id)
+ {
+ removeCategory(*deleted_id);
+ }
}
bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e5b9e11d48..81ee7ac07e 100755
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -137,7 +137,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
LLPanel(p),
mInventoryObserver(NULL),
mCompletionObserver(NULL),
- mFolderRoot(NULL),
mScroller(NULL),
mSortOrderSetting(p.sort_order_setting),
mInventory(p.inventory),
@@ -196,6 +195,32 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
return LLUICtrlFactory::create<LLFolderView>(p);
}
+void LLInventoryPanel::clearFolderRoot()
+{
+ gIdleCallbacks.deleteFunction(idle, this);
+ gIdleCallbacks.deleteFunction(onIdle, this);
+
+ if (mInventoryObserver)
+ {
+ mInventory->removeObserver(mInventoryObserver);
+ delete mInventoryObserver;
+ mInventoryObserver = NULL;
+ }
+ if (mCompletionObserver)
+ {
+ mInventory->removeObserver(mCompletionObserver);
+ delete mCompletionObserver;
+ mCompletionObserver = NULL;
+ }
+
+ if (mScroller)
+ {
+ removeChild(mScroller);
+ delete mScroller;
+ mScroller = NULL;
+ }
+}
+
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
// save off copy of params
@@ -203,23 +228,23 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
// Clear up the root view
// Note: This needs to be done *before* we build the new folder view
LLUUID root_id = getRootFolderID();
- if (mFolderRoot)
+ if (mFolderRoot.get())
{
removeItemID(root_id);
- mFolderRoot->destroyView();
- mFolderRoot = NULL;
+ mFolderRoot.get()->destroyView();
}
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
{
// Determine the root folder in case specified, and
// build the views starting with that folder.
- mFolderRoot = createFolderRoot(root_id);
+ LLFolderView* folder_view = createFolderRoot(root_id);
+ mFolderRoot = folder_view->getHandle();
- addItemID(root_id, mFolderRoot);
+ addItemID(root_id, mFolderRoot.get());
}
mCommitCallbackRegistrar.popScope();
- mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
// Scroller
LLRect scroller_view_rect = getRect();
@@ -228,10 +253,10 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
scroller_params.rect(scroller_view_rect);
mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
addChild(mScroller);
- mScroller->addChild(mFolderRoot);
- mFolderRoot->setScrollContainer(mScroller);
- mFolderRoot->setFollowsAll();
- mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
+ mScroller->addChild(mFolderRoot.get());
+ mFolderRoot.get()->setScrollContainer(mScroller);
+ mFolderRoot.get()->setFollowsAll();
+ mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox);
// Set up the callbacks from the inventory we're viewing, and then build everything.
mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -259,8 +284,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
}
// hide inbox
- getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
- getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+ if (!gSavedSettings.getBOOL("InventoryOutboxMakeVisible"))
+ {
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+ getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+ }
// set the filter for the empty folder if the debug setting is on
if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
@@ -277,23 +305,13 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
LLInventoryPanel::~LLInventoryPanel()
{
- gIdleCallbacks.deleteFunction(idle, this);
-
U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
- if (mSortOrderSetting != INHERIT_SORT_ORDER)
- {
- gSavedSettings.setU32(mSortOrderSetting, sort_order);
- }
-
- gIdleCallbacks.deleteFunction(onIdle, this);
-
- // LLView destructor will take care of the sub-views.
- mInventory->removeObserver(mInventoryObserver);
- mInventory->removeObserver(mCompletionObserver);
- delete mInventoryObserver;
- delete mCompletionObserver;
-
- mScroller = NULL;
+ if (mSortOrderSetting != INHERIT_SORT_ORDER)
+ {
+ gSavedSettings.setU32(mSortOrderSetting, sort_order);
+ }
+
+ clearFolderRoot();
}
void LLInventoryPanel::draw()
@@ -360,9 +378,9 @@ void LLInventoryPanel::setSortOrder(U32 order)
if (order != getFolderViewModel()->getSorter().getSortOrder())
{
getFolderViewModel()->setSorter(sorter);
- mFolderRoot->arrangeAll();
+ mFolderRoot.get()->arrangeAll();
// try to keep selection onscreen, even if it wasn't to start with
- mFolderRoot->scrollToShowSelection();
+ mFolderRoot.get()->scrollToShowSelection();
}
}
@@ -505,7 +523,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
// Add the UI element for this item.
buildNewViews(item_id);
// Select any newly created object that has the auto rename at top of folder root set.
- if(mFolderRoot->getRoot()->needsAutoRename())
+ if(mFolderRoot.get()->getRoot()->needsAutoRename())
{
setSelection(item_id, FALSE);
}
@@ -556,17 +574,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
}
}
-LLFolderView* LLInventoryPanel::getRootFolder()
-{
- return mFolderRoot;
-}
-
LLUUID LLInventoryPanel::getRootFolderID()
{
- if (mFolderRoot && mFolderRoot->getViewModelItem())
+ if (mFolderRoot.get() && mFolderRoot.get()->getViewModelItem())
{
- return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
-
+ return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot.get()->getViewModelItem())->getUUID();
}
else
{
@@ -587,6 +599,9 @@ LLUUID LLInventoryPanel::getRootFolderID()
}
else if (preferred_type != LLFolderType::FT_NONE)
{
+ LLStringExplicit label(mParams.start_folder.name());
+ setLabel(label);
+
root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
if (root_id.isNull())
{
@@ -646,24 +661,33 @@ void LLInventoryPanel::idle(void* user_data)
}
- panel->mFolderRoot->update();
- // while dragging, update selection rendering to reflect single/multi drag status
- if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
- {
- EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
- if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
- {
- panel->mFolderRoot->setShowSingleSelection(TRUE);
- }
- else
- {
- panel->mFolderRoot->setShowSingleSelection(FALSE);
- }
-}
- else
- {
- panel->mFolderRoot->setShowSingleSelection(FALSE);
- }
+ // Take into account the fact that the root folder might be invalidated
+ if (panel->mFolderRoot.get())
+ {
+ panel->mFolderRoot.get()->update();
+ // while dragging, update selection rendering to reflect single/multi drag status
+ if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+ {
+ EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+ if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+ {
+ panel->mFolderRoot.get()->setShowSingleSelection(TRUE);
+ }
+ else
+ {
+ panel->mFolderRoot.get()->setShowSingleSelection(FALSE);
+ }
+ }
+ else
+ {
+ panel->mFolderRoot.get()->setShowSingleSelection(FALSE);
+ }
+ }
+ else
+ {
+ llwarns << "Inventory : Deleted folder root detected on panel" << llendl;
+ panel->clearFolderRoot();
+ }
}
@@ -714,7 +738,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
LLFolderViewFolder::Params params(mParams.folder);
params.name = bridge->getDisplayName();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.tool_tip = params.name;
@@ -730,7 +754,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
params.name = bridge->getDisplayName();
params.creation_date = bridge->getCreationDate();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
@@ -771,7 +795,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
LLInventoryType::IT_CATEGORY,
this,
&mInventoryViewModel,
- mFolderRoot,
+ mFolderRoot.get(),
objectp->getUUID());
if (new_listener)
{
@@ -787,7 +811,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
item->getInventoryType(),
this,
&mInventoryViewModel,
- mFolderRoot,
+ mFolderRoot.get(),
item->getUUID(),
item->getFlags());
@@ -844,7 +868,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
void LLInventoryPanel::openStartFolderOrMyInventory()
{
// Find My Inventory folder and open it up by name
- for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
+ for (LLView *child = mFolderRoot.get()->getFirstChild(); child; child = mFolderRoot.get()->findNextSibling(child))
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
@@ -859,12 +883,12 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
void LLInventoryPanel::onItemsCompletion()
{
- if (mFolderRoot) mFolderRoot->updateMenu();
+ if (mFolderRoot.get()) mFolderRoot.get()->updateMenu();
}
void LLInventoryPanel::openSelected()
{
- LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
+ LLFolderViewItem* folder_item = mFolderRoot.get()->getCurSelectedItem();
if(!folder_item) return;
LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
if(!bridge) return;
@@ -873,7 +897,7 @@ void LLInventoryPanel::openSelected()
void LLInventoryPanel::unSelectAll()
{
- mFolderRoot->setSelection(NULL, FALSE, FALSE);
+ mFolderRoot.get()->setSelection(NULL, FALSE, FALSE);
}
@@ -911,14 +935,14 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
// If folder view is empty the (x, y) point won't be in its rect
// so the handler must be called explicitly.
// but only if was not handled before. See EXT-6746.
- if (!handled && !mFolderRoot->hasVisibleChildren())
+ if (!handled && !mFolderRoot.get()->hasVisibleChildren())
{
- handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ handled = mFolderRoot.get()->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
if (handled)
{
- mFolderRoot->setDragAndDropThisFrame();
+ mFolderRoot.get()->setDragAndDropThisFrame();
}
}
@@ -928,7 +952,7 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLInventoryPanel::onFocusLost()
{
// inventory no longer handles cut/copy/paste/delete
- if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot)
+ if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot.get())
{
LLEditMenuHandler::gEditMenuHandler = NULL;
}
@@ -939,7 +963,7 @@ void LLInventoryPanel::onFocusLost()
void LLInventoryPanel::onFocusReceived()
{
// inventory now handles cut/copy/paste/delete
- LLEditMenuHandler::gEditMenuHandler = mFolderRoot;
+ LLEditMenuHandler::gEditMenuHandler = mFolderRoot.get();
LLPanel::onFocusReceived();
}
@@ -950,7 +974,7 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
if (acceptsBadge())
{
- badge_added = badge->addToView(mFolderRoot);
+ badge_added = badge->addToView(mFolderRoot.get());
}
return badge_added;
@@ -958,8 +982,8 @@ bool LLInventoryPanel::addBadge(LLBadge * badge)
void LLInventoryPanel::openAllFolders()
{
- mFolderRoot->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
- mFolderRoot->arrangeAll();
+ mFolderRoot.get()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_DOWN);
+ mFolderRoot.get()->arrangeAll();
}
void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
@@ -975,9 +999,9 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
{
- if (mFolderRoot)
+ if (mFolderRoot.get())
{
- mFolderRoot->setSelectCallback(cb);
+ mFolderRoot.get()->setSelectCallback(cb);
}
}
@@ -1001,7 +1025,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
}
}
- LLFolderView* fv = getRootFolder();
+ LLFolderView* fv = mFolderRoot.get();
if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
{
fv->setNeedsAutoRename(FALSE);
@@ -1020,7 +1044,7 @@ void LLInventoryPanel::doCreate(const LLSD& userdata)
bool LLInventoryPanel::beginIMSession()
{
- std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();
std::string name;
@@ -1114,7 +1138,7 @@ bool LLInventoryPanel::beginIMSession()
bool LLInventoryPanel::attachObject(const LLSD& userdata)
{
// Copy selected item UUIDs to a vector.
- std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selected_items = mFolderRoot.get()->getSelectionList();
uuid_vec_t items;
for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
set_iter != selected_items.end();
@@ -1141,7 +1165,7 @@ BOOL LLInventoryPanel::getSinceLogoff()
void LLInventoryPanel::dumpSelectionInformation(void* user_data)
{
LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
- iv->mFolderRoot->dumpSelectionInformation();
+ iv->mFolderRoot.get()->dumpSelectionInformation();
}
BOOL is_inventorysp_active()
@@ -1343,7 +1367,7 @@ void LLInventoryPanel::updateSelection()
void LLInventoryPanel::doToSelected(const LLSD& userdata)
{
- LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), userdata.asString());
return;
}
@@ -1357,7 +1381,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
// Open selected items if enter key hit on the inventory panel
if (mask == MASK_NONE)
{
- LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "open");
handled = TRUE;
}
break;
@@ -1367,7 +1391,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
// Note: on Mac laptop keyboards, backspace and delete are one and the same
if (isSelectionRemovable() && (mask == MASK_NONE))
{
- LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
+ LLInventoryAction::doToSelected(mInventory, mFolderRoot.get(), "delete");
handled = TRUE;
}
break;
@@ -1378,9 +1402,9 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
bool LLInventoryPanel::isSelectionRemovable()
{
bool can_delete = false;
- if (mFolderRoot)
+ if (mFolderRoot.get())
{
- std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList();
+ std::set<LLFolderViewItem*> selection_set = mFolderRoot.get()->getSelectionList();
if (!selection_set.empty())
{
can_delete = true;
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 00a90325ad..c0ce513694 100755
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -181,7 +181,7 @@ public:
LLInventoryFilter::EFolderShow getShowFolderState();
// This method is called when something has changed about the inventory.
void modelChanged(U32 mask);
- LLFolderView* getRootFolder();
+ LLFolderView* getRootFolder() { return mFolderRoot.get(); }
LLUUID getRootFolderID();
LLScrollContainer* getScrollableContainer() { return mScroller; }
@@ -217,8 +217,11 @@ public:
void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
void updateSelection();
- LLFolderViewModelInventory* getFolderViewModel();
- const LLFolderViewModelInventory* getFolderViewModel() const;
+ LLFolderViewModelInventory* getFolderViewModel() { return &mInventoryViewModel; }
+ const LLFolderViewModelInventory* getFolderViewModel() const { return &mInventoryViewModel; }
+
+ // Clean up stuff when the folder root gets deleted
+ void clearFolderRoot();
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
@@ -233,7 +236,7 @@ protected:
bool mShowItemLinkOverlays; // Shows link graphic over inventory item icons
bool mShowEmptyMessage;
- LLFolderView* mFolderRoot;
+ LLHandle<LLFolderView> mFolderRoot;
LLScrollContainer* mScroller;
LLFolderViewModelInventory mInventoryViewModel;
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index dd402de394..a92df8250e 100755
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -46,6 +46,7 @@ LLLandmarkList gLandmarkList;
LLLandmarkList::~LLLandmarkList()
{
std::for_each(mList.begin(), mList.end(), DeletePairedPointer());
+ mList.clear();
}
LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t cb)
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 4cbdfde868..bd21d04b4a 100755
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -61,6 +61,7 @@
#include "llglheaders.h"
#include "lltrans.h"
#include "llvoavatarself.h"
+#include "llhudrender.h"
const F32 RADIUS_PIXELS = 100.f; // size in screen space
const F32 SQ_RADIUS = RADIUS_PIXELS * RADIUS_PIXELS;
@@ -452,6 +453,9 @@ BOOL LLManipRotate::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
// Route future Mouse messages here preemptively. (Release on mouse up.)
setMouseCapture( TRUE );
LLSelectMgr::getInstance()->enableSilhouette(FALSE);
+
+ mHelpTextTimer.reset();
+ sNumTimesHelpTextShown++;
return TRUE;
}
@@ -1111,6 +1115,31 @@ void LLManipRotate::renderSnapGuides()
}
}
}
+
+
+ // render help text
+ if (mObjectSelection->getSelectType() != SELECT_TYPE_HUD)
+ {
+ if (mHelpTextTimer.getElapsedTimeF32() < sHelpTextVisibleTime + sHelpTextFadeTime && sNumTimesHelpTextShown < sMaxTimesShowHelpText)
+ {
+ LLVector3 selection_center_start = LLSelectMgr::getInstance()->getSavedBBoxOfSelection().getCenterAgent();
+
+ LLVector3 offset_dir = LLViewerCamera::getInstance()->getUpAxis();
+
+ F32 line_alpha = gSavedSettings.getF32("GridOpacity");
+
+ LLVector3 help_text_pos = selection_center_start + (mRadiusMeters * 3.f * offset_dir);
+ const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
+
+ std::string help_text = LLTrans::getString("manip_hint1");
+ LLColor4 help_text_color = LLColor4::white;
+ help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
+ help_text_pos -= offset_dir * mRadiusMeters * 0.4f;
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ }
+ }
}
// Returns TRUE if center of sphere is visible. Also sets a bunch of member variables that are used later (e.g. mCenterToCam)
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index ae0884ac5d..6dc03d8382 100755
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -59,7 +59,7 @@
#include "v2math.h"
#include "llvoavatar.h"
#include "llmeshrepository.h"
-
+#include "lltrans.h"
const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f;
const F32 SNAP_GUIDE_SCREEN_OFFSET = 0.05f;
@@ -68,7 +68,7 @@ const F32 SELECTED_MANIPULATOR_SCALE = 1.2f;
const F32 MANIPULATOR_SCALE_HALF_LIFE = 0.07f;
const S32 NUM_MANIPULATORS = 14;
-const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] =
+const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] =
{
LLManip::LL_CORNER_NNN,
LLManip::LL_CORNER_NNP,
@@ -87,7 +87,7 @@ const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] =
};
-F32 get_default_max_prim_scale(bool is_flora)
+F32 get_default_max_prim_scale(bool is_flora)
{
// a bit of a hack, but if it's foilage, we don't want to use the
// new larger scale which would result in giant trees and grass
@@ -97,7 +97,7 @@ F32 get_default_max_prim_scale(bool is_flora)
return DEFAULT_MAX_PRIM_SCALE;
}
else
- {
+ {
return DEFAULT_MAX_PRIM_SCALE_NO_MESH;
}
}
@@ -179,7 +179,7 @@ void LLManipScale::handleSelect()
}
LLManipScale::LLManipScale( LLToolComposite* composite )
- :
+ :
LLManip( std::string("Scale"), composite ),
mBoxHandleSize( 1.f ),
mScaledBoxHandleSize( 1.f ),
@@ -190,10 +190,12 @@ LLManipScale::LLManipScale( LLToolComposite* composite )
mScaleSnapUnit1(1.f),
mScaleSnapUnit2(1.f),
mSnapRegimeOffset(0.f),
+ mTickPixelSpacing1(0.f),
+ mTickPixelSpacing2(0.f),
mSnapGuideLength(0.f),
- mInSnapRegime(FALSE),
- mScaleSnapValue(0.f)
-{
+ mSnapRegime(SNAP_REGIME_NONE),
+ mScaleSnappedValue(0.f)
+{
mManipulatorScales = new F32[NUM_MANIPULATORS];
for (S32 i = 0; i < NUM_MANIPULATORS; i++)
{
@@ -214,7 +216,7 @@ void LLManipScale::render()
LLGLDepthTest gls_depth(GL_TRUE);
LLGLEnable gl_blend(GL_BLEND);
LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
-
+
if( canAffectSelection() )
{
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -226,11 +228,11 @@ void LLManipScale::render()
}
////////////////////////////////////////////////////////////////////////
- // Calculate size of drag handles
+ // Calculate size of drag handles
const F32 BOX_HANDLE_BASE_SIZE = 50.0f; // box size in pixels = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR
const F32 BOX_HANDLE_BASE_FACTOR = 0.2f;
-
+
LLVector3 center_agent = gAgent.getPosAgentFromGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal());
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
@@ -283,7 +285,7 @@ void LLManipScale::render()
rot.getAngleAxis(&angle_radians, &x, &y, &z);
gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
-
+
{
LLGLEnable poly_offset(GL_POLYGON_OFFSET_FILL);
glPolygonOffset( -2.f, -2.f);
@@ -345,7 +347,7 @@ BOOL LLManipScale::handleMouseDownOnPart( S32 x, S32 y, MASK mask )
LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
LLVector3 box_center_agent = bbox.getCenterAgent();
LLVector3 box_corner_agent = bbox.localToAgent( unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ) );
-
+
updateSnapGuides(bbox);
mDragStartPointGlobal = gAgent.getPosGlobalFromAgent(box_corner_agent);
@@ -372,27 +374,27 @@ BOOL LLManipScale::handleMouseUp(S32 x, S32 y, MASK mask)
if( hasMouseCapture() )
{
- if( (LL_FACE_MIN <= (S32)mManipPart)
+ if( (LL_FACE_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_FACE_MAX) )
{
sendUpdates(TRUE,TRUE,FALSE);
}
else
- if( (LL_CORNER_MIN <= (S32)mManipPart)
+ if( (LL_CORNER_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_CORNER_MAX) )
{
sendUpdates(TRUE,TRUE,TRUE);
}
-
+
//send texture update
LLSelectMgr::getInstance()->adjustTexturesByScale(TRUE, getStretchTextures());
-
+
LLSelectMgr::getInstance()->enableSilhouette(TRUE);
mManipPart = LL_NO_PART;
// Might have missed last update due to UPDATE_DELAY timing
LLSelectMgr::getInstance()->sendMultipleUpdate( mLastUpdateFlags );
-
+
//gAgent.setObjectTracking(gSavedSettings.getBOOL("TrackFocusObject"));
LLSelectMgr::getInstance()->saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK);
}
@@ -413,15 +415,15 @@ BOOL LLManipScale::handleHover(S32 x, S32 y, MASK mask)
{
drag( x, y );
}
- lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipScale (active)" << llendl;
+ lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipScale (active)" << llendl;
}
else
{
- mInSnapRegime = FALSE;
+ mSnapRegime = SNAP_REGIME_NONE;
// not dragging...
highlightManipulators(x, y);
}
-
+
// Patch up textures, if possible.
LLSelectMgr::getInstance()->adjustTexturesByScale(FALSE, getStretchTextures());
@@ -458,7 +460,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
LLMatrix4 projMatrix = LLViewerCamera::getInstance()->getProjection();
LLMatrix4 modelView = LLViewerCamera::getInstance()->getModelview();
transform.initAll(LLVector3(1.f, 1.f, 1.f), bbox.getRotation(), bbox.getPositionAgent());
-
+
transform *= modelView;
transform *= projMatrix;
}
@@ -477,7 +479,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
mManipulatorVertices[numManips++] = LLVector4(max.mV[VX], min.mV[VY], max.mV[VZ], 1.f);
mManipulatorVertices[numManips++] = LLVector4(max.mV[VX], max.mV[VY], min.mV[VZ], 1.f);
mManipulatorVertices[numManips++] = LLVector4(max.mV[VX], max.mV[VY], max.mV[VZ], 1.f);
-
+
// 1-D highlights are applicable iff one object is selected
if( mObjectSelection->getObjectCount() == 1 )
{
@@ -492,13 +494,13 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
for_each(mProjectedManipulators.begin(), mProjectedManipulators.end(), DeletePointer());
mProjectedManipulators.clear();
-
+
for (S32 i = 0; i < numManips; i++)
{
LLVector4 projectedVertex = mManipulatorVertices[i] * transform;
projectedVertex = projectedVertex * (1.f / projectedVertex.mV[VW]);
- ManipulatorHandle* projManipulator = new ManipulatorHandle(LLVector3(projectedVertex.mV[VX], projectedVertex.mV[VY],
+ ManipulatorHandle* projManipulator = new ManipulatorHandle(LLVector3(projectedVertex.mV[VX], projectedVertex.mV[VY],
projectedVertex.mV[VZ]), MANIPULATOR_IDS[i], (i < 7) ? SCALE_MANIP_CORNER : SCALE_MANIP_FACE);
mProjectedManipulators.insert(projManipulator);
}
@@ -512,13 +514,13 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
mHighlightedPart = LL_NO_PART;
- for (minpulator_list_t::iterator iter = mProjectedManipulators.begin();
+ for (manipulator_list_t::iterator iter = mProjectedManipulators.begin();
iter != mProjectedManipulators.end(); ++iter)
{
ManipulatorHandle* manipulator = *iter;
{
- manip2d.setVec(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height);
-
+ manip2d.set(manipulator->mPosition.mV[VX] * half_width, manipulator->mPosition.mV[VY] * half_height);
+
delta = manip2d - mousePos;
if (delta.magVecSquared() < MAX_MANIP_SELECT_DISTANCE_SQUARED)
{
@@ -549,36 +551,36 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
void LLManipScale::renderFaces( const LLBBox& bbox )
{
- // Don't bother to render the drag handles for 1-D scaling if
+ // Don't bother to render the drag handles for 1-D scaling if
// more than one object is selected or if it is an attachment
if ( mObjectSelection->getObjectCount() > 1 )
{
return;
}
- // This is a flattened representation of the box as render here
- // .
- // (+++) (++-) /|\t
- // +------------+ | (texture coordinates)
- // | | |
- // | 1 | (*) --->s
- // | +X |
+ // This is a flattened representation of the box as render here
+ // .
+ // (+++) (++-) /|\t
+ // +------------+ | (texture coordinates)
+ // | | |
+ // | 1 | (*) --->s
+ // | +X |
// | |
- // (+++) (+-+)| |(+--) (++-) (+++)
- // +------------+------------+------------+------------+
- // |0 3|3 7|7 4|4 0|
- // | 0 | 4 | 5 | 2 |
- // | +Z | -Y | -Z | +Y |
- // | | | | |
- // |1 2|2 6|6 5|5 1|
- // +------------+------------+------------+------------+
- // (-++) (--+)| |(---) (-+-) (-++)
- // | 3 |
- // | -X |
- // | |
- // | |
- // +------------+
- // (-++) (-+-)
+ // (+++) (+-+)| |(+--) (++-) (+++)
+ // +------------+------------+------------+------------+
+ // |0 3|3 7|7 4|4 0|
+ // | 0 | 4 | 5 | 2 |
+ // | +Z | -Y | -Z | +Y |
+ // | | | | |
+ // |1 2|2 6|6 5|5 1|
+ // +------------+------------+------------+------------+
+ // (-++) (--+)| |(---) (-+-) (-++)
+ // | 3 |
+ // | -X |
+ // | |
+ // | |
+ // +------------+
+ // (-++) (-+-)
LLColor4 highlight_color( 1.f, 1.f, 1.f, 0.5f);
LLColor4 normal_color( 1.f, 1.f, 1.f, 0.3f);
@@ -602,7 +604,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
{
gGL.color4fv( default_normal_color.mV );
LLGLDepthTest gls_depth(GL_FALSE);
- gGL.begin(LLRender::QUADS);
+ gGL.begin(LLRender::QUADS);
{
// Face 0
gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]);
@@ -645,9 +647,9 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
// Find nearest vertex
LLVector3 orientWRTHead = bbox.agentToLocalBasis( bbox.getCenterAgent() - gAgentCamera.getCameraPositionAgent() );
- U32 nearest =
- (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
- (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
+ U32 nearest =
+ (orientWRTHead.mV[0] < 0.0f ? 1 : 0) +
+ (orientWRTHead.mV[1] < 0.0f ? 2 : 0) +
(orientWRTHead.mV[2] < 0.0f ? 4 : 0);
// opposite faces on Linden cubes:
@@ -656,7 +658,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
// 2 & 4
// Table of order to draw faces, based on nearest vertex
- static U32 face_list[8][6] = {
+ static U32 face_list[8][6] = {
{ 2,0,1, 4,5,3 }, // v6 F201 F453
{ 2,0,3, 4,5,1 }, // v7 F203 F451
{ 4,0,1, 2,5,3 }, // v5 F401 F253
@@ -723,7 +725,7 @@ void LLManipScale::renderEdges( const LLBBox& bbox )
{
gGL.translatef( center_to_edge.mV[0], center_to_edge.mV[1], center_to_edge.mV[2] );
conditionalHighlight( part );
- gGL.scalef(
+ gGL.scalef(
direction.mV[0] ? edge_width : extent.mV[VX],
direction.mV[1] ? edge_width : extent.mV[VY],
direction.mV[2] ? edge_width : extent.mV[VZ] );
@@ -757,7 +759,7 @@ void LLManipScale::renderCorners( const LLBBox& bbox )
y_offset = bbox.getMaxLocal().mV[VY];
}
x_offset = bbox.getMaxLocal().mV[VX];
- }
+ }
}
@@ -782,7 +784,7 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
{
// Draws a single "jacks" style handle: a long, retangular box from start to end.
LLVector3 offset_start = end - start;
- offset_start.normVec();
+ offset_start.normalize();
offset_start = start + mBoxHandleSize * offset_start;
LLVector3 delta = end - offset_start;
@@ -791,7 +793,7 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
gGL.pushMatrix();
{
gGL.translatef( pos.mV[VX], pos.mV[VY], pos.mV[VZ] );
- gGL.scalef(
+ gGL.scalef(
mBoxHandleSize + llabs(delta.mV[VX]),
mBoxHandleSize + llabs(delta.mV[VY]),
mBoxHandleSize + llabs(delta.mV[VZ]));
@@ -805,21 +807,20 @@ void LLManipScale::renderAxisHandle( const LLVector3& start, const LLVector3& en
}
}
-
+// General scale call
void LLManipScale::drag( S32 x, S32 y )
{
- if( (LL_FACE_MIN <= (S32)mManipPart)
+ if( (LL_FACE_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_FACE_MAX) )
{
dragFace( x, y );
}
- else
- if( (LL_CORNER_MIN <= (S32)mManipPart)
+ else if( (LL_CORNER_MIN <= (S32)mManipPart)
&& ((S32)mManipPart <= LL_CORNER_MAX) )
{
dragCorner( x, y );
}
-
+
// store changes to override updates
for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin();
iter != LLSelectMgr::getInstance()->getSelection()->end(); iter++)
@@ -834,139 +835,110 @@ void LLManipScale::drag( S32 x, S32 y )
selectNode->mLastScale = cur->getScale();
selectNode->mLastPositionLocal = cur->getPosition();
}
- }
+ }
LLSelectMgr::getInstance()->updateSelectionCenter();
- gAgentCamera.clearFocusObject();
+ gAgentCamera.clearFocusObject();
}
-// Scale around the
+// Scale on three axis simultaneously
void LLManipScale::dragCorner( S32 x, S32 y )
{
- LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
-
// Suppress scale if mouse hasn't moved.
if (x == mLastMouseX && y == mLastMouseY)
{
- // sendUpdates(TRUE,TRUE,TRUE);
return;
}
mLastMouseX = x;
mLastMouseY = y;
- LLVector3d drag_start_point_global = mDragStartPointGlobal;
- LLVector3d drag_start_center_global = mDragStartCenterGlobal;
- LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(drag_start_point_global);
- LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global);
+ LLVector3 drag_start_point_agent = gAgent.getPosAgentFromGlobal(mDragStartPointGlobal);
+ LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(mDragStartCenterGlobal);
LLVector3d drag_start_dir_d;
- drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global);
- LLVector3 drag_start_dir_f;
- drag_start_dir_f.setVec(drag_start_dir_d);
+ drag_start_dir_d.set(mDragStartPointGlobal - mDragStartCenterGlobal);
F32 s = 0;
F32 t = 0;
- nearestPointOnLineFromMouse(x, y,
- drag_start_center_agent,
- drag_start_point_agent,
- s, t );
-
- F32 drag_start_dist = dist_vec(drag_start_point_agent, drag_start_center_agent);
+ nearestPointOnLineFromMouse(x, y,
+ drag_start_center_agent,
+ drag_start_point_agent,
+ s, t );
if( s <= 0 ) // we only care about intersections in front of the camera
{
return;
}
+ mDragPointGlobal = lerp(mDragStartCenterGlobal, mDragStartPointGlobal, t);
- LLVector3d drag_point_global = drag_start_center_global + t * drag_start_dir_d;
-
- F32 scale_factor = t;
-
- BOOL uniform = LLManipScale::getUniform();
-
- if( !uniform )
- {
- scale_factor = 0.5f + (scale_factor * 0.5f);
- }
+ LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
+ F32 scale_factor = 1.f;
+ F32 max_scale = partToMaxScale(mManipPart, bbox);
+ F32 min_scale = partToMinScale(mManipPart, bbox);
+ BOOL uniform = LLManipScale::getUniform();
// check for snapping
- LLVector3 drag_center_agent = gAgent.getPosAgentFromGlobal(drag_point_global);
LLVector3 mouse_on_plane1;
- getMousePointOnPlaneAgent(mouse_on_plane1, x, y, drag_center_agent, mScalePlaneNormal1);
- LLVector3 mouse_on_plane2;
- getMousePointOnPlaneAgent(mouse_on_plane2, x, y, drag_center_agent, mScalePlaneNormal2);
- LLVector3 mouse_dir_1 = mouse_on_plane1 - mScaleCenter;
- LLVector3 mouse_dir_2 = mouse_on_plane2 - mScaleCenter;
- LLVector3 mouse_to_scale_line_1 = mouse_dir_1 - projected_vec(mouse_dir_1, mScaleDir);
- LLVector3 mouse_to_scale_line_2 = mouse_dir_2 - projected_vec(mouse_dir_2, mScaleDir);
- LLVector3 mouse_to_scale_line_dir_1 = mouse_to_scale_line_1;
- mouse_to_scale_line_dir_1.normVec();
- if (mouse_to_scale_line_dir_1 * mSnapGuideDir1 < 0.f)
- {
- // need to keep sign of mouse offset wrt to snap guide direction
- mouse_to_scale_line_dir_1 *= -1.f;
- }
- LLVector3 mouse_to_scale_line_dir_2 = mouse_to_scale_line_2;
- mouse_to_scale_line_dir_2.normVec();
- if (mouse_to_scale_line_dir_2 * mSnapGuideDir2 < 0.f)
- {
- // need to keep sign of mouse offset wrt to snap guide direction
- mouse_to_scale_line_dir_2 *= -1.f;
- }
-
- F32 snap_dir_dot_mouse_offset1 = mSnapGuideDir1 * mouse_to_scale_line_dir_1;
- F32 snap_dir_dot_mouse_offset2 = mSnapGuideDir2 * mouse_to_scale_line_dir_2;
+ getMousePointOnPlaneAgent(mouse_on_plane1, x, y, mScaleCenter, mScalePlaneNormal1);
+ mouse_on_plane1 -= mScaleCenter;
- F32 dist_from_scale_line_1 = mouse_to_scale_line_1 * mouse_to_scale_line_dir_1;
- F32 dist_from_scale_line_2 = mouse_to_scale_line_2 * mouse_to_scale_line_dir_2;
+ LLVector3 mouse_on_plane2;
+ getMousePointOnPlaneAgent(mouse_on_plane2, x, y, mScaleCenter, mScalePlaneNormal2);
+ mouse_on_plane2 -= mScaleCenter;
- F32 max_scale = partToMaxScale(mManipPart, bbox);
- F32 min_scale = partToMinScale(mManipPart, bbox);
+ LLVector3 projected_drag_pos1 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane1, mSnapGuideDir1));
+ LLVector3 projected_drag_pos2 = inverse_projected_vec(mScaleDir, orthogonal_component(mouse_on_plane2, mSnapGuideDir2));
BOOL snap_enabled = gSavedSettings.getBOOL("SnapEnabled");
- if (snap_enabled && dist_from_scale_line_1 > mSnapRegimeOffset * snap_dir_dot_mouse_offset1)
+ if (snap_enabled && (mouse_on_plane1 - projected_drag_pos1) * mSnapGuideDir1 > mSnapRegimeOffset)
{
- mInSnapRegime = TRUE;
- LLVector3 projected_drag_pos = mouse_on_plane1 - (dist_from_scale_line_1 / snap_dir_dot_mouse_offset1) * mSnapGuideDir1;
- F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir;
+ F32 drag_dist = mScaleDir * projected_drag_pos1; // Projecting the drag position allows for negative results, vs using the length which will result in a "reverse scaling" bug.
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + projected_drag_pos1, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions);
F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions);
- mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ mScaleSnappedValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ scale_factor = mScaleSnappedValue / dist_vec(drag_start_point_agent, drag_start_center_agent);
+ mScaleSnappedValue /= mScaleSnapUnit1 * 2.f;
+ mSnapRegime = SNAP_REGIME_UPPER;
- scale_factor = mScaleSnapValue / drag_start_dist;
- if( !uniform )
+ if (!uniform)
{
scale_factor *= 0.5f;
}
}
- else if (snap_enabled && dist_from_scale_line_2 > mSnapRegimeOffset * snap_dir_dot_mouse_offset2)
+ else if (snap_enabled && (mouse_on_plane2 - projected_drag_pos2) * mSnapGuideDir2 > mSnapRegimeOffset )
{
- mInSnapRegime = TRUE;
- LLVector3 projected_drag_pos = mouse_on_plane2 - (dist_from_scale_line_2 / snap_dir_dot_mouse_offset2) * mSnapGuideDir2;
- F32 drag_dist = (projected_drag_pos - mScaleCenter) * mScaleDir;
+ F32 drag_dist = mScaleDir * projected_drag_pos2; // Projecting the drag position allows for negative results, vs using the length which will result in a "reverse scaling" bug.
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(projected_drag_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + projected_drag_pos2, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
F32 snap_dist = mScaleSnapUnit2 / (2.f * cur_subdivisions);
F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit2 / cur_subdivisions);
- mScaleSnapValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ mScaleSnappedValue = llclamp((drag_dist - (relative_snap_dist - snap_dist)), min_scale, max_scale);
+ scale_factor = mScaleSnappedValue / dist_vec(drag_start_point_agent, drag_start_center_agent);
+ mScaleSnappedValue /= mScaleSnapUnit2 * 2.f;
+ mSnapRegime = SNAP_REGIME_LOWER;
- scale_factor = mScaleSnapValue / drag_start_dist;
- if( !uniform )
+ if (!uniform)
{
scale_factor *= 0.5f;
}
}
- else
+ else
{
- mInSnapRegime = FALSE;
+ mSnapRegime = SNAP_REGIME_NONE;
+ scale_factor = t;
+ if (!uniform)
+ {
+ scale_factor = 0.5f + (scale_factor * 0.5f);
+ }
}
+
F32 max_scale_factor = get_default_max_prim_scale() / MIN_PRIM_SCALE;
F32 min_scale_factor = MIN_PRIM_SCALE / get_default_max_prim_scale();
@@ -1008,7 +980,7 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
const LLVector3& scale = selectNode->mSavedScale;
cur->setScale( scale_factor * scale );
-
+
LLVector3 delta_pos;
LLVector3 original_pos = cur->getPositionEdit();
LLVector3d new_pos_global = drag_global + (selectNode->mSavedPositionGlobal - drag_global) * scale_factor;
@@ -1018,7 +990,7 @@ void LLManipScale::dragCorner( S32 x, S32 y )
}
cur->setPositionAbsoluteGlobal( new_pos_global );
rebuild(cur);
-
+
delta_pos = cur->getPositionEdit() - original_pos;
if (selectNode->mIndividualSelection)
@@ -1059,7 +1031,7 @@ void LLManipScale::dragCorner( S32 x, S32 y )
{
const LLVector3& scale = selectNode->mSavedScale;
cur->setScale( scale_factor * scale, FALSE );
-
+
if (!selectNode->mIndividualSelection)
{
cur->setPosition(selectNode->mSavedPositionLocal * scale_factor);
@@ -1068,19 +1040,14 @@ void LLManipScale::dragCorner( S32 x, S32 y )
rebuild(cur);
}
}
-
-
-
- mDragPointGlobal = drag_point_global;
}
-
+// Scale on a single axis
void LLManipScale::dragFace( S32 x, S32 y )
{
// Suppress scale if mouse hasn't moved.
if (x == mLastMouseX && y == mLastMouseY)
{
- // sendUpdates(TRUE,TRUE,FALSE);
return;
}
@@ -1093,9 +1060,9 @@ void LLManipScale::dragFace( S32 x, S32 y )
LLVector3 drag_start_center_agent = gAgent.getPosAgentFromGlobal(drag_start_center_global);
LLVector3d drag_start_dir_d;
- drag_start_dir_d.setVec(drag_start_point_global - drag_start_center_global);
+ drag_start_dir_d.set(drag_start_point_global - drag_start_center_global);
LLVector3 drag_start_dir_f;
- drag_start_dir_f.setVec(drag_start_dir_d);
+ drag_start_dir_f.set(drag_start_dir_d);
LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
@@ -1139,26 +1106,26 @@ void LLManipScale::dragFace( S32 x, S32 y )
if (snap_enabled && dist_from_scale_line > mSnapRegimeOffset)
{
- mInSnapRegime = TRUE;
+ mSnapRegime = static_cast<ESnapRegimes>(SNAP_REGIME_UPPER | SNAP_REGIME_LOWER); // A face drag doesn't have split regimes.
- if (dist_along_scale_line > max_drag_dist)
+ if (dist_along_scale_line > max_drag_dist)
{
- mScaleSnapValue = max_drag_dist;
+ mScaleSnappedValue = max_drag_dist;
LLVector3 clamp_point = mScaleCenter + max_drag_dist * mScaleDir;
- drag_delta.setVec(clamp_point - drag_start_point_agent);
+ drag_delta.set(clamp_point - drag_start_point_agent);
}
else if (dist_along_scale_line < min_drag_dist)
{
- mScaleSnapValue = min_drag_dist;
+ mScaleSnappedValue = min_drag_dist;
LLVector3 clamp_point = mScaleCenter + min_drag_dist * mScaleDir;
- drag_delta.setVec(clamp_point - drag_start_point_agent);
+ drag_delta.set(clamp_point - drag_start_point_agent);
}
else
{
F32 drag_dist = scale_center_to_mouse * mScaleDir;
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + mScaleDir * drag_dist, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(mScaleCenter + mScaleDir * drag_dist, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
F32 snap_dist = mScaleSnapUnit1 / (2.f * cur_subdivisions);
F32 relative_snap_dist = fmodf(drag_dist + snap_dist, mScaleSnapUnit1 / cur_subdivisions);
relative_snap_dist -= snap_dist;
@@ -1172,7 +1139,7 @@ void LLManipScale::dragFace( S32 x, S32 y )
drag_dist - max_drag_dist,
drag_dist - min_drag_dist);
- mScaleSnapValue = drag_dist - relative_snap_dist;
+ mScaleSnappedValue = (drag_dist - relative_snap_dist) / (mScaleSnapUnit1 * 2.f);
if (llabs(relative_snap_dist) < snap_dist)
{
@@ -1186,9 +1153,9 @@ void LLManipScale::dragFace( S32 x, S32 y )
}
}
}
- else
+ else
{
- mInSnapRegime = FALSE;
+ mSnapRegime = SNAP_REGIME_NONE;
}
LLVector3 dir_agent;
@@ -1204,7 +1171,7 @@ void LLManipScale::dragFace( S32 x, S32 y )
{
dir_agent = bbox.localToAgentBasis( LLVector3::z_axis );
}
- stretchFace(
+ stretchFace(
projected_vec(drag_start_dir_f, dir_agent) + drag_start_center_agent,
projected_vec(drag_delta, dir_agent));
@@ -1223,7 +1190,7 @@ void LLManipScale::sendUpdates( BOOL send_position_update, BOOL send_scale_updat
U32 update_flags = UPD_NONE;
if (send_position_update) update_flags |= UPD_POSITION;
if (send_scale_update) update_flags |= UPD_SCALE;
-
+
// BOOL send_type = SEND_INDIVIDUALS;
if (corner)
{
@@ -1271,7 +1238,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
S32 axis_index = axis.mV[0] ? 0 : (axis.mV[1] ? 1 : 2 );
LLVector3 delta_local = end_local - start_local;
- F32 delta_local_mag = delta_local.magVec();
+ F32 delta_local_mag = delta_local.length();
LLVector3 dir_local;
if (delta_local_mag == 0.f)
{
@@ -1291,13 +1258,13 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
LLVector3 scale = cur->getScale();
scale.mV[axis_index] = desired_scale;
cur->setScale(scale, FALSE);
- rebuild(cur);
+ rebuild(cur);
LLVector3 delta_pos;
if( !getUniform() )
{
LLVector3 delta_pos_local = axis * (0.5f * desired_delta_size);
LLVector3d delta_pos_global;
- delta_pos_global.setVec(cur_bbox.localToAgent( delta_pos_local ) - cur_bbox.getCenterAgent());
+ delta_pos_global.set(cur_bbox.localToAgent( delta_pos_local ) - cur_bbox.getCenterAgent());
LLVector3 cur_pos = cur->getPositionEdit();
if (cur->isRootEdit() && !cur->isAttachment())
@@ -1346,7 +1313,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
void LLManipScale::renderGuidelinesPart( const LLBBox& bbox )
{
LLVector3 guideline_start = bbox.getCenterLocal();
-
+
LLVector3 guideline_end = unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox );
if (!getUniform())
@@ -1355,7 +1322,7 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox )
}
guideline_end -= guideline_start;
- guideline_end.normVec();
+ guideline_end.normalize();
guideline_end *= LLWorld::getInstance()->getRegionWidthInMeters();
guideline_end += guideline_start;
@@ -1376,26 +1343,27 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
LLQuaternion grid_rotation;
LLSelectMgr::getInstance()->getGrid(grid_origin, grid_rotation, grid_scale);
+ bool uniform = LLManipScale::getUniform();
+
LLVector3 box_corner_agent = bbox.localToAgent(unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ));
- mScaleCenter = getUniform() ? bbox.getCenterAgent() : bbox.localToAgent(unitVectorToLocalBBoxExtent( -1.f * partToUnitVector( mManipPart ), bbox ));
+ mScaleCenter = uniform ? bbox.getCenterAgent() : bbox.localToAgent(unitVectorToLocalBBoxExtent( -1.f * partToUnitVector( mManipPart ), bbox ));
mScaleDir = box_corner_agent - mScaleCenter;
- mScaleDir.normVec();
+ mScaleDir.normalize();
if(mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgentCamera.mHUDCurZoom;
-
}
else
{
- F32 object_distance = dist_vec(mScaleCenter, LLViewerCamera::getInstance()->getOrigin());
+ F32 object_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin());
mSnapRegimeOffset = (SNAP_GUIDE_SCREEN_OFFSET * gViewerWindow->getWorldViewWidthRaw() * object_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
}
LLVector3 cam_at_axis;
F32 snap_guide_length;
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
- cam_at_axis.setVec(1.f, 0.f, 0.f);
+ cam_at_axis.set(1.f, 0.f, 0.f);
snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgentCamera.mHUDCurZoom;
}
else
@@ -1404,22 +1372,21 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
F32 manipulator_distance = dist_vec(box_corner_agent, LLViewerCamera::getInstance()->getOrigin());
snap_guide_length = (SNAP_GUIDE_SCREEN_LENGTH * gViewerWindow->getWorldViewWidthRaw() * manipulator_distance) / LLViewerCamera::getInstance()->getPixelMeterRatio();
}
-
+
mSnapGuideLength = snap_guide_length / llmax(0.1f, (llmin(mSnapGuideDir1 * cam_at_axis, mSnapGuideDir2 * cam_at_axis)));
LLVector3 off_axis_dir = mScaleDir % cam_at_axis;
- off_axis_dir.normVec();
+ off_axis_dir.normalize();
if( (LL_FACE_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_FACE_MAX) )
{
- LLVector3 object_scale = bbox.getMaxLocal();
- object_scale.scaleVec(off_axis_dir * ~bbox.getRotation());
- object_scale.abs();
- if (object_scale.mV[VX] > object_scale.mV[VY] && object_scale.mV[VX] > object_scale.mV[VZ])
+ LLVector3 bbox_relative_cam_dir = off_axis_dir * ~bbox.getRotation();
+ bbox_relative_cam_dir.abs();
+ if (bbox_relative_cam_dir.mV[VX] > bbox_relative_cam_dir.mV[VY] && bbox_relative_cam_dir.mV[VX] > bbox_relative_cam_dir.mV[VZ])
{
mSnapGuideDir1 = LLVector3::x_axis * bbox.getRotation();
}
- else if (object_scale.mV[VY] > object_scale.mV[VZ])
+ else if (bbox_relative_cam_dir.mV[VY] > bbox_relative_cam_dir.mV[VZ])
{
mSnapGuideDir1 = LLVector3::y_axis * bbox.getRotation();
}
@@ -1429,7 +1396,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
LLVector3 scale_snap = grid_scale;
- mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).magVec();
+ mScaleSnapUnit1 = scale_snap.scaleVec(partToUnitVector( mManipPart )).length();
mScaleSnapUnit2 = mScaleSnapUnit1;
mSnapGuideDir1 *= mSnapGuideDir1 * LLViewerCamera::getInstance()->getUpAxis() > 0.f ? 1.f : -1.f;
mSnapGuideDir2 = mSnapGuideDir1 * -1.f;
@@ -1438,7 +1405,6 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
else if( (LL_CORNER_MIN <= (S32)mManipPart) && ((S32)mManipPart <= LL_CORNER_MAX) )
{
- LLVector3 local_scale_dir = partToUnitVector( mManipPart );
LLVector3 local_camera_dir;
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
@@ -1446,74 +1412,133 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
else
{
- local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent()) * ~bbox.getRotation();
- local_camera_dir.normVec();
- }
- local_scale_dir -= projected_vec(local_scale_dir, local_camera_dir);
- local_scale_dir.normVec();
- LLVector3 x_axis_proj_camera = LLVector3::x_axis - projected_vec(LLVector3::x_axis, local_camera_dir);
- x_axis_proj_camera.normVec();
- LLVector3 y_axis_proj_camera = LLVector3::y_axis - projected_vec(LLVector3::y_axis, local_camera_dir);
- y_axis_proj_camera.normVec();
- LLVector3 z_axis_proj_camera = LLVector3::z_axis - projected_vec(LLVector3::z_axis, local_camera_dir);
- z_axis_proj_camera.normVec();
- F32 x_axis_proj = llabs(local_scale_dir * x_axis_proj_camera);
- F32 y_axis_proj = llabs(local_scale_dir * y_axis_proj_camera);
- F32 z_axis_proj = llabs(local_scale_dir * z_axis_proj_camera);
-
- if (x_axis_proj > y_axis_proj && x_axis_proj > z_axis_proj)
- {
- mSnapGuideDir1 = LLVector3::y_axis;
- mScaleSnapUnit2 = grid_scale.mV[VY];
- mSnapGuideDir2 = LLVector3::z_axis;
- mScaleSnapUnit1 = grid_scale.mV[VZ];
- }
- else if (y_axis_proj > z_axis_proj)
- {
- mSnapGuideDir1 = LLVector3::x_axis;
- mScaleSnapUnit2 = grid_scale.mV[VX];
- mSnapGuideDir2 = LLVector3::z_axis;
- mScaleSnapUnit1 = grid_scale.mV[VZ];
- }
- else
- {
- mSnapGuideDir1 = LLVector3::x_axis;
- mScaleSnapUnit2 = grid_scale.mV[VX];
- mSnapGuideDir2 = LLVector3::y_axis;
- mScaleSnapUnit1 = grid_scale.mV[VY];
+ local_camera_dir = (LLViewerCamera::getInstance()->getOrigin() - box_corner_agent) * ~bbox.getRotation();
+ local_camera_dir.normalize();
}
- LLVector3 snap_guide_flip(1.f, 1.f, 1.f);
+ LLVector3 axis_flip;
switch (mManipPart)
{
case LL_CORNER_NNN:
+ axis_flip.set(1.f, 1.f, 1.f);
break;
case LL_CORNER_NNP:
- snap_guide_flip.setVec(1.f, 1.f, -1.f);
+ axis_flip.set(1.f, 1.f, -1.f);
break;
case LL_CORNER_NPN:
- snap_guide_flip.setVec(1.f, -1.f, 1.f);
+ axis_flip.set(1.f, -1.f, 1.f);
break;
case LL_CORNER_NPP:
- snap_guide_flip.setVec(1.f, -1.f, -1.f);
+ axis_flip.set(1.f, -1.f, -1.f);
break;
case LL_CORNER_PNN:
- snap_guide_flip.setVec(-1.f, 1.f, 1.f);
+ axis_flip.set(-1.f, 1.f, 1.f);
break;
case LL_CORNER_PNP:
- snap_guide_flip.setVec(-1.f, 1.f, -1.f);
+ axis_flip.set(-1.f, 1.f, -1.f);
break;
case LL_CORNER_PPN:
- snap_guide_flip.setVec(-1.f, -1.f, 1.f);
+ axis_flip.set(-1.f, -1.f, 1.f);
break;
case LL_CORNER_PPP:
- snap_guide_flip.setVec(-1.f, -1.f, -1.f);
+ axis_flip.set(-1.f, -1.f, -1.f);
+ break;
+ default:
+ break;
+ }
+
+ // account for which side of the object the camera is located and negate appropriate axes
+ local_camera_dir.scaleVec(axis_flip);
+
+ // normalize to object scale
+ LLVector3 bbox_extent = bbox.getExtentLocal();
+ local_camera_dir.scaleVec(LLVector3(1.f / bbox_extent.mV[VX], 1.f / bbox_extent.mV[VY], 1.f / bbox_extent.mV[VZ]));
+
+ S32 scale_face = -1;
+
+ if ((local_camera_dir.mV[VX] > 0.f) == (local_camera_dir.mV[VY] > 0.f))
+ {
+ if ((local_camera_dir.mV[VZ] > 0.f) == (local_camera_dir.mV[VY] > 0.f))
+ {
+ LLVector3 local_camera_dir_abs = local_camera_dir;
+ local_camera_dir_abs.abs();
+ // all neighboring faces of bbox are pointing towards camera or away from camera
+ // use largest magnitude face for snap guides
+ if (local_camera_dir_abs.mV[VX] > local_camera_dir_abs.mV[VY])
+ {
+ if (local_camera_dir_abs.mV[VX] > local_camera_dir_abs.mV[VZ])
+ {
+ scale_face = VX;
+ }
+ else
+ {
+ scale_face = VZ;
+ }
+ }
+ else // y > x
+ {
+ if (local_camera_dir_abs.mV[VY] > local_camera_dir_abs.mV[VZ])
+ {
+ scale_face = VY;
+ }
+ else
+ {
+ scale_face = VZ;
+ }
+ }
+ }
+ else
+ {
+ // z axis facing opposite direction from x and y relative to camera, use x and y for snap guides
+ scale_face = VZ;
+ }
+ }
+ else // x and y axes are facing in opposite directions relative to camera
+ {
+ if ((local_camera_dir.mV[VZ] > 0.f) == (local_camera_dir.mV[VY] > 0.f))
+ {
+ // x axis facing opposite direction from y and z relative to camera, use y and z for snap guides
+ scale_face = VX;
+ }
+ else
+ {
+ // y axis facing opposite direction from x and z relative to camera, use x and z for snap guides
+ scale_face = VY;
+ }
+ }
+
+ switch(scale_face)
+ {
+ case VX:
+ // x axis face being scaled, use y and z for snap guides
+ mSnapGuideDir1 = LLVector3::y_axis.scaledVec(axis_flip);
+ mScaleSnapUnit1 = grid_scale.mV[VZ];
+ mSnapGuideDir2 = LLVector3::z_axis.scaledVec(axis_flip);
+ mScaleSnapUnit2 = grid_scale.mV[VY];
+ break;
+ case VY:
+ // y axis facing being scaled, use x and z for snap guides
+ mSnapGuideDir1 = LLVector3::x_axis.scaledVec(axis_flip);
+ mScaleSnapUnit1 = grid_scale.mV[VZ];
+ mSnapGuideDir2 = LLVector3::z_axis.scaledVec(axis_flip);
+ mScaleSnapUnit2 = grid_scale.mV[VX];
+ break;
+ case VZ:
+ // z axis facing being scaled, use x and y for snap guides
+ mSnapGuideDir1 = LLVector3::x_axis.scaledVec(axis_flip);
+ mScaleSnapUnit1 = grid_scale.mV[VY];
+ mSnapGuideDir2 = LLVector3::y_axis.scaledVec(axis_flip);
+ mScaleSnapUnit2 = grid_scale.mV[VX];
break;
default:
+ mSnapGuideDir1.setZero();
+ mScaleSnapUnit1 = 0.f;
+
+ mSnapGuideDir2.setZero();
+ mScaleSnapUnit2 = 0.f;
break;
}
- mSnapGuideDir1.scaleVec(snap_guide_flip);
- mSnapGuideDir2.scaleVec(snap_guide_flip);
+
mSnapGuideDir1.rotVec(bbox.getRotation());
mSnapGuideDir2.rotVec(bbox.getRotation());
mSnapDir1 = -1.f * mSnapGuideDir2;
@@ -1521,13 +1546,22 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
}
mScalePlaneNormal1 = mSnapGuideDir1 % mScaleDir;
- mScalePlaneNormal1.normVec();
+ mScalePlaneNormal1.normalize();
mScalePlaneNormal2 = mSnapGuideDir2 % mScaleDir;
- mScalePlaneNormal2.normVec();
+ mScalePlaneNormal2.normalize();
mScaleSnapUnit1 = mScaleSnapUnit1 / (mSnapDir1 * mScaleDir);
mScaleSnapUnit2 = mScaleSnapUnit2 / (mSnapDir2 * mScaleDir);
+
+ mTickPixelSpacing1 = llround((F32)MIN_DIVISION_PIXEL_WIDTH / (mScaleDir % mSnapGuideDir1).length());
+ mTickPixelSpacing2 = llround((F32)MIN_DIVISION_PIXEL_WIDTH / (mScaleDir % mSnapGuideDir2).length());
+
+ if (uniform)
+ {
+ mScaleSnapUnit1 *= 0.5f;
+ mScaleSnapUnit2 *= 0.5f;
+ }
}
void LLManipScale::renderSnapGuides(const LLBBox& bbox)
@@ -1537,7 +1571,6 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
return;
}
- F32 max_subdivisions = sGridMaxSubdivisionLevel;
F32 grid_alpha = gSavedSettings.getF32("GridOpacity");
F32 max_point_on_scale_line = partToMaxScale(mManipPart, bbox);
@@ -1551,10 +1584,10 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
LLColor4 tick_color = setupSnapGuideRenderPass(pass);
gGL.begin(LLRender::LINES);
- LLVector3 line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset);
- LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f)));
- LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f));
-
+ LLVector3 line_mid = mScaleCenter + (mScaleSnappedValue * mScaleDir) + (mSnapGuideDir1 * mSnapRegimeOffset);
+ LLVector3 line_start = line_mid - (mScaleDir * (llmin(mScaleSnappedValue, mSnapGuideLength * 0.5f)));
+ LLVector3 line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnappedValue, mSnapGuideLength * 0.5f));
+
gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f);
gGL.vertex3fv(line_start.mV);
gGL.color4fv(tick_color.mV);
@@ -1563,9 +1596,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
gGL.color4f(tick_color.mV[VRED], tick_color.mV[VGREEN], tick_color.mV[VBLUE], tick_color.mV[VALPHA] * 0.1f);
gGL.vertex3fv(line_end.mV);
- line_mid = mScaleCenter + (mScaleSnapValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset);
- line_start = line_mid - (mScaleDir * (llmin(mScaleSnapValue, mSnapGuideLength * 0.5f)));
- line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnapValue, mSnapGuideLength * 0.5f));
+ line_mid = mScaleCenter + (mScaleSnappedValue * mScaleDir) + (mSnapGuideDir2 * mSnapRegimeOffset);
+ line_start = line_mid - (mScaleDir * (llmin(mScaleSnappedValue, mSnapGuideLength * 0.5f)));
+ line_end = line_mid + (mScaleDir * llmin(max_point_on_scale_line - mScaleSnappedValue, mSnapGuideLength * 0.5f));
gGL.vertex3fv(line_start.mV);
gGL.color4fv(tick_color.mV);
gGL.vertex3fv(line_mid.mV);
@@ -1578,31 +1611,38 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
{
LLGLDepthTest gls_depth(GL_FALSE);
- F32 dist_grid_axis = (drag_point - mScaleCenter) * mScaleDir;
+ F32 dist_grid_axis = llmax(0.f, (drag_point - mScaleCenter) * mScaleDir);
+
+ F32 smallest_subdivision1 = mScaleSnapUnit1 / sGridMaxSubdivisionLevel;
+ F32 smallest_subdivision2 = mScaleSnapUnit2 / sGridMaxSubdivisionLevel;
+
+ F32 dist_scale_units_1 = dist_grid_axis / smallest_subdivision1;
+ F32 dist_scale_units_2 = dist_grid_axis / smallest_subdivision2;
+
// find distance to nearest smallest grid unit
- F32 grid_offset1 = fmodf(dist_grid_axis, mScaleSnapUnit1 / max_subdivisions);
- F32 grid_offset2 = fmodf(dist_grid_axis, mScaleSnapUnit2 / max_subdivisions);
+ F32 grid_multiple1 = llfloor(dist_scale_units_1);
+ F32 grid_multiple2 = llfloor(dist_scale_units_2);
+ F32 grid_offset1 = fmodf(dist_grid_axis, smallest_subdivision1);
+ F32 grid_offset2 = fmodf(dist_grid_axis, smallest_subdivision2);
// how many smallest grid units are we away from largest grid scale?
- S32 sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 / sGridMinSubdivisionLevel) / (mScaleSnapUnit1 / max_subdivisions));
- S32 sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 / sGridMinSubdivisionLevel) / (mScaleSnapUnit2 / max_subdivisions));
+ S32 sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 / sGridMinSubdivisionLevel) / smallest_subdivision1);
+ S32 sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 / sGridMinSubdivisionLevel) / smallest_subdivision2);
- S32 num_ticks_per_side1 = llmax(1, lltrunc(0.5f * mSnapGuideLength / (mScaleSnapUnit1 / max_subdivisions)));
- S32 num_ticks_per_side2 = llmax(1, lltrunc(0.5f * mSnapGuideLength / (mScaleSnapUnit2 / max_subdivisions)));
- F32 dist_scale_units_1 = dist_grid_axis / (mScaleSnapUnit1 / max_subdivisions);
- F32 dist_scale_units_2 = dist_grid_axis / (mScaleSnapUnit2 / max_subdivisions);
+ S32 num_ticks_per_side1 = llmax(1, lltrunc(0.5f * mSnapGuideLength / smallest_subdivision1));
+ S32 num_ticks_per_side2 = llmax(1, lltrunc(0.5f * mSnapGuideLength / smallest_subdivision2));
S32 ticks_from_scale_center_1 = lltrunc(dist_scale_units_1);
S32 ticks_from_scale_center_2 = lltrunc(dist_scale_units_2);
- S32 max_ticks1 = llceil(max_point_on_scale_line / (mScaleSnapUnit1 / max_subdivisions) - dist_scale_units_1);
- S32 max_ticks2 = llceil(max_point_on_scale_line / (mScaleSnapUnit2 / max_subdivisions) - dist_scale_units_2);
+ S32 max_ticks1 = llceil(max_point_on_scale_line / smallest_subdivision1 - dist_scale_units_1);
+ S32 max_ticks2 = llceil(max_point_on_scale_line / smallest_subdivision2 - dist_scale_units_2);
S32 start_tick = 0;
S32 stop_tick = 0;
- if (mInSnapRegime)
+ if (mSnapRegime != SNAP_REGIME_NONE)
{
// draw snap guide line
gGL.begin(LLRender::LINES);
- LLVector3 snap_line_center = mScaleCenter + (mScaleSnapValue * mScaleDir);
+ LLVector3 snap_line_center = bbox.localToAgent(unitVectorToLocalBBoxExtent( partToUnitVector( mManipPart ), bbox ));
LLVector3 snap_line_start = snap_line_center + (mSnapGuideDir1 * mSnapRegimeOffset);
LLVector3 snap_line_end = snap_line_center + (mSnapGuideDir2 * mSnapRegimeOffset);
@@ -1624,22 +1664,22 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
LLVector3 arrow_span = mScaleDir;
arrow_dir = snap_line_start - snap_line_center;
- arrow_dir.normVec();
+ arrow_dir.normalize();
gGL.vertex3fv((snap_line_start + arrow_dir * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_start + arrow_span * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_start - arrow_span * mBoxHandleSize).mV);
arrow_dir = snap_line_end - snap_line_center;
- arrow_dir.normVec();
+ arrow_dir.normalize();
gGL.vertex3fv((snap_line_end + arrow_dir * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_end + arrow_span * mBoxHandleSize).mV);
gGL.vertex3fv((snap_line_end - arrow_span * mBoxHandleSize).mV);
}
gGL.end();
}
-
+
LLVector2 screen_translate_axis(llabs(mScaleDir * LLViewerCamera::getInstance()->getLeftAxis()), llabs(mScaleDir * LLViewerCamera::getInstance()->getUpAxis()));
- screen_translate_axis.normVec();
+ screen_translate_axis.normalize();
S32 tick_label_spacing = llround(screen_translate_axis * sTickLabelSpacing);
@@ -1655,17 +1695,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
for (S32 i = start_tick; i <= stop_tick; i++)
{
F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side1)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit1 / max_subdivisions * (F32)i - grid_offset1));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1);
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, mTickPixelSpacing1), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
- if (fmodf((F32)(i + sub_div_offset_1), (max_subdivisions / cur_subdivisions)) != 0.f)
+ if (fmodf((F32)(i + sub_div_offset_1), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f)
{
continue;
}
F32 tick_scale = 1.f;
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + sub_div_offset_1), division_level) == 0.f)
{
@@ -1688,17 +1728,17 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
for (S32 i = start_tick; i <= stop_tick; i++)
{
F32 alpha = (1.f - (1.f * ((F32)llabs(i) / (F32)num_ticks_per_side2)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit2 / max_subdivisions * (F32)i - grid_offset2));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2);
- F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
+ F32 cur_subdivisions = llclamp(getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, mTickPixelSpacing2), sGridMinSubdivisionLevel, sGridMaxSubdivisionLevel);
- if (fmodf((F32)(i + sub_div_offset_2), (max_subdivisions / cur_subdivisions)) != 0.f)
+ if (fmodf((F32)(i + sub_div_offset_2), (sGridMaxSubdivisionLevel / cur_subdivisions)) != 0.f)
{
continue;
}
F32 tick_scale = 1.f;
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + sub_div_offset_2), division_level) == 0.f)
{
@@ -1716,21 +1756,21 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
gGL.end();
}
- // render tick labels
+ // render upper tick labels
start_tick = -(llmin(ticks_from_scale_center_1, num_ticks_per_side1));
stop_tick = llmin(max_ticks1, num_ticks_per_side1);
F32 grid_resolution = mObjectSelection->getSelectType() == SELECT_TYPE_HUD ? 0.25f : llmax(gSavedSettings.getF32("GridResolution"), 0.001f);
- S32 label_sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 * 32.f) / (mScaleSnapUnit1 / max_subdivisions));
- S32 label_sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 * 32.f) / (mScaleSnapUnit2 / max_subdivisions));
+ S32 label_sub_div_offset_1 = llround(fmod(dist_grid_axis - grid_offset1, mScaleSnapUnit1 * 32.f) / smallest_subdivision1);
+ S32 label_sub_div_offset_2 = llround(fmod(dist_grid_axis - grid_offset2, mScaleSnapUnit2 * 32.f) / smallest_subdivision2);
for (S32 i = start_tick; i <= stop_tick; i++)
{
F32 tick_scale = 1.f;
F32 alpha = grid_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side1)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit1 / max_subdivisions * (F32)i - grid_offset1));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple1 + i) * smallest_subdivision1);
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + label_sub_div_offset_1), division_level) == 0.f)
{
@@ -1739,39 +1779,34 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
tick_scale *= 0.7f;
}
- if (fmodf((F32)(i + label_sub_div_offset_1), (max_subdivisions / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, tick_label_spacing)))) == 0.f)
+ if (fmodf((F32)(i + label_sub_div_offset_1), (sGridMaxSubdivisionLevel / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit1, tick_label_spacing)))) == 0.f)
{
- LLVector3 text_origin = tick_pos +
- (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale));
+ LLVector3 text_origin = tick_pos + (mSnapGuideDir1 * mSnapRegimeOffset * (1.f + tick_scale));
EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode();
- F32 tick_val;
+ F32 tick_value;
if (grid_mode == GRID_MODE_WORLD)
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit1 / grid_resolution);
+ tick_value = (grid_multiple1 + i) / (sGridMaxSubdivisionLevel / grid_resolution);
}
else
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit1 * 2.f);
- }
-
- if (getUniform())
- {
- tick_val *= 2.f;
+ tick_value = (grid_multiple1 + i) / (2.f * sGridMaxSubdivisionLevel);
}
F32 text_highlight = 0.8f;
- if (is_approx_equal(tick_val, mScaleSnapValue) && mInSnapRegime)
+ // Highlight this text if the tick value matches the snapped to value, and if either the second set of ticks isn't going to be shown or cursor is in the first snap regime.
+ if (is_approx_equal(tick_value, mScaleSnappedValue) && (mScaleSnapUnit2 == mScaleSnapUnit1 || (mSnapRegime & SNAP_REGIME_UPPER)))
{
text_highlight = 1.f;
}
- renderTickValue(text_origin, tick_val, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
+ renderTickValue(text_origin, tick_value, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
}
}
- // label ticks on opposite side
+ // label ticks on opposite side, only can happen in scaling modes that effect more than one axis and when the object's axis don't have the same scale. A differing scale indicates both conditions.
if (mScaleSnapUnit2 != mScaleSnapUnit1)
{
start_tick = -(llmin(ticks_from_scale_center_2, num_ticks_per_side2));
@@ -1780,9 +1815,9 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
{
F32 tick_scale = 1.f;
F32 alpha = grid_alpha * (1.f - (0.5f * ((F32)llabs(i) / (F32)num_ticks_per_side2)));
- LLVector3 tick_pos = drag_point + (mScaleDir * (mScaleSnapUnit2 / max_subdivisions * (F32)i - grid_offset2));
+ LLVector3 tick_pos = mScaleCenter + (mScaleDir * (grid_multiple2 + i) * smallest_subdivision2);
- for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
+ for (F32 division_level = sGridMaxSubdivisionLevel; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
{
if (fmodf((F32)(i + label_sub_div_offset_2), division_level) == 0.f)
{
@@ -1791,35 +1826,29 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
tick_scale *= 0.7f;
}
- if (fmodf((F32)(i + label_sub_div_offset_2), (max_subdivisions / llmin(max_subdivisions, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, tick_label_spacing)))) == 0.f)
+ if (fmodf((F32)(i + label_sub_div_offset_2), (sGridMaxSubdivisionLevel / llmin(sGridMaxSubdivisionLevel, getSubdivisionLevel(tick_pos, mScaleDir, mScaleSnapUnit2, tick_label_spacing)))) == 0.f)
{
- LLVector3 text_origin = tick_pos +
- (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale));
+ LLVector3 text_origin = tick_pos + (mSnapGuideDir2 * mSnapRegimeOffset * (1.f + tick_scale));
EGridMode grid_mode = LLSelectMgr::getInstance()->getGridMode();
- F32 tick_val;
+ F32 tick_value;
if (grid_mode == GRID_MODE_WORLD)
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit2 / grid_resolution);
+ tick_value = (grid_multiple2 + i) / (sGridMaxSubdivisionLevel / grid_resolution);
}
else
{
- tick_val = (tick_pos - mScaleCenter) * mScaleDir / (mScaleSnapUnit2 * 2.f);
- }
-
- if (getUniform())
- {
- tick_val *= 2.f;
+ tick_value = (grid_multiple2 + i) / (2.f * sGridMaxSubdivisionLevel);
}
F32 text_highlight = 0.8f;
- if (is_approx_equal(tick_val, mScaleSnapValue) && mInSnapRegime)
+ if (is_approx_equal(tick_value, mScaleSnappedValue) && (mSnapRegime & SNAP_REGIME_LOWER))
{
text_highlight = 1.f;
}
- renderTickValue(text_origin, tick_val, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
+ renderTickValue(text_origin, tick_value, grid_mode == GRID_MODE_WORLD ? std::string("m") : std::string("x"), LLColor4(text_highlight, text_highlight, text_highlight, alpha));
}
}
}
@@ -1845,13 +1874,13 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
LLVector3 help_text_pos = selection_center_start + (mSnapRegimeOffset * 5.f * offset_dir);
const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
- std::string help_text = "Move mouse cursor over ruler";
+ std::string help_text = LLTrans::getString("manip_hint1");
LLColor4 help_text_color = LLColor4::white;
help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, grid_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
- help_text = "to snap to grid";
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapRegimeOffset * 0.4f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
}
}
}
@@ -1860,17 +1889,15 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)
// Returns unit vector in direction of part of an origin-centered cube
LLVector3 LLManipScale::partToUnitVector( S32 part ) const
{
- if( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) )
+ if ( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) )
{
return faceToUnitVector( part );
}
- else
- if( (LL_CORNER_MIN <= part) && (part <= LL_CORNER_MAX) )
+ else if ( (LL_CORNER_MIN <= part) && (part <= LL_CORNER_MAX) )
{
return cornerToUnitVector( part );
}
- else
- if( (LL_EDGE_MIN <= part) && (part <= LL_EDGE_MAX ) )
+ else if ( (LL_EDGE_MIN <= part) && (part <= LL_EDGE_MAX ) )
{
return edgeToUnitVector( part );
}
@@ -1882,27 +1909,32 @@ LLVector3 LLManipScale::partToUnitVector( S32 part ) const
LLVector3 LLManipScale::faceToUnitVector( S32 part ) const
{
llassert( (LL_FACE_MIN <= part) && (part <= LL_FACE_MAX) );
+ LLVector3 vec;
switch( part )
{
case LL_FACE_POSX:
- return LLVector3( 1.f, 0.f, 0.f );
-
+ vec.set( 1.f, 0.f, 0.f );
+ break;
case LL_FACE_NEGX:
- return LLVector3( -1.f, 0.f, 0.f );
-
+ vec.set( -1.f, 0.f, 0.f );
+ break;
case LL_FACE_POSY:
- return LLVector3( 0.f, 1.f, 0.f );
-
+ vec.set( 0.f, 1.f, 0.f );
+ break;
case LL_FACE_NEGY:
- return LLVector3( 0.f, -1.f, 0.f );
-
+ vec.set( 0.f, -1.f, 0.f );
+ break;
case LL_FACE_POSZ:
- return LLVector3( 0.f, 0.f, 1.f );
-
+ vec.set( 0.f, 0.f, 1.f );
+ break;
case LL_FACE_NEGZ:
- return LLVector3( 0.f, 0.f, -1.f );
+ vec.set( 0.f, 0.f, -1.f );
+ break;
+ default:
+ vec.clear();
}
- return LLVector3();
+
+ return vec;
}
@@ -1914,31 +1946,31 @@ LLVector3 LLManipScale::cornerToUnitVector( S32 part ) const
switch(part)
{
case LL_CORNER_NNN:
- vec.setVec(-F_SQRT3, -F_SQRT3, -F_SQRT3);
+ vec.set(-OO_SQRT3, -OO_SQRT3, -OO_SQRT3);
break;
- case LL_CORNER_NNP:
- vec.setVec(-F_SQRT3, -F_SQRT3, F_SQRT3);
+ case LL_CORNER_NNP:
+ vec.set(-OO_SQRT3, -OO_SQRT3, OO_SQRT3);
break;
case LL_CORNER_NPN:
- vec.setVec(-F_SQRT3, F_SQRT3, -F_SQRT3);
+ vec.set(-OO_SQRT3, OO_SQRT3, -OO_SQRT3);
break;
case LL_CORNER_NPP:
- vec.setVec(-F_SQRT3, F_SQRT3, F_SQRT3);
+ vec.set(-OO_SQRT3, OO_SQRT3, OO_SQRT3);
break;
case LL_CORNER_PNN:
- vec.setVec(F_SQRT3, -F_SQRT3, -F_SQRT3);
+ vec.set(OO_SQRT3, -OO_SQRT3, -OO_SQRT3);
break;
case LL_CORNER_PNP:
- vec.setVec(F_SQRT3, -F_SQRT3, F_SQRT3);
+ vec.set(OO_SQRT3, -OO_SQRT3, OO_SQRT3);
break;
case LL_CORNER_PPN:
- vec.setVec(F_SQRT3, F_SQRT3, -F_SQRT3);
+ vec.set(OO_SQRT3, OO_SQRT3, -OO_SQRT3);
break;
case LL_CORNER_PPP:
- vec.setVec(F_SQRT3, F_SQRT3, F_SQRT3);
+ vec.set(OO_SQRT3, OO_SQRT3, OO_SQRT3);
break;
default:
- vec.clearVec();
+ vec.clear();
}
return vec;
@@ -1965,8 +1997,8 @@ LLVector3 LLManipScale::unitVectorToLocalBBoxExtent( const LLVector3& v, const L
LLVector3 ctr = bbox.getCenterLocal();
return LLVector3(
- v.mV[0] ? (v.mV[0]>0 ? max.mV[0] : min.mV[0] ) : ctr.mV[0],
- v.mV[1] ? (v.mV[1]>0 ? max.mV[1] : min.mV[1] ) : ctr.mV[1],
+ v.mV[0] ? (v.mV[0]>0 ? max.mV[0] : min.mV[0] ) : ctr.mV[0],
+ v.mV[1] ? (v.mV[1]>0 ? max.mV[1] : min.mV[1] ) : ctr.mV[1],
v.mV[2] ? (v.mV[2]>0 ? max.mV[2] : min.mV[2] ) : ctr.mV[2] );
}
@@ -1984,7 +2016,7 @@ F32 LLManipScale::partToMaxScale( S32 part, const LLBBox &bbox ) const
max_extent = bbox_extents.mV[i];
}
}
- max_scale_factor = bbox_extents.magVec() * get_default_max_prim_scale() / max_extent;
+ max_scale_factor = bbox_extents.length() * get_default_max_prim_scale() / max_extent;
if (getUniform())
{
@@ -2007,7 +2039,7 @@ F32 LLManipScale::partToMinScale( S32 part, const LLBBox &bbox ) const
min_extent = bbox_extents.mV[i];
}
}
- F32 min_scale_factor = bbox_extents.magVec() * MIN_PRIM_SCALE / min_extent;
+ F32 min_scale_factor = bbox_extents.length() * MIN_PRIM_SCALE / min_extent;
if (getUniform())
{
@@ -2058,7 +2090,7 @@ LLVector3 LLManipScale::nearestAxis( const LLVector3& v ) const
// virtual
BOOL LLManipScale::canAffectSelection()
{
- // An selection is scalable if you are allowed to both edit and move
+ // An selection is scalable if you are allowed to both edit and move
// everything in it, and it does not have any sitting agents
BOOL can_scale = mObjectSelection->getObjectCount() != 0;
if (can_scale)
diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h
index 5cb8898fd0..e1da7a1bb5 100755
--- a/indra/newview/llmanipscale.h
+++ b/indra/newview/llmanipscale.h
@@ -51,6 +51,13 @@ typedef enum e_scale_manipulator_type
SCALE_MANIP_FACE
} EScaleManipulatorType;
+typedef enum e_snap_regimes
+{
+ SNAP_REGIME_NONE = 0, //!< The cursor is not in either of the snap regimes.
+ SNAP_REGIME_UPPER = 0x1, //!< The cursor is, non-exclusively, in the first of the snap regimes. Prefer to treat as bitmask.
+ SNAP_REGIME_LOWER = 0x2 //!< The cursor is, non-exclusively, in the second of the snap regimes. Prefer to treat as bitmask.
+} ESnapRegimes;
+
class LLManipScale : public LLManip
{
@@ -96,7 +103,7 @@ private:
void renderSnapGuides( const LLBBox& local_bbox );
void revert();
-
+
inline void conditionalHighlight( U32 part, const LLColor4* highlight = NULL, const LLColor4* normal = NULL );
void drag( S32 x, S32 y );
@@ -135,33 +142,35 @@ private:
};
- F32 mBoxHandleSize; // The size of the handles at the corners of the bounding box
- F32 mScaledBoxHandleSize; // handle size after scaling for selection feedback
+ F32 mBoxHandleSize; //!< The size of the handles at the corners of the bounding box.
+ F32 mScaledBoxHandleSize; //!< Handle size after scaling for selection feedback.
LLVector3d mDragStartPointGlobal;
- LLVector3d mDragStartCenterGlobal; // The center of the bounding box of all selected objects at time of drag start
+ LLVector3d mDragStartCenterGlobal; //!< The center of the bounding box of all selected objects at time of drag start.
LLVector3d mDragPointGlobal;
LLVector3d mDragFarHitGlobal;
S32 mLastMouseX;
S32 mLastMouseY;
BOOL mSendUpdateOnMouseUp;
U32 mLastUpdateFlags;
- typedef std::set<ManipulatorHandle*, compare_manipulators> minpulator_list_t;
- minpulator_list_t mProjectedManipulators;
+ typedef std::set<ManipulatorHandle*, compare_manipulators> manipulator_list_t;
+ manipulator_list_t mProjectedManipulators;
LLVector4 mManipulatorVertices[14];
- F32 mScaleSnapUnit1; // size of snap multiples for axis 1
- F32 mScaleSnapUnit2; // size of snap multiples for axis 2
- LLVector3 mScalePlaneNormal1; // normal of plane in which scale occurs that most faces camera
- LLVector3 mScalePlaneNormal2; // normal of plane in which scale occurs that most faces camera
- LLVector3 mSnapGuideDir1;
- LLVector3 mSnapGuideDir2;
- LLVector3 mSnapDir1;
- LLVector3 mSnapDir2;
- F32 mSnapRegimeOffset;
+ F32 mScaleSnapUnit1; //!< Size of snap multiples for the upper scale.
+ F32 mScaleSnapUnit2; //!< Size of snap multiples for the lower scale.
+ LLVector3 mScalePlaneNormal1; //!< Normal of plane in which scale occurs that most faces camera.
+ LLVector3 mScalePlaneNormal2; //!< Normal of plane in which scale occurs that most faces camera.
+ LLVector3 mSnapGuideDir1; //!< The direction in which the upper snap guide tick marks face.
+ LLVector3 mSnapGuideDir2; //!< The direction in which the lower snap guide tick marks face.
+ LLVector3 mSnapDir1; //!< The direction in which the upper snap guides face.
+ LLVector3 mSnapDir2; //!< The direction in which the lower snap guides face.
+ F32 mSnapRegimeOffset; //!< How far off the scale axis centerline the mouse can be before it exits/enters the snap regime.
+ F32 mTickPixelSpacing1; //!< The pixel spacing between snap guide tick marks for the upper scale.
+ F32 mTickPixelSpacing2; //!< The pixel spacing between snap guide tick marks for the lower scale.
F32 mSnapGuideLength;
- LLVector3 mScaleCenter;
- LLVector3 mScaleDir;
- F32 mScaleSnapValue;
- BOOL mInSnapRegime;
+ LLVector3 mScaleCenter; //!< The location of the origin of the scaling operation.
+ LLVector3 mScaleDir; //!< The direction of the scaling action. In face-dragging this is aligned with one of the cardinal axis relative to the prim, but in corner-dragging this is along the diagonal.
+ F32 mScaleSnappedValue; //!< The distance of the current position nearest the mouse location, measured along mScaleDir. Is measured either from the center or from the far face/corner depending upon whether uniform scaling is true or false respectively.
+ ESnapRegimes mSnapRegime; //<! Which, if any, snap regime the cursor is currently residing in.
F32* mManipulatorScales;
};
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 06bf294417..d237e5ef44 100755
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -61,6 +61,7 @@
#include "llui.h"
#include "pipeline.h"
#include "llviewershadermgr.h"
+#include "lltrans.h"
const S32 NUM_AXES = 3;
const S32 MOUSE_DRAG_SLOP = 2; // pixels
@@ -111,7 +112,6 @@ LLManipTranslate::LLManipTranslate( LLToolComposite* composite )
: LLManip( std::string("Move"), composite ),
mLastHoverMouseX(-1),
mLastHoverMouseY(-1),
- mSendUpdateOnMouseUp(FALSE),
mMouseOutsideSlop(FALSE),
mCopyMadeThisDrag(FALSE),
mMouseDownX(-1),
@@ -125,7 +125,6 @@ LLManipTranslate::LLManipTranslate( LLToolComposite* composite )
mSnapOffsetMeters(0.f),
mSubdivisions(10.f),
mInSnapRegime(FALSE),
- mSnapped(FALSE),
mArrowScales(1.f, 1.f, 1.f),
mPlaneScales(1.f, 1.f, 1.f),
mPlaneManipPositions(1.f, 1.f, 1.f, 1.f)
@@ -1441,13 +1440,13 @@ void LLManipTranslate::renderSnapGuides()
LLVector3 help_text_pos = selection_center_start + (snap_offset_meters_up * 3.f * mSnapOffsetAxis);
const LLFontGL* big_fontp = LLFontGL::getFontSansSerif();
- std::string help_text = "Move mouse cursor over ruler";
+ std::string help_text = LLTrans::getString("manip_hint1");
LLColor4 help_text_color = LLColor4::white;
help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f);
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
- help_text = "to snap to grid";
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
+ help_text = LLTrans::getString("manip_hint2");
help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f;
- hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);
+ hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);
}
}
}
diff --git a/indra/newview/llmaniptranslate.h b/indra/newview/llmaniptranslate.h
index 37567c7bd1..3c37bbd698 100755
--- a/indra/newview/llmaniptranslate.h
+++ b/indra/newview/llmaniptranslate.h
@@ -85,7 +85,6 @@ protected:
private:
S32 mLastHoverMouseX;
S32 mLastHoverMouseY;
- BOOL mSendUpdateOnMouseUp;
BOOL mMouseOutsideSlop; // true after mouse goes outside slop region
BOOL mCopyMadeThisDrag;
S32 mMouseDownX;
@@ -107,7 +106,6 @@ private:
LLVector3 mGridScale;
F32 mSubdivisions;
BOOL mInSnapRegime;
- BOOL mSnapped;
LLVector3 mArrowScales;
LLVector3 mPlaneScales;
LLVector4 mPlaneManipPositions;
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 0b009b68f7..05c9d76810 100755
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -30,6 +30,7 @@
#include "llagent.h"
#include "llhttpclient.h"
+#include "llsdserialize.h"
#include "lltimer.h"
#include "lltrans.h"
#include "llviewercontrol.h"
@@ -135,19 +136,25 @@ namespace LLMarketplaceImport
llinfos << " SLM POST status: " << status << llendl;
llinfos << " SLM POST reason: " << reason << llendl;
llinfos << " SLM POST content: " << content.asString() << llendl;
-
llinfos << " SLM POST timer: " << slmPostTimer.getElapsedTimeF32() << llendl;
}
- if ((status == MarketplaceErrorCodes::IMPORT_REDIRECT) ||
- (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
- (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ // MAINT-2301 : we determined we can safely ignore that error in that context
+ if (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT)
{
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM POST clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ llinfos << " SLM POST : Ignoring time out status and treating it as success" << llendl;
+ }
+ status = MarketplaceErrorCodes::IMPORT_DONE;
+ }
+
+ if (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST)
+ {
+ if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
+ {
+ llinfos << " SLM POST clearing marketplace cookie due to client or server error" << llendl;
}
-
sMarketplaceCookie.clear();
}
@@ -182,20 +189,25 @@ namespace LLMarketplaceImport
llinfos << " SLM GET status: " << status << llendl;
llinfos << " SLM GET reason: " << reason << llendl;
llinfos << " SLM GET content: " << content.asString() << llendl;
-
llinfos << " SLM GET timer: " << slmGetTimer.getElapsedTimeF32() << llendl;
}
- if ((status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR) ||
- (status == MarketplaceErrorCodes::IMPORT_JOB_TIMEOUT))
+ // MAINT-2452 : Do not clear the cookie on IMPORT_DONE_WITH_ERRORS : Happens when trying to import objects with wrong permissions
+ // ACME-1221 : Do not clear the cookie on IMPORT_NOT_FOUND : Happens for newly created Merchant accounts that are initally empty
+ if ((status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST) &&
+ (status != MarketplaceErrorCodes::IMPORT_DONE_WITH_ERRORS) &&
+ (status != MarketplaceErrorCodes::IMPORT_NOT_FOUND))
{
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM GET clearing marketplace cookie due to authentication failure or timeout" << llendl;
+ llinfos << " SLM GET clearing marketplace cookie due to client or server error" << llendl;
}
-
sMarketplaceCookie.clear();
}
+ else if (gSavedSettings.getBOOL("InventoryOutboxLogging") && (status >= MarketplaceErrorCodes::IMPORT_BAD_REQUEST))
+ {
+ llinfos << " SLM GET : Got error status = " << status << ", but marketplace cookie not cleared." << llendl;
+ }
sImportInProgress = (status == MarketplaceErrorCodes::IMPORT_PROCESSING);
sImportGetPending = false;
@@ -256,7 +268,12 @@ namespace LLMarketplaceImport
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM GET: " << url << llendl;
+ llinfos << " SLM GET: establishMarketplaceSessionCookie, LLHTTPClient::get, url = " << url << llendl;
+ LLSD headers = LLViewerMedia::getHeaders();
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(headers, str);
+ llinfos << " SLM GET: headers " << llendl;
+ llinfos << str.str() << llendl;
}
slmGetTimer.start();
@@ -287,7 +304,11 @@ namespace LLMarketplaceImport
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM GET: " << url << llendl;
+ llinfos << " SLM GET: pollStatus, LLHTTPClient::get, url = " << url << llendl;
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(headers, str);
+ llinfos << " SLM GET: headers " << llendl;
+ llinfos << str.str() << llendl;
}
slmGetTimer.start();
@@ -321,11 +342,15 @@ namespace LLMarketplaceImport
if (gSavedSettings.getBOOL("InventoryOutboxLogging"))
{
- llinfos << " SLM POST: " << url << llendl;
+ llinfos << " SLM POST: triggerImport, LLHTTPClient::post, url = " << url << llendl;
+ std::stringstream str;
+ LLSDSerialize::toPrettyXML(headers, str);
+ llinfos << " SLM POST: headers " << llendl;
+ llinfos << str.str() << llendl;
}
slmPostTimer.start();
- LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
+ LLHTTPClient::post(url, LLSD(), new LLImportPostResponder(), headers);
return true;
}
@@ -356,6 +381,7 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter()
: mAutoTriggerImport(false)
, mImportInProgress(false)
, mInitialized(false)
+ , mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED)
, mErrorInitSignal(NULL)
, mStatusChangedSignal(NULL)
, mStatusReportSignal(NULL)
@@ -394,20 +420,27 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallb
void LLMarketplaceInventoryImporter::initialize()
{
- llassert(!mInitialized);
+ if (mInitialized)
+ {
+ return;
+ }
if (!LLMarketplaceImport::hasSessionCookie())
{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_INITIALIZING;
LLMarketplaceImport::establishMarketplaceSessionCookie();
}
+ else
+ {
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;
+ }
}
void LLMarketplaceInventoryImporter::reinitializeAndTriggerImport()
{
mInitialized = false;
-
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED;
initialize();
-
mAutoTriggerImport = true;
}
@@ -459,17 +492,30 @@ void LLMarketplaceInventoryImporter::updateImport()
if (mInitialized)
{
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_MERCHANT;
// Follow up with auto trigger of import
if (mAutoTriggerImport)
{
mAutoTriggerImport = false;
-
mImportInProgress = triggerImport();
}
}
- else if (mErrorInitSignal)
+ else
{
- (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ U32 status = LLMarketplaceImport::getResultStatus();
+ if ((status == MarketplaceErrorCodes::IMPORT_FORBIDDEN) ||
+ (status == MarketplaceErrorCodes::IMPORT_AUTHENTICATION_ERROR))
+ {
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT;
+ }
+ else
+ {
+ mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE;
+ }
+ if (mErrorInitSignal && (mMarketPlaceStatus == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE))
+ {
+ (*mErrorInitSignal)(LLMarketplaceImport::getResultStatus(), LLMarketplaceImport::getResults());
+ }
}
}
}
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 4b8f7a1ac7..abe60890a3 100755
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -47,10 +47,27 @@ namespace MarketplaceErrorCodes
IMPORT_DONE = 200,
IMPORT_PROCESSING = 202,
IMPORT_REDIRECT = 302,
+ IMPORT_BAD_REQUEST = 400,
IMPORT_AUTHENTICATION_ERROR = 401,
+ IMPORT_FORBIDDEN = 403,
+ IMPORT_NOT_FOUND = 404,
IMPORT_DONE_WITH_ERRORS = 409,
IMPORT_JOB_FAILED = 410,
IMPORT_JOB_TIMEOUT = 499,
+ IMPORT_SERVER_SITE_DOWN = 500,
+ IMPORT_SERVER_API_DISABLED = 503,
+ };
+}
+
+namespace MarketplaceStatusCodes
+{
+ enum sCode
+ {
+ MARKET_PLACE_NOT_INITIALIZED = 0,
+ MARKET_PLACE_INITIALIZING = 1,
+ MARKET_PLACE_CONNECTION_FAILURE = 2,
+ MARKET_PLACE_MERCHANT = 3,
+ MARKET_PLACE_NOT_MERCHANT = 4,
};
}
@@ -73,6 +90,8 @@ public:
void initialize();
bool triggerImport();
bool isImportInProgress() const { return mImportInProgress; }
+ bool isInitialized() const { return mInitialized; }
+ U32 getMarketPlaceStatus() const { return mMarketPlaceStatus; }
protected:
void reinitializeAndTriggerImport();
@@ -82,6 +101,7 @@ private:
bool mAutoTriggerImport;
bool mImportInProgress;
bool mInitialized;
+ U32 mMarketPlaceStatus;
status_report_signal_t * mErrorInitSignal;
status_changed_signal_t * mStatusChangedSignal;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 5afd2cb329..b0c8aa2d3a 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2004,9 +2004,9 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
result["asset_type"] = "mesh";
result["inventory_type"] = "object";
result["description"] = "(No Description)";
- result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms());
- result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms());
- result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms());
+ result["next_owner_mask"] = LLSD::Integer(LLFloaterPerms::getNextOwnerPerms("Uploads"));
+ result["group_mask"] = LLSD::Integer(LLFloaterPerms::getGroupPerms("Uploads"));
+ result["everyone_mask"] = LLSD::Integer(LLFloaterPerms::getEveryonePerms("Uploads"));
res["mesh_list"] = LLSD::emptyArray();
res["texture_list"] = LLSD::emptyArray();
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 32b168b8c5..8bddf49fb5 100755
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -698,14 +698,14 @@ void LLPanelStandStopFlying::updatePosition()
S32 y_pos = 0;
S32 bottom_tb_center = 0;
- if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarView::TOOLBAR_BOTTOM))
+ if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM))
{
y_pos = toolbar_bottom->getRect().getHeight();
bottom_tb_center = toolbar_bottom->getRect().getCenterX();
}
S32 left_tb_width = 0;
- if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarView::TOOLBAR_LEFT))
+ if (LLToolBar* toolbar_left = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT))
{
left_tb_width = toolbar_left->getRect().getWidth();
}
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 7ddd04fed0..3b5a69fd3a 100755
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -64,8 +64,7 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
mNameColumnIndex(p.name_column.column_index),
mNameColumn(p.name_column.column_name),
mAllowCallingCardDrop(p.allow_calling_card_drop),
- mShortNames(p.short_names),
- mAvatarNameCacheConnection()
+ mShortNames(p.short_names)
{}
// public
@@ -328,13 +327,16 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
else
{
// ...schedule a callback
- // This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached.
- // *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list.
- if (mAvatarNameCacheConnection.connected())
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id);
+ if (it != mAvatarNameCacheConnections.end())
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
}
- mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle()));
+ mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle()));
}
break;
}
@@ -391,9 +393,18 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
const LLAvatarName& av_name,
+ std::string suffix,
LLHandle<LLNameListItem> item)
{
- mAvatarNameCacheConnection.disconnect();
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id);
+ if (it != mAvatarNameCacheConnections.end())
+ {
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
+ }
std::string name;
if (mShortNames)
@@ -401,6 +412,12 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
else
name = av_name.getCompleteName();
+ // Append optional suffix.
+ if (!suffix.empty())
+ {
+ name.append(suffix);
+ }
+
LLNameListItem* list_item = item.get();
if (list_item && list_item->getUUID() == agent_id)
{
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 92e82b672d..4ed260d847 100755
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -114,10 +114,14 @@ protected:
LLNameListCtrl(const Params&);
virtual ~LLNameListCtrl()
{
- if (mAvatarNameCacheConnection.connected())
+ for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
}
+ mAvatarNameCacheConnections.clear();
}
friend class LLUICtrlFactory;
public:
@@ -155,14 +159,15 @@ public:
/*virtual*/ void mouseOverHighlightNthItem( S32 index );
private:
void showInspector(const LLUUID& avatar_id, bool is_group);
- void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle<LLNameListItem> item);
+ void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle<LLNameListItem> item);
private:
S32 mNameColumnIndex;
std::string mNameColumn;
BOOL mAllowCallingCardDrop;
bool mShortNames; // display name only, no SLID
- boost::signals2::connection mAvatarNameCacheConnection;
+ typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+ avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index c15b6bd0d3..ff8bfafb79 100755
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -343,7 +343,7 @@ private:
//////////////////////////////////////////////////////////////////////////
-static LLRegisterPanelClassWrapper<LLOutfitsList> t_outfits_list("outfits_list");
+static LLPanelInjector<LLOutfitsList> t_outfits_list("outfits_list");
LLOutfitsList::LLOutfitsList()
: LLPanelAppearanceTab()
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 115114bb53..9665314e75 100755
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -48,7 +48,7 @@
#include "llsidetraypanelcontainer.h"
#include "llviewercontrol.h"
-static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
+static LLPanelInjector<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
//
// Constants
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 1a427338e5..89a9e0dc16 100755
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -59,6 +59,7 @@
#include "llviewerregion.h"
#include "llviewerwindow.h"
#include "llworld.h"
+#include "llfloaterperms.h"
//
// Imported globals
@@ -156,12 +157,14 @@ void LLPanelContents::onClickNewScript(void *userdata)
{
LLPermissions perm;
perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+
+ // Parameters are base, owner, everyone, group, next
perm.initMasks(
PERM_ALL,
PERM_ALL,
- PERM_NONE,
- PERM_NONE,
- PERM_MOVE | PERM_TRANSFER);
+ LLFloaterPerms::getEveryonePerms("Scripts"),
+ LLFloaterPerms::getGroupPerms("Scripts"),
+ PERM_MOVE | LLFloaterPerms::getNextOwnerPerms("Scripts"));
std::string desc;
LLViewerAssetType::generateDescriptionFor(LLAssetType::AT_LSL_TEXT, desc);
LLPointer<LLViewerInventoryItem> new_item =
@@ -179,6 +182,8 @@ void LLPanelContents::onClickNewScript(void *userdata)
time_corrected());
object->saveScript(new_item, TRUE, true);
+ std::string name = new_item->getName();
+
// *NOTE: In order to resolve SL-22177, we needed to create
// the script first, and then you have to click it in
// inventory to edit it.
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index e71dba5cae..0621cc8fad 100755
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -62,7 +62,7 @@
#include "llappearancemgr.h"
// register panel with appropriate XML
-static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable");
+static LLPanelInjector<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable");
// subparts of the UI for focus, camera position, etc.
enum ESubpart {
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index ae217958f0..180c1d6ab5 100755
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -55,7 +55,7 @@
#include "lltrans.h"
-static LLRegisterPanelClassWrapper<LLPanelGroup> t_panel_group("panel_group_info_sidetray");
+static LLPanelInjector<LLPanelGroup> t_panel_group("panel_group_info_sidetray");
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 0cd93b330a..eaf33c7108 100755
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -53,7 +53,7 @@
#include "lltrans.h"
#include "llviewerwindow.h"
-static LLRegisterPanelClassWrapper<LLPanelGroupGeneral> t_panel_group_general("panel_group_general");
+static LLPanelInjector<LLPanelGroupGeneral> t_panel_group_general("panel_group_general");
// consts
const S32 MATURE_CONTENT = 1;
@@ -63,14 +63,12 @@ const S32 DECLINE_TO_STATE = 0;
LLPanelGroupGeneral::LLPanelGroupGeneral()
: LLPanelGroupTab(),
- mPendingMemberUpdate(FALSE),
mChanged(FALSE),
mFirstUse(TRUE),
mGroupNameEditor(NULL),
mFounderName(NULL),
mInsignia(NULL),
mEditCharter(NULL),
- mListVisibleMembers(NULL),
mCtrlShowInGroupList(NULL),
mComboMature(NULL),
mCtrlOpenEnrollment(NULL),
@@ -79,18 +77,13 @@ LLPanelGroupGeneral::LLPanelGroupGeneral()
mCtrlReceiveNotices(NULL),
mCtrlListGroup(NULL),
mActiveTitleLabel(NULL),
- mComboActiveTitle(NULL),
- mAvatarNameCacheConnection()
+ mComboActiveTitle(NULL)
{
}
LLPanelGroupGeneral::~LLPanelGroupGeneral()
{
- if (mAvatarNameCacheConnection.connected())
- {
- mAvatarNameCacheConnection.disconnect();
- }
}
BOOL LLPanelGroupGeneral::postBuild()
@@ -105,17 +98,6 @@ BOOL LLPanelGroupGeneral::postBuild()
mEditCharter->setFocusChangedCallback(boost::bind(onFocusEdit, _1, this));
}
-
-
- mListVisibleMembers = getChild<LLNameListCtrl>("visible_members", recurse);
- if (mListVisibleMembers)
- {
- mListVisibleMembers->setDoubleClickCallback(openProfile, this);
- mListVisibleMembers->setContextMenu(LLScrollListCtrl::MENU_AVATAR);
-
- mListVisibleMembers->setSortCallback(boost::bind(&LLPanelGroupGeneral::sortMembersList,this,_1,_2,_3));
- }
-
// Options
mCtrlShowInGroupList = getChild<LLCheckBoxCtrl>("show_in_group_list", recurse);
if (mCtrlShowInGroupList)
@@ -290,21 +272,6 @@ void LLPanelGroupGeneral::onClickInfo(void *userdata)
}
-// static
-void LLPanelGroupGeneral::openProfile(void* data)
-{
- LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
-
- if (self && self->mListVisibleMembers)
- {
- LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected();
- if (selected)
- {
- LLAvatarActions::showProfile(selected->getUUID());
- }
- }
-}
-
bool LLPanelGroupGeneral::needsApply(std::string& mesg)
{
updateChanged();
@@ -336,11 +303,6 @@ void LLPanelGroupGeneral::activate()
void LLPanelGroupGeneral::draw()
{
LLPanelGroupTab::draw();
-
- if (mPendingMemberUpdate)
- {
- updateMembers();
- }
}
bool LLPanelGroupGeneral::apply(std::string& mesg)
@@ -522,10 +484,6 @@ bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LL
return false;
}
-static F32 sSDTime = 0.0f;
-static F32 sElementTime = 0.0f;
-static F32 sAllTime = 0.0f;
-
// virtual
void LLPanelGroupGeneral::update(LLGroupChange gc)
{
@@ -666,132 +624,10 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
{
mEditCharter->setText(gdatap->mCharter);
}
-
- if (mListVisibleMembers)
- {
- mListVisibleMembers->deleteAllItems();
-
- if (gdatap->isMemberDataComplete())
- {
- mMemberProgress = gdatap->mMembers.begin();
- mPendingMemberUpdate = TRUE;
-
- sSDTime = 0.0f;
- sElementTime = 0.0f;
- sAllTime = 0.0f;
- }
- else
- {
- std::stringstream pending;
- pending << "Retrieving member list (" << gdatap->mMembers.size() << "\\" << gdatap->mMemberCount << ")";
-
- LLSD row;
- row["columns"][0]["value"] = pending.str();
- row["columns"][0]["column"] = "name";
-
- mListVisibleMembers->setEnabled(FALSE);
- mListVisibleMembers->addElement(row);
- }
- }
resetDirty();
}
-void LLPanelGroupGeneral::updateMembers()
-{
- mPendingMemberUpdate = FALSE;
-
- LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
-
- if (!mListVisibleMembers
- || !gdatap
- || !gdatap->isMemberDataComplete()
- || gdatap->mMembers.empty())
- {
- return;
- }
-
- LLTimer update_time;
- update_time.setTimerExpirySec(UPDATE_MEMBERS_SECONDS_PER_FRAME);
-
- LLAvatarName av_name;
-
- for( ; mMemberProgress != gdatap->mMembers.end() && !update_time.hasExpired();
- ++mMemberProgress)
- {
- LLGroupMemberData* member = mMemberProgress->second;
- if (!member)
- {
- continue;
- }
-
- if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
- {
- addMember(mMemberProgress->second);
- }
- else
- {
- // If name is not cached, onNameCache() should be called when it is cached and add this member to list.
- // *TODO : Use a callback per member, not for the panel group.
- if (mAvatarNameCacheConnection.connected())
- {
- mAvatarNameCacheConnection.disconnect();
- }
- mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, gdatap->getMemberVersion(), member, _2));
- }
- }
-
- if (mMemberProgress == gdatap->mMembers.end())
- {
- lldebugs << " member list completed." << llendl;
- mListVisibleMembers->setEnabled(TRUE);
- }
- else
- {
- mPendingMemberUpdate = TRUE;
- mListVisibleMembers->setEnabled(FALSE);
- }
-}
-
-void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
-{
- LLNameListCtrl::NameItem item_params;
- item_params.value = member->getID();
-
- LLScrollListCell::Params column;
- item_params.columns.add().column("name").font.name("SANSSERIF_SMALL");
-
- item_params.columns.add().column("title").value(member->getTitle()).font.name("SANSSERIF_SMALL");
-
- item_params.columns.add().column("status").value(member->getOnlineStatus()).font.name("SANSSERIF_SMALL");
-
- LLScrollListItem* member_row = mListVisibleMembers->addNameItemRow(item_params);
-
- if ( member->isOwner() )
- {
- LLScrollListText* name_textp = dynamic_cast<LLScrollListText*>(member_row->getColumn(0));
- if (name_textp)
- name_textp->setFontStyle(LLFontGL::BOLD);
- }
-}
-
-void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
-{
- mAvatarNameCacheConnection.disconnect();
-
- LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
-
- if (!gdatap
- || !gdatap->isMemberDataComplete()
- || gdatap->getMemberVersion() != update_id)
- {
- // Stale data
- return;
- }
-
- addMember(member);
-}
-
void LLPanelGroupGeneral::updateChanged()
{
// List all the controls we want to check for changes...
@@ -867,17 +703,6 @@ void LLPanelGroupGeneral::reset()
mEditCharter->setText(empty_str);
mGroupNameEditor->setText(empty_str);
}
-
- {
- LLSD row;
- row["columns"][0]["value"] = "no members yet";
- row["columns"][0]["column"] = "name";
-
- mListVisibleMembers->deleteAllItems();
- mListVisibleMembers->setEnabled(FALSE);
- mListVisibleMembers->addElement(row);
- }
-
{
mComboMature->setEnabled(true);
@@ -964,18 +789,3 @@ void LLPanelGroupGeneral::setGroupID(const LLUUID& id)
activate();
}
-S32 LLPanelGroupGeneral::sortMembersList(S32 col_idx,const LLScrollListItem* i1,const LLScrollListItem* i2)
-{
- const LLScrollListCell *cell1 = i1->getColumn(col_idx);
- const LLScrollListCell *cell2 = i2->getColumn(col_idx);
-
- if(col_idx == 2)
- {
- if(LLStringUtil::compareDict(cell1->getValue().asString(),"Online") == 0 )
- return 1;
- if(LLStringUtil::compareDict(cell2->getValue().asString(),"Online") == 0 )
- return -1;
- }
-
- return LLStringUtil::compareDict(cell1->getValue().asString(), cell2->getValue().asString());
-}
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index b7f4a01139..11972bafa9 100755
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -62,8 +62,6 @@ public:
virtual void setGroupID(const LLUUID& id);
virtual void setupCtrls (LLPanel* parent);
-
- void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
private:
void reset();
@@ -75,18 +73,12 @@ private:
static void onCommitEnrollment(LLUICtrl* ctrl, void* data);
static void onClickInfo(void* userdata);
static void onReceiveNotices(LLUICtrl* ctrl, void* data);
- static void openProfile(void* data);
-
- S32 sortMembersList(S32,const LLScrollListItem*,const LLScrollListItem*);
- void addMember(LLGroupMemberData* member);
static bool joinDlgCB(const LLSD& notification, const LLSD& response);
- void updateMembers();
void updateChanged();
bool confirmMatureApply(const LLSD& notification, const LLSD& response);
- BOOL mPendingMemberUpdate;
BOOL mChanged;
BOOL mFirstUse;
std::string mIncompleteMemberDataStr;
@@ -97,8 +89,6 @@ private:
LLTextureCtrl *mInsignia;
LLTextEditor *mEditCharter;
- LLNameListCtrl *mListVisibleMembers;
-
// Options (include any updates in updateChanged)
LLCheckBoxCtrl *mCtrlShowInGroupList;
LLCheckBoxCtrl *mCtrlOpenEnrollment;
@@ -109,9 +99,6 @@ private:
LLTextBox *mActiveTitleLabel;
LLComboBox *mComboActiveTitle;
LLComboBox *mComboMature;
-
- LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
- boost::signals2::connection mAvatarNameCacheConnection;
};
#endif
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index c927aeacb3..17707557bb 100755
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -55,7 +55,7 @@
#include "llfloaterworldmap.h"
#include "llviewermessage.h"
-static LLRegisterPanelClassWrapper<LLPanelGroupLandMoney> t_panel_group_money("panel_group_land_money");
+static LLPanelInjector<LLPanelGroupLandMoney> t_panel_group_money("panel_group_land_money");
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 522ba5afae..0dfb8fef53 100755
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -57,7 +57,7 @@
#include "llnotificationsutil.h"
#include "llgiveinventory.h"
-static LLRegisterPanelClassWrapper<LLPanelGroupNotices> t_panel_group_notices("panel_group_notices");
+static LLPanelInjector<LLPanelGroupNotices> t_panel_group_notices("panel_group_notices");
/////////////////////////
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index fdcd1f5ebb..4cb6506b61 100755
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -55,7 +55,7 @@
#include "roles_constants.h"
-static LLRegisterPanelClassWrapper<LLPanelGroupRoles> t_panel_group_roles("panel_group_roles");
+static LLPanelInjector<LLPanelGroupRoles> t_panel_group_roles("panel_group_roles");
bool agentCanRemoveFromRole(const LLUUID& group_id,
const LLUUID& role_id)
@@ -733,7 +733,7 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable)
////////////////////////////
-static LLRegisterPanelClassWrapper<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab");
+static LLPanelInjector<LLPanelGroupMembersSubTab> t_panel_group_members_subtab("panel_group_members_subtab");
LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
: LLPanelGroupSubTab(),
@@ -743,17 +743,20 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
mChanged(FALSE),
mPendingMemberUpdate(FALSE),
mHasMatch(FALSE),
- mNumOwnerAdditions(0),
- mAvatarNameCacheConnection()
+ mNumOwnerAdditions(0)
{
}
LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
{
- if (mAvatarNameCacheConnection.connected())
+ for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
}
+ mAvatarNameCacheConnections.clear();
if (mMembersList)
{
gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName());
@@ -1636,14 +1639,25 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
item_params.columns.add().column("online").value(data->getOnlineStatus())
.font.name("SANSSERIF_SMALL").style("NORMAL");
+
+ item_params.columns.add().column("title").value(data->getTitle()).font.name("SANSSERIF_SMALL").style("NORMAL");;
+
mMembersList->addNameItemRow(item_params);
mHasMatch = TRUE;
}
-void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
+void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id)
{
- mAvatarNameCacheConnection.disconnect();
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(av_id);
+ if (it != mAvatarNameCacheConnections.end())
+ {
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
+ }
LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
if (!gdatap
@@ -1716,12 +1730,16 @@ void LLPanelGroupMembersSubTab::updateMembers()
else
{
// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
- // *TODO : Add one callback per fetched avatar name
- if (mAvatarNameCacheConnection.connected())
+ avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(mMemberProgress->first);
+ if (it != mAvatarNameCacheConnections.end())
{
- mAvatarNameCacheConnection.disconnect();
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ mAvatarNameCacheConnections.erase(it);
}
- mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
+ mAvatarNameCacheConnections[mMemberProgress->first] = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2, _1));
}
}
@@ -1752,7 +1770,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
// LLPanelGroupRolesSubTab
////////////////////////////
-static LLRegisterPanelClassWrapper<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab");
+static LLPanelInjector<LLPanelGroupRolesSubTab> t_panel_group_roles_subtab("panel_group_roles_subtab");
LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab()
: LLPanelGroupSubTab(),
@@ -2466,7 +2484,7 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role)
// LLPanelGroupActionsSubTab
////////////////////////////
-static LLRegisterPanelClassWrapper<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab");
+static LLPanelInjector<LLPanelGroupActionsSubTab> t_panel_group_actions_subtab("panel_group_actions_subtab");
LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab()
@@ -2658,7 +2676,7 @@ void LLPanelGroupRoles::setGroupID(const LLUUID& id)
button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE));
if(mSubTabContainer)
- mSubTabContainer->selectTab(0);
+ mSubTabContainer->selectTab(1);
activate();
}
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 0cf272f3ee..baa2d40c7e 100755
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -189,7 +189,7 @@ public:
virtual void setGroupID(const LLUUID& id);
void addMemberToList(LLGroupMemberData* data);
- void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
+ void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name, const LLUUID& av_id);
protected:
typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;
@@ -215,7 +215,8 @@ protected:
U32 mNumOwnerAdditions;
LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
- boost::signals2::connection mAvatarNameCacheConnection;
+ typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+ avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
diff --git a/indra/newview/llpanelhome.cpp b/indra/newview/llpanelhome.cpp
index b03bab3127..ab0ccffae4 100755
--- a/indra/newview/llpanelhome.cpp
+++ b/indra/newview/llpanelhome.cpp
@@ -31,7 +31,7 @@
#include "llmediactrl.h"
#include "llviewerhome.h"
-static LLRegisterPanelClassWrapper<LLPanelHome> t_home("panel_sidetray_home");
+static LLPanelInjector<LLPanelHome> t_home("panel_sidetray_home");
LLPanelHome::LLPanelHome() :
LLPanel(),
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 5c9b968ac9..934f8ed8c7 100755
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -53,7 +53,7 @@ typedef std::pair<LLUUID, std::string> folder_pair_t;
static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
-static LLRegisterPanelClassWrapper<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
+static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
// Statics for textures filenames
static std::string icon_pg;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 1ff0bfd091..68c22c12fd 100755
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -58,7 +58,7 @@
const std::string FILTERS_FILENAME("filters.xml");
-static LLRegisterPanelClassWrapper<LLPanelMainInventory> t_inventory("panel_main_inventory");
+static LLPanelInjector<LLPanelMainInventory> t_inventory("panel_main_inventory");
void on_file_loaded_for_save(BOOL success,
LLViewerFetchedTexture *src_vi,
@@ -574,13 +574,16 @@ void LLPanelMainInventory::draw()
void LLPanelMainInventory::updateItemcountText()
{
- // *TODO: Calling setlocale() on each frame may be inefficient.
- //LLLocale locale(LLStringUtil::getLocale());
- std::string item_count_string;
- LLResMgr::getInstance()->getIntegerString(item_count_string, gInventory.getItemCount());
+ if(mItemCount != gInventory.getItemCount())
+ {
+ mItemCount = gInventory.getItemCount();
+ mItemCountString = "";
+ LLLocale locale(LLLocale::USER_LOCALE);
+ LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
+ }
LLStringUtil::format_map_t string_args;
- string_args["[ITEM_COUNT]"] = item_count_string;
+ string_args["[ITEM_COUNT]"] = mItemCountString;
string_args["[FILTER]"] = getFilterText();
std::string text = "";
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index fc8cc67c33..21f0ca0cae 100755
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -131,6 +131,8 @@ private:
LLSaveFolderState* mSavedFolderState;
std::string mFilterText;
std::string mFilterSubString;
+ S32 mItemCount;
+ std::string mItemCountString;
//////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index dcecce6fe4..79e079f6bd 100755
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -38,7 +38,7 @@
#include "llviewercontrol.h"
-static LLRegisterPanelClassWrapper<LLPanelMarketplaceInbox> t_panel_marketplace_inbox("panel_marketplace_inbox");
+static LLPanelInjector<LLPanelMarketplaceInbox> t_panel_marketplace_inbox("panel_marketplace_inbox");
const LLPanelMarketplaceInbox::Params& LLPanelMarketplaceInbox::getDefaultParams()
{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index adfb2dee86..da938712d7 100755
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -69,7 +69,7 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
LLInboxFolderViewFolder::Params params;
params.name = bridge->getDisplayName();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.tool_tip = params.name;
params.font_color = item_color;
@@ -86,7 +86,7 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
params.name = bridge->getDisplayName();
params.creation_date = bridge->getCreationDate();
- params.root = mFolderRoot;
+ params.root = mFolderRoot.get();
params.listener = bridge;
params.rect = LLRect (0, 0, 0, 0);
params.tool_tip = params.name;
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index a9af56f750..7a408e736f 100755
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -48,7 +48,7 @@
#include "lltabcontainer.h"
#include "lltexturectrl.h"
-static LLRegisterPanelClassWrapper<LLPanelMe> t_panel_me_profile("panel_me");
+static LLPanelInjector<LLPanelMe> t_panel_me_profile("panel_me");
LLPanelMe::LLPanelMe(void)
: LLPanelProfile()
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index c09d4393c8..f75d76da94 100755
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -74,7 +74,7 @@
#include "llwearabletype.h"
#include "llweb.h"
-static LLRegisterPanelClassWrapper<LLPanelOutfitEdit> t_outfit_edit("panel_outfit_edit");
+static LLPanelInjector<LLPanelOutfitEdit> t_outfit_edit("panel_outfit_edit");
const U64 WEARABLE_MASK = (1LL << LLInventoryType::IT_WEARABLE);
const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LLInventoryType::IT_OBJECT);
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index f90236f6f2..e0132d20fb 100755
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -46,7 +46,7 @@
static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
static const std::string COF_TAB_NAME = "cof_tab";
-static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
+static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
mMyOutfitsPanel(NULL),
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index f551fc96ee..f5542ee7a6 100755
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -216,7 +216,7 @@ static const LLAvatarItemStatusComparator STATUS_COMPARATOR;
static LLAvatarItemDistanceComparator DISTANCE_COMPARATOR;
static const LLAvatarItemRecentSpeakerComparator RECENT_SPEAKER_COMPARATOR;
-static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
+static LLPanelInjector<LLPanelPeople> t_people("panel_people");
//=============================================================================
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index cfbc8f1a94..f0617266db 100755
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -69,7 +69,7 @@ static const std::string CLASSIFIED_ID("classified_id");
static const std::string CLASSIFIED_NAME("classified_name");
-static LLRegisterPanelClassWrapper<LLPanelPicks> t_panel_picks("panel_picks");
+static LLPanelInjector<LLPanelPicks> t_panel_picks("panel_picks");
class LLPickHandler : public LLCommandHandler,
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 5d9971c16c..14b5d9af47 100755
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -53,7 +53,7 @@
#include "llviewerparcelmgr.h"
#include "llviewerregion.h"
-static LLRegisterPanelClassWrapper<LLPanelPlaceProfile> t_place_profile("panel_place_profile");
+static LLPanelInjector<LLPanelPlaceProfile> t_place_profile("panel_place_profile");
// Statics for textures filenames
static std::string icon_pg;
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 8bb3ace2d9..499b9ab62e 100755
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -229,7 +229,7 @@ private:
};
-static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
+static LLPanelInjector<LLPanelPlaces> t_places("panel_places");
LLPanelPlaces::LLPanelPlaces()
: LLPanel(),
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index 381c11348d..47e46a968f 100755
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -60,7 +60,7 @@ private:
void onSend();
};
-static LLRegisterPanelClassWrapper<LLPanelSnapshotInventory> panel_class("llpanelsnapshotinventory");
+static LLPanelInjector<LLPanelSnapshotInventory> panel_class("llpanelsnapshotinventory");
LLPanelSnapshotInventory::LLPanelSnapshotInventory()
{
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index d153ff598d..43e38b95e2 100755
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -63,7 +63,7 @@ private:
void onSaveFlyoutCommit(LLUICtrl* ctrl);
};
-static LLRegisterPanelClassWrapper<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal");
+static LLPanelInjector<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal");
LLPanelSnapshotLocal::LLPanelSnapshotLocal()
{
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 554fabe5b3..455c1c9e5f 100755
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -56,7 +56,7 @@ private:
void onSaveToComputer();
};
-static LLRegisterPanelClassWrapper<LLPanelSnapshotOptions> panel_class("llpanelsnapshotoptions");
+static LLPanelInjector<LLPanelSnapshotOptions> panel_class("llpanelsnapshotoptions");
LLPanelSnapshotOptions::LLPanelSnapshotOptions()
{
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index f2bb8f530b..aa109e9a51 100755
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -79,7 +79,7 @@ private:
std::string mAgentEmail;
};
-static LLRegisterPanelClassWrapper<LLPanelSnapshotPostcard> panel_class("llpanelsnapshotpostcard");
+static LLPanelInjector<LLPanelSnapshotPostcard> panel_class("llpanelsnapshotpostcard");
LLPanelSnapshotPostcard::LLPanelSnapshotPostcard()
: mHasFirstMsgFocus(false)
diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp
index a706318369..8949eb73eb 100755
--- a/indra/newview/llpanelsnapshotprofile.cpp
+++ b/indra/newview/llpanelsnapshotprofile.cpp
@@ -64,7 +64,7 @@ private:
void onSend();
};
-static LLRegisterPanelClassWrapper<LLPanelSnapshotProfile> panel_class("llpanelsnapshotprofile");
+static LLPanelInjector<LLPanelSnapshotProfile> panel_class("llpanelsnapshotprofile");
LLPanelSnapshotProfile::LLPanelSnapshotProfile()
{
diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp
index 6be2ea6481..6f0a1624a7 100755
--- a/indra/newview/llpanelvoicedevicesettings.cpp
+++ b/indra/newview/llpanelvoicedevicesettings.cpp
@@ -40,7 +40,7 @@
#include "lluictrlfactory.h"
-static LLRegisterPanelClassWrapper<LLPanelVoiceDeviceSettings> t_panel_group_general("panel_voice_device_settings");
+static LLPanelInjector<LLPanelVoiceDeviceSettings> t_panel_group_general("panel_voice_device_settings");
static const std::string DEFAULT_DEVICE("Default");
diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp
index 5fec6d967d..7da553801a 100755
--- a/indra/newview/llpanelvoiceeffect.cpp
+++ b/indra/newview/llpanelvoiceeffect.cpp
@@ -36,7 +36,7 @@
#include "lltransientfloatermgr.h"
#include "llvoiceclient.h"
-static LLRegisterPanelClassWrapper<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect");
+static LLPanelInjector<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect");
LLPanelVoiceEffect::LLPanelVoiceEffect()
: mVoiceEffectCombo(NULL)
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index aa3ed22bee..edb624e3aa 100755
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -151,7 +151,7 @@ protected:
std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null;
-static LLRegisterPanelClassWrapper<LLPanelWearing> t_panel_wearing("panel_wearing");
+static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing");
LLPanelWearing::LLPanelWearing()
: LLPanelAppearanceTab()
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 4c2213c198..5eadd65884 100755
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -91,17 +91,17 @@ LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
void LLPlacesInventoryPanel::saveFolderState()
{
mSavedFolderState->setApply(FALSE);
- mFolderRoot->applyFunctorRecursively(*mSavedFolderState);
+ mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);
}
// re-open folders which state was saved
void LLPlacesInventoryPanel::restoreFolderState()
{
mSavedFolderState->setApply(TRUE);
- mFolderRoot->applyFunctorRecursively(*mSavedFolderState);
+ mFolderRoot.get()->applyFunctorRecursively(*mSavedFolderState);
LLOpenFoldersWithSelection opener;
- mFolderRoot->applyFunctorRecursively(opener);
- mFolderRoot->scrollToShowSelection();
+ mFolderRoot.get()->applyFunctorRecursively(opener);
+ mFolderRoot.get()->scrollToShowSelection();
}
S32 LLPlacesInventoryPanel::notify(const LLSD& info)
@@ -111,11 +111,11 @@ S32 LLPlacesInventoryPanel::notify(const LLSD& info)
std::string str_action = info["action"];
if(str_action == "select_first")
{
- return mFolderRoot->notify(info);
+ return mFolderRoot.get()->notify(info);
}
else if(str_action == "select_last")
{
- return mFolderRoot->notify(info);
+ return mFolderRoot.get()->notify(info);
}
}
return 0;
diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index 08829c1184..153f0930c2 100755
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -27,7 +27,7 @@
#include "llpopupview.h"
-static LLRegisterPanelClassWrapper<LLPopupView> r("popup_holder");
+static LLPanelInjector<LLPopupView> r("popup_holder");
bool view_visible_and_enabled(LLView* viewp)
{
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 989f0b0e60..1257ee7f94 100755
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -59,7 +59,7 @@ S32 gStartImageWidth = 1;
S32 gStartImageHeight = 1;
const F32 FADE_TO_WORLD_TIME = 1.0f;
-static LLRegisterPanelClassWrapper<LLProgressView> r("progress_view");
+static LLPanelInjector<LLProgressView> r("progress_view");
// XUI: Translate
LLProgressView::LLProgressView()
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 7b397d46f3..c83b459279 100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6187,8 +6187,8 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
if (shader)
- { //switch to "solid color" program for SH-2690 -- works around driver bug causing bad triangles when rendering silhouettes
- gSolidColorProgram.bind();
+ { //use UI program for selection highlights (texture color modulated by vertex color)
+ gUIProgram.bind();
}
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -6243,10 +6243,11 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
gGL.begin(LLRender::LINES);
{
+ gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+
for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2)
{
u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
- gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
gGL.texCoord2f( u_coord, v_coord );
gGL.vertex3fv( mSilhouetteVertices[i].mV);
u_coord += u_divisor * LLSelectMgr::sHighlightUScale;
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index df413ab849..ec6a1d9bdc 100755
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -49,7 +49,7 @@
#include "llvoavatarself.h"
#include "llviewerwearable.h"
-static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
+static LLPanelInjector<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
class LLCurrentlyWornFetchObserver : public LLInventoryFetchItemsObserver
{
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index cbf43dbb93..040cbc22a6 100755
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -59,7 +59,7 @@
#include "llviewernetwork.h"
#include "llweb.h"
-static LLRegisterPanelClassWrapper<LLSidepanelInventory> t_inventory("sidepanel_inventory");
+static LLPanelInjector<LLSidepanelInventory> t_inventory("sidepanel_inventory");
//
// Constants
@@ -119,7 +119,6 @@ private:
LLSidepanelInventory::LLSidepanelInventory()
: LLPanel()
, mItemPanel(NULL)
- , mInventoryPanelInbox(NULL)
, mPanelMainInventory(NULL)
, mInboxEnabled(false)
, mCategoriesObserver(NULL)
@@ -299,7 +298,7 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
// (this can happen multiple times on the initial session that creates the inbox)
//
- if (mInventoryPanelInbox != NULL)
+ if (mInventoryPanelInbox.get() != NULL)
{
return;
}
@@ -333,7 +332,8 @@ void LLSidepanelInventory::observeInboxModifications(const LLUUID& inboxID)
//
LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
- mInventoryPanelInbox = inbox->setupInventoryPanel();
+ LLInventoryPanel* inventory_panel = inbox->setupInventoryPanel();
+ mInventoryPanelInbox = inventory_panel->getInventoryPanelHandle();
}
void LLSidepanelInventory::enableInbox(bool enabled)
@@ -461,9 +461,9 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
if (!current_item)
{
- if (mInventoryPanelInbox)
+ if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
+ current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
}
if (!current_item)
@@ -614,10 +614,10 @@ void LLSidepanelInventory::updateVerbs()
bool LLSidepanelInventory::canShare()
{
- LLInventoryPanel* inbox = mInventoryPanelInbox;
+ LLInventoryPanel* inbox = mInventoryPanelInbox.get();
// Avoid flicker in the Recent tab while inventory is being loaded.
- if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty())
+ if ( (!inbox || !inbox->getRootFolder() || inbox->getRootFolder()->getSelectionList().empty())
&& (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
{
return false;
@@ -652,9 +652,9 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
if (!current_item)
{
- if (mInventoryPanelInbox)
+ if (mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
+ current_item = mInventoryPanelInbox.get()->getRootFolder()->getCurSelectedItem();
}
if (!current_item)
@@ -671,12 +671,12 @@ U32 LLSidepanelInventory::getSelectedCount()
{
int count = 0;
- std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+ std::set<LLFolderViewItem*> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
count += selection_list.size();
- if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
+ if ((count == 0) && mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+ selection_list = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
count += selection_list.size();
}
@@ -714,9 +714,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
}
}
- if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL))
+ if (clearInbox && mInboxEnabled && mInventoryPanelInbox.get())
{
- mInventoryPanelInbox->clearSelection();
+ mInventoryPanelInbox.get()->clearSelection();
}
updateVerbs();
@@ -726,9 +726,9 @@ std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
{
std::set<LLFolderViewItem*> inventory_selected_uuids;
- if (mInboxEnabled && (mInventoryPanelInbox != NULL))
+ if (mInboxEnabled && mInventoryPanelInbox.get() && mInventoryPanelInbox.get()->getRootFolder())
{
- inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+ inventory_selected_uuids = mInventoryPanelInbox.get()->getRootFolder()->getSelectionList();
}
return inventory_selected_uuids;
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index e8b2808d4f..17a3098db9 100755
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -57,7 +57,7 @@ public:
/*virtual*/ void onOpen(const LLSD& key);
LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
- LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox; }
+ LLInventoryPanel* getInboxPanel() const { return mInventoryPanelInbox.get(); }
LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }
BOOL isMainInventoryPanelActive() const;
@@ -99,7 +99,7 @@ protected:
//
private:
LLPanel* mInventoryPanel; // Main inventory view
- LLInventoryPanel* mInventoryPanelInbox;
+ LLHandle<LLInventoryPanel> mInventoryPanelInbox;
LLSidepanelItemInfo* mItemPanel; // Individual item view
LLSidepanelTaskInfo* mTaskPanel; // Individual in-world object view
LLPanelMainInventory* mPanelMainInventory;
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 92c2863ffd..e52b2f2559 100755
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -127,7 +127,7 @@ void LLObjectInventoryObserver::inventoryChanged(LLViewerObject* object,
/// Class LLSidepanelItemInfo
///----------------------------------------------------------------------------
-static LLRegisterPanelClassWrapper<LLSidepanelItemInfo> t_item_info("sidepanel_item_info");
+static LLPanelInjector<LLSidepanelItemInfo> t_item_info("sidepanel_item_info");
// Default constructor
LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p)
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 9be6d0c5f1..4428098929 100755
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -71,7 +71,7 @@
LLSidepanelTaskInfo* LLSidepanelTaskInfo::sActivePanel = NULL;
-static LLRegisterPanelClassWrapper<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
+static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
// Default constructor
LLSidepanelTaskInfo::LLSidepanelTaskInfo()
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 67a76460a7..d4b3fcf28a 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -786,14 +786,18 @@ bool idle_startup()
display_startup();
LLPanelLogin::giveFocus();
- if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ // MAINT-3231 Show first run dialog only for Desura viewer
+ if (gSavedSettings.getString("sourceid") == "1208_desura")
{
- LL_INFOS("AppInit") << "FirstLoginThisInstall, calling show_first_run_dialog()" << LL_ENDL;
- show_first_run_dialog();
- }
- else
- {
- LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;
+ if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+ {
+ LL_INFOS("AppInit") << "FirstLoginThisInstall, calling show_first_run_dialog()" << LL_ENDL;
+ show_first_run_dialog();
+ }
+ else
+ {
+ LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;
+ }
}
LLStartUp::setStartupState( STATE_LOGIN_WAIT ); // Wait for user input
@@ -3506,7 +3510,8 @@ bool process_login_success_response()
{
success = true;
}
-
+ LLAppViewer* pApp = LLAppViewer::instance();
+ pApp->writeDebugInfo(); //Write our static data now that we have username, session_id, etc.
return success;
}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 4300cafb6b..ea837c9127 100755
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -820,7 +820,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
{
mNoCopyTextureSelected = TRUE;
}
- mImageAssetID = itemp->getAssetUUID();
+ setImageID(itemp->getAssetUUID());
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if (user_action && mCanPreview)
{
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 3a41bf28b4..c983527762 100755
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -41,11 +41,12 @@
#include "llnotificationsutil.h"
#include "llviewermessage.h"
#include "llfloaterimsession.h"
+#include "llavataractions.h"
const S32 BOTTOM_PAD = VPAD * 3;
const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
S32 BUTTON_WIDTH = 90;
-// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
+// *TODO: magic numbers(?) - copied from llnotify.cpp(250)
const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
@@ -130,6 +131,7 @@ LLToastNotifyPanel::~LLToastNotifyPanel()
mButtonClickConnection.disconnect();
std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
+ mBtnCallbackData.clear();
if (mIsTip)
{
LLNotifications::getInstance()->cancel(mNotification);
@@ -313,6 +315,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
mTextBox->setVisible(TRUE);
mTextBox->setPlainText(!show_images);
mTextBox->setValue(mNotification->getMessage());
+ mTextBox->setIsFriendCallback(LLAvatarActions::isFriend);
// add buttons for a script notification
if (mIsTip)
diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h
index ecc435d844..c5bad9d532 100755
--- a/indra/newview/lltool.h
+++ b/indra/newview/lltool.h
@@ -39,7 +39,7 @@ class LLView;
class LLPanel;
class LLTool
-: public LLMouseHandler
+: public LLMouseHandler, public LLThreadSafeRefCount
{
public:
LLTool( const std::string& name, LLToolComposite* composite = NULL );
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 78a555d67d..36d4654393 100755
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -77,7 +77,7 @@ LLToolBarView::LLToolBarView(const LLToolBarView::Params& p)
mToolbarsLoaded(false),
mBottomToolbarPanel(NULL)
{
- for (S32 i = 0; i < TOOLBAR_COUNT; i++)
+ for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; i++)
{
mToolbars[i] = NULL;
}
@@ -96,12 +96,18 @@ LLToolBarView::~LLToolBarView()
BOOL LLToolBarView::postBuild()
{
- mToolbars[TOOLBAR_LEFT] = getChild<LLToolBar>("toolbar_left");
- mToolbars[TOOLBAR_RIGHT] = getChild<LLToolBar>("toolbar_right");
- mToolbars[TOOLBAR_BOTTOM] = getChild<LLToolBar>("toolbar_bottom");
+ mToolbars[LLToolBarEnums::TOOLBAR_LEFT] = getChild<LLToolBar>("toolbar_left");
+ mToolbars[LLToolBarEnums::TOOLBAR_LEFT]->getCenterLayoutPanel()->setLocationId(LLToolBarEnums::TOOLBAR_LEFT);
+
+ mToolbars[LLToolBarEnums::TOOLBAR_RIGHT] = getChild<LLToolBar>("toolbar_right");
+ mToolbars[LLToolBarEnums::TOOLBAR_RIGHT]->getCenterLayoutPanel()->setLocationId(LLToolBarEnums::TOOLBAR_RIGHT);
+
+ mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM] = getChild<LLToolBar>("toolbar_bottom");
+ mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM]->getCenterLayoutPanel()->setLocationId(LLToolBarEnums::TOOLBAR_BOTTOM);
+
mBottomToolbarPanel = getChild<LLView>("bottom_toolbar_panel");
- for (int i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (int i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
mToolbars[i]->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
mToolbars[i]->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
@@ -115,9 +121,9 @@ BOOL LLToolBarView::postBuild()
S32 LLToolBarView::hasCommand(const LLCommandId& commandId) const
{
- S32 command_location = TOOLBAR_NONE;
+ S32 command_location = LLToolBarEnums::TOOLBAR_NONE;
- for (S32 loc = TOOLBAR_FIRST; loc <= TOOLBAR_LAST; loc++)
+ for (S32 loc = LLToolBarEnums::TOOLBAR_FIRST; loc <= LLToolBarEnums::TOOLBAR_LAST; loc++)
{
if (mToolbars[loc]->hasCommand(commandId))
{
@@ -129,7 +135,7 @@ S32 LLToolBarView::hasCommand(const LLCommandId& commandId) const
return command_location;
}
-S32 LLToolBarView::addCommand(const LLCommandId& commandId, EToolBarLocation toolbar, int rank)
+S32 LLToolBarView::addCommand(const LLCommandId& commandId, LLToolBarEnums::EToolBarLocation toolbar, int rank)
{
int old_rank;
removeCommand(commandId, old_rank);
@@ -144,7 +150,7 @@ S32 LLToolBarView::removeCommand(const LLCommandId& commandId, int& rank)
S32 command_location = hasCommand(commandId);
rank = LLToolBar::RANK_NONE;
- if (command_location != TOOLBAR_NONE)
+ if (command_location != LLToolBarEnums::TOOLBAR_NONE)
{
rank = mToolbars[command_location]->removeCommand(commandId);
}
@@ -156,7 +162,7 @@ S32 LLToolBarView::enableCommand(const LLCommandId& commandId, bool enabled)
{
S32 command_location = hasCommand(commandId);
- if (command_location != TOOLBAR_NONE)
+ if (command_location != LLToolBarEnums::TOOLBAR_NONE)
{
mToolbars[command_location]->enableCommand(commandId, enabled);
}
@@ -168,7 +174,7 @@ S32 LLToolBarView::stopCommandInProgress(const LLCommandId& commandId)
{
S32 command_location = hasCommand(commandId);
- if (command_location != TOOLBAR_NONE)
+ if (command_location != LLToolBarEnums::TOOLBAR_NONE)
{
mToolbars[command_location]->stopCommandInProgress(commandId);
}
@@ -180,7 +186,7 @@ S32 LLToolBarView::flashCommand(const LLCommandId& commandId, bool flash, bool f
{
S32 command_location = hasCommand(commandId);
- if (command_location != TOOLBAR_NONE)
+ if (command_location != LLToolBarEnums::TOOLBAR_NONE)
{
mToolbars[command_location]->flashCommand(commandId, flash, force_flashing);
}
@@ -259,7 +265,7 @@ bool LLToolBarView::loadToolbars(bool force_default)
}
// Clear the toolbars now before adding the loaded commands and settings
- for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
if (mToolbars[i])
{
@@ -268,46 +274,46 @@ bool LLToolBarView::loadToolbars(bool force_default)
}
// Add commands to each toolbar
- if (toolbar_set.left_toolbar.isProvided() && mToolbars[TOOLBAR_LEFT])
+ if (toolbar_set.left_toolbar.isProvided() && mToolbars[LLToolBarEnums::TOOLBAR_LEFT])
{
if (toolbar_set.left_toolbar.button_display_mode.isProvided())
{
LLToolBarEnums::ButtonType button_type = toolbar_set.left_toolbar.button_display_mode;
- mToolbars[TOOLBAR_LEFT]->setButtonType(button_type);
+ mToolbars[LLToolBarEnums::TOOLBAR_LEFT]->setButtonType(button_type);
}
BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.left_toolbar.commands)
{
- if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_LEFT]))
+ if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_LEFT]))
{
llwarns << "Error adding command '" << command_params.name() << "' to left toolbar." << llendl;
}
}
}
- if (toolbar_set.right_toolbar.isProvided() && mToolbars[TOOLBAR_RIGHT])
+ if (toolbar_set.right_toolbar.isProvided() && mToolbars[LLToolBarEnums::TOOLBAR_RIGHT])
{
if (toolbar_set.right_toolbar.button_display_mode.isProvided())
{
LLToolBarEnums::ButtonType button_type = toolbar_set.right_toolbar.button_display_mode;
- mToolbars[TOOLBAR_RIGHT]->setButtonType(button_type);
+ mToolbars[LLToolBarEnums::TOOLBAR_RIGHT]->setButtonType(button_type);
}
BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.right_toolbar.commands)
{
- if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_RIGHT]))
+ if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_RIGHT]))
{
llwarns << "Error adding command '" << command_params.name() << "' to right toolbar." << llendl;
}
}
}
- if (toolbar_set.bottom_toolbar.isProvided() && mToolbars[TOOLBAR_BOTTOM])
+ if (toolbar_set.bottom_toolbar.isProvided() && mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM])
{
if (toolbar_set.bottom_toolbar.button_display_mode.isProvided())
{
LLToolBarEnums::ButtonType button_type = toolbar_set.bottom_toolbar.button_display_mode;
- mToolbars[TOOLBAR_BOTTOM]->setButtonType(button_type);
+ mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM]->setButtonType(button_type);
}
BOOST_FOREACH(const LLCommandId::Params& command_params, toolbar_set.bottom_toolbar.commands)
{
- if (addCommandInternal(LLCommandId(command_params), mToolbars[TOOLBAR_BOTTOM]))
+ if (addCommandInternal(LLCommandId(command_params), mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM]))
{
llwarns << "Error adding command '" << command_params.name() << "' to bottom toolbar." << llendl;
}
@@ -319,7 +325,7 @@ bool LLToolBarView::loadToolbars(bool force_default)
bool LLToolBarView::clearToolbars()
{
- for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
if (mToolbars[i])
{
@@ -371,20 +377,20 @@ void LLToolBarView::saveToolbars() const
// Build the parameter tree from the toolbar data
LLToolBarView::ToolbarSet toolbar_set;
- if (mToolbars[TOOLBAR_LEFT])
+ if (mToolbars[LLToolBarEnums::TOOLBAR_LEFT])
{
- toolbar_set.left_toolbar.button_display_mode = mToolbars[TOOLBAR_LEFT]->getButtonType();
- addToToolset(mToolbars[TOOLBAR_LEFT]->getCommandsList(), toolbar_set.left_toolbar);
+ toolbar_set.left_toolbar.button_display_mode = mToolbars[LLToolBarEnums::TOOLBAR_LEFT]->getButtonType();
+ addToToolset(mToolbars[LLToolBarEnums::TOOLBAR_LEFT]->getCommandsList(), toolbar_set.left_toolbar);
}
- if (mToolbars[TOOLBAR_RIGHT])
+ if (mToolbars[LLToolBarEnums::TOOLBAR_RIGHT])
{
- toolbar_set.right_toolbar.button_display_mode = mToolbars[TOOLBAR_RIGHT]->getButtonType();
- addToToolset(mToolbars[TOOLBAR_RIGHT]->getCommandsList(), toolbar_set.right_toolbar);
+ toolbar_set.right_toolbar.button_display_mode = mToolbars[LLToolBarEnums::TOOLBAR_RIGHT]->getButtonType();
+ addToToolset(mToolbars[LLToolBarEnums::TOOLBAR_RIGHT]->getCommandsList(), toolbar_set.right_toolbar);
}
- if (mToolbars[TOOLBAR_BOTTOM])
+ if (mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM])
{
- toolbar_set.bottom_toolbar.button_display_mode = mToolbars[TOOLBAR_BOTTOM]->getButtonType();
- addToToolset(mToolbars[TOOLBAR_BOTTOM]->getCommandsList(), toolbar_set.bottom_toolbar);
+ toolbar_set.bottom_toolbar.button_display_mode = mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM]->getButtonType();
+ addToToolset(mToolbars[LLToolBarEnums::TOOLBAR_BOTTOM]->getCommandsList(), toolbar_set.bottom_toolbar);
}
// Serialize the parameter tree
@@ -511,9 +517,9 @@ void LLToolBarView::onToolBarButtonRemoved(LLView* button)
void LLToolBarView::draw()
{
- LLRect toolbar_rects[TOOLBAR_COUNT];
+ LLRect toolbar_rects[LLToolBarEnums::TOOLBAR_COUNT];
- for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
if (mToolbars[i])
{
@@ -532,7 +538,7 @@ void LLToolBarView::draw()
}
}
- for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
mToolbars[i]->getParent()->setVisible(mShowToolbars
&& (mToolbars[i]->hasButtons()
@@ -544,7 +550,7 @@ void LLToolBarView::draw()
{
LLColor4 drop_color = LLUIColorTable::instance().getColor( "ToolbarDropZoneColor" );
- for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
gl_rect_2d(toolbar_rects[i], drop_color, TRUE);
}
@@ -620,7 +626,7 @@ BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* t
S32 old_toolbar_loc = gToolBarView->hasCommand(command_id);
LLToolBar* old_toolbar = NULL;
- if (old_toolbar_loc != TOOLBAR_NONE)
+ if (old_toolbar_loc != LLToolBarEnums::TOOLBAR_NONE)
{
llassert(gToolBarView->mDragToolbarButton);
old_toolbar = gToolBarView->mDragToolbarButton->getParentByType<LLToolBar>();
@@ -683,7 +689,7 @@ bool LLToolBarView::isModified() const
{
bool modified = false;
- for (S32 i = TOOLBAR_FIRST; i <= TOOLBAR_LAST; i++)
+ for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
{
modified |= mToolbars[i]->isModified();
}
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index dcc3862074..a230c2fdee 100755
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -40,19 +40,6 @@ class LLUICtrlFactory;
class LLToolBarView : public LLUICtrl
{
public:
- typedef enum
- {
- TOOLBAR_NONE = 0,
- TOOLBAR_LEFT,
- TOOLBAR_RIGHT,
- TOOLBAR_BOTTOM,
-
- TOOLBAR_COUNT,
-
- TOOLBAR_FIRST = TOOLBAR_LEFT,
- TOOLBAR_LAST = TOOLBAR_BOTTOM,
- } EToolBarLocation;
-
// Xui structure of the toolbar panel
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> {};
@@ -84,9 +71,9 @@ public:
virtual void draw();
// Toolbar view interface with the rest of the world
- // Checks if the commandId is being used somewhere in one of the toolbars, returns EToolBarLocation
+ // Checks if the commandId is being used somewhere in one of the toolbars, returns LLToolBarEnums::EToolBarLocation
S32 hasCommand(const LLCommandId& commandId) const;
- S32 addCommand(const LLCommandId& commandId, EToolBarLocation toolbar, int rank = LLToolBar::RANK_NONE);
+ S32 addCommand(const LLCommandId& commandId, LLToolBarEnums::EToolBarLocation toolbar, int rank = LLToolBar::RANK_NONE);
S32 removeCommand(const LLCommandId& commandId, int& rank); // Sets the rank the removed command was at, RANK_NONE if not found
S32 enableCommand(const LLCommandId& commandId, bool enabled);
S32 stopCommandInProgress(const LLCommandId& commandId);
@@ -109,7 +96,7 @@ public:
static void resetDragTool(LLToolBarButton* toolbarButton);
LLInventoryObject* getDragItem();
LLView* getBottomToolbar() { return mBottomToolbarPanel; }
- LLToolBar* getToolbar(EToolBarLocation toolbar) { return mToolbars[toolbar]; }
+ LLToolBar* getToolbar(LLToolBarEnums::EToolBarLocation toolbar) { return mToolbars[toolbar]; }
bool isModified() const;
protected:
@@ -127,7 +114,7 @@ private:
static void onToolBarButtonRemoved(LLView* button);
// Pointers to the toolbars handled by the toolbar view
- LLToolBar* mToolbars[TOOLBAR_COUNT];
+ LLToolBar* mToolbars[LLToolBarEnums::TOOLBAR_COUNT];
bool mToolbarsLoaded;
bool mDragStarted;
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 5270c3d33f..b75d6b3dcb 100755
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -61,7 +61,7 @@ extern LLControlGroup gSavedSettings;
// we use this in various places instead of NULL
-static LLTool* sNullTool = new LLTool(std::string("null"), NULL);
+static LLPointer<LLTool> sNullTool(new LLTool(std::string("null"), NULL));
//-----------------------------------------------------------------------
// LLToolComposite
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 00b15a5f26..0c34db39b5 100755
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -307,7 +307,7 @@ bool LLURLDispatcher::dispatchRightClick(const std::string& slurl)
}
// static
-bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
+bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl, bool trusted_content)
{
// *NOTE: Text editors are considered sources of trusted URLs
// in order to make avatar profile links in chat history work.
@@ -315,9 +315,9 @@ bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
// receiving resident will see it and must affirmatively
// click on it.
// *TODO: Make this trust model more refined. JC
- const bool trusted_browser = true;
+
LLMediaCtrl* web = NULL;
- return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_browser);
+ return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_content);
}
diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h
index 6309a97af5..9b05260af1 100755
--- a/indra/newview/llurldispatcher.h
+++ b/indra/newview/llurldispatcher.h
@@ -53,7 +53,7 @@ public:
static bool dispatchRightClick(const std::string& slurl);
- static bool dispatchFromTextEditor(const std::string& slurl);
+ static bool dispatchFromTextEditor(const std::string& slurl, bool trusted_content);
};
#endif
diff --git a/indra/newview/llurldispatcherlistener.cpp b/indra/newview/llurldispatcherlistener.cpp
index c7b9afafef..7545f3a9b3 100755
--- a/indra/newview/llurldispatcherlistener.cpp
+++ b/indra/newview/llurldispatcherlistener.cpp
@@ -71,5 +71,5 @@ void LLURLDispatcherListener::dispatchRightClick(const LLSD& params) const
void LLURLDispatcherListener::dispatchFromTextEditor(const LLSD& params) const
{
- LLURLDispatcher::dispatchFromTextEditor(params["url"]);
+ LLURLDispatcher::dispatchFromTextEditor(params["url"], false);
}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index a8eeddb798..632a7d8bc3 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -262,6 +262,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);
LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);
LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
+ LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPermsDefault>);
LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
@@ -270,7 +271,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("prefs_translation", "floater_translation_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTranslationSettings>);
LLFloaterReg::add("prefs_spellchecker", "floater_spellcheck.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSpellCheckerSettings>);
LLFloaterReg::add("prefs_autoreplace", "floater_autoreplace.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAutoReplaceSettings>);
- LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index a179b61cff..991f6b40e6 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -30,6 +30,9 @@
#include "lldictionary.h"
#include "llmemory.h"
#include "llvisualparam.h"
+#include "llcontrol.h"
+
+extern LLControlGroup gSavedSettings;
static const std::string empty_string;
@@ -132,8 +135,9 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
- addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
- addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
+ bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
+ addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
+ addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Merchant Outbox", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index fff9821e86..e8ae621e41 100755
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -65,6 +65,7 @@
#include "llavataractions.h"
#include "lllogininstance.h"
#include "llfavoritesbar.h"
+#include "llfloaterperms.h"
// Two do-nothing ops for use in callbacks.
void no_op_inventory_func(const LLUUID&) {}
@@ -989,24 +990,73 @@ void activate_gesture_cb(const LLUUID& inv_item)
LLGestureMgr::instance().activateGesture(inv_item);
}
-void create_gesture_cb(const LLUUID& inv_item)
+void create_script_cb(const LLUUID& inv_item)
{
- if (inv_item.isNull())
- return;
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts"));
- LLGestureMgr::instance().activateGesture(inv_item);
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
+void create_gesture_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLGestureMgr::instance().activateGesture(inv_item);
- LLViewerInventoryItem* item = gInventory.getItem(inv_item);
- if (!item) return;
- gInventory.updateItem(item);
- gInventory.notifyObservers();
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
- LLPreviewGesture* preview = LLPreviewGesture::show(inv_item, LLUUID::null);
- // Force to be entirely onscreen.
- gFloaterView->adjustToFitScreen(preview, FALSE);
+ LLPreviewGesture* preview = LLPreviewGesture::show(inv_item, LLUUID::null);
+ // Force to be entirely onscreen.
+ gFloaterView->adjustToFitScreen(preview, FALSE);
+ }
+ }
}
+void create_notecard_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ LLPermissions perm = item->getPermissions();
+ perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards"));
+ perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards"));
+
+ item->setPermissions(perm);
+
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
LLInventoryCallbackManager gInventoryCallbacks;
void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
@@ -1260,22 +1310,45 @@ void create_new_item(const std::string& name,
LLViewerAssetType::generateDescriptionFor(asset_type, desc);
next_owner_perm = (next_owner_perm) ? next_owner_perm : PERM_MOVE | PERM_TRANSFER;
-
- if (inv_type == LLInventoryType::IT_GESTURE)
- {
- LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
- NOT_WEARABLE, next_owner_perm, cb);
- }
- else
+ LLPointer<LLInventoryCallback> cb = NULL;
+
+ switch (inv_type)
{
- LLPointer<LLInventoryCallback> cb = NULL;
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
- NOT_WEARABLE, next_owner_perm, cb);
+ case LLInventoryType::IT_LSL:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_script_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Scripts");
+ break;
+ }
+
+ case LLInventoryType::IT_GESTURE:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Gestures");
+ break;
+ }
+
+ case LLInventoryType::IT_NOTECARD:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_notecard_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Notecards");
+ break;
+ }
+ default:
+ break;
}
-
+
+ create_inventory_item(gAgent.getID(),
+ gAgent.getSessionID(),
+ parent_id,
+ LLTransactionID::tnull,
+ name,
+ desc,
+ asset_type,
+ inv_type,
+ NOT_WEARABLE,
+ next_owner_perm,
+ cb);
}
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
@@ -1316,7 +1389,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
parent_id,
LLAssetType::AT_LSL_TEXT,
LLInventoryType::IT_LSL,
- PERM_MOVE | PERM_TRANSFER);
+ PERM_MOVE | PERM_TRANSFER); // overridden in create_new_item
}
else if ("notecard" == type_name)
{
@@ -1325,7 +1398,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
parent_id,
LLAssetType::AT_NOTECARD,
LLInventoryType::IT_NOTECARD,
- PERM_ALL);
+ PERM_ALL); // overridden in create_new_item
}
else if ("gesture" == type_name)
{
@@ -1334,7 +1407,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
parent_id,
LLAssetType::AT_GESTURE,
LLInventoryType::IT_GESTURE,
- PERM_ALL);
+ PERM_ALL); // overridden in create_new_item
}
else
{
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index ab19a12014..dc2fdb8c8d 100755
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -249,7 +249,9 @@ void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachme
void activate_gesture_cb(const LLUUID& inv_item);
+void create_script_cb(const LLUUID& inv_item);
void create_gesture_cb(const LLUUID& inv_item);
+void create_notecard_cb(const LLUUID& inv_item);
class AddFavoriteLandmarkCallback : public LLInventoryCallback
{
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 21fb8d519b..e21752da53 100755
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -191,7 +191,7 @@ public:
// 500 means "Internal Server error" but we decided it's okay to
// accept this and go past it in the MIME type probe
// 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com
- // 499 is a code specifc to join.secondlife.com (????) apparently safe to ignore
+ // 499 is a code specifc to join.secondlife.com (?) apparently safe to ignore
// if( ((status >= 200) && (status < 300)) ||
// ((status >= 400) && (status < 499)) ||
// (status == 500) ||
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index fb07ab8fbe..c7c8da27f3 100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7197,6 +7197,17 @@ class LLAdvancedClickRenderProfile: public view_listener_t
}
};
+void gpu_benchmark();
+
+class LLAdvancedClickRenderBenchmark: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ gpu_benchmark();
+ return true;
+ }
+};
+
void menu_toggle_attached_lights(void* user_data)
{
LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
@@ -7806,6 +7817,22 @@ void handle_show_url(const LLSD& param)
}
+void handle_report_bug(const LLSD& param)
+{
+ LLUIString url(param.asString());
+
+ LLStringUtil::format_map_t replace;
+ replace["[ENVIRONMENT]"] = LLURI::escape(LLAppViewer::instance()->getViewerInfoString());
+ LLSLURL location_url;
+ LLAgentUI::buildSLURL(location_url);
+ replace["[LOCATION]"] = location_url.getSLURLString();
+
+ LLUIString file_bug_url = gSavedSettings.getString("ReportBugURL");
+ file_bug_url.setArgs(replace);
+
+ LLWeb::loadURLExternal(file_bug_url.getString());
+}
+
void handle_buy_currency_test(void*)
{
std::string url =
@@ -8637,6 +8664,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
+ view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
@@ -8652,6 +8680,7 @@ void initialize_menus()
commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser
commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater
commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
+ commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2));
view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index be78603e2d..16e75a4ad7 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -442,9 +442,9 @@ class LLFileUploadBulk : public view_listener_t
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms(),
- LLFloaterPerms::getGroupPerms(),
- LLFloaterPerms::getEveryonePerms(),
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
display_name,
callback,
expected_upload_cost,
@@ -1004,9 +1004,9 @@ void upload_done_callback(
0,
LLFolderType::FT_NONE,
LLInventoryType::IT_NONE,
- PERM_NONE,
- PERM_NONE,
- PERM_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
display_name,
callback,
expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 267aa9532c..db3e7049d9 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -644,25 +644,57 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
gAgent.sendMessage();
}
+static LLSD sSavedGroupInvite;
+static LLSD sSavedResponse;
+
bool join_group_response(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+// A bit of variable saving and restoring is used to deal with the case where your group list is full and you
+// receive an invitation to another group. The data from that invitation is stored in the sSaved
+// variables. If you then drop a group and click on the Join button the stored data is restored and used
+// to join the group.
+ LLSD notification_adjusted = notification;
+ LLSD response_adjusted = response;
+
+ std::string action = notification["name"];
+
+// Storing all the information by group id allows for the rare case of being at your maximum
+// group count and receiving more than one invitation.
+ std::string id = notification_adjusted["payload"]["group_id"].asString();
+
+ if ("JoinGroup" == action || "JoinGroupCanAfford" == action)
+ {
+ sSavedGroupInvite[id] = notification;
+ sSavedResponse[id] = response;
+ }
+ else if ("JoinedTooManyGroupsMember" == action)
+ {
+ S32 opt = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == opt) // Join button pressed
+ {
+ notification_adjusted = sSavedGroupInvite[id];
+ response_adjusted = sSavedResponse[id];
+ }
+ }
+
+ S32 option = LLNotificationsUtil::getSelectedOption(notification_adjusted, response_adjusted);
bool accept_invite = false;
- LLUUID group_id = notification["payload"]["group_id"].asUUID();
- LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
- std::string name = notification["payload"]["name"].asString();
- std::string message = notification["payload"]["message"].asString();
- S32 fee = notification["payload"]["fee"].asInteger();
+ LLUUID group_id = notification_adjusted["payload"]["group_id"].asUUID();
+ LLUUID transaction_id = notification_adjusted["payload"]["transaction_id"].asUUID();
+ std::string name = notification_adjusted["payload"]["name"].asString();
+ std::string message = notification_adjusted["payload"]["message"].asString();
+ S32 fee = notification_adjusted["payload"]["fee"].asInteger();
if (option == 2 && !group_id.isNull())
{
LLGroupActions::show(group_id);
LLSD args;
args["MESSAGE"] = message;
- LLNotificationsUtil::add("JoinGroup", args, notification["payload"]);
+ LLNotificationsUtil::add("JoinGroup", args, notification_adjusted["payload"]);
return false;
}
+
if(option == 0 && !group_id.isNull())
{
// check for promotion or demotion.
@@ -677,7 +709,8 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
{
LLSD args;
args["NAME"] = name;
- LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
+ LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification_adjusted["payload"]);
+ return false;
}
}
@@ -691,7 +724,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
args["COST"] = llformat("%d", fee);
// Set the fee for next time to 0, so that we don't keep
// asking about a fee.
- LLSD next_payload = notification["payload"];
+ LLSD next_payload = notification_adjusted["payload"];
next_payload["fee"] = 0;
LLNotificationsUtil::add("JoinGroupCanAfford",
args,
@@ -717,6 +750,9 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
transaction_id);
}
+ sSavedGroupInvite[id] = LLSD::emptyMap();
+ sSavedResponse[id] = LLSD::emptyMap();
+
return false;
}
@@ -1876,6 +1912,7 @@ void inventory_offer_handler(LLOfferInfo* info)
return;
}
+ bool bAutoAccept(false);
// Avoid the Accept/Discard dialog if the user so desires. JC
if (gSavedSettings.getBOOL("AutoAcceptNewInventory")
&& (info->mType == LLAssetType::AT_NOTECARD
@@ -1884,8 +1921,7 @@ void inventory_offer_handler(LLOfferInfo* info)
{
// For certain types, just accept the items into the inventory,
// and possibly open them on receipt depending upon "ShowNewInventory".
- info->forceResponse(IOR_ACCEPT);
- return;
+ bAutoAccept = true;
}
// Strip any SLURL from the message display. (DEV-2754)
@@ -1953,7 +1989,7 @@ void inventory_offer_handler(LLOfferInfo* info)
LLNotification::Params p;
// Object -> Agent Inventory Offer
- if (info->mFromObject)
+ if (info->mFromObject && !bAutoAccept)
{
// Inventory Slurls don't currently work for non agent transfers, so only display the object name.
args["ITEM_SLURL"] = msg;
@@ -1999,11 +2035,12 @@ void inventory_offer_handler(LLOfferInfo* info)
send_do_not_disturb_message(gMessageSystem, info->mFromID);
}
- // Inform user that there is a script floater via toast system
+ if( !bAutoAccept ) // if we auto accept, do not pester the user
{
+ // Inform user that there is a script floater via toast system
payload["give_inventory_notification"] = TRUE;
- p.payload = payload;
- LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
+ p.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
}
}
@@ -2409,14 +2446,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
&& from_id.notNull() //not a system message
&& to_id.notNull()) //not global message
{
- // return a standard "do not disturb" message, but only do it to online IM
+ // return a standard "do not disturb" message, but only do it to online IM
// (i.e. not other auto responses and not store-and-forward IM)
- if (!gIMMgr->hasSession(session_id))
- {
- // if there is not a panel for this conversation (i.e. it is a new IM conversation
- // initiated by the other party) then...
- send_do_not_disturb_message(msg, from_id, session_id);
- }
+
+ send_do_not_disturb_message(msg, from_id, session_id);
// now store incoming IM in chat history
@@ -5985,7 +6018,7 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
}
}
- send_sound_trigger(LLUUID(gSavedSettings.getString("UISndRestart")), 1.0f);
+ make_ui_sound("UISndRestart");
}
LLNotificationsUtil::add(notificationID, llsdBlock);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1544e66431..21ab1bdca5 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -100,6 +100,7 @@
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
+#include "llfloaterperms.h"
//#define DEBUG_UPDATE_TYPE
@@ -236,7 +237,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mOnMap(FALSE),
mStatic(FALSE),
mNumFaces(0),
- mTimeDilation(1.f),
mRotTime(0.f),
mAngularVelocityRot(),
mPreviousRotation(),
@@ -943,7 +943,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U16 time_dilation16;
mesgsys->getU16Fast(_PREHASH_RegionData, _PREHASH_TimeDilation, time_dilation16);
F32 time_dilation = ((F32) time_dilation16) / 65535.f;
- mTimeDilation = time_dilation;
mRegionp->setTimeDilation(time_dilation);
// this will be used to determine if we've really changed position
@@ -1986,7 +1985,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
if (cdp)
{
- F32 ping_delay = 0.5f * mTimeDilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
+ F32 ping_delay = 0.5f * time_dilation * ( ((F32)cdp->getPingDelay()) * 0.001f + gFrameDTClamped);
LLVector3 diff = getVelocity() * ping_delay;
new_pos_parent += diff;
}
@@ -2185,35 +2184,33 @@ BOOL LLViewerObject::isActive() const
-void LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
{
//static LLFastTimer::DeclareTimer ftm("Viewer Object");
//LLFastTimer t(ftm);
if (!mDead)
{
- // CRO - don't velocity interp linked objects!
- // Leviathan - but DO velocity interp joints
- if (!mStatic && sVelocityInterpolate && !isSelected())
- {
- // calculate dt from last update
- F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
- F32 dt = mTimeDilation * dt_raw;
+ if (!mStatic && sVelocityInterpolate && !isSelected())
+ {
+ // calculate dt from last update
+ F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f;
+ F32 dt = time_dilation * (F32)(time - mLastInterpUpdateSecs);
applyAngularVelocity(dt);
if (isAttachment())
- {
- mLastInterpUpdateSecs = time;
+ {
+ mLastInterpUpdateSecs = time;
return;
+ }
+ else
+ { // Move object based on it's velocity and rotation
+ interpolateLinearMotion(time, dt);
+ }
}
- else
- { // Move object based on it's velocity and rotation
- interpolateLinearMotion(time, dt);
- }
- }
- updateDrawable(FALSE);
+ updateDrawable(FALSE);
}
}
@@ -2503,6 +2500,7 @@ void LLViewerObject::saveScript(
* interaction with doUpdateInventory() called below.
*/
lldebugs << "LLViewerObject::saveScript() " << item->getUUID() << " " << item->getAssetUUID() << llendl;
+
LLPointer<LLViewerInventoryItem> task_item =
new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
item->getAssetUUID(), item->getType(),
@@ -4063,7 +4061,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
{
LLPrimitive::setTE(te, texture_entry);
- const LLUUID& image_id = getTE(te)->getID();
+ const LLUUID& image_id = getTE(te)->getID();
mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
if (getTE(te)->getMaterialParams().notNull())
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 80bdd628a1..c34d4493d5 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -143,7 +143,7 @@ public:
LLNameValue* getNVPair(const std::string& name) const; // null if no name value pair by that name
// Object create and update functions
- virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ virtual void idleUpdate(LLAgent &agent, const F64 &time);
// Types of media we can associate
enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
@@ -305,7 +305,7 @@ public:
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
- S32 setTETextureCore(const U8 te, LLViewerTexture *image);
+ S32 setTETextureCore(const U8 te, LLViewerTexture *image);
S32 setTENormalMapCore(const U8 te, LLViewerTexture *image);
S32 setTESpecularMapCore(const U8 te, LLViewerTexture *image);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
@@ -743,7 +743,6 @@ protected:
BOOL mStatic; // Object doesn't move.
S32 mNumFaces;
- F32 mTimeDilation; // Time dilation sent with the object.
F32 mRotTime; // Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
LLQuaternion mAngularVelocityRot; // accumulated rotation from the angular velocity computations
LLQuaternion mPreviousRotation;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index b4e287c446..63c69b4481 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -76,6 +76,7 @@
#include "object_flags.h"
#include "llappviewer.h"
+#include "llfloaterperms.h"
extern F32 gMinObjectDistance;
extern BOOL gAnimateTextures;
@@ -399,10 +400,10 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only?
{
- compressed_dp.unpackUUID(fullid, "ID");
- compressed_dp.unpackU32(local_id, "LocalID");
- compressed_dp.unpackU8(pcode, "PCode");
- }
+ compressed_dp.unpackUUID(fullid, "ID");
+ compressed_dp.unpackU32(local_id, "LocalID");
+ compressed_dp.unpackU8(pcode, "PCode");
+ }
else
{
compressed_dp.unpackU32(local_id, "LocalID");
@@ -561,7 +562,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
}
recorder.objectUpdateEvent(local_id, update_type, objectp, msg_size);
- objectp->setLastUpdateType(update_type);
+ objectp->setLastUpdateType(update_type);
objectp->setLastUpdateCached(bCached);
}
@@ -852,7 +853,7 @@ private:
LLSD mObjectIDs;
};
-void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
+void LLViewerObjectList::update(LLAgent &agent)
{
// Update globals
LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") );
@@ -942,7 +943,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
objectp = *iter;
if (objectp->isAvatar())
{
- objectp->idleUpdate(agent, world, frame_time);
+ objectp->idleUpdate(agent, frame_time);
}
}
}
@@ -953,7 +954,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
{
objectp = *idle_iter;
llassert(objectp->isActive());
- objectp->idleUpdate(agent, world, frame_time);
+ objectp->idleUpdate(agent, frame_time);
}
//update flexible objects
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 6518c25d09..98b50fa789 100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -83,7 +83,7 @@ public:
void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
void updateApparentAngles(LLAgent &agent);
- void update(LLAgent &agent, LLWorld &world);
+ void update(LLAgent &agent);
void fetchObjectCosts();
void fetchPhysicsFlags();
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index c6ae7d7fa0..5440d515be 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -71,6 +71,7 @@
#include "stringize.h"
#include "llviewercontrol.h"
#include "llsdserialize.h"
+#include "llfloaterperms.h"
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
@@ -302,9 +303,14 @@ public:
if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
{
- llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;
+ llinfos << "BaseCapabilitiesCompleteTracker " << "sim " << regionp->getName()
+ << " sent duplicate seed caps that differs in size - most likely content. "
+ << (S32) regionp->getRegionImpl()->mCapabilities.size() << " vs " << regionp->getRegionImpl()->mSecondCapabilitiesTracker.size()
+ << llendl;
+
//todo#add cap debug versus original check?
- /*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
+ /*
+ CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
while (iter!=regionp->getRegionImpl()->mCapabilities.end() )
{
llinfos << "BaseCapabilitiesCompleteTracker Original " << iter->first << " " << iter->second<<llendl;
@@ -395,6 +401,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE
mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE
mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE
+
+ mRenderInfoRequestTimer.resetWithExpiry(0.f); // Set timer to be expired
+ setCapabilitiesReceivedCallback(boost::bind(&LLAvatarRenderInfoAccountant::expireRenderInfoReportTimer, _1));
}
@@ -1576,9 +1585,11 @@ void LLViewerRegion::unpackRegionHandshake()
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
{
+ capabilityNames.append("AgentPreferences");
capabilityNames.append("AgentState");
capabilityNames.append("AttachmentResources");
capabilityNames.append("AvatarPickerSearch");
+ capabilityNames.append("AvatarRenderInfo");
capabilityNames.append("CharacterProperties");
capabilityNames.append("ChatSessionRequest");
capabilityNames.append("CopyInventoryFromNotecard");
@@ -1844,6 +1855,8 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
{
mCapabilitiesReceivedSignal(getRegionID());
+ LLFloaterPermsDefault::sendInitialPerms();
+
// This is a single-shot signal. Forget callbacks to save resources.
mCapabilitiesReceivedSignal.disconnect_all_slots();
}
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 553f6a2d59..e88b22b461 100755
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -87,6 +87,8 @@ LLGLSLShader gClipProgram;
LLGLSLShader gDownsampleDepthProgram;
LLGLSLShader gDownsampleDepthRectProgram;
LLGLSLShader gAlphaMaskProgram;
+LLGLSLShader gBenchmarkProgram;
+
//object shaders
LLGLSLShader gObjectSimpleProgram;
@@ -681,6 +683,7 @@ void LLViewerShaderMgr::unloadShaders()
gClipProgram.unload();
gDownsampleDepthProgram.unload();
gDownsampleDepthRectProgram.unload();
+ gBenchmarkProgram.unload();
gAlphaMaskProgram.unload();
gUIProgram.unload();
gPathfindingProgram.unload();
@@ -3190,6 +3193,26 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gBenchmarkProgram.mName = "Benchmark Shader";
+ gBenchmarkProgram.mShaderFiles.clear();
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gBenchmarkProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
+ gDownsampleDepthRectProgram.mShaderFiles.clear();
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
+ gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDownsampleDepthRectProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
gDownsampleDepthRectProgram.mShaderFiles.clear();
gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 3d89f8d20a..53569ca7ab 100755
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -183,6 +183,7 @@ extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;
extern LLGLSLShader gDownsampleDepthProgram;
extern LLGLSLShader gDownsampleDepthRectProgram;
+extern LLGLSLShader gBenchmarkProgram;
//output tex0[tc0] + tex1[tc1]
extern LLGLSLShader gTwoTextureAddProgram;
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 8036a4e258..e51f7b2c71 100755
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -689,6 +689,11 @@ void LLViewerTextEditor::makePristine()
LLTextEditor::makePristine();
}
+void LLViewerTextEditor::handleVisibilityChange( BOOL new_visibility )
+{
+ LLUICtrl::handleVisibilityChange(new_visibility);
+}
+
BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index fb428d0dc1..33b78a5964 100755
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -46,6 +46,8 @@ public:
virtual ~LLViewerTextEditor();
virtual void makePristine();
+
+ /*virtual*/ void handleVisibilityChange( BOOL new_visibility );
// mousehandler overrides
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 693eca8a06..3da6d33d72 100755
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -422,7 +422,9 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sDefaultImagep = NULL;
LLViewerFetchedTexture::sSmokeImagep = NULL;
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
+ LLTexUnit::sWhiteTexture = 0;
LLViewerFetchedTexture::sWhiteImagep = NULL;
+
LLViewerFetchedTexture::sFlatNormalImagep = NULL;
LLViewerMediaTexture::cleanUpClass() ;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index cb7536edce..3193a2955b 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1860,6 +1860,14 @@ void LLViewerWindow::initBase()
// Constrain floaters to inside the menu and status bar regions.
gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
+ for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; ++i)
+ {
+ LLToolBar * toolbarp = gToolBarView->getToolbar((LLToolBarEnums::EToolBarLocation)i);
+ if (toolbarp)
+ {
+ toolbarp->getCenterLayoutPanel()->setReshapeCallback(boost::bind(&LLFloaterView::setToolbarRect, gFloaterView, _1, _2));
+ }
+ }
gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
@@ -3236,8 +3244,6 @@ void LLViewerWindow::updateUI()
updateLayout();
- mLastMousePoint = mCurrentMousePoint;
-
// cleanup unused selections when no modal dialogs are open
if (LLModalDialog::activeCount() == 0)
{
@@ -3475,6 +3481,9 @@ void LLViewerWindow::saveLastMouse(const LLCoordGL &point)
{
// Store last mouse location.
// If mouse leaves window, pretend last point was on edge of window
+
+ mLastMousePoint = mCurrentMousePoint;
+
if (point.mX < 0)
{
mCurrentMousePoint.mX = 0;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 1e7d1644b2..c47b6d2335 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -116,16 +116,16 @@ using namespace LLAvatarAppearanceDefines;
//-----------------------------------------------------------------------------
// Global constants
//-----------------------------------------------------------------------------
-const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise"
-const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot"
-const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing"
-const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye"
-const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust"
-const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion"
-const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot"
-const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix"
-const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target"
-const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust"
+const LLUUID ANIM_AGENT_BODY_NOISE = LLUUID("9aa8b0a6-0c6f-9518-c7c3-4f41f2c001ad"); //"body_noise"
+const LLUUID ANIM_AGENT_BREATHE_ROT = LLUUID("4c5a103e-b830-2f1c-16bc-224aa0ad5bc8"); //"breathe_rot"
+const LLUUID ANIM_AGENT_EDITING = LLUUID("2a8eba1d-a7f8-5596-d44a-b4977bf8c8bb"); //"editing"
+const LLUUID ANIM_AGENT_EYE = LLUUID("5c780ea8-1cd1-c463-a128-48c023f6fbea"); //"eye"
+const LLUUID ANIM_AGENT_FLY_ADJUST = LLUUID("db95561f-f1b0-9f9a-7224-b12f71af126e"); //"fly_adjust"
+const LLUUID ANIM_AGENT_HAND_MOTION = LLUUID("ce986325-0ba7-6e6e-cc24-b17c4b795578"); //"hand_motion"
+const LLUUID ANIM_AGENT_HEAD_ROT = LLUUID("e6e8d1dd-e643-fff7-b238-c6b4b056a68d"); //"head_rot"
+const LLUUID ANIM_AGENT_PELVIS_FIX = LLUUID("0c5dd2a2-514d-8893-d44d-05beffad208b"); //"pelvis_fix"
+const LLUUID ANIM_AGENT_TARGET = LLUUID("0e4896cb-fba4-926c-f355-8720189d5b55"); //"target"
+const LLUUID ANIM_AGENT_WALK_ADJUST = LLUUID("829bc85b-02fc-ec41-be2e-74cc6dd7215d"); //"walk_adjust"
const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df440d987"); //"physics_motion"
@@ -253,7 +253,7 @@ struct LLAppearanceMessageContents
};
struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
- {
+{
Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone;
Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume;
@@ -813,17 +813,17 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
//------------------------------------------------------------------------
LLVOAvatar::~LLVOAvatar()
{
- if (!mFullyLoaded)
- {
+ if (!mFullyLoaded)
+ {
debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
- }
- else
- {
+ }
+ else
+ {
debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
- }
+ }
logPendingPhases();
-
+
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
@@ -1207,7 +1207,7 @@ void LLVOAvatar::initInstance(void)
registerMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create );
registerMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create );
}
-
+
LLAvatarAppearance::initInstance();
// preload specific motions here
@@ -1646,7 +1646,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
return hit;
}
-
+
LLVOAvatar* LLVOAvatar::asAvatar()
{
return this;
@@ -1981,22 +1981,22 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU
}
if (!result)
-{
+ {
const std::string url = getImageURL(te,uuid);
if (!url.empty())
- {
+ {
LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl;
result = LLViewerTextureManager::getFetchedTextureFromUrl(
url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
- }
- else
- {
+ }
+ else
+ {
LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl;
LLHost host = getObjectHost();
result = LLViewerTextureManager::getFetchedTexture(
uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+ }
}
-}
return result;
}
@@ -2047,7 +2047,7 @@ void LLVOAvatar::dumpAnimationState()
//------------------------------------------------------------------------
// idleUpdate()
//------------------------------------------------------------------------
-void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
{
LLFastTimer t(FTM_AVATAR_UPDATE);
@@ -2102,7 +2102,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
if (isSelf())
{
- LLViewerObject::idleUpdate(agent, world, time);
+ LLViewerObject::idleUpdate(agent, time);
// trigger fidget anims
if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS))
@@ -2114,7 +2114,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
// Should override the idleUpdate stuff and leave out the angular update part.
LLQuaternion rotation = getRotation();
- LLViewerObject::idleUpdate(agent, world, time);
+ LLViewerObject::idleUpdate(agent, time);
setRotation(rotation);
}
@@ -4162,7 +4162,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
{
LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
if (hair_mesh)
- {
+ {
num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
}
first_pass = FALSE;
@@ -4172,7 +4172,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
}
}
-
+
return num_indices;
}
@@ -5237,7 +5237,7 @@ void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_age
//-----------------------------------------------------------------------------
F32 LLVOAvatar::getTimeDilation()
{
- return mTimeDilation;
+ return mRegionp ? mRegionp->getTimeDilation() : 1.f;
}
@@ -5289,9 +5289,9 @@ BOOL LLVOAvatar::loadSkeletonNode ()
{
if (!LLAvatarAppearance::loadSkeletonNode())
{
- return FALSE;
- }
-
+ return FALSE;
+ }
+
// ATTACHMENTS
{
LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
@@ -5834,7 +5834,8 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
}
}
}
- }
+}
+
//-----------------------------------------------------------------------------
// detachObject()
//-----------------------------------------------------------------------------
@@ -6047,18 +6048,18 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
if (texture_dict->mWearableType == type)
- {
+ {
// Thus, you must check to see if the corresponding baked texture is defined.
// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
// gets baked into a texture that always exists (upper or lower).
if (texture_dict->mIsUsedByBakedTexture)
- {
+ {
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
- }
+ }
return FALSE;
- }
+ }
}
return FALSE;
}
@@ -6123,7 +6124,7 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL
{
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setColor( color );
}
}
@@ -6191,9 +6192,9 @@ void LLVOAvatar::updateRezzedStatusTimers()
{
// load level has decreased. start phase timers for higher load levels.
for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
- {
+ {
startPhase("load_" + LLVOAvatar::rezStatusToString(i));
- }
+ }
}
else if (rez_status > mLastRezzedStatus)
{
@@ -6202,16 +6203,16 @@ void LLVOAvatar::updateRezzedStatusTimers()
{
stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
- }
+ }
if (rez_status == 3)
- {
+ {
// "fully loaded", mark any pending appearance change complete.
selfStopPhase("update_appearance_from_cof");
selfStopPhase("wear_inventory_category", false);
selfStopPhase("process_initial_wearables_update", false);
}
}
-
+
mLastRezzedStatus = rez_status;
}
}
@@ -6238,7 +6239,7 @@ void LLVOAvatar::startPhase(const std::string& phase_name)
}
void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
- {
+{
F32 elapsed;
bool completed;
if (getPhases().getPhaseValues(phase_name, elapsed, completed))
@@ -6270,7 +6271,7 @@ void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
void LLVOAvatar::logPendingPhases()
{
if (!isAgentAvatarValid())
- {
+ {
return;
}
@@ -6286,14 +6287,14 @@ void LLVOAvatar::logPendingPhases()
if (!completed)
{
logMetricsTimerRecord(phase_name, elapsed, completed);
- }
+ }
}
}
- }
+}
//static
void LLVOAvatar::logPendingPhasesAllAvatars()
- {
+{
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)
{
@@ -6304,14 +6305,14 @@ void LLVOAvatar::logPendingPhasesAllAvatars()
}
inst->logPendingPhases();
}
- }
+}
void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
- {
+{
if (!isAgentAvatarValid())
- {
+ {
return;
- }
+ }
LLSD record;
record["timer_name"] = phase_name;
@@ -6320,15 +6321,15 @@ void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapse
record["completed"] = completed;
U32 grid_x(0), grid_y(0);
if (getRegion())
- {
+ {
record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
- }
+ }
record["grid_x"] = LLSD::Integer(grid_x);
record["grid_y"] = LLSD::Integer(grid_y);
record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
record["is_self"] = isSelf();
-
+
if (isAgentAvatarValid())
{
gAgentAvatarp->addMetricsTimerRecord(record);
@@ -6536,28 +6537,28 @@ void LLVOAvatar::updateMeshTextures()
use_lkg_baked_layer[i],
last_id_string.c_str());
}
-
+
for (U32 i=0; i < mBakedTextureDatas.size(); i++)
{
debugColorizeSubMeshes(i, LLColor4::white);
LLViewerTexLayerSet* layerset = getTexLayerSet(i);
if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
- {
+ {
LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
mBakedTextureDatas[i].mIsUsed = TRUE;
debugColorizeSubMeshes(i,LLColor4::red);
-
+
avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
for (; iter != end; ++iter)
- {
+ {
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setTexture( baked_img );
- }
+ }
}
}
else if (!isUsingLocalAppearance() && is_layer_baked[i])
@@ -6601,7 +6602,7 @@ void LLVOAvatar::updateMeshTextures()
if (mesh)
{
mesh->setLayerSet( layerset );
- }
+ }
}
}
else
@@ -6623,7 +6624,7 @@ void LLVOAvatar::updateMeshTextures()
{
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setColor( color );
mesh->setTexture( hair_img );
}
@@ -6651,7 +6652,15 @@ void LLVOAvatar::updateMeshTextures()
}
}
}
- removeMissingBakedTextures();
+
+ // removeMissingBakedTextures() will call back into this rountine if something is removed, and can blow up the stack
+ static bool call_remove_missing = true;
+ if (call_remove_missing)
+ {
+ call_remove_missing = false;
+ removeMissingBakedTextures(); // May call back into this function if anything is removed
+ call_remove_missing = true;
+ }
}
// virtual
@@ -6711,13 +6720,13 @@ void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_com
for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
-{
+ {
const LLMaskedMorph* maskedMorph = (*iter);
LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
if (morph_target)
- {
+ {
morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
-}
+ }
}
}
@@ -7000,8 +7009,8 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()
// param_location_name(vparam->getParamLocation()).c_str()
);
- }
-
+}
+
void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
const LLAppearanceMessageContents& contents)
@@ -7015,9 +7024,9 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
outfile.open(fullpath, LL_APR_WB );
apr_file_t* file = outfile.getFileHandle();
if (!file)
- {
- return;
- }
+ {
+ return;
+ }
else
{
LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl;
@@ -7051,7 +7060,7 @@ void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
}
apr_file_printf(file, "</textures>\n");
- }
+}
void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)
{
@@ -7068,7 +7077,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
// For future use:
//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
}
-
+
// Parse visual params, if any.
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
@@ -7296,19 +7305,19 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
LLVisualParam* param = contents.mParams[i];
F32 newWeight = contents.mParamWeights[i];
- if (is_first_appearance_message || (param->getWeight() != newWeight))
+ if (is_first_appearance_message || (param->getWeight() != newWeight))
+ {
+ params_changed = TRUE;
+ if(is_first_appearance_message)
{
- params_changed = TRUE;
- if(is_first_appearance_message)
- {
- param->setWeight(newWeight, FALSE);
- }
- else
- {
- interp_params = TRUE;
- param->setAnimationTarget(newWeight, FALSE);
- }
+ param->setWeight(newWeight, FALSE);
}
+ else
+ {
+ interp_params = TRUE;
+ param->setAnimationTarget(newWeight, FALSE);
+ }
+ }
}
const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
if (num_params != expected_tweakable_count)
@@ -7564,12 +7573,12 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
avatar_joint_mesh_list_t::iterator end = mBakedTextureDatas[i].mJointMeshes.end();
for (; iter != end; ++iter)
- {
+ {
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setTexture( image_baked );
- }
+ }
}
}
@@ -7593,7 +7602,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
{
LLAvatarJointMesh* mesh = (*iter);
if (mesh)
- {
+ {
mesh->setColor( LLColor4::white );
}
}
@@ -7612,7 +7621,7 @@ std::string get_sequential_numbered_file_name(const std::string& prefix,
file_num_type::iterator it = file_nums.find(prefix);
S32 num = 0;
if (it != file_nums.end())
-{
+ {
num = it->second;
}
file_nums[prefix] = num+1;
@@ -7629,7 +7638,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
outprefix = getFullname() + (isSelf()?"_s":"_o");
}
if (outprefix.empty())
-{
+ {
outprefix = getFullname() + (isSelf()?"_s":"_o");
}
if (outprefix.empty())
@@ -7658,36 +7667,36 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
if (group_by_wearables)
{
for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
- {
- const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
- apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
+ {
+ const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+ apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
- {
- LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
- if( (viewer_param->getWearableType() == type) &&
- (viewer_param->isTweakable() ) )
{
+ LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+ if( (viewer_param->getWearableType() == type) &&
+ (viewer_param->isTweakable() ) )
+ {
dump_visual_param(file, viewer_param, viewer_param->getWeight());
+ }
}
- }
- for (U8 te = 0; te < TEX_NUM_INDICES; te++)
- {
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
+ for (U8 te = 0; te < TEX_NUM_INDICES; te++)
{
- // MULTIPLE_WEARABLES: extend to multiple wearables?
- LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
- if( te_image )
+ if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
{
- std::string uuid_str;
- te_image->getID().toString( uuid_str );
- apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ // MULTIPLE_WEARABLES: extend to multiple wearables?
+ LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+ if( te_image )
+ {
+ std::string uuid_str;
+ te_image->getID().toString( uuid_str );
+ apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+ }
}
}
}
}
- }
else
{
// Just dump all params sequentially.
@@ -7833,12 +7842,12 @@ void LLVOAvatar::startAppearanceAnimation()
// virtual
void LLVOAvatar::bodySizeChanged()
-{
+{
if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
{ // notify simulator of change in size
// but not if we are in the middle of updating appearance
gAgent.sendAgentSetAppearance();
-}
+ }
}
BOOL LLVOAvatar::isUsingServerBakes() const
@@ -7850,25 +7859,25 @@ BOOL LLVOAvatar::isUsingServerBakes() const
F32 wt = appearance_version_param->getWeight();
F32 expect_wt = mUseServerBakes ? 1.0 : 0.0;
if (!is_approx_equal(wt,expect_wt))
-{
+ {
llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;
}
#endif
return mUseServerBakes;
- }
-
+}
+
void LLVOAvatar::setIsUsingServerBakes(BOOL newval)
- {
+{
mUseServerBakes = newval;
LLVisualParam* appearance_version_param = getVisualParam(11000);
llassert(appearance_version_param);
appearance_version_param->setWeight(newval ? 1.0 : 0.0, false);
- }
+}
// virtual
void LLVOAvatar::removeMissingBakedTextures()
- {
+{
}
//virtual
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 0e4121f1c4..cd8a5ecdf2 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -129,28 +129,28 @@ public:
/*virtual*/ void updateGL();
/*virtual*/ LLVOAvatar* asAvatar();
virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
- void **user_data,
- U32 block_num,
- const EObjectUpdateType update_type,
- LLDataPacker *dp);
- virtual void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ void **user_data,
+ U32 block_num,
+ const EObjectUpdateType update_type,
+ LLDataPacker *dp);
+ virtual void idleUpdate(LLAgent &agent, const F64 &time);
/*virtual*/ BOOL updateLOD();
BOOL updateJointLODs();
void updateLODRiggedAttachments( void );
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
S32 totalTextureMemForUUIDS(std::set<LLUUID>& ids);
- bool allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
- bool allLocalTexturesCompletelyDownloaded() const;
- bool allBakedTexturesCompletelyDownloaded() const;
- void bakedTextureOriginCounts(S32 &sb_count, S32 &host_count,
- S32 &both_count, S32 &neither_count);
- std::string bakedTextureOriginInfo();
- void collectLocalTextureUUIDs(std::set<LLUUID>& ids) const;
- void collectBakedTextureUUIDs(std::set<LLUUID>& ids) const;
- void collectTextureUUIDs(std::set<LLUUID>& ids);
- void releaseOldTextures();
+ bool allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
+ bool allLocalTexturesCompletelyDownloaded() const;
+ bool allBakedTexturesCompletelyDownloaded() const;
+ void bakedTextureOriginCounts(S32 &sb_count, S32 &host_count,
+ S32 &both_count, S32 &neither_count);
+ std::string bakedTextureOriginInfo();
+ void collectLocalTextureUUIDs(std::set<LLUUID>& ids) const;
+ void collectBakedTextureUUIDs(std::set<LLUUID>& ids) const;
+ void collectTextureUUIDs(std::set<LLUUID>& ids);
+ void releaseOldTextures();
/*virtual*/ void updateTextures();
- LLViewerFetchedTexture* getBakedTextureImage(const U8 te, const LLUUID& uuid);
+ LLViewerFetchedTexture* getBakedTextureImage(const U8 te, const LLUUID& uuid);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
/*virtual*/ void onShift(const LLVector4a& shift_vector);
/*virtual*/ U32 getPartitionType() const;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 9ce99444d9..082a85e217 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -625,11 +625,11 @@ BOOL LLVOAvatarSelf::isValid() const
}
// virtual
-void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time)
{
if (isValid())
{
- LLVOAvatar::idleUpdate(agent, world, time);
+ LLVOAvatar::idleUpdate(agent, time);
idleUpdateTractorBeam();
}
}
@@ -847,7 +847,7 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
if (!tex || tex->isMissingAsset())
{
LLViewerTexture *imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
- if (imagep)
+ if (imagep && imagep != tex)
{
setTEImage(te, imagep);
removed = TRUE;
@@ -863,13 +863,13 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
layerset->setUpdatesEnabled(TRUE);
invalidateComposite(layerset, FALSE);
}
- updateMeshTextures();
+ updateMeshTextures(); // may call back into this function
if (getRegion() && !getRegion()->getCentralBakeVersion())
{
- requestLayerSetUploads();
+ requestLayerSetUploads();
+ }
}
}
-}
//virtual
void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
@@ -1310,7 +1310,7 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
discard_level < local_tex_obj->getDiscard())
{
local_tex_obj->setDiscard(discard_level);
- requestLayerSetUpdate(index);
+ requestLayerSetUpdate(index);
if (isEditingAppearance())
{
LLVisualParamHint::requestHintUpdates();
@@ -1799,11 +1799,11 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
{
requestLayerSetUpdate(type);
if (isEditingAppearance())
- {
- LLVisualParamHint::requestHintUpdates();
+ {
+ LLVisualParamHint::requestHintUpdates();
+ }
}
}
- }
else
{
tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
@@ -2580,25 +2580,25 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
//if (!covered_by_baked)
{
if (imagep->getID() != IMG_DEFAULT_AVATAR)
- {
+ {
imagep->setNoDelete();
if (imagep->getDiscardLevel() != 0)
- {
- F32 desired_pixels;
- desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
-
- imagep->setBoostLevel(getAvatarBoostLevel());
- imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
- imagep->resetTextureStats();
- imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
- imagep->addTextureStats( desired_pixels / texel_area_ratio );
- imagep->forceUpdateBindStats() ;
- if (imagep->getDiscardLevel() < 0)
{
- mHasGrey = TRUE; // for statistics gathering
+ F32 desired_pixels;
+ desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
+
+ imagep->setBoostLevel(getAvatarBoostLevel());
+ imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
+ imagep->resetTextureStats();
+ imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
+ imagep->addTextureStats( desired_pixels / texel_area_ratio );
+ imagep->forceUpdateBindStats() ;
+ if (imagep->getDiscardLevel() < 0)
+ {
+ mHasGrey = TRUE; // for statistics gathering
+ }
}
}
- }
else
{
// texture asset is missing
@@ -2921,17 +2921,17 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
{
- /* switch(index)
- case TEX_HEAD_BAKED:
- case TEX_HEAD_BODYPAINT:
- return mHeadLayerSet; */
+ /* switch(index)
+ case TEX_HEAD_BAKED:
+ case TEX_HEAD_BODYPAINT:
+ return mHeadLayerSet; */
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
- if (texture_dict->mIsUsedByBakedTexture)
- {
- const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+ if (texture_dict->mIsUsedByBakedTexture)
+ {
+ const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
return getLayerSet(baked_index);
- }
- return NULL;
+ }
+ return NULL;
}
LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
@@ -2959,7 +2959,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
gAgentAvatarp->mUseLocalAppearance = true;
if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
-{
+ {
gAgentCamera.changeCameraToCustomizeAvatar();
}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 3b7b6bac64..521c86e1c3 100755
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -84,7 +84,7 @@ protected:
//--------------------------------------------------------------------
public:
/*virtual*/ void updateRegion(LLViewerRegion *regionp);
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
//--------------------------------------------------------------------
// LLCharacter interface and related
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 591d5cae0b..600b44d371 100755
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -241,6 +241,7 @@ void LLVOGrass::initClass()
void LLVOGrass::cleanupClass()
{
for_each(sSpeciesTable.begin(), sSpeciesTable.end(), DeletePairedPointer());
+ sSpeciesTable.clear();
}
U32 LLVOGrass::processUpdateMessage(LLMessageSystem *mesgsys,
@@ -277,7 +278,7 @@ BOOL LLVOGrass::isActive() const
return TRUE;
}
-void LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOGrass::idleUpdate(LLAgent &agent, const F64 &time)
{
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS)))
{
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index e54de85412..ff4fa6b00d 100755
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -74,7 +74,7 @@ public:
void plantBlades();
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 97b7418b40..c1273e684c 100755
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -49,7 +49,7 @@ LLVOGround::~LLVOGround()
{
}
-void LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOGround::idleUpdate(LLAgent &agent, const F64 &time)
{
}
diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h
index 290579b4da..a53f309e46 100755
--- a/indra/newview/llvoground.h
+++ b/indra/newview/llvoground.h
@@ -41,7 +41,7 @@ protected:
public:
LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
// Graphical stuff for objects - maybe broken out into render class
// later?
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 9497041482..050d9dd785 100755
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -261,6 +261,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mSessionTerminateRequested(false),
mRelogRequested(false),
mConnected(false),
+ mTerminateDaemon(false),
mPump(NULL),
mSpatialJoiningNum(0),
@@ -695,7 +696,7 @@ void LLVivoxVoiceClient::stateMachine()
setVoiceEnabled(false);
}
- if(mVoiceEnabled || !mIsInitialized)
+ if(mVoiceEnabled || (!mIsInitialized &&!mTerminateDaemon) )
{
updatePosition();
}
@@ -708,11 +709,12 @@ void LLVivoxVoiceClient::stateMachine()
if((getState() != stateDisabled) && (getState() != stateDisableCleanup))
{
// User turned off voice support. Send the cleanup messages, close the socket, and reset.
- if(!mConnected)
+ if(!mConnected || mTerminateDaemon)
{
// if voice was turned off after the daemon was launched but before we could connect to it, we may need to issue a kill.
LL_INFOS("Voice") << "Disabling voice before connection to daemon, terminating." << LL_ENDL;
killGateway();
+ mTerminateDaemon = false;
}
logout();
@@ -753,7 +755,7 @@ void LLVivoxVoiceClient::stateMachine()
// Voice is locked out, we must not launch the vivox daemon.
setState(stateJail);
}
- else if(!isGatewayRunning())
+ else if(!isGatewayRunning() && gSavedSettings.getBOOL("EnableVoiceChat"))
{
if (true) // production build, not test
{
@@ -1136,6 +1138,7 @@ void LLVivoxVoiceClient::stateMachine()
std::stringstream errs;
errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000";
args["HOSTID"] = errs.str();
+ mTerminateDaemon = true;
if (LLGridManager::getInstance()->isSystemGrid())
{
LLNotificationsUtil::add("NoVoiceConnect", args);
@@ -2618,6 +2621,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st
std::stringstream errs;
errs << mVoiceAccountServerURI << "\n:UDP: 3478, 3479, 5060, 5062, 12000-17000";
args["HOSTID"] = errs.str();
+ mTerminateDaemon = true;
if (LLGridManager::getInstance()->isSystemGrid())
{
LLNotificationsUtil::add("NoVoiceConnect", args);
@@ -2633,6 +2637,7 @@ void LLVivoxVoiceClient::connectorCreateResponse(int statusCode, std::string &st
LL_INFOS("Voice") << "Connector.Create succeeded, Vivox SDK version is " << versionID << LL_ENDL;
mVoiceVersion.serverVersion = versionID;
mConnectorHandle = connectorHandle;
+ mTerminateDaemon = false;
if(getState() == stateConnectorStarting)
{
setState(stateConnectorStarted);
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index e2d1585c15..c325d72ba6 100755
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -659,6 +659,8 @@ private:
LLSocket::ptr_t mSocket;
bool mConnected;
+ // We should kill the voice daemon in case of connection alert
+ bool mTerminateDaemon;
LLPumpIO *mPump;
friend class LLVivoxProtocolParser;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 9f4f11b317..54e27ff4c6 100755
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -200,7 +200,7 @@ void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(p);
}
-void LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOPartGroup::idleUpdate(LLAgent &agent, const F64 &time)
{
}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 724e915d02..a94a2291ed 100755
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -63,7 +63,7 @@ public:
LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
/*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate.
- void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ void idleUpdate(LLAgent &agent, const F64 &time);
virtual F32 getBinRadius();
virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 36793017ed..93f0e50336 100755
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -1052,7 +1052,7 @@ void LLVOSky::calcAtmospherics(void)
mFadeColor.setAlpha(0);
}
-void LLVOSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOSky::idleUpdate(LLAgent &agent, const F64 &time)
{
}
diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h
index 2a150eccb9..ee8e91fb71 100755
--- a/indra/newview/llvosky.h
+++ b/indra/newview/llvosky.h
@@ -461,7 +461,7 @@ public:
void cleanupGL();
void restoreGL();
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
BOOL updateSky();
// Graphical stuff for objects - maybe broken out into render class
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index cd12cd9552..b82c4fe769 100755
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -269,6 +269,7 @@ void LLVOTree::initClass()
void LLVOTree::cleanupClass()
{
std::for_each(sSpeciesTable.begin(), sSpeciesTable.end(), DeletePairedPointer());
+ sSpeciesTable.clear();
}
U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
@@ -339,7 +340,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
return retval;
}
-void LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
{
if (mDead || !(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE)))
{
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 2ecb0303a1..6137ae412d 100755
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -59,7 +59,7 @@ public:
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
LLDataPacker *dp);
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
// Graphical stuff for objects - maybe broken out into render class later?
/*virtual*/ void render(LLAgent &agent);
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index e8a1c3d1d6..21595ee0bc 100755
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -100,7 +100,7 @@ void LLVOWater::updateTextures()
}
// Never gets called
-void LLVOWater::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOWater::idleUpdate(LLAgent &agent, const F64 &time)
{
}
diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h
index cf9323ef2e..7a8d819215 100755
--- a/indra/newview/llvowater.h
+++ b/indra/newview/llvowater.h
@@ -58,7 +58,7 @@ public:
static void initClass();
static void cleanupClass();
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
/*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 4e26587184..e7435b6860 100755
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -92,7 +92,7 @@ void LLVOWLSky::initSunDirection(LLVector3 const & sun_direction,
{
}
-void LLVOWLSky::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOWLSky::idleUpdate(LLAgent &agent, const F64 &time)
{
}
diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
index 729dced15e..1d419b5fea 100755
--- a/indra/newview/llvowlsky.h
+++ b/indra/newview/llvowlsky.h
@@ -53,7 +53,7 @@ public:
void initSunDirection(LLVector3 const & sun_direction,
LLVector3 const & sun_angular_velocity);
- /*virtual*/ void idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
/*virtual*/ BOOL isActive(void) const;
/*virtual*/ LLDrawable * createDrawable(LLPipeline *pipeline);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 103668d051..85614f397c 100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -143,23 +143,24 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
std::string seedUrl;
if (regionp)
{
- llinfos << "Region exists, removing it " << llendl;
LLHost old_host = regionp->getHost();
// region already exists!
if (host == old_host && regionp->isAlive())
{
// This is a duplicate for the same host and it's alive, don't bother.
+ llinfos << "Region already exists and is alive, using existing region" << llendl;
return regionp;
}
if (host != old_host)
{
llwarns << "LLWorld::addRegion exists, but old host " << old_host
- << " does not match new host " << host << llendl;
+ << " does not match new host " << host
+ << ", removing old region and creating new" << llendl;
}
if (!regionp->isAlive())
{
- llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
+ llwarns << "LLWorld::addRegion exists, but isn't alive. Removing old region and creating new" << llendl;
}
// Save capabilities seed URL
@@ -169,14 +170,18 @@ LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
// matches, because all the agent state for the new camera is completely different.
removeRegion(old_host);
}
+ else
+ {
+ llinfos << "Region does not exist, creating new one" << llendl;
+ }
U32 iindex = 0;
U32 jindex = 0;
from_region_handle(region_handle, &iindex, &jindex);
S32 x = (S32)(iindex/mWidth);
S32 y = (S32)(jindex/mWidth);
- llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
- llinfos << "Host: " << host << llendl;
+ llinfos << "Adding new region (" << x << ":" << y << ")"
+ << " on host: " << host << llendl;
LLVector3d origin_global;
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index ae334d4bd2..786e4f2de6 100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1595,14 +1595,6 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
}
-BOOL outside_slop(S32 x, S32 y, S32 start_x, S32 start_y)
-{
- S32 dx = x - start_x;
- S32 dy = y - start_y;
-
- return (dx <= -2 || 2 <= dx || dy <= -2 || 2 <= dy);
-}
-
BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )
{
gFocusMgr.setMouseCapture( this );
@@ -1685,7 +1677,7 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
{
if (hasMouseCapture())
{
- if (mPanning || outside_slop(x, y, mMouseDownX, mMouseDownY))
+ if (mPanning || llabs(x - mMouseDownX) > 1 || llabs(y - mMouseDownY) > 1)
{
// just started panning, so hide cursor
if (!mPanning)
@@ -1702,8 +1694,6 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
sPanY += delta_y;
sTargetPanX = sPanX;
sTargetPanY = sPanY;
-
- gViewerWindow->moveCursorToCenter();
}
// doesn't matter, cursor should be hidden
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 5da8a78b1b..805dc99654 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1362,49 +1362,10 @@ void LLPipeline::createLUTBuffers()
{
if (!mLightFunc)
{
- /*U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
- U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
- U8* ls = new U8[lightResX*lightResY];
- F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
- // Calculate the (normalized) Blinn-Phong specular lookup texture.
- for (U32 y = 0; y < lightResY; ++y)
- {
- for (U32 x = 0; x < lightResX; ++x)
- {
- ls[y*lightResX+x] = 0;
- F32 sa = (F32) x/(lightResX-1);
- F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * specExp;
-
- // Nothing special here. Just your typical blinn-phong term.
- spec = powf(sa, n);
-
- // Apply our normalization function.
- // Note: This is the full equation that applies the full normalization curve, not an approximation.
- // This is fine, given we only need to create our LUT once per buffer initialization.
- // The only trade off is we have a really low dynamic range.
- // This means we have to account for things not being able to exceed 0 to 1 in our shaders.
- spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
-
- // Always sample at a 1.0/2.2 curve.
- // This "Gamma corrects" our specular term, boosting our lower exponent reflections.
- spec = powf(spec, 1.f/2.2f);
-
- // Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders.
- // This allows for our specular term to exceed a value of 1 in our shaders.
- // This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1.
- // Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times.
- // This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents.
- // Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
- ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
- }
- }*/
-
-
U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
F32* ls = new F32[lightResX*lightResY];
- //F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); // Note: only use this when creating new specular lighting functions.
+ F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
// Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
for (U32 y = 0; y < lightResY; ++y)
{
@@ -1413,7 +1374,7 @@ void LLPipeline::createLUTBuffers()
ls[y*lightResX+x] = 0;
F32 sa = (F32) x/(lightResX-1);
F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * 368;
+ F32 n = spec * spec * specExp;
// Nothing special here. Just your typical blinn-phong term.
spec = powf(sa, n);
@@ -1426,23 +1387,6 @@ void LLPipeline::createLUTBuffers()
// Since we use R16F, we no longer have a dynamic range issue we need to work around here.
// Though some older drivers may not like this, newer drivers shouldn't have this problem.
ls[y*lightResX+x] = spec;
-
-
- //beckmann distribution
- /*F32 alpha = acosf((F32) x/(lightResX-1));
- F32 m = 1.f - (F32) y/(lightResY-1);
-
- F32 cos4_alpha = cosf(alpha);
- cos4_alpha *= cos4_alpha;
- cos4_alpha *= cos4_alpha;
-
- F32 tan_alpha = tanf(alpha);
- F32 tan2_alpha = tan_alpha*tan_alpha;
-
- F32 k = expf(-(tan2_alpha)/(m*m)) /
- (3.14159f*m*m*cos4_alpha);
-
- ls[y*lightResX+x] = k;*/
}
}
@@ -1455,7 +1399,6 @@ void LLPipeline::createLUTBuffers()
LLImageGL::generateTextures(1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
- //LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_UNSIGNED_BYTE, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 703015af20..9668cfa526 100755
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -9,63 +9,7 @@
save_rect="true"
title="ABOUT [CAPITALIZED_APP_NAME]"
width="470">
- <floater.string
- name="AboutHeader">
-[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
-[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
-
-</floater.string>
- <floater.string
- name="AboutCompiler">
-Built with [COMPILER] version [COMPILER_VERSION]
-
-</floater.string>
- <floater.string
- name="AboutPosition">
-You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
-SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
-(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
-[SERVER_VERSION]
-[SERVER_RELEASE_NOTES_URL]
-
-</floater.string>
- <!-- *NOTE: Do not translate text like GPU, Graphics Card, etc -
- Most PC users who know what these mean will be used to the English versions,
- and this info sometimes gets sent to support. -->
- <floater.string
- name="AboutSystem">
-CPU: [CPU]
-Memory: [MEMORY_MB] MB
-OS Version: [OS_VERSION]
-Graphics Card Vendor: [GRAPHICS_CARD_VENDOR]
-Graphics Card: [GRAPHICS_CARD]
-</floater.string>
- <floater.string
- name="AboutDriver">
-Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION]
-</floater.string>
- <floater.string
- name="AboutLibs">
-OpenGL Version: [OPENGL_VERSION]
-
-libcurl Version: [LIBCURL_VERSION]
-J2C Decoder Version: [J2C_VERSION]
-Audio Driver Version: [AUDIO_DRIVER_VERSION]
-Qt Webkit Version: [QT_WEBKIT_VERSION]
-Voice Server Version: [VOICE_VERSION]
-</floater.string>
- <floater.string
- name="none">
- (none)
- </floater.string>
- <floater.string
- name="AboutTraffic">
-Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)
-</floater.string>
-<floater.string
- name="ErrorFetchingServerReleaseNotesURL">
-Error fetching server release notes URL.
-</floater.string>
+
<tab_container
follows="all"
top="25"
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
index 5fdd4aa49d..49be4290c7 100755
--- a/indra/newview/skins/default/xui/en/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
@@ -47,7 +47,7 @@
width="16" />
<scroll_list.columns
name="text"
- width="234" />
+ relative_width="1" />
</scroll_list>
<text
type="string"
@@ -77,7 +77,7 @@
width="16" />
<scroll_list.columns
name="text"
- width="234" />
+ relative_width="1" />
</scroll_list>
<text
type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
deleted file mode 100755
index ff454e3ebf..0000000000
--- a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- height="180"
- layout="topleft"
- name="perm prefs"
- help_topic="perm_prefs"
- save_rect="true"
- title="DEFAULT UPLOAD PERMISSIONS"
- width="315">
- <panel
- follows="left|top|right|bottom"
- height="120"
- label="Permissions"
- layout="topleft"
- left="10"
- name="permissions"
- top="20"
- width="315">
- <check_box
- control_name="ShareWithGroup"
- height="16"
- label="Share with group"
- layout="topleft"
- left="10"
- name="share_with_group"
- top="5"
- width="150" />
- <check_box
- control_name="EveryoneCopy"
- height="16"
- label="Allow anyone to copy"
- layout="topleft"
- left_delta="0"
- name="everyone_copy"
- top_pad="5"
- width="150" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- name="NextOwnerLabel"
- top_pad="5"
- width="200">
- Next owner can:
- </text>
- <check_box
- control_name="NextOwnerModify"
- height="16"
- label="Modify"
- layout="topleft"
- left_delta="0"
- name="next_owner_modify"
- top_pad="5"
- width="150" />
- <check_box
- control_name="NextOwnerCopy"
- height="16"
- label="Copy"
- layout="topleft"
- left_delta="0"
- name="next_owner_copy"
- top_pad="5"
- width="150" >
- <check_box.commit_callback
- function="Perms.Copy" />
- </check_box>
- <check_box
- enabled_control="NextOwnerCopy"
- control_name="NextOwnerTransfer"
- enabled="false"
- height="16"
- initial_value="true"
- label="Resell/Give away"
- layout="topleft"
- left_delta="0"
- name="next_owner_transfer"
- top_pad="5"
- width="150" />
- </panel>
- <button
- height="20"
- label="OK"
- label_selected="OK"
- layout="topleft"
- left="90"
- name="ok"
- top="150"
- width="100">
- <button.commit_callback
- function="Perms.OK" />
- </button>
- <button
- height="20"
- label="Cancel"
- label_selected="Cancel"
- layout="topleft"
- left_pad="5"
- name="cancel"
- top_delta="0"
- width="100">
- <button.commit_callback
- function="Perms.Cancel" />
- </button>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_perms_default.xml b/indra/newview/skins/default/xui/en/floater_perms_default.xml
new file mode 100644
index 0000000000..ceb260fffb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_perms_default.xml
@@ -0,0 +1,503 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ height="250"
+ layout="topleft"
+ name="perms default"
+ help_topic="perms_default"
+ save_rect="true"
+ title="DEFAULT CREATION PERMISSIONS"
+ width="700">
+ <panel
+ follows="left|top|right|bottom"
+ height="200"
+ label="Default Permissions"
+ layout="topleft"
+ left="10"
+ name="default permissions"
+ top="20"
+ width="690">
+ <view_border
+ bevel_style="none"
+ height="18"
+ top="8"
+ left="0"
+ width="430" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="right"
+ layout="topleft"
+ left="0"
+ top="10"
+ width="115">
+ Next owner:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ width="100">
+ Copy
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ width="100">
+ Modify
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ width="100">
+ Transfer
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="32"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ word_wrap="true"
+ width="100">
+ Share with group
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="32"
+ halign="center"
+ layout="topleft"
+ left_pad="5"
+ top="10"
+ word_wrap="true"
+ width="120">
+ Allow anyone to copy
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ top_pad="10"
+ tool_tip="Set default permissions for when Objects are created"
+ width="100">
+ Objects
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Object"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="ObjectsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="objects_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Objects" />
+ </check_box>
+ <check_box
+ control_name="ObjectsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="objects_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="ObjectsNextOwnerCopy"
+ control_name="ObjectsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="objects_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="ObjectsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="objects_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="ObjectsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="objects_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for uploaded items"
+ width="100">
+ Uploads
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Texture"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="UploadsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="uploads_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Uploads" />
+ </check_box>
+ <check_box
+ control_name="UploadsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="uploads_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="UploadsNextOwnerCopy"
+ control_name="UploadsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="uploads_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="UploadsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="uploads_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="UploadsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="uploads_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Scripts are created"
+ width="100">
+ Scripts
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Script"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="ScriptsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="scripts_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Scripts" />
+ </check_box>
+ <check_box
+ control_name="ScriptsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="scripts_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="ScriptsNextOwnerCopy"
+ control_name="ScriptsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="scripts_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="ScriptsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="scripts_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="ScriptsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="scripts_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Notecards are created"
+ width="100">
+ Notecards
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Notecard"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="NotecardsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="notecards_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Notecards" />
+ </check_box>
+ <check_box
+ control_name="NotecardsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="notecards_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="NotecardsNextOwnerCopy"
+ control_name="NotecardsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="notecards_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="NotecardsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="notecards_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="NotecardsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="notecards_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Gestures are created"
+ width="100">
+ Gestures
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Gesture"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="GesturesNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="gestures_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Gestures" />
+ </check_box>
+ <check_box
+ control_name="GesturesNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="gestures_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="GesturesNextOwnerCopy"
+ control_name="GesturesNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="gestures_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="GesturesShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="gestures_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="GesturesEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="gestures_a"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when Clothing or Body Parts are created"
+ width="100">
+ Wearables
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_BodyShape"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="WearablesNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="wearables_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Wearables" />
+ </check_box>
+ <check_box
+ control_name="WearablesNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="wearables_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="WearablesNextOwnerCopy"
+ control_name="WearablesNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="wearables_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="WearablesShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="wearables_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="WearablesEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="wearables_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ </panel>
+ <button
+ height="20"
+ label="OK"
+ label_selected="OK"
+ layout="topleft"
+ name="ok"
+ left="475"
+ width="100">
+ <button.commit_callback
+ function="PermsDefault.OK" />
+ </button>
+ <button
+ height="20"
+ label="Cancel"
+ label_selected="Cancel"
+ layout="topleft"
+ left_pad="5"
+ name="cancel"
+ top_delta="0"
+ width="100">
+ <button.commit_callback
+ function="PermsDefault.Cancel" />
+ </button>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
index 7c7ee2df4c..99b812a880 100755
--- a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
@@ -10,33 +10,34 @@
width="600"
default_tab_group="1">
<text_editor
- left="10"
- type="string"
- length="1"
- follows="left|right|bottom"
- font="Monospace"
- height="366"
- width="576"
- ignore_tab="false"
- layout="topleft"
- max_length="65536"
- name="region_debug_console_output"
- show_line_numbers="false"
- word_wrap="true"
- track_end="true"
- read_only="true">
+ left="10"
+ type="string"
+ length="1"
+ follows="all"
+ font="Monospace"
+ height="366"
+ width="576"
+ ignore_tab="false"
+ layout="topleft"
+ max_length="65536"
+ name="region_debug_console_output"
+ show_line_numbers="false"
+ word_wrap="true"
+ track_end="true"
+ read_only="true">
</text_editor>
<line_editor
- border_style="line"
- border_thickness="1"
- tab_group="1"
- follows="left|top|right"
- font="SansSerif"
- height="19"
- layout="topleft"
- bottom_delta="20"
- max_length="127"
- name="region_debug_console_input"
- top_delta="0"
- width="576" />
+ border_style="line"
+ border_thickness="1"
+ tab_group="1"
+ follows="left|right|bottom"
+ font="SansSerif"
+ height="19"
+ layout="topleft"
+ bottom_delta="20"
+ max_length="127"
+ name="region_debug_console_input"
+ top_delta="0"
+ width="576">
+ </line_editor>
</floater>
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 77b9095f7c..410caa7290 100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml
@@ -31,6 +31,12 @@
<on_click function="AvatarIcon.Action" parameter="teleport"/>
</menu_item_call>
<menu_item_call
+ label="Request Teleport"
+ layout="topleft"
+ name="Request Teleport">
+ <on_click function="AvatarIcon.Action" parameter="request_teleport"/>
+ </menu_item_call>
+ <menu_item_call
label="Voice call"
layout="topleft"
name="Voice Call">
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 29720a680b..afeb1bf226 100755
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -63,13 +63,6 @@
function="File.UploadBulk"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Set Default Upload Permissions"
- name="perm prefs">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="perm_prefs" />
- </menu_item_call>
</menu>
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 64de010eb5..b30553281f 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1187,8 +1187,9 @@
<menu_item_call.on_enable
function="SomethingSelected" />
</menu_item_call>
+ <menu_item_separator/>
<menu_item_call
- label="Grid Options"
+ label="Grid Options..."
name="Grid Options"
shortcut="control|shift|B">
<menu_item_call.on_click
@@ -1197,6 +1198,13 @@
<menu_item_call.on_enable
function="Tools.EnableToolNotPie" />
</menu_item_call>
+ <menu_item_call
+ label="Set Default Permissions..."
+ name="Set default permissions">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="perms_default" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -1264,13 +1272,6 @@
function="File.UploadBulk"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Set Default Upload Permissions"
- name="perm prefs">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="perm_prefs" />
- </menu_item_call>
</menu>
<menu_item_separator/>
<menu_item_call
@@ -1381,8 +1382,7 @@
label="Report Bug"
name="Report Bug">
<menu_item_call.on_click
- function="ShowHelp"
- parameter="report_bug" />
+ function="Advanced.ReportBug"/>
</menu_item_call>
<menu_item_separator/>
@@ -2397,6 +2397,12 @@
<menu_item_call.on_click
function="Advanced.ClickRenderProfile" />
</menu_item_call>
+ <menu_item_call
+ label="Benchmark"
+ name="Benchmark">
+ <menu_item_call.on_click
+ function="Advanced.ClickRenderBenchmark" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -2554,6 +2560,16 @@
parameter="lights" />
</menu_item_check>
<menu_item_check
+ label="Particles"
+ name="Particles">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="particles" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="particles" />
+ </menu_item_check>
+ <menu_item_check
label="Collision Skeleton"
name="Collision Skeleton">
<menu_item_check.on_check
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a93601f5fd..9af80a23a7 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -271,7 +271,7 @@ See the [[MARKETPLACE_IMPORTS_URL] error log] for more information.
icon="OutboxStatus_Error"
name="OutboxImportFailed"
type="outbox">
-Transfer failed
+Transfer failed with error &apos;[ERROR_CODE]&apos;
No folders were sent to the Marketplace because of a system or network error. Try again later.
@@ -284,7 +284,7 @@ No folders were sent to the Marketplace because of a system or network error. T
icon="OutboxStatus_Error"
name="OutboxInitFailed"
type="outbox">
-Marketplace initialization failed
+Marketplace initialization failed with error &apos;[ERROR_CODE]&apos;
Initialization with the Marketplace failed because of a system or network error. Try again later.
@@ -4758,6 +4758,14 @@ Problems adding a new estate manager. One or more estates may have a full manag
<notification
icon="alertmodal.tga"
+ name="ProblemAddingEstateBanManager"
+ type="alertmodal">
+Unable to add estate owner or manager to ban list.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ProblemAddingEstateGeneric"
type="alertmodal">
Problems adding to this estate list. One or more estates may have a full list.
@@ -9293,8 +9301,17 @@ Object uses too many physics resources -- its dynamics have been disabled.
<notification
icon="alertmodal.tga"
+ name="EstateManagerFailedllTeleportHome"
+ persist="false"
+ type="notify">
+ <tag>fail</tag>
+The object '[OBJECT_NAME]' at [SLURL] cannot teleport estate managers home.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="TeleportedHomeByObjectOnParcel"
- persist="true"
+ persist="false"
type="notify">
<tag>fail</tag>
You have been teleported home by the object '[OBJECT_NAME]' on the parcel '[PARCEL_NAME]'
@@ -9303,7 +9320,7 @@ You have been teleported home by the object '[OBJECT_NAME]' on the parcel '[PARC
<notification
icon="alertmodal.tga"
name="TeleportedHomeByObject"
- persist="true"
+ persist="false"
type="notify">
<tag>fail</tag>
You have been teleported home by the object '[OBJECT_NAME]'
@@ -9747,15 +9764,7 @@ Only the first 10 selected objects have been disabled. Refresh and make addition
type="notify">
<tag>fail</tag>
You need to update your viewer to buy this parcel.
- </notification>
-
- <notification
- icon="alertmodal.tga"
- name="LandBuyAccessBlocked"
- type="notify">
- <tag>fail</tag>
-You can't buy this land due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
- </notification>
+ </notification>
<notification
icon="alertmodal.tga"
@@ -9818,7 +9827,9 @@ Not enough leased parcels in selection to join.
name="CantDivideLandMultipleParcelsSelected"
type="notify">
<tag>fail</tag>
-Can't divide land.\nThere is more than one parcel selected.\nTry selecting a smaller piece of land.
+Can't divide land.
+There is more than one parcel selected.
+Try selecting a smaller piece of land.
</notification>
<notification
@@ -9826,7 +9837,9 @@ Can't divide land.\nThere is more than one parcel selected.\nTry selecting a sma
name="CantDivideLandCantFindParcel"
type="notify">
<tag>fail</tag>
-Can't divide land.\nCan't find the parcel.\nPlease report with Help -> Reprt Bug...
+Can't divide land.
+Can't find the parcel.
+Please report with Help -> Report Bug...
</notification>
<notification
@@ -9834,7 +9847,8 @@ Can't divide land.\nCan't find the parcel.\nPlease report with Help -> Reprt Bug
name="CantDivideLandWholeParcelSelected"
type="notify">
<tag>fail</tag>
-Can't divide land. Whole parcel is selected.\nTry selecting a smaller piece of land.
+Can't divide land. Whole parcel is selected.
+Try selecting a smaller piece of land.
</notification>
<notification
@@ -10209,5 +10223,16 @@ Cannot create large prims that intersect other players. Please re-try when othe
name="okignore"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DefaultObjectPermissions"
+ type="alert">
+ There was a problem saving the default permissions due to the following reason: [REASON]. Please try setting the default permissions later.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 38b680ba86..26f54bacbc 100755
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
label="General"
- height="604"
+ height="420"
width="304"
class="panel_group_general"
name="general_tab">
@@ -101,31 +101,7 @@ Hover your mouse over the options for more help.
text_readonly_color="White"
word_wrap="true">
Group Charter
- </text_editor>
- <name_list
- column_padding="0"
- draw_heading="true"
- follows="left|top|right"
- heading_height="23"
- height="160"
- layout="topleft"
- left="0"
- name="visible_members"
- short_names="false"
- top_pad="2">
- <name_list.columns
- label="Member"
- name="name"
- relative_width="0.4" />
- <name_list.columns
- label="Title"
- name="title"
- relative_width="0.4" />
- <name_list.columns
- label="Status"
- name="status"
- relative_width="0.2" />
- </name_list>
+ </text_editor>
<text
follows="left|top|right"
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 206496cc0e..b3326d8da6 100755
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -131,7 +131,7 @@ background_visible="true"
expanded="false"
layout="topleft"
name="group_roles_tab"
- title="Roles"
+ title="Roles &amp; Members"
fit_panel="false">
<panel
border="false"
diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml
index df91ad8b5e..9ac5b8800e 100755
--- a/indra/newview/skins/default/xui/en/panel_group_roles.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml
@@ -94,11 +94,15 @@ clicking on their names.
<name_list.columns
label="Donation"
name="donated"
- relative_width="0.25" />
+ relative_width="0.2" />
<name_list.columns
label="Status"
name="online"
- relative_width="0.14" />
+ relative_width="0.18" />
+ <name_list.columns
+ label="Title"
+ name="title"
+ relative_width="0.18" />
</name_list>
<button
height="23"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 50fd57494f..2e778014c5 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -222,4 +222,15 @@
name="show_develop_menu_check"
top_pad="5"
width="237"/>
+ <button
+ height="20"
+ label="Default Creation Permissions"
+ layout="topleft"
+ name="default_creation_permissions"
+ left="30"
+ top_pad = "20"
+ width="250">
+ <button.commit_callback
+ function="Pref.PermsDefault" />
+ </button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_social_photo.xml b/indra/newview/skins/default/xui/en/panel_social_photo.xml
index a55613b52a..c79a246d9d 100644
--- a/indra/newview/skins/default/xui/en/panel_social_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_social_photo.xml
@@ -113,14 +113,6 @@
type="string"
word_wrap="true">
</text_editor>
- <check_box
- follows="left|top"
- initial_value="true"
- label="Include location in posting"
- name="add_location_cb"
- left="9"
- height="16"
- top_pad="8"/>
</layout_panel>
<layout_panel
name="photo_button_panel"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 7e79d297ef..e44a013dc7 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -20,6 +20,42 @@
<string name="StartupInitializingVFS">Initializing VFS...</string>
<string name="StartupRequireDriverUpdate">Graphics initialization failed. Please update your graphics driver!</string>
+ <!-- about dialog/support string-->
+ <string name="AboutHeader">
+[APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL])
+[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]
+ </string>
+ <string name="AboutCompiler">Built with [COMPILER] version [COMPILER_VERSION]</string>
+ <string name="AboutPosition">
+You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
+[SERVER_VERSION]
+[SERVER_RELEASE_NOTES_URL]
+ </string>
+ <!-- *NOTE: Do not translate text like GPU, Graphics Card, etc -
+ Most PC users who know what these mean will be used to the English versions,
+ and this info sometimes gets sent to support. -->
+ <string name="AboutSystem">
+CPU: [CPU]
+Memory: [MEMORY_MB] MB
+OS Version: [OS_VERSION]
+Graphics Card Vendor: [GRAPHICS_CARD_VENDOR]
+Graphics Card: [GRAPHICS_CARD]
+ </string>
+ <string name="AboutDriver">Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION]</string>
+ <string name="AboutLibs">
+OpenGL Version: [OPENGL_VERSION]
+
+libcurl Version: [LIBCURL_VERSION]
+J2C Decoder Version: [J2C_VERSION]
+Audio Driver Version: [AUDIO_DRIVER_VERSION]
+Qt Webkit Version: [QT_WEBKIT_VERSION]
+Voice Server Version: [VOICE_VERSION]
+ </string>
+ <string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>
+ <string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>
+
<!-- progress -->
<string name="ProgressRestoring">Restoring...</string>
<string name="ProgressChangingResolution">Changing resolution...</string>
@@ -383,6 +419,8 @@ Please try logging in again in a minute.</string>
<string name="multiple_textures">Multiple</string>
<string name="use_texture">Use texture</string>
+ <string name="manip_hint1">Move mouse cursor over ruler</string>
+ <string name="manip_hint2">to snap to grid</string>
<!-- world map -->
<string name="texture_loading">Loading...</string>
@@ -2209,6 +2247,16 @@ If you'd like to become a merchant, you'll need to [[MARKETPLACE_CREATE_STORE_UR
<string name="InventoryOutboxNoItems">
Drag folders to this area and click "Send to Marketplace" to list them for sale on the [[MARKETPLACE_DASHBOARD_URL] Marketplace].
</string>
+ <string name="InventoryOutboxInitializingTitle">Initializing Marketplace.</string>
+ <string name="InventoryOutboxInitializingTooltip"></string>
+ <string name="InventoryOutboxInitializing">
+We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace store].
+ </string>
+ <string name="InventoryOutboxErrorTitle">Marketplace Errors.</string>
+ <string name="InventoryOutboxErrorTooltip"></string>
+ <string name="InventoryOutboxError">
+The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
+ </string>
<string name="Marketplace Error None">No errors</string>
<string name="Marketplace Error Not Merchant">Error: Before sending items to the Marketplace you will need to set yourself up as a merchant (free of charge).</string>
@@ -2303,8 +2351,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
<string name="InvFolder Merchant Outbox">Merchant Outbox</string>
<!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
- <string name="InvFolder Friends">Friends</string>
- <string name="InvFolder Received Items">Received Items</string>
+ <string name="InvFolder Friends">Friends</string>
<string name="InvFolder All">All</string>
<string name="no_attachments">No attachments worn</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index fe0774b409..f7b3a45e8d 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -7,7 +7,7 @@
$LicenseInfo:firstyear=2006&license=viewerlgpl$
Second Life Viewer Source Code
-Copyright (C) 2006-2011, Linden Research, Inc.
+Copyright (C) 2006-2014, 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
@@ -749,7 +749,6 @@ class Darwin_i386_Manifest(ViewerManifest):
"libcollada14dom.dylib",
"libexpat.1.5.2.dylib",
"libexception_handler.dylib",
- "libfmodex.dylib",
"libGLOD.dylib",
):
dylibs += path_optional(os.path.join(libdir, libfile), libfile)
@@ -765,6 +764,20 @@ class Darwin_i386_Manifest(ViewerManifest):
'SLVoice',
):
self.path2basename(libdir, libfile)
+
+ # dylibs that vary based on configuration
+ if self.args['configuration'].lower() == 'debug':
+ for libfile in (
+ "libfmodexL.dylib",
+ ):
+ dylibs += path_optional(os.path.join("../packages/lib/debug",
+ libfile), libfile)
+ else:
+ for libfile in (
+ "libfmodex.dylib",
+ ):
+ dylibs += path_optional(os.path.join("../packages/lib/release",
+ libfile), libfile)
# our apps
for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 3c9a4b9756..c6070020db 100755
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -12,6 +12,7 @@ include(LLWindow)
include(LLXML)
include(Linking)
include(LLSharedLibs)
+include(GoogleBreakpad)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
@@ -20,6 +21,7 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
+ ${BREAKPAD_INCLUDE_DIRECTORIES}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
@@ -68,6 +70,7 @@ find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR})
add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES})
target_link_libraries(windows-crash-logger
+ ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}
${LLCRASHLOGGER_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLVFS_LIBRARIES}
diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp
index 36d988ead7..6a272fd166 100755..100644
--- a/indra/win_crash_logger/llcrashloggerwindows.cpp
+++ b/indra/win_crash_logger/llcrashloggerwindows.cpp
@@ -42,6 +42,11 @@
#include "lldxhardware.h"
#include "lldir.h"
#include "llsdserialize.h"
+#include "llsdutil.h"
+#include "stringize.h"
+
+#include <client/windows/crash_generation/crash_generation_server.h>
+#include <client/windows/crash_generation/client_info.h>
#define MAX_LOADSTRING 100
#define MAX_STRING 2048
@@ -64,6 +69,7 @@ BOOL gFirstDialog = TRUE; // Are we currently handling the Send/Don't Send dialo
std::stringstream gDXInfo;
bool gSendLogs = false;
+LLCrashLoggerWindows* LLCrashLoggerWindows::sInstance = NULL;
//Conversion from char* to wchar*
//Replacement for ATL macros, doesn't allocate memory
@@ -240,10 +246,178 @@ LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
LLCrashLoggerWindows::LLCrashLoggerWindows(void)
{
+ if (LLCrashLoggerWindows::sInstance==NULL)
+ {
+ sInstance = this;
+ }
}
LLCrashLoggerWindows::~LLCrashLoggerWindows(void)
{
+ sInstance = NULL;
+}
+
+bool LLCrashLoggerWindows::getMessageWithTimeout(MSG *msg, UINT to)
+{
+ bool res;
+ UINT_PTR timerID = SetTimer(NULL, NULL, to, NULL);
+ res = GetMessage(msg, NULL, 0, 0);
+ KillTimer(NULL, timerID);
+ if (!res)
+ return false;
+ if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == 1)
+ return false; //TIMEOUT! You could call SetLastError() or something...
+ return true;
+}
+
+int LLCrashLoggerWindows::processingLoop() {
+ const int millisecs=1000;
+ int retries = 0;
+ const int max_retries = 60;
+
+ LL_DEBUGS("CRASHREPORT") << "Entering processing loop for OOP server" << LL_ENDL;
+
+ LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE );
+
+ MSG msg;
+
+ bool result;
+
+ while (1)
+ {
+ result = getMessageWithTimeout(&msg, millisecs);
+ if ( result )
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ if ( retries < max_retries ) //Wait up to 1 minute for the viewer to say hello.
+ {
+ if (mClientsConnected == 0)
+ {
+ LL_DEBUGS("CRASHREPORT") << "Waiting for client to connect." << LL_ENDL;
+ ++retries;
+ }
+ else
+ {
+ LL_INFOS("CRASHREPORT") << "Client has connected!" << LL_ENDL;
+ retries = max_retries;
+ }
+ }
+ else
+ {
+ if (mClientsConnected == 0)
+ {
+ break;
+ }
+ if (!mKeyMaster.isProcessAlive(mPID, mProcName) )
+ {
+ break;
+ }
+ }
+ }
+
+ llinfos << "session ending.." << llendl;
+
+ std::string per_run_dir = options["dumpdir"].asString();
+ std::string per_run_file = per_run_dir + "\\SecondLife.log";
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.log");
+
+ if (gDirUtilp->fileExists(per_run_dir))
+ {
+ LL_INFOS ("CRASHREPORT") << "Copying " << log_file << " to " << per_run_file << llendl;
+ LLFile::copy(log_file, per_run_file);
+ }
+ return 0;
+}
+
+
+void LLCrashLoggerWindows::OnClientConnected(void* context,
+ const google_breakpad::ClientInfo* client_info)
+{
+ sInstance->mClientsConnected++;
+ LL_INFOS("CRASHREPORT") << "Client connected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL;
+}
+
+void LLCrashLoggerWindows::OnClientExited(void* context,
+ const google_breakpad::ClientInfo* client_info)
+{
+ sInstance->mClientsConnected--;
+ LL_INFOS("CRASHREPORT") << "Client disconnected. pid = " << client_info->pid() << " total clients " << sInstance->mClientsConnected << LL_ENDL;
+}
+
+
+void LLCrashLoggerWindows::OnClientDumpRequest(void* context,
+ const google_breakpad::ClientInfo* client_info,
+ const std::wstring* file_path)
+{
+ if (!file_path)
+ {
+ llwarns << "dump with no file path" << llendl;
+ return;
+ }
+ if (!client_info)
+ {
+ llwarns << "dump with no client info" << llendl;
+ return;
+ }
+
+ LLCrashLoggerWindows* self = static_cast<LLCrashLoggerWindows*>(context);
+ if (!self)
+ {
+ llwarns << "dump with no context" << llendl;
+ return;
+ }
+
+ //DWORD pid = client_info->pid();
+}
+
+
+bool LLCrashLoggerWindows::initCrashServer()
+{
+ //For Breakpad on Windows we need a full Out of Process service to get good data.
+ //This routine starts up the service on a named pipe that the viewer will then
+ //communicate with.
+ using namespace google_breakpad;
+
+ LLSD options = getOptionData( LLApp::PRIORITY_COMMAND_LINE );
+ std::string dump_path = options["dumpdir"].asString();
+ mClientsConnected = 0;
+ mPID = options["pid"].asInteger();
+ mProcName = options["procname"].asString();
+
+ //Generate a quasi-uniq name for the named pipe. For our purposes
+ //this is unique-enough with least hassle. Worst case for duplicate name
+ //is a second instance of the viewer will not do crash reporting.
+ std::wstring wpipe_name;
+ wpipe_name = mCrashReportPipeStr + std::wstring(wstringize(mPID));
+
+ std::wstring wdump_path( wstringize(dump_path) );
+
+ //Pipe naming conventions: http://msdn.microsoft.com/en-us/library/aa365783%28v=vs.85%29.aspx
+ mCrashHandler = new CrashGenerationServer( wpipe_name,
+ NULL,
+ &LLCrashLoggerWindows::OnClientConnected, this,
+ /*NULL, NULL, */ &LLCrashLoggerWindows::OnClientDumpRequest, this,
+ &LLCrashLoggerWindows::OnClientExited, this,
+ NULL, NULL,
+ true, &wdump_path);
+
+ if (!mCrashHandler) {
+ //Failed to start the crash server.
+ llwarns << "Failed to init crash server." << llendl;
+ return false;
+ }
+
+ // Start servicing clients.
+ if (!mCrashHandler->Start()) {
+ llwarns << "Failed to start crash server." << llendl;
+ return false;
+ }
+
+ LL_INFOS("CRASHREPORT") << "Initialized OOP server with pipe named " << stringize(wpipe_name) << LL_ENDL;
+ return true;
}
bool LLCrashLoggerWindows::init(void)
@@ -251,10 +425,12 @@ bool LLCrashLoggerWindows::init(void)
bool ok = LLCrashLogger::init();
if(!ok) return false;
+ initCrashServer();
+
/*
mbstowcs( gProductName, mProductName.c_str(), LL_ARRAY_SIZE(gProductName) );
gProductName[ LL_ARRY_SIZE(gProductName) - 1 ] = 0;
- swprintf(gProductName, L"Second Life");
+ swprintf(gProductName, L"Second Life");
*/
llinfos << "Loading dialogs" << llendl;
@@ -291,18 +467,16 @@ void LLCrashLoggerWindows::gatherPlatformSpecificFiles()
SetCursor(gCursorWait);
// At this point we're responsive enough the user could click the close button
SetCursor(gCursorArrow);
- mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo();
+ //mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo(); //Not initialized.
}
bool LLCrashLoggerWindows::mainLoop()
{
llinfos << "CrashSubmitBehavior is " << mCrashBehavior << llendl;
-
// Note: parent hwnd is 0 (the desktop). No dlg proc. See Petzold (5th ed) HexCalc example, Chapter 11, p529
// win_crash_logger.rc has been edited by hand.
// Dialogs defined with CLASS "WIN_CRASH_LOGGER" (must be same as szWindowClass)
gProductName = mProductName;
-
gHwndProgress = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PROGRESS), 0, NULL);
ProcessCaption(gHwndProgress);
ShowWindow(gHwndProgress, SW_HIDE );
@@ -310,7 +484,7 @@ bool LLCrashLoggerWindows::mainLoop()
if (mCrashBehavior == CRASH_BEHAVIOR_ALWAYS_SEND)
{
llinfos << "Showing crash report submit progress window." << llendl;
- ShowWindow(gHwndProgress, SW_SHOW );
+ //ShowWindow(gHwndProgress, SW_SHOW ); Maint-5707
sendCrashLogs();
}
else if (mCrashBehavior == CRASH_BEHAVIOR_ASK)
@@ -371,5 +545,7 @@ bool LLCrashLoggerWindows::cleanup()
}
PostQuitMessage(0);
commonCleanup();
+ mKeyMaster.releaseMaster();
return true;
}
+
diff --git a/indra/win_crash_logger/llcrashloggerwindows.h b/indra/win_crash_logger/llcrashloggerwindows.h
index 5c45a998b3..1812e2737e 100755..100644
--- a/indra/win_crash_logger/llcrashloggerwindows.h
+++ b/indra/win_crash_logger/llcrashloggerwindows.h
@@ -31,20 +31,54 @@
#include "windows.h"
#include "llstring.h"
+class LLSD;
+
+namespace google_breakpad {
+ class CrashGenerationServer;
+ class ClientInfo;
+}
+
class LLCrashLoggerWindows : public LLCrashLogger
{
public:
LLCrashLoggerWindows(void);
~LLCrashLoggerWindows(void);
+ static LLCrashLoggerWindows* sInstance;
+
virtual bool init();
virtual bool mainLoop();
virtual void updateApplication(const std::string& message = LLStringUtil::null);
virtual bool cleanup();
virtual void gatherPlatformSpecificFiles();
void setHandle(HINSTANCE hInst) { mhInst = hInst; }
+ int clients_connected() const {
+ return mClientsConnected;
+ }
+ bool getMessageWithTimeout(MSG *msg, UINT to);
+
+ // Starts the processing loop. This function does not return unless the
+ // user is logging off or the user closes the crash service window. The
+ // return value is a good number to pass in ExitProcess().
+ int processingLoop();
private:
void ProcessDlgItemText(HWND hWnd, int nIDDlgItem);
void ProcessCaption(HWND hWnd);
+ bool initCrashServer();
+ google_breakpad::CrashGenerationServer* mCrashHandler;
+ static void OnClientConnected(void* context,
+ const google_breakpad::ClientInfo* client_info);
+
+ static void OnClientDumpRequest(
+ void* context,
+ const google_breakpad::ClientInfo* client_info,
+ const std::wstring* file_path);
+
+ static void OnClientExited(void* context,
+ const google_breakpad::ClientInfo* client_info);
+ int mClientsConnected;
+ int mPID;
+ std::string mProcName;
+
HINSTANCE mhInst;
};
diff --git a/indra/win_crash_logger/win_crash_logger.cpp b/indra/win_crash_logger/win_crash_logger.cpp
index 8e916ae437..79b8514725 100755
--- a/indra/win_crash_logger/win_crash_logger.cpp
+++ b/indra/win_crash_logger/win_crash_logger.cpp
@@ -34,18 +34,24 @@ int APIENTRY WinMain(HINSTANCE hInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
- llinfos << "Starting crash reporter." << llendl;
-
+ llinfos << "Starting crash reporter with args" << &lpCmdLine << llendl;
LLCrashLoggerWindows app;
app.setHandle(hInstance);
app.parseCommandOptions(__argc, __argv);
+ LLSD options = LLApp::instance()->getOptionData(
+ LLApp::PRIORITY_COMMAND_LINE);
+ if (!(options.has("pid") && options.has("dumpdir")))
+ {
+ llwarns << "Insufficient parameters to crash report." << llendl;
+ }
if (! app.init())
{
llwarns << "Unable to initialize application." << llendl;
- return -1;
+ return 1;
}
+ app.processingLoop();
app.mainLoop();
app.cleanup();
llinfos << "Crash reporter finished normally." << llendl;