summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autobuild.xml16
-rwxr-xr-xdoc/contributions.txt2
-rw-r--r--indra/llappearance/llavatarappearance.cpp87
-rw-r--r--indra/llappearance/llavatarappearance.h4
-rw-r--r--indra/llappearance/llwearable.cpp2
-rw-r--r--indra/llcharacter/llmultigesture.cpp15
-rw-r--r--indra/llcharacter/llmultigesture.h30
-rw-r--r--indra/llcommon/llcoros.cpp1
-rw-r--r--indra/llcommon/llerror.cpp42
-rw-r--r--indra/llcommon/llerror.h23
-rw-r--r--indra/llcommon/llexception.cpp1
-rw-r--r--indra/llcommon/llstring.cpp106
-rw-r--r--indra/llcommon/llstring.h7
-rw-r--r--indra/llcorehttp/_httpservice.cpp1
-rw-r--r--indra/llimage/llimagebmp.cpp1
-rw-r--r--indra/llimage/llimagedxt.cpp1
-rw-r--r--indra/llimage/llimagetga.cpp1
-rw-r--r--indra/llprimitive/llprimitive.cpp6
-rw-r--r--indra/llprimitive/llprimitive.h2
-rw-r--r--indra/llrender/llimagegl.cpp3
-rw-r--r--indra/llui/llaccordionctrl.cpp17
-rw-r--r--indra/llui/llaccordionctrl.h2
-rw-r--r--indra/llui/llaccordionctrltab.h10
-rw-r--r--indra/llui/llbutton.cpp13
-rw-r--r--indra/llui/llbutton.h2
-rw-r--r--indra/llui/llcombobox.cpp15
-rw-r--r--indra/llui/llflatlistview.cpp49
-rw-r--r--indra/llui/llflatlistview.h11
-rw-r--r--indra/llui/llfloater.cpp3
-rw-r--r--indra/llui/llfloater.h4
-rw-r--r--indra/llui/llfolderview.cpp8
-rw-r--r--indra/llui/llfolderviewitem.cpp4
-rw-r--r--indra/llui/llfolderviewmodel.cpp4
-rw-r--r--indra/llui/llfolderviewmodel.h2
-rw-r--r--indra/llui/lllineeditor.cpp28
-rw-r--r--indra/llui/lllineeditor.h3
-rw-r--r--indra/llui/llmenugl.cpp7
-rw-r--r--indra/llui/llmodaldialog.cpp3
-rw-r--r--indra/llui/llnotifications.cpp4
-rw-r--r--indra/llui/llnotifications.h1
-rw-r--r--indra/llui/lltabcontainer.cpp31
-rw-r--r--indra/llui/lltabcontainer.h4
-rw-r--r--indra/llui/lltexteditor.cpp1
-rw-r--r--indra/llui/lltoolbar.cpp3
-rw-r--r--indra/llui/lltransutil.cpp10
-rw-r--r--indra/llui/llui.h2
-rw-r--r--indra/llui/lluictrl.h1
-rw-r--r--indra/llwindow/llwindow.h8
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm1
-rw-r--r--indra/llwindow/llwindowmacosx.cpp502
-rw-r--r--indra/llwindow/llwindowmacosx.h5
-rw-r--r--indra/llwindow/llwindowwin32.cpp5
-rw-r--r--indra/llwindow/llwindowwin32.h5
-rw-r--r--indra/llxml/llcontrol.cpp4
-rw-r--r--indra/llxml/llxmlnode.cpp2
-rw-r--r--indra/newview/app_settings/camera/Front.xml22
-rw-r--r--indra/newview/app_settings/camera/Rear.xml22
-rw-r--r--indra/newview/app_settings/camera/Side.xml22
-rw-r--r--indra/newview/app_settings/settings.xml2298
-rw-r--r--indra/newview/installers/windows/installer_template.nsi12
-rw-r--r--indra/newview/llagentcamera.cpp3
-rw-r--r--indra/newview/llagentpicksinfo.cpp12
-rw-r--r--indra/newview/llagentpicksinfo.h4
-rw-r--r--indra/newview/llappcorehttp.cpp1
-rw-r--r--indra/newview/llappearancemgr.cpp56
-rw-r--r--indra/newview/llappearancemgr.h13
-rw-r--r--indra/newview/llappviewer.cpp39
-rw-r--r--indra/newview/llappviewer.h1
-rw-r--r--indra/newview/llavatariconctrl.cpp26
-rw-r--r--indra/newview/llavatarpropertiesprocessor.cpp475
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h143
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp2
-rw-r--r--indra/newview/llchannelmanager.cpp19
-rw-r--r--indra/newview/llcofwearables.cpp4
-rw-r--r--indra/newview/llcompilequeue.cpp13
-rw-r--r--indra/newview/llcontrolavatar.cpp32
-rw-r--r--indra/newview/llconversationmodel.h2
-rw-r--r--indra/newview/llenvironment.cpp2
-rw-r--r--indra/newview/llfilepicker.cpp6
-rw-r--r--indra/newview/llfloateravatarpicker.cpp10
-rw-r--r--indra/newview/llfloatercolorpicker.cpp10
-rw-r--r--indra/newview/llfloaterconversationpreview.cpp3
-rw-r--r--indra/newview/llfloaterenvironmentadjust.cpp2
-rw-r--r--indra/newview/llfloaterexperiencepicker.cpp9
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp3
-rw-r--r--indra/newview/llfloaterimnearbychathandler.cpp2
-rw-r--r--indra/newview/llfloaterimsession.cpp6
-rw-r--r--indra/newview/llfloaterjoystick.cpp30
-rw-r--r--indra/newview/llfloaterjoystick.h1
-rw-r--r--indra/newview/llfloaternotificationstabbed.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp11
-rw-r--r--indra/newview/llfloaterprofiletexture.cpp9
-rw-r--r--indra/newview/llfloatersearch.cpp6
-rwxr-xr-xindra/newview/llfloaterworldmap.cpp12
-rw-r--r--indra/newview/llgesturemgr.cpp77
-rw-r--r--indra/newview/llgesturemgr.h11
-rw-r--r--indra/newview/llgroupactions.cpp23
-rw-r--r--indra/newview/llgroupactions.h2
-rw-r--r--indra/newview/llgrouplist.cpp21
-rw-r--r--indra/newview/llgrouplist.h2
-rw-r--r--indra/newview/llimhandler.cpp5
-rw-r--r--indra/newview/llimview.cpp12
-rw-r--r--indra/newview/llinspect.cpp6
-rw-r--r--indra/newview/llinspectavatar.cpp15
-rw-r--r--indra/newview/llinspecttoast.cpp4
-rw-r--r--indra/newview/llinventorybridge.cpp308
-rw-r--r--indra/newview/llinventorybridge.h46
-rw-r--r--indra/newview/llinventoryfunctions.cpp243
-rw-r--r--indra/newview/llinventoryfunctions.h4
-rw-r--r--indra/newview/llinventorygallery.cpp190
-rw-r--r--indra/newview/llinventorygallerymenu.cpp15
-rw-r--r--indra/newview/llinventoryitemslist.cpp2
-rw-r--r--indra/newview/llinventoryitemslist.h8
-rw-r--r--indra/newview/llinventorymodel.cpp27
-rw-r--r--indra/newview/llinventorymodel.h12
-rw-r--r--indra/newview/llinventorypanel.cpp56
-rw-r--r--indra/newview/llinventorypanel.h10
-rw-r--r--indra/newview/lllocationinputctrl.cpp20
-rw-r--r--indra/newview/lllocationinputctrl.h1
-rw-r--r--indra/newview/lllogchat.cpp21
-rw-r--r--indra/newview/lllogchat.h1
-rw-r--r--indra/newview/llmeshrepository.cpp10
-rw-r--r--indra/newview/llnavigationbar.cpp3
-rw-r--r--indra/newview/llnotificationalerthandler.cpp2
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp5
-rw-r--r--indra/newview/llnotificationofferhandler.cpp3
-rw-r--r--indra/newview/llnotificationscripthandler.cpp5
-rw-r--r--indra/newview/llnotificationtiphandler.cpp5
-rw-r--r--indra/newview/lloutfitgallery.cpp41
-rw-r--r--indra/newview/lloutfitgallery.h4
-rw-r--r--indra/newview/lloutfitslist.cpp199
-rw-r--r--indra/newview/lloutfitslist.h23
-rw-r--r--indra/newview/llpanelappearancetab.cpp27
-rw-r--r--indra/newview/llpanelappearancetab.h13
-rw-r--r--indra/newview/llpanelavatar.cpp58
-rw-r--r--indra/newview/llpanelavatar.h14
-rw-r--r--indra/newview/llpanelclassified.cpp5
-rw-r--r--indra/newview/llpaneleditwater.cpp2
-rw-r--r--indra/newview/llpanelface.cpp12
-rw-r--r--indra/newview/llpanelgroup.cpp30
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanelobject.cpp6
-rw-r--r--indra/newview/llpanelobjectinventory.cpp8
-rw-r--r--indra/newview/llpaneloutfitedit.cpp5
-rw-r--r--indra/newview/llpaneloutfitsinventory.cpp30
-rw-r--r--indra/newview/llpaneloutfitsinventory.h1
-rw-r--r--indra/newview/llpanelprofile.cpp537
-rw-r--r--indra/newview/llpanelprofile.h45
-rw-r--r--indra/newview/llpanelprofilepicks.cpp22
-rw-r--r--indra/newview/llpanelprofilepicks.h4
-rw-r--r--indra/newview/llpanelwearing.cpp13
-rw-r--r--indra/newview/llpanelwearing.h2
-rw-r--r--indra/newview/llpersistentnotificationstorage.cpp2
-rw-r--r--indra/newview/llpresetsmanager.cpp15
-rw-r--r--indra/newview/llpreviewgesture.cpp11
-rw-r--r--indra/newview/llpreviewgesture.h1
-rw-r--r--indra/newview/llscreenchannel.cpp3
-rw-r--r--indra/newview/llscreenchannel.h6
-rw-r--r--indra/newview/llscriptfloater.cpp2
-rw-r--r--indra/newview/llsearchhistory.cpp11
-rw-r--r--indra/newview/llsetkeybinddialog.cpp9
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp34
-rw-r--r--indra/newview/llslurl.cpp816
-rw-r--r--indra/newview/llslurl.h5
-rw-r--r--indra/newview/llspatialpartition.cpp27
-rw-r--r--indra/newview/llstartup.cpp23
-rw-r--r--indra/newview/llsyswellwindow.cpp4
-rw-r--r--indra/newview/lltexturectrl.cpp11
-rw-r--r--indra/newview/lltexturectrl.h7
-rw-r--r--indra/newview/lltextureview.cpp4
-rw-r--r--indra/newview/lltoastalertpanel.cpp6
-rw-r--r--indra/newview/lltooldraganddrop.cpp7
-rw-r--r--indra/newview/lltoolmorph.cpp7
-rw-r--r--indra/newview/lltoolpie.cpp11
-rw-r--r--indra/newview/llurldispatcher.cpp5
-rw-r--r--indra/newview/llviewerassetupload.cpp2
-rw-r--r--indra/newview/llvieweraudio.cpp25
-rw-r--r--indra/newview/llviewercontrol.cpp30
-rw-r--r--indra/newview/llviewerdisplay.cpp10
-rw-r--r--indra/newview/llviewerjoystick.cpp194
-rw-r--r--indra/newview/llviewerjoystick.h14
-rw-r--r--indra/newview/llviewermenu.cpp93
-rw-r--r--indra/newview/llviewermessage.cpp29
-rw-r--r--indra/newview/llviewerobject.cpp18
-rw-r--r--indra/newview/llviewerparcelmgr.cpp6
-rwxr-xr-xindra/newview/llviewerparceloverlay.cpp512
-rw-r--r--indra/newview/llviewerparceloverlay.h25
-rwxr-xr-xindra/newview/llviewerregion.cpp8
-rw-r--r--indra/newview/llviewerregion.h2
-rw-r--r--indra/newview/llviewertexlayer.cpp6
-rw-r--r--indra/newview/llviewertexturelist.cpp9
-rw-r--r--indra/newview/llviewerwindow.cpp19
-rw-r--r--indra/newview/llvoavatar.cpp23
-rw-r--r--indra/newview/llvoicecallhandler.cpp6
-rw-r--r--indra/newview/llwearableitemslist.cpp46
-rw-r--r--indra/newview/pipeline.cpp2
-rw-r--r--indra/newview/skins/default/textures/icons/Group_Notices.pngbin0 -> 3502 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_media_browser.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_gesture.xml15
-rw-r--r--indra/newview/skins/default/xui/en/floater_region_info.xml10
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml74
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml55
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item.xml16
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_list_item_short.xml15
-rw-r--r--indra/newview/skins/default/xui/en/panel_main_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_firstlife.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml103
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml8
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml19
-rw-r--r--indra/newview/tests/llslurl_test.cpp6
-rw-r--r--scripts/code_tools/fix_xml_indentations.py122
215 files changed, 4203 insertions, 5131 deletions
diff --git a/autobuild.xml b/autobuild.xml
index 0e5a5a2a25..879657b748 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -2563,11 +2563,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>eb1316584188dafb591f80b46b357c737f90d1a7</string>
+ <string>8a04e6b3c6ff7f645219955a1389035565eb10d8</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-08bf5ee/viewer_manager-3.0-08bf5ee-darwin64-08bf5ee.tar.zst</string>
+ <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-f14b5ec-D591/viewer_manager-3.0-f14b5ec-darwin64-f14b5ec.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -2577,11 +2577,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>f4677b0ebd9880f29c118af51ada50883dd0a1e4</string>
+ <string>a1e467c08ecbe6ab24fc8756a815a431a9b00f62</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-08bf5ee/viewer_manager-3.0-08bf5ee-linux64-08bf5ee.tar.zst</string>
+ <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-f14b5ec-D591/viewer_manager-3.0-f14b5ec-linux64-f14b5ec.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@@ -2591,11 +2591,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
- <string>7426c5a1d7eb231b476625637a1f2daba0a6bc55</string>
+ <string>56b613decdd36b2a17646bf3e2cfc2fed8456b8c</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
- <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-08bf5ee/viewer_manager-3.0-08bf5ee-windows64-08bf5ee.tar.zst</string>
+ <string>https://github.com/secondlife/viewer-manager/releases/download/v3.0-f14b5ec-D591/viewer_manager-3.0-f14b5ec-windows64-f14b5ec.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@@ -2607,8 +2607,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>LICENSE</string>
<key>copyright</key>
<string>Copyright (c) 2000-2012, Linden Research, Inc.</string>
- <key>version</key>
- <string>3.0-08bf5ee</string>
<key>name</key>
<string>viewer-manager</string>
<key>description</key>
@@ -2617,6 +2615,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<string>https://bitbucket.org/lindenlab/vmp-standalone</string>
<key>source_type</key>
<string>hg</string>
+ <key>version</key>
+ <string>3.0-f14b5ec</string>
</map>
<key>vlc-bin</key>
<map>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index a097aad7f6..0f3cd12f36 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -241,6 +241,7 @@ Ansariel Hiller
SL-19140
SL-4126
SL-20224
+ SL-20524
Aralara Rajal
Arare Chantilly
CHUIBUG-191
@@ -383,6 +384,7 @@ Chaser Zaks
BUG-225599
BUG-227485
SL-16874
+ SL-20442
Cherry Cheevers
ChickyBabes Zuzu
Chorazin Allen
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 18b03c1f89..8e39f47829 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -508,70 +508,45 @@ void LLAvatarAppearance::computeBodySize()
mCurrBodySizeState["mAnkleLeft scale"] = mAnkleLeftp->getScale();
mCurrBodySizeState["mFootLeft pos"] = mFootLeftp->getPosition();
- LLVector3 pelvis_scale = mPelvisp->getScale();
-
- // some of the joints have not been cached
- LLVector3 skull = mSkullp->getPosition();
- //LLVector3 skull_scale = mSkullp->getScale();
-
- LLVector3 neck = mNeckp->getPosition();
- LLVector3 neck_scale = mNeckp->getScale();
-
- LLVector3 chest = mChestp->getPosition();
- LLVector3 chest_scale = mChestp->getScale();
-
- // the rest of the joints have been cached
- LLVector3 head = mHeadp->getPosition();
- LLVector3 head_scale = mHeadp->getScale();
-
- LLVector3 torso = mTorsop->getPosition();
- LLVector3 torso_scale = mTorsop->getScale();
-
- LLVector3 hip = mHipLeftp->getPosition();
- LLVector3 hip_scale = mHipLeftp->getScale();
-
- LLVector3 knee = mKneeLeftp->getPosition();
- LLVector3 knee_scale = mKneeLeftp->getScale();
-
- LLVector3 ankle = mAnkleLeftp->getPosition();
- LLVector3 ankle_scale = mAnkleLeftp->getScale();
-
- LLVector3 foot = mFootLeftp->getPosition();
-
+ F32 old_height = mBodySize.mV[VZ];
F32 old_offset = mAvatarOffset.mV[VZ];
- mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER);
-
- mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
- knee.mV[VZ] * hip_scale.mV[VZ] -
- ankle.mV[VZ] * knee_scale.mV[VZ] -
- foot.mV[VZ] * ankle_scale.mV[VZ];
+ // TODO: Measure the real depth and width
+ mPelvisToFoot = computePelvisToFoot();
+ F32 new_height = computeBodyHeight();
+ mBodySize.set(DEFAULT_AGENT_DEPTH, DEFAULT_AGENT_WIDTH, new_height);
+ F32 new_offset = getVisualParamWeight(AVATAR_HOVER);
+ mAvatarOffset.set(0, 0, new_offset);
- LLVector3 new_body_size;
- new_body_size.mV[VZ] = mPelvisToFoot +
- // the sqrt(2) correction below is an approximate
- // correction to get to the top of the head
- F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
- head.mV[VZ] * neck_scale.mV[VZ] +
- neck.mV[VZ] * chest_scale.mV[VZ] +
- chest.mV[VZ] * torso_scale.mV[VZ] +
- torso.mV[VZ] * pelvis_scale.mV[VZ];
-
- // TODO -- measure the real depth and width
- new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
- new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
-
- mAvatarOffset.mV[VX] = 0.0f;
- mAvatarOffset.mV[VY] = 0.0f;
-
- if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ])
+ if (mBodySize.mV[VZ] != old_height || new_offset != old_offset)
{
- mBodySize = new_body_size;
-
compareJointStateMaps(mLastBodySizeState, mCurrBodySizeState);
}
}
+F32 LLAvatarAppearance::computeBodyHeight()
+{
+ F32 result = mPelvisToFoot +
+ // all these relative positions usually are positive
+ mPelvisp->getScale().mV[VZ] * mTorsop->getPosition().mV[VZ] +
+ mTorsop->getScale().mV[VZ] * mChestp->getPosition().mV[VZ] +
+ mChestp->getScale().mV[VZ] * mNeckp->getPosition().mV[VZ] +
+ mNeckp->getScale().mV[VZ] * mHeadp->getPosition().mV[VZ] +
+ mHeadp->getScale().mV[VZ] * mSkullp->getPosition().mV[VZ] * 2;
+ return result;
+}
+
+F32 LLAvatarAppearance::computePelvisToFoot()
+{
+ F32 result =
+ // all these relative positions usually are negative
+ mPelvisp->getScale().mV[VZ] * mHipLeftp->getPosition().mV[VZ] +
+ mHipLeftp->getScale().mV[VZ] * mKneeLeftp->getPosition().mV[VZ] +
+ mKneeLeftp->getScale().mV[VZ] * mAnkleLeftp->getPosition().mV[VZ] +
+ mAnkleLeftp->getScale().mV[VZ] * mFootLeftp->getPosition().mV[VZ] / 2;
+ return -result;
+}
+
//-----------------------------------------------------------------------------
// parseSkeletonFile()
//-----------------------------------------------------------------------------
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index e3444efcf6..72e194c9c1 100644
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -146,7 +146,9 @@ public:
joint_state_map_t mCurrBodySizeState;
void compareJointStateMaps(joint_state_map_t& last_state,
joint_state_map_t& curr_state);
- void computeBodySize();
+ void computeBodySize();
+ F32 computeBodyHeight();
+ F32 computePelvisToFoot();
public:
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
index 10d668d0af..736d24681a 100644
--- a/indra/llappearance/llwearable.cpp
+++ b/indra/llappearance/llwearable.cpp
@@ -550,7 +550,7 @@ void LLWearable::revertValues()
if(param)
{
F32 value = vp_pair.second;
- setVisualParamWeight(id, value);
+ param->setWeight(value);
mSavedVisualParamMap[id] = param->getWeight();
}
}
diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp
index 7ed242f90a..15cad4ea16 100644
--- a/indra/llcharacter/llmultigesture.cpp
+++ b/indra/llcharacter/llmultigesture.cpp
@@ -42,16 +42,6 @@ const S32 GESTURE_VERSION = 2;
// LLMultiGesture
//---------------------------------------------------------------------------
LLMultiGesture::LLMultiGesture()
-: mKey(),
- mMask(),
- mName(),
- mTrigger(),
- mReplaceText(),
- mSteps(),
- mPlaying(FALSE),
- mCurrentStep(0),
- mDoneCallback(NULL),
- mCallbackData(NULL)
{
reset();
}
@@ -67,8 +57,11 @@ void LLMultiGesture::reset()
mPlaying = FALSE;
mCurrentStep = 0;
mWaitTimer.reset();
- mWaitingTimer = FALSE;
mWaitingAnimations = FALSE;
+ mWaitingKeyRelease = FALSE;
+ mWaitingTimer = FALSE;
+ mTriggeredByKey = FALSE;
+ mKeyReleased = FALSE;
mWaitingAtEnd = FALSE;
mRequestedAnimIDs.clear();
mPlayingAnimIDs.clear();
diff --git a/indra/llcharacter/llmultigesture.h b/indra/llcharacter/llmultigesture.h
index 92820159d4..a664b45a97 100644
--- a/indra/llcharacter/llmultigesture.h
+++ b/indra/llcharacter/llmultigesture.h
@@ -59,11 +59,11 @@ protected:
const LLMultiGesture& operator=(const LLMultiGesture& rhs);
public:
- KEY mKey;
- MASK mMask;
+ KEY mKey { 0 };
+ MASK mMask { 0 };
// This name can be empty if the inventory item is not around and
- // the gesture manager has not yet set the name
+ // the gesture manager has not yet set the name
std::string mName;
// String, like "/foo" or "hello" that makes it play
@@ -75,25 +75,34 @@ public:
std::vector<LLGestureStep*> mSteps;
// Is the gesture currently playing?
- BOOL mPlaying;
+ BOOL mPlaying { FALSE };
// "instruction pointer" for steps
- S32 mCurrentStep;
+ S32 mCurrentStep { 0 };
// We're waiting for triggered animations to stop playing
- BOOL mWaitingAnimations;
+ BOOL mWaitingAnimations { FALSE };
+
+ // We're waiting for key release
+ BOOL mWaitingKeyRelease { FALSE };
// We're waiting a fixed amount of time
- BOOL mWaitingTimer;
+ BOOL mWaitingTimer { FALSE };
+
+ // We're waiting for triggered animations to stop playing
+ BOOL mTriggeredByKey { FALSE };
+
+ // Has the key been released?
+ BOOL mKeyReleased { FALSE };
// Waiting after the last step played for all animations to complete
- BOOL mWaitingAtEnd;
+ BOOL mWaitingAtEnd { FALSE };
// Timer for waiting
LLFrameTimer mWaitTimer;
- void (*mDoneCallback)(LLMultiGesture* gesture, void* data);
- void* mCallbackData;
+ void (*mDoneCallback)(LLMultiGesture* gesture, void* data) { NULL };
+ void* mCallbackData { NULL };
// Animations that we requested to start
std::set<LLUUID> mRequestedAnimIDs;
@@ -210,6 +219,7 @@ public:
const U32 WAIT_FLAG_TIME = 0x01;
const U32 WAIT_FLAG_ALL_ANIM = 0x02;
+const U32 WAIT_FLAG_KEY_RELEASE = 0x04;
class LLGestureStepWait : public LLGestureStep
{
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 3ab97b557f..1d383f174d 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -278,6 +278,7 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
catch (std::bad_alloc&)
{
// Out of memory on stack allocation?
+ LLError::LLUserWarningMsg::showOutOfMemory();
printActiveCoroutines();
LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL;
}
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 414515854a..3de641fcba 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1601,6 +1601,48 @@ namespace LLError
{
return out << boost::stacktrace::stacktrace();
}
+
+ // LLOutOfMemoryWarning
+ std::string LLUserWarningMsg::sLocalizedOutOfMemoryTitle;
+ std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning;
+ LLUserWarningMsg::Handler LLUserWarningMsg::sHandler;
+
+ void LLUserWarningMsg::show(const std::string& message)
+ {
+ if (sHandler)
+ {
+ sHandler(std::string(), message);
+ }
+ }
+
+ void LLUserWarningMsg::showOutOfMemory()
+ {
+ if (sHandler && !sLocalizedOutOfMemoryTitle.empty())
+ {
+ sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning);
+ }
+ }
+
+ void LLUserWarningMsg::showMissingFiles()
+ {
+ // Files Are missing, likely can't localize.
+ const std::string error_string =
+ "Second Life viewer couldn't access some of the files it needs and will be closed."
+ "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
+ "contact https://support.secondlife.com if issue persists after reinstall.";
+ sHandler("Missing Files", error_string);
+ }
+
+ void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler)
+ {
+ sHandler = handler;
+ }
+
+ void LLUserWarningMsg::setOutOfMemoryStrings(const std::string& title, const std::string& message)
+ {
+ sLocalizedOutOfMemoryTitle = title;
+ sLocalizedOutOfMemoryWarning = message;
+ }
}
void crashdriver(void (*callback)(int*))
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 05dd88ee51..6f6b349cf5 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -39,6 +39,7 @@
#include "llpreprocessor.h"
#include <boost/static_assert.hpp>
+#include <functional> // std::function
const int LL_ERR_NOERR = 0;
@@ -301,6 +302,28 @@ namespace LLError
{
friend std::ostream& operator<<(std::ostream& out, const LLStacktrace&);
};
+
+ // Provides access to OS notification popup on error, since
+ // not everything has access to OS's messages
+ class LLUserWarningMsg
+ {
+ public:
+ typedef std::function<void(const std::string&, const std::string&)> Handler;
+ static void setHandler(const Handler&);
+ static void setOutOfMemoryStrings(const std::string& title, const std::string& message);
+
+ // When viewer encounters bad alloc or can't access files try warning user about reasons
+ static void showOutOfMemory();
+ static void showMissingFiles();
+ // Genering error
+ static void show(const std::string&);
+
+ private:
+ // needs to be preallocated before viewer runs out of memory
+ static std::string sLocalizedOutOfMemoryTitle;
+ static std::string sLocalizedOutOfMemoryWarning;
+ static Handler sHandler;
+ };
}
//this is cheaper than llcallstacks if no need to output other variables to call stacks.
diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp
index 46560b5e4c..0787bde57f 100644
--- a/indra/llcommon/llexception.cpp
+++ b/indra/llcommon/llexception.cpp
@@ -37,6 +37,7 @@
#include "llerror.h"
#include "llerrorcontrol.h"
+
// used to attach and extract stacktrace information to/from boost::exception,
// see https://www.boost.org/doc/libs/release/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.exceptions_with_stacktrace
// apparently the struct passed as the first template param needs no definition?
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index f6629803ee..9a2251e0a7 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -600,6 +600,7 @@ std::string mbcsstring_makeASCII(const std::string& wstr)
}
return out_str;
}
+
std::string utf8str_removeCRLF(const std::string& utf8str)
{
if (0 == utf8str.length())
@@ -621,6 +622,43 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
return out;
}
+// Search for any emoji symbol, return true if found
+bool wstring_has_emoji(const LLWString& wstr)
+{
+ for (const llwchar& wch : wstr)
+ {
+ if (LLStringOps::isEmoji(wch))
+ return true;
+ }
+
+ return false;
+}
+
+// Cut emoji symbols if exist
+bool wstring_remove_emojis(LLWString& wstr)
+{
+ bool found = false;
+ for (size_t i = 0; i < wstr.size(); ++i)
+ {
+ if (LLStringOps::isEmoji(wstr[i]))
+ {
+ wstr.erase(i--, 1);
+ found = true;
+ }
+ }
+ return found;
+}
+
+// Cut emoji symbols if exist
+bool utf8str_remove_emojis(std::string& utf8str)
+{
+ LLWString wstr = utf8str_to_wstring(utf8str);
+ if (!wstring_remove_emojis(wstr))
+ return false;
+ utf8str = wstring_to_utf8str(wstr);
+ return true;
+}
+
#if LL_WINDOWS
unsigned int ll_wstring_default_code_page()
{
@@ -833,6 +871,66 @@ std::string LLStringOps::sDayFormat;
std::string LLStringOps::sAM;
std::string LLStringOps::sPM;
+// static
+bool LLStringOps::isEmoji(llwchar wch)
+{
+ // Most of the following symbols are not actually emoticons, but rather small pictures
+
+ // 0x1F000 .. 0x1F02F - mahjong tiles
+ // https://symbl.cc/en/unicode/table/#mahjong-tiles
+
+ // 0x1F030 .. 0x1F09F - domino tiles
+ // https://symbl.cc/en/unicode/table/#domino-tiles
+
+ // 0x1F0A0 .. 0x1F0FF - playing cards
+ // https://symbl.cc/en/unicode/table/#playing-cards
+
+ // 0x1F100 .. 0x1F1FF - enclosed alphanumeric supplement
+ // https://symbl.cc/en/unicode/table/#enclosed-alphanumeric-supplement
+
+ // 0x1F200 .. 0x1F2FF - enclosed ideographic supplement
+ // https://symbl.cc/en/unicode/table/#enclosed-ideographic-supplement
+
+ // 0x1F300 .. 0x1F5FF - miscellaneous symbols and pictographs
+ // https://symbl.cc/en/unicode/table/#miscellaneous-symbols-and-pictographs
+
+ // 0x1F600 .. 0x1F64F - emoticons
+ // https://symbl.cc/en/unicode/table/#emoticons
+
+ // 0x1F650 .. 0x1F67F - ornamental dingbats
+ // https://symbl.cc/en/unicode/table/#ornamental-dingbats
+
+ // 0x1F680 .. 0x1F6FF - transport and map symbols
+ // https://symbl.cc/en/unicode/table/#transport-and-map-symbols
+
+ // 0x1F700 .. 0x1F77F - alchemical symbols
+ // https://symbl.cc/en/unicode/table/#alchemical-symbols
+
+ // 0x1F780 .. 0x1F7FF - geometric shapes extended
+ // https://symbl.cc/en/unicode/table/#geometric-shapes-extended
+
+ // 0x1F800 .. 0x1F8FF - supplemental arrows c
+ // https://symbl.cc/en/unicode/table/#supplemental-arrows-c
+
+ // 0x1F900 .. 0x1F9FF - supplemental symbols and pictographs
+ // https://symbl.cc/en/unicode/table/#supplemental-symbols-and-pictographs
+
+ // 0x1FA00 .. 0x1FA6F - chess symbols
+ // https://symbl.cc/en/unicode/table/#chess-symbols
+
+ // 0x1FA70 .. 0x1FAFF - symbols and pictographs extended a
+ // https://symbl.cc/en/unicode/table/#symbols-and-pictographs-extended-a
+
+ // 0x1FB00 .. 0x1FBFF - symbols for legacy computing
+ // https://symbl.cc/en/unicode/table/#symbols-for-legacy-computing
+
+ // 0x1FC00 .. 0x1FFFF - undefined block 44
+ // These symbols aren't defined yet
+ // https://symbl.cc/en/unicode/table/#undefined-block-44
+
+ return wch >= 0x1F000 && wch < 0x1FC00;
+}
+
S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
{
@@ -1235,9 +1333,17 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
}
else
{
+#if 0
+ // EXT-1565 : Zai Lynch, James Linden : 15/Oct/09
+ // [BSI] Feedback: Viewer clock mentions SLT, but would prefer it to show PST/PDT
// "slt" = Second Life Time, which is deprecated.
// If not utc or user local time, fallback to Pacific time
replacement = LLStringOps::getPacificDaylightTime() ? "PDT" : "PST";
+#else
+ // SL-20370 : Steeltoe Linden : 29/Sep/23
+ // Change "PDT" to "SLT" on menu bar
+ replacement = "SLT";
+#endif
}
return true;
}
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 1fd6cac14a..6e70a6fa5c 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -189,6 +189,8 @@ public:
static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
+ static bool isEmoji(llwchar wch);
+
static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
static S32 collate(const llwchar* a, const llwchar* b);
@@ -737,6 +739,11 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
+LL_COMMON_API bool wstring_has_emoji(const LLWString& wstr);
+
+LL_COMMON_API bool wstring_remove_emojis(LLWString& wstr);
+
+LL_COMMON_API bool utf8str_remove_emojis(std::string& utf8str);
#if LL_WINDOWS
/* @name Windows string helpers
diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp
index 294acd7f63..517076804d 100644
--- a/indra/llcorehttp/_httpservice.cpp
+++ b/indra/llcorehttp/_httpservice.cpp
@@ -320,6 +320,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
LLMemory::logMemoryInfo(TRUE);
//output possible call stacks to log file.
+ LLError::LLUserWarningMsg::showOutOfMemory();
LLError::LLCallStacks::print();
LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL;
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index 90b7272efa..cdea0da68d 100644
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
@@ -321,6 +321,7 @@ bool LLImageBMP::updateData()
mColorPalette = new(std::nothrow) U8[color_palette_size];
if (!mColorPalette)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL;
return false;
}
diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp
index 36317a5ba8..ae76c5243f 100644
--- a/indra/llimage/llimagedxt.cpp
+++ b/indra/llimage/llimagedxt.cpp
@@ -437,6 +437,7 @@ bool LLImageDXT::convertToDXR()
U8* newdata = (U8*)ll_aligned_malloc_16(total_bytes);
if (!newdata)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Out of memory in LLImageDXT::convertToDXR()" << LL_ENDL;
return false;
}
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 88bdae9b80..152a7f309c 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -266,6 +266,7 @@ bool LLImageTGA::updateData()
mColorMap = new(std::nothrow) U8[ color_map_bytes ];
if (!mColorMap)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Out of Memory in bool LLImageTGA::updateData()" << LL_ENDL;
return false;
}
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 904747af2d..91b9e4f84e 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -118,7 +118,7 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f;
const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
-const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
+const LLUUID SCULPT_DEFAULT_TEXTURE("be293869-d0d9-0a69-5989-ad27f1946fd4"); // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
// Texture rotations are sent over the wire as a S16. This is used to scale the actual float
// value to a S16. Don't use 7FFF as it introduces some odd rounding with 180 since it
@@ -2073,7 +2073,7 @@ bool LLFlexibleObjectData::fromLLSD(LLSD& sd)
LLSculptParams::LLSculptParams()
{
mType = PARAMS_SCULPT;
- mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
+ mSculptTexture = SCULPT_DEFAULT_TEXTURE;
mSculptType = LL_SCULPT_TYPE_SPHERE;
}
@@ -2159,7 +2159,7 @@ void LLSculptParams::setSculptTexture(const LLUUID& texture_id, U8 sculpt_type)
U8 flags = sculpt_type & LL_SCULPT_FLAG_MASK;
if (sculpt_type != (type | flags) || type > LL_SCULPT_TYPE_MAX)
{
- mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
+ mSculptTexture = SCULPT_DEFAULT_TEXTURE;
mSculptType = LL_SCULPT_TYPE_SPHERE;
}
else
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 0b7dbd703a..0d287bc7ca 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -89,7 +89,7 @@ extern const F32 OBJECT_REV_MIN;
extern const F32 OBJECT_REV_MAX;
extern const F32 OBJECT_REV_INC;
-extern const char *SCULPT_DEFAULT_TEXTURE;
+extern const LLUUID SCULPT_DEFAULT_TEXTURE;
//============================================================================
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index c6fd824c4e..56a12b07b1 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1353,6 +1353,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
scratch = new(std::nothrow) U32[width * height];
if (!scratch)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
}
@@ -1378,6 +1379,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
scratch = new(std::nothrow) U32[width * height];
if (!scratch)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
}
@@ -1406,6 +1408,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
scratch = new(std::nothrow) U32[width * height];
if (!scratch)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32))
<< " bytes for a manual image W" << width << " H" << height << LL_ENDL;
}
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 0a82bed896..e18c40e7c3 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -936,3 +936,20 @@ S32 LLAccordionCtrl::calcExpandedTabHeight(S32 tab_index /* = 0 */, S32 availabl
expanded_tab_height /= num_expanded;
return expanded_tab_height;
}
+
+void LLAccordionCtrl::collapseAllTabs()
+{
+ if (mAccordionTabs.size() > 0)
+ {
+ for (size_t i = 0; i < mAccordionTabs.size(); ++i)
+ {
+ LLAccordionCtrlTab *tab = mAccordionTabs[i];
+
+ if (tab->getDisplayChildren())
+ {
+ tab->setDisplayChildren(false);
+ }
+ }
+ arrange();
+ }
+}
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 6a1989afba..f226d38bed 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -122,6 +122,8 @@ public:
void setComparator(const LLTabComparator* comp) { mTabComparator = comp; }
void sort();
+ void collapseAllTabs();
+
/**
* Sets filter substring as a search_term for help text when there are no any visible tabs.
*/
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index 896a34cac4..496c34c38b 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -126,12 +126,12 @@ public:
void setSelected(bool is_selected);
- bool getCollapsible() {return mCollapsible;};
+ bool getCollapsible() { return mCollapsible; };
- void setCollapsible(bool collapsible) {mCollapsible = collapsible;};
+ void setCollapsible(bool collapsible) { mCollapsible = collapsible; };
void changeOpenClose(bool is_open);
- void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
+ void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close; };
bool canOpenClose() const { return mCanOpenClose; };
virtual BOOL postBuild();
@@ -142,8 +142,8 @@ public:
void draw();
- void storeOpenCloseState ();
- void restoreOpenCloseState ();
+ void storeOpenCloseState();
+ void restoreOpenCloseState();
protected:
LLAccordionCtrlTab(const LLAccordionCtrlTab::Params&);
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 49d275997a..ceceb90f0a 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -58,10 +58,11 @@ static LLDefaultChildRegistry::Register<LLButton> r("button");
template class LLButton* LLView::getChild<class LLButton>(
const std::string& name, BOOL recurse) const;
-// globals loaded from settings.xml
-S32 LLBUTTON_H_PAD = 0;
-S32 BTN_HEIGHT_SMALL= 0;
-S32 BTN_HEIGHT = 0;
+// globals
+S32 LLBUTTON_H_PAD = 4;
+S32 BTN_HEIGHT_SMALL= 23;
+S32 BTN_HEIGHT = 23;
+S32 BTN_DROP_SHADOW = 2;
LLButton::Params::Params()
: label_selected("label_selected"), // requires is_toggle true
@@ -91,8 +92,8 @@ LLButton::Params::Params()
image_overlay_disabled_color("image_overlay_disabled_color", LLColor4::white % 0.3f),
image_overlay_selected_color("image_overlay_selected_color", LLColor4::white),
flash_color("flash_color"),
- pad_right("pad_right", LLUI::getInstance()->mSettingGroups["config"]->getS32("ButtonHPad")),
- pad_left("pad_left", LLUI::getInstance()->mSettingGroups["config"]->getS32("ButtonHPad")),
+ pad_right("pad_right", LLBUTTON_H_PAD),
+ pad_left("pad_left", LLBUTTON_H_PAD),
pad_bottom("pad_bottom"),
click_callback("click_callback"),
mouse_down_callback("mouse_down_callback"),
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index ccd31e90c0..ab64440c19 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -43,10 +43,10 @@
//
// PLEASE please use these "constants" when building your own buttons.
-// They are loaded from settings.xml at run time.
extern S32 LLBUTTON_H_PAD;
extern S32 BTN_HEIGHT_SMALL;
extern S32 BTN_HEIGHT;
+extern S32 BTN_DROP_SHADOW;
//
// Helpful functions
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 9ca05a16f3..7a925c0659 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -482,8 +482,6 @@ void LLComboBox::onFocusLost()
void LLComboBox::setButtonVisible(BOOL visible)
{
- static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
-
mButton->setVisible(visible);
if (mTextEntry)
{
@@ -491,7 +489,7 @@ void LLComboBox::setButtonVisible(BOOL visible)
if (visible)
{
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
- text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * BTN_DROP_SHADOW;
}
//mTextEntry->setRect(text_entry_rect);
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
@@ -530,19 +528,18 @@ void LLComboBox::setEnabledByValue(const LLSD& value, BOOL enabled)
void LLComboBox::createLineEditor(const LLComboBox::Params& p)
{
- static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
LLRect rect = getLocalRect();
if (mAllowTextEntry)
{
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
- S32 shadow_size = drop_shadow_button;
+ S32 shadow_size = BTN_DROP_SHADOW;
mButton->setRect(LLRect( getRect().getWidth() - llmax(8,arrow_width) - 2 * shadow_size,
rect.mTop, rect.mRight, rect.mBottom));
mButton->setTabStop(FALSE);
mButton->setHAlign(LLFontGL::HCENTER);
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * BTN_DROP_SHADOW;
// clear label on button
std::string cur_label = mButton->getLabelSelected();
LLLineEditor::Params params = p.combo_editor;
@@ -1081,13 +1078,11 @@ void LLComboBox::onSetHighlight() const
void LLComboBox::imageLoaded()
{
- static LLUICachedControl<S32> drop_shadow_button("DropShadowButton", 0);
-
if (mAllowTextEntry)
{
LLRect rect = getLocalRect();
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
- S32 shadow_size = drop_shadow_button;
+ S32 shadow_size = BTN_DROP_SHADOW;
mButton->setRect(LLRect(getRect().getWidth() - llmax(8, arrow_width) - 2 * shadow_size,
rect.mTop, rect.mRight, rect.mBottom));
if (mButton->getVisible())
@@ -1096,7 +1091,7 @@ void LLComboBox::imageLoaded()
if (mTextEntry)
{
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- text_entry_rect.mRight -= llmax(8, arrow_width) + 2 * drop_shadow_button;
+ text_entry_rect.mRight -= llmax(8, arrow_width) + 2 * BTN_DROP_SHADOW;
mTextEntry->reshape(text_entry_rect.getWidth(), text_entry_rect.getHeight(), TRUE);
}
}
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 460bd0945b..fd4c33df30 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -1361,26 +1361,28 @@ void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
mForceShowingUnmatchedItems = show;
}
-void LLFlatListViewEx::setFilterSubString(const std::string& filter_str)
+void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent)
{
if (0 != LLStringUtil::compareInsensitive(filter_str, mFilterSubString))
{
mFilterSubString = filter_str;
updateNoItemsMessage(mFilterSubString);
- filterItems();
+ filterItems(false, notify_parent);
}
}
-void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
+bool LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
{
- if (!item) return;
+ if (!item)
+ return false;
+
+ BOOL visible = TRUE;
// 0 signifies that filter is matched,
// i.e. we don't hide items that don't support 'match_filter' action, separators etc.
if (0 == item->notify(action))
{
mHasMatchedItems = true;
- item->setVisible(true);
}
else
{
@@ -1388,34 +1390,45 @@ void LLFlatListViewEx::updateItemVisibility(LLPanel* item, const LLSD &action)
if (!mForceShowingUnmatchedItems)
{
selectItem(item, false);
+ visible = FALSE;
}
- item->setVisible(mForceShowingUnmatchedItems);
}
+
+ if (item->getVisible() != visible)
+ {
+ item->setVisible(visible);
+ return true;
+ }
+
+ return false;
}
-void LLFlatListViewEx::filterItems()
+void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
{
- typedef std::vector <LLPanel*> item_panel_list_t;
-
std::string cur_filter = mFilterSubString;
LLStringUtil::toUpper(cur_filter);
LLSD action;
action.with("match_filter", cur_filter);
- item_panel_list_t items;
- getItems(items);
-
mHasMatchedItems = false;
- item_panel_list_t::iterator iter = items.begin(), iter_end = items.end();
- while (iter < iter_end)
+ bool visibility_changed = false;
+ pairs_const_iterator_t iter = getItemPairs().begin(), iter_end = getItemPairs().end();
+ while (iter != iter_end)
{
- LLPanel* pItem = *(iter++);
- updateItemVisibility(pItem, action);
+ LLPanel* pItem = (*(iter++))->first;
+ visibility_changed |= updateItemVisibility(pItem, action);
}
- sort();
- notifyParentItemsRectChanged();
+ if (re_sort)
+ {
+ sort();
+ }
+
+ if (visibility_changed && notify_parent)
+ {
+ notifyParentItemsRectChanged();
+ }
}
bool LLFlatListViewEx::hasMatchedItems()
diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h
index d47c1cf333..adb0e3e553 100644
--- a/indra/llui/llflatlistview.h
+++ b/indra/llui/llflatlistview.h
@@ -300,6 +300,7 @@ public:
virtual S32 notify(const LLSD& info) ;
virtual ~LLFlatListView();
+
protected:
/** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */
@@ -375,7 +376,9 @@ protected:
LLRect getLastSelectedItemRect();
- void ensureSelectedVisible();
+ void ensureSelectedVisible();
+
+ const pairs_list_t& getItemPairs() { return mItemPairs; }
private:
@@ -482,14 +485,14 @@ public:
/**
* Sets up new filter string and filters the list.
*/
- void setFilterSubString(const std::string& filter_str);
+ void setFilterSubString(const std::string& filter_str, bool notify_parent);
std::string getFilterSubString() { return mFilterSubString; }
/**
* Filters the list, rearranges and notifies parent about shape changes.
* Derived classes may want to overload rearrangeItems() to exclude repeated separators after filtration.
*/
- void filterItems();
+ void filterItems(bool re_sort, bool notify_parent);
/**
* Returns true if last call of filterItems() found at least one matching item
@@ -513,7 +516,7 @@ protected:
* @param item - item we are changing
* @param item - action - parameters to determin visibility from
*/
- void updateItemVisibility(LLPanel* item, const LLSD &action);
+ bool updateItemVisibility(LLPanel* item, const LLSD &action);
private:
std::string mNoFilteredItemsMsg;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 2303cd24b7..d08084cdf5 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1961,10 +1961,9 @@ void LLFloater::drawShadow(LLPanel* panel)
S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH;
S32 bottom = LLPANEL_BORDER_WIDTH;
- static LLUICachedControl<S32> shadow_offset_S32 ("DropShadowFloater", 0);
static LLUIColor shadow_color_cached = LLUIColorTable::instance().getColor("ColorDropShadow");
LLColor4 shadow_color = shadow_color_cached;
- F32 shadow_offset = (F32)shadow_offset_S32;
+ F32 shadow_offset = (F32)DROP_SHADOW_FLOATER;
if (!panel->isBackgroundOpaque())
{
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 3d15708295..9f9d950189 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -61,6 +61,10 @@ const BOOL CLOSE_NO = FALSE;
const BOOL ADJUST_VERTICAL_YES = TRUE;
const BOOL ADJUST_VERTICAL_NO = FALSE;
+const F32 CONTEXT_CONE_IN_ALPHA = 0.f;
+const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
+const F32 CONTEXT_CONE_FADE_TIME = .08f;
+
namespace LLFloaterEnums
{
enum EOpenPositioning
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 650ae9ae75..d7ba47c9f5 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -335,9 +335,9 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
void LLFolderView::filter( LLFolderViewFilter& filter )
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
- static LLCachedControl<S32> time_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
- static LLCachedControl<S32> time_invisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1);
- filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));
+ const S32 TIME_VISIBLE = 10; // in milliseconds
+ const S32 TIME_INVISIBLE = 1;
+ filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? TIME_VISIBLE : TIME_INVISIBLE), 1, 100));
// Note: we filter the model, not the view
getViewModelItem()->filter(filter);
@@ -765,7 +765,7 @@ void LLFolderView::removeSelectedItems()
}
else
{
- LL_INFOS() << "Cannot delete " << item->getName() << LL_ENDL;
+ LL_DEBUGS() << "Cannot delete " << item->getName() << LL_ENDL;
return;
}
}
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0dc66bf37a..6ae150dca5 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -601,15 +601,13 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
{
- static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::getInstance()->mSettingGroups["config"],"DragAndDropDistanceThreshold", 3);
-
mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
if( hasMouseCapture() && isMovable() )
{
LLFolderView* root = getRoot();
- if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > drag_and_drop_threshold() * drag_and_drop_threshold()
+ if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > DRAG_N_DROP_DISTANCE_THRESHOLD * DRAG_N_DROP_DISTANCE_THRESHOLD
&& root->getAllowDrag()
&& root->getCurSelectedItem()
&& root->startDrag())
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index f217b743a0..96aca62927 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -48,8 +48,8 @@ std::string LLFolderViewModelCommon::getStatusText(bool is_empty_folder)
void LLFolderViewModelCommon::filter()
{
- static LLCachedControl<S32> max_time(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10);
- getFilter().resetTime(llclamp(max_time(), 1, 100));
+ const S32 MAX_FILTER_TIME = 10;
+ getFilter().resetTime(MAX_FILTER_TIME);
mFolderView->getViewModelItem()->filter(getFilter());
}
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 551a60e097..0f11560790 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -170,7 +170,7 @@ public:
virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
- virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
+ virtual BOOL isItemRemovable( bool check_worn = true ) const = 0; // Can be destroyed
virtual BOOL removeItem() = 0;
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 60dbfd68c6..06ece90e30 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -95,6 +95,7 @@ LLLineEditor::Params::Params()
commit_on_focus_lost("commit_on_focus_lost", true),
ignore_tab("ignore_tab", true),
is_password("is_password", false),
+ allow_emoji("allow_emoji"),
cursor_color("cursor_color"),
use_bg_color("use_bg_color", false),
bg_color("bg_color"),
@@ -141,6 +142,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mIgnoreArrowKeys( FALSE ),
mIgnoreTab( p.ignore_tab ),
mDrawAsterixes( p.is_password ),
+ mAllowEmoji( p.allow_emoji ),
mSpellCheck( p.spellcheck ),
mSpellCheckStart(-1),
mSpellCheckEnd(-1),
@@ -414,8 +416,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit
all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived);
std::string truncated_utf8 = new_text;
+ if (!mAllowEmoji)
+ {
+ // Cut emoji symbols if exist
+ utf8str_remove_emojis(truncated_utf8);
+ }
if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes)
- {
+ {
truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes);
}
mText.assign(truncated_utf8);
@@ -587,13 +594,21 @@ void LLLineEditor::replaceWithSuggestion(U32 index)
{
if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
{
+ LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
+ if (!mAllowEmoji)
+ {
+ // Cut emoji symbols if exist
+ wstring_remove_emojis(suggestion);
+ }
+ if (suggestion.empty())
+ return;
+
deselect();
// Delete the misspelled word
mText.erase(it->first, it->second - it->first);
// Insert the suggestion in its place
- LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
mText.insert(it->first, suggestion);
setCursor(it->first + (S32)suggestion.length());
@@ -956,9 +971,11 @@ void LLLineEditor::removeChar()
}
}
-
void LLLineEditor::addChar(const llwchar uni_char)
{
+ if (!mAllowEmoji && LLStringOps::isEmoji(uni_char))
+ return;
+
llwchar new_c = uni_char;
if (hasSelection())
{
@@ -1258,6 +1275,11 @@ void LLLineEditor::pasteHelper(bool is_primary)
if (!paste.empty())
{
+ if (!mAllowEmoji)
+ {
+ wstring_remove_emojis(paste);
+ }
+
if (!prevalidateInput(paste))
return;
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index f983828d2b..5b19e044cc 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -92,6 +92,7 @@ public:
ignore_tab,
bg_image_always_focused,
is_password,
+ allow_emoji,
use_bg_color;
// colors
@@ -238,6 +239,7 @@ public:
void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; }
void setIgnoreTab(BOOL b) { mIgnoreTab = b; }
void setPassDelete(BOOL b) { mPassDelete = b; }
+ void setAllowEmoji(BOOL b) { mAllowEmoji = b; }
void setDrawAsterixes(BOOL b);
// get the cursor position of the beginning/end of the prev/next word in the text
@@ -399,6 +401,7 @@ protected:
BOOL mShowImageFocused;
+ bool mAllowEmoji;
bool mUseBgColor;
LLWString mPreeditWString;
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index cebca70b59..10da3fb7e0 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -66,8 +66,8 @@
LLMenuHolderGL *LLMenuGL::sMenuContainer = NULL;
view_listener_t::listener_map_t view_listener_t::sListeners;
-S32 MENU_BAR_HEIGHT = 0;
-S32 MENU_BAR_WIDTH = 0;
+S32 MENU_BAR_HEIGHT = 18;
+S32 MENU_BAR_WIDTH = 410;
///============================================================================
/// Local function declarations, constants, enums, and typedefs
@@ -3229,10 +3229,9 @@ void LLMenuGL::draw( void )
}
if (mDropShadowed && !mTornOff)
{
- static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
- color_drop_shadow, drop_shadow_floater );
+ color_drop_shadow, DROP_SHADOW_FLOATER);
}
if( mBgVisible )
diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp
index 3e5978eb59..22d98469ec 100644
--- a/indra/llui/llmodaldialog.cpp
+++ b/indra/llui/llmodaldialog.cpp
@@ -284,10 +284,9 @@ BOOL LLModalDialog::handleKeyHere(KEY key, MASK mask )
void LLModalDialog::draw()
{
static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow");
- static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 0);
gl_drop_shadow( 0, getRect().getHeight(), getRect().getWidth(), 0,
- shadow_color, shadow_lines);
+ shadow_color, DROP_SHADOW_FLOATER);
LLFloater::draw();
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index d736aa6634..25062f2cad 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -88,6 +88,7 @@ LLNotificationForm::FormInput::FormInput()
: type("type"),
text("text"),
max_length_chars("max_length_chars"),
+ allow_emoji("allow_emoji"),
width("width", 0),
value("value")
{}
@@ -1553,6 +1554,7 @@ bool LLNotifications::loadTemplates()
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1563,6 +1565,7 @@ bool LLNotifications::loadTemplates()
if(!params.validateBlock())
{
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1629,6 +1632,7 @@ bool LLNotifications::loadVisibilityRules()
if(!params.validateBlock())
{
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL;
return false;
}
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 921398a693..0729c00946 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -201,6 +201,7 @@ public:
Mandatory<std::string> type;
Optional<S32> width;
Optional<S32> max_length_chars;
+ Optional<bool> allow_emoji;
Optional<std::string> text;
Optional<std::string> value;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index cb36f72f6e..be40a5bb4f 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -225,7 +225,8 @@ LLTabContainer::Params::Params()
tabs_flashing_color("tabs_flashing_color"),
tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0),
use_ellipses("use_ellipses"),
- font_halign("halign")
+ font_halign("halign"),
+ use_tab_offset("use_tab_offset", false)
{}
LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
@@ -264,7 +265,8 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
mTabIconCtrlPad(p.tab_icon_ctrl_pad),
mEnableTabsFlashing(p.enable_tabs_flashing),
mTabsFlashingColor(p.tabs_flashing_color),
- mUseTabEllipses(p.use_ellipses)
+ mUseTabEllipses(p.use_ellipses),
+ mUseTabOffset(p.use_tab_offset)
{
static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0);
@@ -1023,11 +1025,10 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)
}
else
{
- tab_panel_rect = LLRect(LLPANEL_BORDER_WIDTH * 3,
- tab_panel_top,
- getRect().getWidth() - LLPANEL_BORDER_WIDTH * 2,
- tab_panel_bottom );
- }
+ S32 left_offset = mUseTabOffset ? LLPANEL_BORDER_WIDTH * 3 : LLPANEL_BORDER_WIDTH;
+ S32 right_offset = mUseTabOffset ? LLPANEL_BORDER_WIDTH * 2 : LLPANEL_BORDER_WIDTH;
+ tab_panel_rect = LLRect(left_offset, tab_panel_top, getRect().getWidth() - right_offset, tab_panel_bottom);
+ }
child->setFollowsAll();
child->translate( tab_panel_rect.mLeft - child->getRect().mLeft, tab_panel_rect.mBottom - child->getRect().mBottom);
child->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE );
@@ -1516,25 +1517,23 @@ BOOL LLTabContainer::selectTab(S32 which)
LLTabTuple* selected_tuple = getTab(which);
if (!selected_tuple)
- {
return FALSE;
- }
-
+
LLSD cbdata;
if (selected_tuple->mTabPanel)
cbdata = selected_tuple->mTabPanel->getName();
- BOOL res = FALSE;
- if( !mValidateSignal || (*mValidateSignal)( this, cbdata ) )
+ BOOL result = FALSE;
+ if (!mValidateSignal || (*mValidateSignal)(this, cbdata))
{
- res = setTab(which);
- if (res && mCommitSignal)
+ result = setTab(which);
+ if (result && mCommitSignal)
{
(*mCommitSignal)(this, cbdata);
}
}
-
- return res;
+
+ return result;
}
// private
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index aa4a08c4ff..7d6fd15927 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -121,6 +121,8 @@ public:
*/
Optional<S32> tab_icon_ctrl_pad;
+ Optional<bool> use_tab_offset;
+
Params();
};
@@ -321,6 +323,8 @@ private:
S32 mTabIconCtrlPad;
bool mUseTabEllipses;
LLFrameTimer mMouseDownTimer;
+
+ bool mUseTabOffset;
};
#endif // LL_TABCONTAINER_H
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 3d2a426913..513cc56a02 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2600,6 +2600,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length )
char* text = new char[ text_len + 1];
if (text == NULL)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "Memory allocation failure." << LL_ENDL;
return FALSE;
}
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 2707f7a15c..58ecf3e603 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -1134,8 +1134,7 @@ BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
BOOL handled = FALSE;
S32 mouse_distance_squared = (x - mMouseDownX) * (x - mMouseDownX) + (y - mMouseDownY) * (y - mMouseDownY);
- static LLCachedControl<S32> drag_threshold(*LLUI::getInstance()->mSettingGroups["config"], "DragAndDropDistanceThreshold", 3);
- if (mouse_distance_squared > drag_threshold * drag_threshold
+ if (mouse_distance_squared > DRAG_N_DROP_DISTANCE_THRESHOLD * DRAG_N_DROP_DISTANCE_THRESHOLD
&& hasMouseCapture() &&
mStartDragItemCallback && mHandleDragItemCallback)
{
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 5da722a72b..06760c4196 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -44,8 +44,13 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
if (!success)
{
- gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
- LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ //gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
+ const std::string error_string =
+ "Second Life viewer couldn't access some of the files it needs and will be closed."
+ "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
+ "contact https://support.secondlife.com if issue persists after reinstall.";
+ LLError::LLUserWarningMsg::show(error_string);
+ LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL;
return false;
}
@@ -60,6 +65,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename)
if (!success)
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Couldn't load localization table " << xml_filename << LL_ENDL;
return false;
}
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 86b23c8c93..34a82387cd 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -53,7 +53,7 @@ class LLWindow;
class LLView;
class LLHelp;
-
+const S32 DRAG_N_DROP_DISTANCE_THRESHOLD = 3;
// this enum is used by the llview.h (viewer) and the llassetstorage.h (viewer and sim)
enum EDragAndDropType
{
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index be1c7dd0b6..ef295976a2 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -41,6 +41,7 @@
const BOOL TAKE_FOCUS_YES = TRUE;
const BOOL TAKE_FOCUS_NO = FALSE;
+const S32 DROP_SHADOW_FLOATER = 5;
class LLUICtrl
: public LLView, public boost::signals2::trackable
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index f435d46584..279e269f43 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -199,7 +199,13 @@ public:
// windows only DirectInput8 for joysticks
virtual void* getDirectInput8() { return NULL; };
- virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
+ virtual bool getInputDevices(U32 device_type_filter,
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata)
+ {
+ return false;
+ };
virtual S32 getRefreshRate() { return mRefreshRate; }
protected:
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 690fe058db..2e75d309ea 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -27,6 +27,7 @@
#include <AppKit/AppKit.h>
#include <Cocoa/Cocoa.h>
+#include <errno.h>
#include "llopenglview-objc.h"
#include "llwindowmacosx-objc.h"
#include "llappdelegate-objc.h"
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 778e5d3898..41665419aa 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -43,6 +43,13 @@
#include <CoreServices/CoreServices.h>
#include <CoreGraphics/CGDisplayConfiguration.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/hid/IOHIDUsageTables.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/usb/IOUSBLib.h>
+
extern BOOL gDebugWindowProc;
BOOL gHiDPISupport = TRUE;
@@ -212,13 +219,16 @@ bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask)
bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask, wchar_t character)
{
- if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y'))
- {
- key = gKeyboard->inverseTranslateKey('Y');
- }
- else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z'))
+ //if (mask!=MASK_NONE)
{
- key = gKeyboard->inverseTranslateKey('Z');
+ if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y'))
+ {
+ key = gKeyboard->inverseTranslateKey('Y');
+ }
+ else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z'))
+ {
+ key = gKeyboard->inverseTranslateKey('Z');
+ }
}
mRawKeyEvent = event;
@@ -1841,6 +1851,486 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
}
}
+// String should match ndof, so string mapping code was copied as is
+static char mapChar( char c )
+{
+ unsigned char uc = ( unsigned char ) c;
+
+ switch( uc )
+ {
+ case '/': return '-'; // use dash instead of slash
+
+ case 0x7F: return ' ';
+ case 0x80: return 'A';
+ case 0x81: return 'A';
+ case 0x82: return 'C';
+ case 0x83: return 'E';
+ case 0x84: return 'N';
+ case 0x85: return 'O';
+ case 0x86: return 'U';
+ case 0x87: return 'a';
+ case 0x88: return 'a';
+ case 0x89: return 'a';
+ case 0x8A: return 'a';
+ case 0x8B: return 'a';
+ case 0x8C: return 'a';
+ case 0x8D: return 'c';
+ case 0x8E: return 'e';
+ case 0x8F: return 'e';
+ case 0x90: return ' ';
+ case 0x91: return ' '; // ? '
+ case 0x92: return ' '; // ? '
+ case 0x93: return ' '; // ? "
+ case 0x94: return ' '; // ? "
+ case 0x95: return ' ';
+ case 0x96: return ' ';
+ case 0x97: return ' ';
+ case 0x98: return ' ';
+ case 0x99: return ' ';
+ case 0x9A: return ' ';
+ case 0x9B: return 0x27;
+ case 0x9C: return 0x22;
+ case 0x9D: return ' ';
+ case 0x9E: return ' ';
+ case 0x9F: return ' ';
+ case 0xA0: return ' ';
+ case 0xA1: return ' ';
+ case 0xA2: return ' ';
+ case 0xA3: return ' ';
+ case 0xA4: return ' ';
+ case 0xA5: return ' ';
+ case 0xA6: return ' ';
+ case 0xA7: return ' ';
+ case 0xA8: return ' ';
+ case 0xA9: return ' ';
+ case 0xAA: return ' ';
+ case 0xAB: return ' ';
+ case 0xAC: return ' ';
+ case 0xAD: return ' ';
+ case 0xAE: return ' ';
+ case 0xAF: return ' ';
+ case 0xB0: return ' ';
+ case 0xB1: return ' ';
+ case 0xB2: return ' ';
+ case 0xB3: return ' ';
+ case 0xB4: return ' ';
+ case 0xB5: return ' ';
+ case 0xB6: return ' ';
+ case 0xB7: return ' ';
+ case 0xB8: return ' ';
+ case 0xB9: return ' ';
+ case 0xBA: return ' ';
+ case 0xBB: return ' ';
+ case 0xBC: return ' ';
+ case 0xBD: return ' ';
+ case 0xBE: return ' ';
+ case 0xBF: return ' ';
+ case 0xC0: return ' ';
+ case 0xC1: return ' ';
+ case 0xC2: return ' ';
+ case 0xC3: return ' ';
+ case 0xC4: return ' ';
+ case 0xC5: return ' ';
+ case 0xC6: return ' ';
+ case 0xC7: return ' ';
+ case 0xC8: return ' ';
+ case 0xC9: return ' ';
+ case 0xCA: return ' ';
+ case 0xCB: return 'A';
+ case 0xCC: return 'A';
+ case 0xCD: return 'O';
+ case 0xCE: return ' ';
+ case 0xCF: return ' ';
+ case 0xD0: return '-';
+ case 0xD1: return '-';
+ case 0xD2: return 0x22;
+ case 0xD3: return 0x22;
+ case 0xD4: return 0x27;
+ case 0xD5: return 0x27;
+ case 0xD6: return '-'; // use dash instead of slash
+ case 0xD7: return ' ';
+ case 0xD8: return 'y';
+ case 0xD9: return 'Y';
+ case 0xDA: return '-'; // use dash instead of slash
+ case 0xDB: return ' ';
+ case 0xDC: return '<';
+ case 0xDD: return '>';
+ case 0xDE: return ' ';
+ case 0xDF: return ' ';
+ case 0xE0: return ' ';
+ case 0xE1: return ' ';
+ case 0xE2: return ',';
+ case 0xE3: return ',';
+ case 0xE4: return ' ';
+ case 0xE5: return 'A';
+ case 0xE6: return 'E';
+ case 0xE7: return 'A';
+ case 0xE8: return 'E';
+ case 0xE9: return 'E';
+ case 0xEA: return 'I';
+ case 0xEB: return 'I';
+ case 0xEC: return 'I';
+ case 0xED: return 'I';
+ case 0xEE: return 'O';
+ case 0xEF: return 'O';
+ case 0xF0: return ' ';
+ case 0xF1: return 'O';
+ case 0xF2: return 'U';
+ case 0xF3: return 'U';
+ case 0xF4: return 'U';
+ case 0xF5: return '|';
+ case 0xF6: return ' ';
+ case 0xF7: return ' ';
+ case 0xF8: return ' ';
+ case 0xF9: return ' ';
+ case 0xFA: return '.';
+ case 0xFB: return ' ';
+ case 0xFC: return ' ';
+ case 0xFD: return 0x22;
+ case 0xFE: return ' ';
+ case 0xFF: return ' ';
+ }
+ return c;
+}
+
+// String should match ndof for manufacturer based search to work
+static void sanitizeString( char* inCStr )
+{
+ char* charIt = inCStr;
+ while ( *charIt )
+ {
+ *charIt = mapChar( *charIt );
+ charIt++;
+ }
+}
+
+struct HidDevice
+{
+ long mAxis;
+ long mLocalID;
+ char mProduct[256];
+ char mManufacturer[256];
+ long mUsage;
+ long mUsagePage;
+};
+
+static void populate_device_info( io_object_t io_obj_p, CFDictionaryRef device_dic, HidDevice* devicep )
+{
+ CFMutableDictionaryRef io_properties = nil;
+ io_registry_entry_t entry1;
+ io_registry_entry_t entry2;
+ kern_return_t rc;
+
+ // Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
+ // get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
+ // try to get parent1
+ rc = IORegistryEntryGetParentEntry( io_obj_p, kIOServicePlane, &entry1 );
+ if ( KERN_SUCCESS == rc )
+ {
+ rc = IORegistryEntryGetParentEntry( entry1, kIOServicePlane, &entry2 );
+
+ IOObjectRelease( entry1 );
+
+ if ( KERN_SUCCESS == rc )
+ {
+ rc = IORegistryEntryCreateCFProperties( entry2, &io_properties, kCFAllocatorDefault, kNilOptions );
+ // either way, release parent2
+ IOObjectRelease( entry2 );
+ }
+ }
+ if ( KERN_SUCCESS == rc )
+ {
+ // IORegistryEntryCreateCFProperties() succeeded
+ if ( io_properties != nil )
+ {
+ CFTypeRef dict_element = 0;
+ // get device info
+ // try hid dictionary first, if fail then go to usb dictionary
+
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR(kIOHIDProductKey) );
+ if ( !dict_element )
+ {
+ dict_element = CFDictionaryGetValue( io_properties, CFSTR( "USB Product Name" ) );
+ }
+ if ( dict_element )
+ {
+ bool res = CFStringGetCString((CFStringRef)dict_element, devicep->mProduct, 256, kCFStringEncodingUTF8);
+ sanitizeString(devicep->mProduct);
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mProduct" << LL_ENDL;
+ }
+ }
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDManufacturerKey ) );
+ if ( !dict_element )
+ {
+ dict_element = CFDictionaryGetValue( io_properties, CFSTR( "USB Vendor Name" ) );
+ }
+ if ( dict_element )
+ {
+ bool res = CFStringGetCString( (CFStringRef)dict_element, devicep->mManufacturer, 256, kCFStringEncodingUTF8 );
+ sanitizeString(devicep->mManufacturer);
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mManufacturer" << LL_ENDL;
+ }
+ }
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDLocationIDKey ) );
+ if ( !dict_element )
+ {
+ dict_element = CFDictionaryGetValue( io_properties, CFSTR( "locationID" ) );
+ }
+ if ( dict_element )
+ {
+ bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mLocalID );
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mLocalID" << LL_ENDL;
+ }
+ }
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDPrimaryUsagePageKey ) );
+ if ( dict_element )
+ {
+ bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mUsagePage );
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mUsagePage" << LL_ENDL;
+ }
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDPrimaryUsageKey ) );
+ if ( dict_element )
+ {
+ if ( !CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mUsage ) )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mUsage" << LL_ENDL;
+ }
+ }
+ }
+
+ //Add axis, because ndof lib checks sutability by axises as well as other elements
+ devicep->mAxis = 0;
+ CFTypeRef hid_elements = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDElementKey ) );
+ if ( hid_elements && CFGetTypeID( hid_elements ) == CFArrayGetTypeID( ) )
+ {
+ long count = CFArrayGetCount( (CFArrayRef) hid_elements );
+ for (int i = 0; i < count; ++i)
+ {
+ CFTypeRef element = CFArrayGetValueAtIndex((CFArrayRef) hid_elements, i);
+ if (element && CFGetTypeID( element ) == CFDictionaryGetTypeID( ))
+ {
+ long type = 0, usage_page = 0, usage = 0;
+
+ CFTypeRef ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementTypeKey ) );
+ if ( ref_value )
+ {
+ CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &type );
+ }
+
+ ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementUsagePageKey ) );
+ if ( ref_value )
+ {
+ CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &usage_page );
+ }
+
+ ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementUsageKey ) );
+ if ( ref_value )
+ {
+ CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &usage );
+ }
+ if ( type != 0
+ && type != kIOHIDElementTypeCollection
+ && usage_page == kHIDPage_GenericDesktop)
+ {
+ switch( usage )
+ {
+ case kHIDUsage_GD_X:
+ case kHIDUsage_GD_Y:
+ case kHIDUsage_GD_Z:
+ case kHIDUsage_GD_Rx:
+ case kHIDUsage_GD_Ry:
+ case kHIDUsage_GD_Rz:
+ devicep->mAxis++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ CFRelease(io_properties);
+ }
+ else
+ {
+ LL_WARNS("Joystick") << "Failed to populate fields" << LL_ENDL;
+ }
+ }
+}
+
+HidDevice populate_device( io_object_t io_obj )
+{
+ void* interfacep = nullptr;
+ HidDevice device;
+ memset( &device, 0, sizeof( HidDevice ) );
+ CFMutableDictionaryRef device_dic = 0;
+ kern_return_t result = IORegistryEntryCreateCFProperties( io_obj, &device_dic, kCFAllocatorDefault, kNilOptions );
+
+ if ( KERN_SUCCESS == result
+ && device_dic )
+ {
+ IOReturn io_result = kIOReturnSuccess;
+ HRESULT query_result = S_OK;
+ SInt32 the_score = 0;
+ IOCFPlugInInterface **the_interface = NULL;
+
+
+ io_result = IOCreatePlugInInterfaceForService( io_obj, kIOHIDDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID, &the_interface, &the_score );
+ if ( io_result == kIOReturnSuccess )
+ {
+ query_result = ( *the_interface )->QueryInterface( the_interface, CFUUIDGetUUIDBytes( kIOHIDDeviceInterfaceID ), ( LPVOID * ) & ( interfacep ) );
+ if ( query_result != S_OK )
+ {
+ LL_WARNS("Joystick") << "QueryInterface failed" << LL_ENDL;
+ }
+ IODestroyPlugInInterface( the_interface );
+ }
+ else
+ {
+ LL_WARNS("Joystick") << "IOCreatePlugInInterfaceForService failed" << LL_ENDL;
+ }
+
+ if ( interfacep )
+ {
+ result = ( *( IOHIDDeviceInterface** )interfacep )->open( interfacep, 0 );
+
+ if ( result != kIOReturnSuccess)
+ {
+ LL_WARNS("Joystick") << "open failed" << LL_ENDL;
+ }
+ }
+ // extract needed fields
+ populate_device_info( io_obj, device_dic, &device );
+
+ // Release interface
+ if ( interfacep )
+ {
+ ( *( IOHIDDeviceInterface** ) interfacep )->close( interfacep );
+
+ ( *( IOHIDDeviceInterface** ) interfacep )->Release( interfacep );
+
+ interfacep = NULL;
+ }
+
+ CFRelease( device_dic );
+ }
+ else
+ {
+ LL_WARNS("Joystick") << "populate_device failed" << LL_ENDL;
+ }
+
+ return device;
+}
+
+static void get_devices(std::list<HidDevice> &list_of_devices,
+ io_iterator_t inIODeviceIterator)
+{
+ IOReturn result = kIOReturnSuccess; // assume success( optimist! )
+ io_object_t io_obj = 0;
+
+ while ( 0 != (io_obj = IOIteratorNext( inIODeviceIterator ) ) )
+ {
+ HidDevice device = populate_device( io_obj );
+
+ // Should match ndof
+ if (device.mAxis >= 3
+ || (device.mUsagePage == kHIDPage_GenericDesktop
+ && (device.mUsage == kHIDUsage_GD_MultiAxisController
+ || device.mUsage == kHIDUsage_GD_GamePad
+ || device.mUsage == kHIDUsage_GD_Joystick))
+ || (device.mUsagePage == kHIDPage_Game
+ && device.mUsage == kHIDUsage_Game_3DGameController)
+ || strstr(device.mManufacturer, "3Dconnexion"))
+ {
+ list_of_devices.push_back(device);
+ }
+ else
+ {
+ LL_DEBUGS("Joystick");
+ list_of_devices.push_back(device);
+ LL_CONT << "Device axes: " << (S32)device.mAxis
+ << " Device HIDUsepage: " << (S32)device.mUsagePage
+ << " Device HIDUsage: " << (S32)device.mUsage;
+ LL_ENDL;
+ }
+
+
+ // release the device object, it is no longer needed
+ result = IOObjectRelease( io_obj );
+ if ( KERN_SUCCESS != result )
+ {
+ LL_WARNS("Joystick") << "IOObjectRelease failed" << LL_ENDL;
+ }
+ }
+}
+
+bool LLWindowMacOSX::getInputDevices(U32 device_type_filter,
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata)
+{
+ bool return_value = false;
+ CFMutableDictionaryRef device_dict_ref;
+ IOReturn result = kIOReturnSuccess; // assume success( optimist! )
+
+ // Set up matching dictionary to search the I/O Registry for HID devices we are interested in. Dictionary reference is NULL if error.
+
+ // A dictionary to match devices to?
+ device_dict_ref = IOServiceMatching( kIOHIDDeviceKey );
+
+ // BUG FIX! one reference is consumed by IOServiceGetMatchingServices
+ CFRetain( device_dict_ref );
+ io_iterator_t io_iter = 0;
+
+ // create an IO object iterator
+ result = IOServiceGetMatchingServices( kIOMasterPortDefault, device_dict_ref, &io_iter );
+ if ( kIOReturnSuccess != result )
+ {
+ LL_WARNS("Joystick") << "IOServiceGetMatchingServices failed" << LL_ENDL;
+ }
+
+ if ( io_iter )
+ {
+ // add all existing devices
+ std::list<HidDevice> device_list;
+
+ get_devices(device_list, io_iter);
+
+ std::list<HidDevice>::iterator iter;
+
+ for (iter = device_list.begin(); iter != device_list.end(); ++iter)
+ {
+ std::string label(iter->mProduct);
+ LLSD data;
+ data["manufacturer"] = std::string(iter->mManufacturer);
+ data["product"] = label;
+
+ if (osx_callback(label, data, userdata))
+ {
+ break; //found device
+ }
+ }
+ return_value = true;
+ }
+
+ CFRelease( device_dict_ref );
+ return return_value;
+}
+
LLSD LLWindowMacOSX::getNativeKeyData()
{
LLSD result = LLSD::emptyMap();
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 7614167213..d577d90c1c 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -115,6 +115,11 @@ public:
void interruptLanguageTextInput() override;
void spawnWebBrowser(const std::string& escaped_url, bool async) override;
F32 getSystemUISize() override;
+
+ bool getInputDevices(U32 device_type_filter,
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata) override;
static std::vector<std::string> getDisplaysResolutionList();
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 057d7a700e..99a11f772b 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -4490,7 +4490,10 @@ void* LLWindowWin32::getDirectInput8()
return &gDirectInput8;
}
-bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata)
+bool LLWindowWin32::getInputDevices(U32 device_type_filter,
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback,
+ void * di8_devices_callback,
+ void* userdata)
{
if (gDirectInput8 != NULL)
{
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index ff287a140e..79bc4ad797 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -131,7 +131,10 @@ public:
static void setDPIAwareness();
/*virtual*/ void* getDirectInput8();
- /*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata);
+ /*virtual*/ bool getInputDevices(U32 device_type_filter,
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata);
U32 getRawWParam() { return mRawWParam; }
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 2960ecf829..27e17ec4bb 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -1497,8 +1497,6 @@ DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"];
DECL_LLCC(LLSD, test_llsd);
-static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment");
-
void test_cached_control()
{
#define TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL
@@ -1515,8 +1513,6 @@ void test_cached_control()
TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd);
-
- if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL;
}
#endif // TEST_CACHED_CONTROL
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 455df13e48..43d4adbc26 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -837,7 +837,7 @@ bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root,
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Problem reading UI description file: " << filename << LL_ENDL;
+ LL_WARNS() << "Problem reading UI description file: " << filename << " " << errno << LL_ENDL;
return false;
}
diff --git a/indra/newview/app_settings/camera/Front.xml b/indra/newview/app_settings/camera/Front.xml
index 39f44e11a8..f96d3bc779 100644
--- a/indra/newview/app_settings/camera/Front.xml
+++ b/indra/newview/app_settings/camera/Front.xml
@@ -1,16 +1,5 @@
<llsd>
<map>
- <key>AppearanceCameraMovement</key>
- <map>
- <key>Comment</key>
- <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AvatarSitRotation</key>
<map>
<key>Comment</key>
@@ -90,17 +79,6 @@
<key>Value</key>
<real>0.90322577953338623</real>
</map>
- <key>EditCameraMovement</key>
- <map>
- <key>Comment</key>
- <string>When entering build mode, camera moves up above avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FocusOffsetRearView</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/camera/Rear.xml b/indra/newview/app_settings/camera/Rear.xml
index 8dc36353ce..7eda566e48 100644
--- a/indra/newview/app_settings/camera/Rear.xml
+++ b/indra/newview/app_settings/camera/Rear.xml
@@ -1,16 +1,5 @@
<llsd>
<map>
- <key>AppearanceCameraMovement</key>
- <map>
- <key>Comment</key>
- <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AvatarSitRotation</key>
<map>
<key>Comment</key>
@@ -90,17 +79,6 @@
<key>Value</key>
<real>0.90322577953338623</real>
</map>
- <key>EditCameraMovement</key>
- <map>
- <key>Comment</key>
- <string>When entering build mode, camera moves up above avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FocusOffsetRearView</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/camera/Side.xml b/indra/newview/app_settings/camera/Side.xml
index 089ab93a8f..77f73f1df1 100644
--- a/indra/newview/app_settings/camera/Side.xml
+++ b/indra/newview/app_settings/camera/Side.xml
@@ -1,16 +1,5 @@
<llsd>
<map>
- <key>AppearanceCameraMovement</key>
- <map>
- <key>Comment</key>
- <string>When entering appearance editing mode, camera zooms in on currently selected portion of avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AvatarSitRotation</key>
<map>
<key>Comment</key>
@@ -90,17 +79,6 @@
<key>Value</key>
<real>0.90322577953338623</real>
</map>
- <key>EditCameraMovement</key>
- <map>
- <key>Comment</key>
- <string>When entering build mode, camera moves up above avatar</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FocusOffsetRearView</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 00b59f9a4d..b9779e183d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -137,17 +137,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AdvanceOutfitSnapshot</key>
- <map>
- <key>Comment</key>
- <string>Display advanced parameter settings in outfit snaphot interface</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AgentPause</key>
<map>
<key>Comment</key>
@@ -214,17 +203,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AnimationDebug</key>
- <map>
- <key>Comment</key>
- <string>Show active animations in a bubble above avatars head</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>AppearanceCameraMovement</key>
<map>
<key>Comment</key>
@@ -269,17 +247,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AskedAboutCrashReports</key>
- <map>
- <key>Comment</key>
- <string>Turns off dialog asking if you want to enable crash reporting</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>AuctionShowFence</key>
<map>
<key>Comment</key>
@@ -302,17 +269,6 @@
<key>Value</key>
<real>0.5</real>
</map>
- <key>AudioLevelDoppler</key>
- <map>
- <key>Comment</key>
- <string>Scale of doppler effect on moving audio sources (1.0 = normal, &lt;1.0 = diminished doppler effect, &gt;1.0 = enhanced doppler effect)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.0</real>
- </map>
<key>AudioLevelMaster</key>
<map>
<key>Comment</key>
@@ -357,28 +313,6 @@
<key>Value</key>
<real>0.3</real>
</map>
- <key>AudioLevelRolloff</key>
- <map>
- <key>Comment</key>
- <string>Controls the distance-based dropoff of audio volume (fraction or multiple of default audio rolloff)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.0</real>
- </map>
- <key>AudioLevelUnderwaterRolloff</key>
- <map>
- <key>Comment</key>
- <string>Controls the distance-based dropoff of audio volume underwater(fraction or multiple of default audio rolloff)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>5.0</real>
- </map>
<key>AudioLevelSFX</key>
<map>
<key>Comment</key>
@@ -412,17 +346,6 @@
<key>Value</key>
<real>0.5</real>
</map>
- <key>AudioLevelWind</key>
- <map>
- <key>Comment</key>
- <string>Audio level of wind noise when standing still</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.5</real>
- </map>
<key>AudioStreamingMedia</key>
<map>
<key>Comment</key>
@@ -456,7 +379,7 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AutoAcceptNewInventory</key>
+ <key>AutoAcceptNewInventory</key>
<map>
<key>Comment</key>
<string>Automatically accept new notecards/textures/landmarks</string>
@@ -478,17 +401,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>AutoLoadWebProfiles</key>
- <map>
- <key>Comment</key>
- <string>Automatically load ALL profile webpages without asking first.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>AutoLogin</key>
<map>
<key>Comment</key>
@@ -687,17 +599,6 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>AvatarBacklight</key>
- <map>
- <key>Comment</key>
- <string>Add rim lighting to avatar rendering to approximate shininess of skin</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AvatarFeathering</key>
<map>
<key>Comment</key>
@@ -709,32 +610,6 @@
<key>Value</key>
<real>16.0</real>
</map>
- <key>AvatarPickerSortOrder</key>
- <map>
- <key>Comment</key>
- <string>Specifies sort key for textures in avatar picker (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>2</integer>
- </map>
- <key>AvatarPosFinalOffset</key>
- <map>
- <key>Comment</key>
- <string>After-everything-else fixup for avatar position.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.0</real>
- <real>0.0</real>
- </array>
- </map>
<key>AvatarPickerURL</key>
<map>
<key>Comment</key>
@@ -746,50 +621,6 @@
<key>Value</key>
<string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/avatars.html</string>
</map>
- <key>AvatarRotateThresholdSlow</key>
- <map>
- <key>Comment</key>
- <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving slowly (degrees)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <integer>60</integer>
- </map>
- <key>AvatarRotateThresholdFast</key>
- <map>
- <key>Comment</key>
- <string>Angle between avatar facing and camera facing at which avatar turns to face same direction as camera, when moving fast (degrees)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <integer>2</integer>
- </map>
- <key>AvatarBakedTextureUploadTimeout</key>
- <map>
- <key>Comment</key>
- <string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance. Set to 0 to disable and wait until all baked textures are at highest resolution.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>60</integer>
- </map>
- <key>AvatarBakedLocalTextureUpdateTimeout</key>
- <map>
- <key>Comment</key>
- <string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>10</integer>
- </map>
<key>AvatarPhysics</key>
<map>
<key>Comment</key>
@@ -823,28 +654,6 @@
<key>Value</key>
<integer>40</integer>
</map>
- <key>BottomPanelNew</key>
- <map>
- <key>Comment</key>
- <string>Enable the new bottom panel</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>BrowserHomePage</key>
- <map>
- <key>Comment</key>
- <string>[NOT USED]</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>http://www.secondlife.com</string>
- </map>
<key>BrowserIgnoreSSLCertErrors</key>
<map>
<key>Comment</key>
@@ -878,17 +687,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>BlockSomeAvatarAppearanceVisualParams</key>
- <map>
- <key>Comment</key>
- <string>Drop around 50% of VisualParam occurances in appearance messages (for simulating Ruth)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>BrowserProxyAddress</key>
<map>
<key>Comment</key>
@@ -911,17 +709,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>BrowserProxyExclusions</key>
- <map>
- <key>Comment</key>
- <string>[NOT USED]</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string />
- </map>
<key>BrowserProxyPort</key>
<map>
<key>Comment</key>
@@ -933,17 +720,6 @@
<key>Value</key>
<integer>3128</integer>
</map>
- <key>BrowserProxySocks45</key>
- <map>
- <key>Comment</key>
- <string>[NOT USED]</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>5</integer>
- </map>
<key>Socks5ProxyEnabled</key>
<map>
<key>Comment</key>
@@ -1329,39 +1105,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ButtonHPad</key>
- <map>
- <key>Comment</key>
- <string>Default horizontal spacing between buttons (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>4</integer>
- </map>
- <key>ButtonHeight</key>
- <map>
- <key>Comment</key>
- <string>Default height for normal buttons (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>23</integer>
- </map>
- <key>ButtonHeightSmall</key>
- <map>
- <key>Comment</key>
- <string>Default height for small buttons (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>23</integer>
- </map>
<key>EnableDiskCacheDebugInfo</key>
<map>
<key>Comment</key>
@@ -1417,17 +1160,6 @@
<key>Value</key>
<string />
</map>
- <key>CacheNumberOfRegionsForObjects</key>
- <map>
- <key>Comment</key>
- <string>Controls number of regions to be cached for objects.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>128</integer>
- </map>
<key>CacheSize</key>
<map>
<key>Comment</key>
@@ -1513,51 +1245,6 @@
<real>0.75</real>
</array>
</map>
- <key>CameraOffsetFrontView</key>
- <map>
- <key>Comment</key>
- <string>Initial camera offset from avatar in Front View</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
- <key>Value</key>
- <array>
- <real>2.2</real>
- <real>0.0</real>
- <real>0.0</real>
- </array>
- </map>
- <key>CameraOffsetGroupView</key>
- <map>
- <key>Comment</key>
- <string>Initial camera offset from avatar in Group View</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
- <key>Value</key>
- <array>
- <real>-1.0</real>
- <real>0.7</real>
- <real>0.5</real>
- </array>
- </map>
- <key>CameraOffsetCustomPreset</key>
- <map>
- <key>Comment</key>
- <string>Initial camera offset from avatar for the custom camera preset</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
- <key>Value</key>
- <array>
- <real>-3.0</real>
- <real>0.0</real>
- <real>0.75</real>
- </array>
- </map>
<key>CameraOffsetScale</key>
<map>
<key>Comment</key>
@@ -1712,17 +1399,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ChatBarStealsFocus</key>
- <map>
- <key>Comment</key>
- <string>Whenever keyboard focus is removed from the UI, and the chat bar is visible, the chat bar takes focus</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>LetterKeysFocusChatBar</key>
<map>
<key>Comment</key>
@@ -1767,17 +1443,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ChatHistoryTornOff</key>
- <map>
- <key>Comment</key>
- <string>Show chat history window separately from Communicate window.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ChatLoadGroupMaxMembers</key>
<map>
<key>Comment</key>
@@ -1789,17 +1454,6 @@
<key>Value</key>
<integer>100</integer>
</map>
- <key>ChatLoadGroupTimeout</key>
- <map>
- <key>Comment</key>
- <string>Time we give the server to send group participants before we hit the server for group info (seconds)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>10.0</real>
- </map>
<key>ChatOnlineNotification</key>
<map>
<key>Comment</key>
@@ -1811,28 +1465,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ChatPersistTime</key>
- <map>
- <key>Comment</key>
- <string>Time for which chat stays visible in console (seconds)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>20.0</real>
- </map>
- <key>ChatShowTimestamps</key>
- <map>
- <key>Comment</key>
- <string>Show timestamps in chat</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>CheesyBeacon</key>
<map>
<key>Comment</key>
@@ -1855,50 +1487,6 @@
<key>Value</key>
<string />
</map>
- <key>ContextConeInAlpha</key>
- <map>
- <key>Comment</key>
- <string>Cone In Alpha</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.0</real>
- </map>
- <key>ContextConeOutAlpha</key>
- <map>
- <key>Comment</key>
- <string>Cone Out Alpha</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.0</real>
- </map>
- <key>ContextConeFadeTime</key>
- <map>
- <key>Comment</key>
- <string>Cone Fade Time</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>.08</real>
- </map>
- <key>ConversationHistoryPageSize</key>
- <map>
- <key>Comment</key>
- <string>Chat history of conversation opened from call log is displayed by pages. So this is number of entries per page.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>100</integer>
- </map>
<key>ConversationSortOrder</key>
<map>
<key>Comment</key>
@@ -2077,17 +1665,6 @@
<key>Value</key>
<integer>40</integer>
</map>
- <key>ContactsTornOff</key>
- <map>
- <key>Comment</key>
- <string>Show contacts window separately from Communicate window.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>CookiesEnabled</key>
<map>
<key>Comment</key>
@@ -2132,17 +1709,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ChatBarCustomWidth</key>
- <map>
- <key>Comment</key>
- <string>Stores customized width of chat bar.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>CoroutineStackSize</key>
<map>
<key>Comment</key>
@@ -2209,17 +1775,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>CurlMaximumNumberOfHandles</key>
- <map>
- <key>Comment</key>
- <string>Maximum number of handles curl can use (requires restart)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>256</integer>
- </map>
<key>CurlRequestTimeOut</key>
<map>
<key>Comment</key>
@@ -2231,17 +1786,6 @@
<key>Value</key>
<real>120.0</real>
</map>
- <key>CurlUseMultipleThreads</key>
- <map>
- <key>Comment</key>
- <string>Use background threads for executing curl_multi_perform (requires restart)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>Cursor3D</key>
<map>
<key>Comment</key>
@@ -2264,17 +1808,6 @@
<key>Value</key>
<string></string>
</map>
- <key>CustomServer</key>
- <map>
- <key>Comment</key>
- <string>Specifies IP address or hostname of grid to which you connect</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string />
- </map>
<key>DebugAnimatedObjects</key>
<map>
<key>Comment</key>
@@ -2297,17 +1830,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AnimatedObjectsIgnoreLimits</key>
- <map>
- <key>Comment</key>
- <string>Ignore server-enforced limits on animated objects. This is only useful for server testing.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>AnimatedObjectsAllowLeftClick</key>
<map>
<key>Comment</key>
@@ -2319,17 +1841,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AnimatedObjectsGlobalScale</key>
- <map>
- <key>Comment</key>
- <string>Temporary testing: allow an extra scale factor to be forced on animated objects.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.00</real>
- </map>
<key>AnimatedObjectsMaxLegalOffset</key>
<map>
<key>Comment</key>
@@ -2352,17 +1863,6 @@
<key>Value</key>
<real>64.0</real>
</map>
- <key>AvatarBoundingBoxComplexity</key>
- <map>
- <key>Comment</key>
- <string>How many aspects to consider for avatar bounding box</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>3</integer>
- </map>
<key>DebugAvatarAppearanceMessage</key>
<map>
<key>Comment</key>
@@ -2473,17 +1973,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>DebugInventoryFilters</key>
- <map>
- <key>Comment</key>
- <string>Turn on debugging display for inventory filtering</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>DebugPermissions</key>
<map>
<key>Comment</key>
@@ -2550,18 +2039,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DebugShowPrivateMem</key>
- <!-- deprecated (see MAINT-8091) -->
- <map>
- <key>Comment</key>
- <string>(Deprecated) Show Private Mem Info</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>DebugShowRenderInfo</key>
<map>
<key>Comment</key>
@@ -2628,435 +2105,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DebugSlshareLogTag</key>
- <map>
- <key>Comment</key>
- <string>Request slshare-service debug logging</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string/>
- </map>
- <key>DebugStatModeFPS</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeBandwidth</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModePacketLoss</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatMode</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeKTrisDrawnFr</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeKTrisDrawnSec</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeTotalObjs</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeNewObjs</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeTextureCount</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeRawCount</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeGLMem</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeFormattedMem</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeRawMem</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeBoundMem</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModePacketsIn</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModePacketsOut</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeObjects</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeTexture</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeAsset</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeLayers</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeActualIn</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeActualOut</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeTimeDialation</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimFPS</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModePhysicsFPS</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModePinnedObjects</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeLowLODObjects</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeMemoryAllocated</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeAgentUpdatesSec</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeMainAgents</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeChildAgents</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimObjects</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimActiveObjects</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimActiveScripts</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimScriptEvents</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimInPPS</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimOutPPS</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
- <key>DebugStatModeSimPendingDownloads</key>
- <map>
- <key>Comment</key>
- <string>Mode of stat in Statistics floater</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>-1</integer>
- </map>
<key>SimPendingUploads</key>
<map>
<key>Comment</key>
@@ -3244,17 +2292,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>DefaultBlankNormalTexture</key>
- <map>
- <key>Comment</key>
- <string>Texture used as 'Blank' in texture picker for normal maps. (UUID texture reference)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>5b53359e-59dd-d8a2-04c3-9e65134da47a</string>
- </map>
<key>DefaultFemaleAvatar</key>
<map>
<key>Comment</key>
@@ -3288,28 +2325,6 @@
<key>Value</key>
<string>Male Shape &amp; Outfit</string>
</map>
- <key>DefaultObjectNormalTexture</key>
- <map>
- <key>Comment</key>
- <string>Texture used as 'Default' in texture picker for normal map. (UUID texture reference)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>85f28839-7a1c-b4e3-d71d-967792970a7b</string>
- </map>
- <key>DefaultObjectSpecularTexture</key>
- <map>
- <key>Comment</key>
- <string>Texture used as 'Default' in texture picker for specular map. (UUID texture reference)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>87e0e8f7-8729-1ea8-cfc9-8915773009db</string>
- </map>
<key>DefaultObjectTexture</key>
<map>
<key>Comment</key>
@@ -3321,17 +2336,6 @@
<key>Value</key>
<string>89556747-24cb-43ed-920b-47caed15465f</string>
</map>
- <key>DefaultUploadCost</key>
- <map>
- <key>Comment</key>
- <string>Default sound/image/file upload cost(in case economy data is not available).</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>10</integer>
- </map>
<key>DestinationGuideURL</key>
<map>
<key>Comment</key>
@@ -3431,94 +2435,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnableIMChatPopups</key>
- <map>
- <key>Comment</key>
- <string>Enable Incoming IM Chat Popups</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DisplayAvatarAgentTarget</key>
- <map>
- <key>Comment</key>
- <string>Show avatar positioning locators (animation debug)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>DisplayChat</key>
- <map>
- <key>Comment</key>
- <string>Display Latest Chat message on LCD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DisplayDebug</key>
- <map>
- <key>Comment</key>
- <string>Display Network Information on LCD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DisplayDebugConsole</key>
- <map>
- <key>Comment</key>
- <string>Display Console Debug Information on LCD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DisplayIM</key>
- <map>
- <key>Comment</key>
- <string>Display Latest IM message on LCD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DisplayLinden</key>
- <map>
- <key>Comment</key>
- <string>Display Account Information on LCD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>DisplayRegion</key>
- <map>
- <key>Comment</key>
- <string>Display Location information on LCD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>DisplayTimecode</key>
<map>
<key>Comment</key>
@@ -3552,28 +2468,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ClickActionBuyEnabled</key>
- <map>
- <key>Comment</key>
- <string>Enable click to buy actions in tool pie menu</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>ClickActionPayEnabled</key>
- <map>
- <key>Comment</key>
- <string>Enable click to pay actions in tool pie menu</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>DoubleClickAutoPilot</key>
<map>
<key>Comment</key>
@@ -3607,72 +2501,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>DragAndDropToolTipDelay</key>
- <map>
- <key>Comment</key>
- <string>Seconds before displaying tooltip when performing drag and drop operation</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.10000000149</real>
- </map>
- <key>DragAndDropDistanceThreshold</key>
- <map>
- <key>Comment</key>
- <string>Number of pixels that mouse should move before triggering drag and drop mode</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>3</integer>
- </map>
- <key>DropShadowButton</key>
- <map>
- <key>Comment</key>
- <string>Drop shadow width for buttons (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>2</integer>
- </map>
- <key>DropShadowFloater</key>
- <map>
- <key>Comment</key>
- <string>Drop shadow width for floaters (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>5</integer>
- </map>
- <key>DropShadowSlider</key>
- <map>
- <key>Comment</key>
- <string>Drop shadow width for sliders (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>3</integer>
- </map>
- <key>DropShadowTooltip</key>
- <map>
- <key>Comment</key>
- <string>Drop shadow width for tooltips (pixels)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>4</integer>
- </map>
<key>DynamicCameraStrength</key>
<map>
<key>Comment</key>
@@ -3706,17 +2534,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>IncludeEnhancedSkeleton</key>
- <map>
- <key>Comment</key>
- <string>Include extended skeleton joints when rendering skinned meshes.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>MinObjectsForUnlinkConfirm</key>
<map>
<key>Comment</key>
@@ -3816,39 +2633,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnergyFromTop</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>20</integer>
- </map>
- <key>EnergyHeight</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>40</integer>
- </map>
- <key>EnergyWidth</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>175</integer>
- </map>
<key>EventURL</key>
<map>
<key>Comment</key>
@@ -3860,61 +2644,6 @@
<key>Value</key>
<string>http://events.[GRID]/viewer/embed/event/[EVENT_ID]</string>
</map>
- <key>FastCacheFetchEnabled</key>
- <map>
- <key>Comment</key>
- <string>Enable texture fast cache fetching if set</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <string>1</string>
- </map>
- <key>FeatureManagerHTTPTable</key>
- <map>
- <key>Comment</key>
- <string>Deprecated</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string></string>
- </map>
- <key>FPSLogFrequency</key>
- <map>
- <key>Comment</key>
- <string>Seconds between display of FPS in log (0 for never)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>10.0</real>
- </map>
- <key>FilterItemsMaxTimePerFrameVisible</key>
- <map>
- <key>Comment</key>
- <string>Max time devoted to items filtering per frame for visible inventory listings (in milliseconds)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>10</integer>
- </map>
- <key>FilterItemsMaxTimePerFrameUnvisible</key>
- <map>
- <key>Comment</key>
- <string>Max time devoted to items filtering per frame for non visible inventory listings (in milliseconds)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>MainWorkTime</key>
<map>
<key>Comment</key>
@@ -3926,72 +2655,6 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>QueueInventoryFetchTimeout</key>
- <map>
- <key>Comment</key>
- <string>Max time llcompilequeue will wait for inventory fetch to complete (in seconds)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>300.0</real>
- </map>
- <key>FindLandArea</key>
- <map>
- <key>Comment</key>
- <string>Enables filtering of land search results by area</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>FindLandPrice</key>
- <map>
- <key>Comment</key>
- <string>Enables filtering of land search results by price</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FindLandType</key>
- <map>
- <key>Comment</key>
- <string>Controls which type of land you are searching for in Find Land interface ("All", "Auction", "For Sale")</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>All</string>
- </map>
- <key>FindPeopleOnline</key>
- <map>
- <key>Comment</key>
- <string>Limits people search to only users who are logged on</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>FindPlacesPictures</key>
- <map>
- <key>Comment</key>
- <string>Display only results of find places that have pictures</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>FirstName</key>
<map>
<key>Comment</key>
@@ -4383,17 +3046,6 @@
<key>Value</key>
<real>16.0</real>
</map>
- <key>FlycamZoomDirect</key>
- <map>
- <key>Comment</key>
- <string>Map flycam zoom axis directly to camera zoom.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FlyingAtExit</key>
<map>
<key>Comment</key>
@@ -4420,51 +3072,6 @@
<real>1.0</real>
</array>
</map>
- <key>FocusOffsetFrontView</key>
- <map>
- <key>Comment</key>
- <string>Initial focus point offset relative to avatar for the camera preset Front View</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3D</string>
- <key>Value</key>
- <array>
- <real>0.0</real>
- <real>0.0</real>
- <real>0.0</real>
- </array>
- </map>
- <key>FocusOffsetGroupView</key>
- <map>
- <key>Comment</key>
- <string>Initial focus point offset relative to avatar for the camera preset Group View</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3D</string>
- <key>Value</key>
- <array>
- <real>1.5</real>
- <real>0.7</real>
- <real>1.0</real>
- </array>
- </map>
- <key>FocusOffsetCustomPreset</key>
- <map>
- <key>Comment</key>
- <string>Initial focus point offset relative to avatar for the custom camera preset (x-axis is forward)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3D</string>
- <key>Value</key>
- <array>
- <real>1.0</real>
- <real>0.0</real>
- <real>1.0</real>
- </array>
- </map>
<key>AvatarSitRotation</key>
<map>
<key>Comment</key>
@@ -4507,17 +3114,6 @@
<key>Value</key>
<real>0.75</real>
</map>
- <key>FolderLoadingMessageWaitTime</key>
- <map>
- <key>Comment</key>
- <string>Seconds to wait before showing the LOADING... text in folder views</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.5</real>
- </map>
<key>FontScreenDPI</key>
<map>
<key>Comment</key>
@@ -4573,17 +3169,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ForceMandatoryUpdate</key>
- <map>
- <key>Comment</key>
- <string>For QA: On next startup, forces the auto-updater to run</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>FreezeTime</key>
<map>
<key>Comment</key>
@@ -4705,28 +3290,6 @@
<key>Value</key>
<integer>32</integer>
</map>
- <key>GroupNotifyBoxHeight</key>
- <map>
- <key>Comment</key>
- <string>Height of group notice messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>260</integer>
- </map>
- <key>GroupNotifyBoxWidth</key>
- <map>
- <key>Comment</key>
- <string>Width of group notice messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>305</integer>
- </map>
<key>HelpURLFormat</key>
<map>
<key>Comment</key>
@@ -4815,17 +3378,6 @@
<key>Value</key>
<string />
</map>
- <key>HtmlHelpLastPage</key>
- <map>
- <key>Comment</key>
- <string>Last URL visited via help system</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string />
- </map>
<key>HttpPipelining</key>
<map>
<key>Comment</key>
@@ -4848,17 +3400,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>IMShowTimestamps</key>
- <map>
- <key>Comment</key>
- <string>Show timestamps in IM</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>IMShowControlPanel</key>
<map>
<key>Comment</key>
@@ -4870,17 +3411,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>IMShowContentPanel</key>
- <map>
- <key>Comment</key>
- <string>Show Toolbar and Body Panels</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>IgnoreFOVZoomForLODs</key>
<map>
<key>Comment</key>
@@ -4947,28 +3477,6 @@
<key>Value</key>
<real>0.0</real>
</map>
- <key>InspectorFadeTime</key>
- <map>
- <key>Comment</key>
- <string>Fade out timing for inspectors</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.5</real>
- </map>
- <key>InspectorShowTime</key>
- <map>
- <key>Comment</key>
- <string>Stay timing for inspectors</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>3.0</real>
- </map>
<key>InstallLanguage</key>
<map>
<key>Comment</key>
@@ -5035,17 +3543,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>InventoryOutboxDisplayBoth</key>
- <map>
- <key>Comment</key>
- <string>(Deprecated) Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>InventoryOutboxLogging</key>
<map>
<key>Comment</key>
@@ -5295,7 +3792,7 @@
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>String</string>
+ <string>LLSD</string>
<key>Value</key>
<string />
</map>
@@ -5376,17 +3873,6 @@
<key>Value</key>
<real>2.0</real>
</map>
- <key>LCDDestination</key>
- <map>
- <key>Comment</key>
- <string>Which LCD to use</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>LeapCommand</key>
<map>
<key>Comment</key>
@@ -5597,105 +4083,6 @@
<string>0.0.0</string>
</map>
- <key>LastSnapshotToProfileHeight</key>
- <map>
- <key>Comment</key>
- <string>The height of the last profile snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>768</integer>
- </map>
- <key>LastSnapshotToEmailHeight</key>
- <map>
- <key>Comment</key>
- <string>The height of the last email snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>768</integer>
- </map>
- <key>LastSnapshotToProfileWidth</key>
- <map>
- <key>Comment</key>
- <string>The width of the last profile snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>1024</integer>
- </map>
- <key>LastSnapshotToEmailWidth</key>
- <map>
- <key>Comment</key>
- <string>The width of the last email snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>1024</integer>
- </map>
- <key>LastSnapshotToDiskHeight</key>
- <map>
- <key>Comment</key>
- <string>The height of the last disk snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>768</integer>
- </map>
- <key>LastSnapshotToDiskWidth</key>
- <map>
- <key>Comment</key>
- <string>The width of the last disk snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>1024</integer>
- </map>
- <key>LastSnapshotToInventoryHeight</key>
- <map>
- <key>Comment</key>
- <string>The height of the last texture snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>512</integer>
- </map>
- <key>LastSnapshotToInventoryWidth</key>
- <map>
- <key>Comment</key>
- <string>The width of the last texture snapshot, in px</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>512</integer>
- </map>
- <key>LeftClickShowMenu</key>
- <map>
- <key>Comment</key>
- <string>Unused obsolete setting</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>LimitDragDistance</key>
<map>
<key>Comment</key>
@@ -5862,17 +4249,6 @@
<key>Value</key>
<real>40.0</real>
</map>
- <key>LoginSRVPump</key>
- <map>
- <key>Comment</key>
- <string>(Deprecated) Name of the message pump that handles SRV request)</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>LLAres</string>
- </map>
<key>LogMessages</key>
<map>
<key>Comment</key>
@@ -5961,17 +4337,6 @@
<key>Value</key>
<real>60.0</real>
</map>
- <key>MapOverlayIndex</key>
- <map>
- <key>Comment</key>
- <string>Currently selected world map type</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>MapScale</key>
<map>
<key>Comment</key>
@@ -6711,28 +5076,6 @@
<key>Value</key>
<real>0.25</real>
</map>
- <key>MenuBarHeight</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>18</integer>
- </map>
- <key>MenuBarWidth</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>410</integer>
- </map>
<key>MePanelOpened</key>
<map>
<key>Comment</key>
@@ -7187,28 +5530,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>NotifyBoxHeight</key>
- <map>
- <key>Comment</key>
- <string>Height of notification messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>200</integer>
- </map>
- <key>NotifyBoxWidth</key>
- <map>
- <key>Comment</key>
- <string>Width of notification messages</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>305</integer>
- </map>
<key>NotificationConferenceIMOptions</key>
<map>
<key>Comment</key>
@@ -7386,17 +5707,6 @@
<key>Value</key>
<integer>90</integer>
</map>
- <key>ChannelBottomPanelMargin</key>
- <map>
- <key>Comment</key>
- <string>Space from a lower toast to the Bottom Tray</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>35</integer>
- </map>
<key>NotificationChannelRightMargin</key>
<map>
<key>Comment</key>
@@ -8075,17 +6385,6 @@
<key>Value</key>
<real>6.0</real>
</map>
- <key>ClothingLoadingDelay</key>
- <map>
- <key>Comment</key>
- <string>Time to wait for avatar appearance to resolve before showing world (seconds)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>10.0</real>
- </map>
<key>PreferredMaturity</key>
<map>
<key>Comment</key>
@@ -8528,17 +6827,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RadioLandBrushSize</key>
- <map>
- <key>Comment</key>
- <string>Size of land modification brush (0 = small, 1 = medium, 2 = large)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>LandBrushForce</key>
<map>
<key>Comment</key>
@@ -8550,17 +6838,6 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>MediaBrowserWindowLimit</key>
- <map>
- <key>Comment</key>
- <string>Maximum number of media brower windows that can be open at once in the media browser floater (0 for no limit)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>5</integer>
- </map>
<key>WebContentWindowLimit</key>
<map>
<key>Comment</key>
@@ -8839,17 +7116,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderAvatar</key>
- <map>
- <key>Comment</key>
- <string>Render Avatars</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>RenderAvatarCloth</key>
<map>
<key>Comment</key>
@@ -11576,17 +9842,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>SecondLifeEnterprise</key>
- <map>
- <key>Comment</key>
- <string>Enables Second Life Enterprise features</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>SelectMovableOnly</key>
<map>
<key>Comment</key>
@@ -11862,17 +10117,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowEmptyFoldersWhenSearching</key>
- <map>
- <key>Comment</key>
- <string>Shows folders that do not have any visible contents when applying a filter to inventory</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>ShowEventRecorderMenuItems</key>
<map>
<key>Comment</key>
@@ -12214,136 +10458,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ShowPGSearchAll</key>
- <map>
- <key>Comment</key>
- <string>Display results of search All that are flagged as general</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>ShowMatureSearchAll</key>
- <map>
- <key>Comment</key>
- <string>Display results of search All that are flagged as moderate</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowAdultSearchAll</key>
- <map>
- <key>Comment</key>
- <string>Display results of search All that are flagged as adult</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowPGGroups</key>
- <map>
- <key>Comment</key>
- <string>Display results of find groups that are flagged as general</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>ShowMatureGroups</key>
- <map>
- <key>Comment</key>
- <string>Display results of find groups that are flagged as moderate</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowAdultGroups</key>
- <map>
- <key>Comment</key>
- <string>Display results of find groups that are flagged as adult</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowPGClassifieds</key>
- <map>
- <key>Comment</key>
- <string>Display results of find classifieds that are flagged as general</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>ShowMatureClassifieds</key>
- <map>
- <key>Comment</key>
- <string>Display results of find classifieds that are flagged as moderate</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowAdultClassifieds</key>
- <map>
- <key>Comment</key>
- <string>Display results of find classifieds that are flagged as adult</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>ShowPGEvents</key>
- <map>
- <key>Comment</key>
- <string>Display results of find events that are flagged as general</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>HideFromEditor</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>ShowMatureEvents</key>
<map>
<key>Comment</key>
@@ -12580,17 +10694,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>ShowToolBar</key>
- <map>
- <key>Comment</key>
- <string>Show toolbar at bottom of screen</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>ShowTutorial</key>
<map>
<key>Comment</key>
@@ -13032,28 +11135,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>TexturePickerShowFolders</key>
- <map>
- <key>Comment</key>
- <string>Show folders with no texures in texture picker</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>TexturePickerSortOrder</key>
- <map>
- <key>Comment</key>
- <string>Specifies sort key for textures in texture picker (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>2</integer>
- </map>
<key>TextureReverseByteRange</key>
<map>
<key>Comment</key>
@@ -13103,17 +11184,6 @@
<key>Value</key>
<real>3000.0</real>
</map>
- <key>UpdaterMaximumBandwidth</key>
- <map>
- <key>Comment</key>
- <string>Obsolete: this parameter is no longer used.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>500.0</real>
- </map>
<key>ToolTipDelay</key>
<map>
<key>Comment</key>
@@ -13246,17 +11316,6 @@
<key>Value</key>
<string></string>
</map>
- <key>BingTranslateAPIKey</key>
- <map>
- <key>Comment</key>
- <string>(Deprecated) Bing AppID to use with the Microsoft Translator API</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string></string>
- </map>
<key>AzureTranslateAPIKey</key>
<map>
<key>Comment</key>
@@ -13323,28 +11382,6 @@
<key>Value</key>
<integer>6</integer>
</map>
- <key>UICheckboxctrlBtnSize</key>
- <map>
- <key>Comment</key>
- <string>UI Checkbox Control Button Size</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>13</integer>
- </map>
- <key>UICheckboxctrlHeight</key>
- <map>
- <key>Comment</key>
- <string>UI Checkbox Control Height</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>16</integer>
- </map>
<key>UICheckboxctrlHPad</key>
<map>
<key>Comment</key>
@@ -13576,61 +11613,6 @@
<key>Value</key>
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
</map>
- <key>StartUpChannelUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>B56AF90D-6684-48E4-B1E4-722D3DEB2CB6</string>
- </map>
- <key>NearByChatChannelUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>E1158BD6-661C-4981-9DAD-4DCBFF062502</string>
- </map>
- <key>NotificationChannelUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>AEED3193-8709-4693-8558-7452CCA97AE5</string>
- </map>
- <key>AlertChannelUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string>
- </map>
- <key>UIImgWhiteUUID</key>
- <map>
- <key>Comment</key>
- <string />
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>5748decc-f629-461c-9a36-a35a221fe21f</string>
- </map>
<key>UILineEditorCursorThickness</key>
<map>
<key>Comment</key>
@@ -13807,17 +11789,6 @@
<key>Value</key>
<real>1.0</real>
</map>
- <key>LastSystemUIScaleFactor</key>
- <map>
- <key>Comment</key>
- <string>OBSOLETE: System UI scale factor is now automatically and independently from UIScaleFactor applied</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.0</real>
- </map>
<key>UIScrollbarSize</key>
<map>
<key>Comment</key>
@@ -14137,17 +12108,6 @@
<key>Value</key>
<integer>16</integer>
</map>
- <key>UISpinctrlDefaultLabelWidth</key>
- <map>
- <key>Comment</key>
- <string>UI spin control default label width</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>10</integer>
- </map>
<key>UISpinctrlSpacing</key>
<map>
<key>Comment</key>
@@ -14269,39 +12229,6 @@
<key>Value</key>
<integer>3</integer>
</map>
- <key>UpdaterServiceCheckPeriod</key>
- <map>
- <key>Comment</key>
- <string>Obsolete; no longer used.</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>3600</integer>
- </map>
- <key>UpdaterServiceURL</key>
- <map>
- <key>Comment</key>
- <string>Obsolete; no longer used.</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>https://update.secondlife.com</string>
- </map>
- <key>UpdaterServicePath</key>
- <map>
- <key>Comment</key>
- <string>Obsolete: no longer used</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>update</string>
- </map>
<key>UpdaterWillingToTest</key>
<map>
<key>Comment</key>
@@ -14434,17 +12361,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>UseEnvironmentFromRegion</key>
- <map>
- <key>Comment</key>
- <string>Choose whether to use the region's environment settings, or override them with the local settings.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>EnvironmentPersistAcrossLogin</key>
<map>
<key>Comment</key>
@@ -14456,62 +12372,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>UseDayCycle</key>
- <map>
- <key>Comment</key>
- <string>Whether to use use a day cycle or a fixed sky.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>WaterPresetName</key>
- <map>
- <key>Comment</key>
- <string>Water preset to use. May be superseded by region settings.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>Default</string>
- </map>
- <key>SkyPresetName</key>
- <map>
- <key>Comment</key>
- <string>Sky preset to use. May be superseded by region settings or by a day cycle (see DayCycleName).</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>Default</string>
- </map>
- <key>DayCycleName</key>
- <map>
- <key>Comment</key>
- <string>Day cycle to use. May be superseded by region settings.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>Default</string>
- </map>
- <key>UseExternalBrowser</key>
- <!-- deprecated (see MAINT-4127) -->
- <map>
- <key>Comment</key>
- <string>(Deprecated) Use default browser when opening web pages instead of in-world browser.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <boolean>1</boolean>
- </map>
<key>PreferredBrowserBehavior</key>
<map>
<key>Comment</key>
@@ -14567,6 +12427,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderDelayVBUpdate</key>
+ <map>
+ <key>Comment</key>
+ <string>Delay vertex buffer updates until just before rendering</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>SocialPhotoResolution</key>
<map>
<key>Comment</key>
@@ -15372,17 +13243,6 @@
<key>Value</key>
<real>-1.0</real>
</map>
- <key>ForcePeriodicRenderingTime</key>
- <map>
- <key>Comment</key>
- <string>Periodically enable all rendering masks for a single frame.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>-1.0</real>
- </map>
<key>ZoomDirect</key>
<map>
<key>Comment</key>
@@ -15548,17 +13408,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AssetStorageLogFrequency</key>
- <map>
- <key>Comment</key>
- <string>Seconds between display of AssetStorage info in log (0 for never)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>60.0</real>
- </map>
<key>LogWearableAssetSave</key>
<map>
<key>Comment</key>
@@ -15796,28 +13645,6 @@
<key>Value</key>
<real>120.0</real>
</map>
- <key>DestinationGuideHintTimeout</key>
- <map>
- <key>Comment</key>
- <string>Number of seconds to wait before telling resident about destination guide.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1200.0</real>
- </map>
- <key>SidePanelHintTimeout</key>
- <map>
- <key>Comment</key>
- <string>Number of seconds to wait before telling resident about side panel.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>300.0</real>
- </map>
<key>GroupMembersSortOrder</key>
<map>
<key>Comment</key>
@@ -15862,17 +13689,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AvatarInspectorTooltipDelay</key>
- <map>
- <key>Comment</key>
- <string>Seconds before displaying avatar inspector tooltip</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.35</real>
- </map>
<key>ObjectInspectorTooltipDelay</key>
<map>
<key>Comment</key>
@@ -15906,17 +13722,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnableGroupInfo</key>
- <map>
- <key>Comment</key>
- <string>Enable viewing and editing of group info from web link</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>EnablePlaceProfile</key>
<map>
<key>Comment</key>
@@ -15928,28 +13733,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnablePicks</key>
- <map>
- <key>Comment</key>
- <string>Enable editing of picks from web link</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>EnableWorldMap</key>
- <map>
- <key>Comment</key>
- <string>Enable opening world map from web link</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>EnableAvatarPay</key>
<map>
<key>Comment</key>
@@ -15961,17 +13744,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnableVoiceCall</key>
- <map>
- <key>Comment</key>
- <string>Enable voice calls from web link</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>EnableAvatarShare</key>
<map>
<key>Comment</key>
@@ -15994,17 +13766,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>EnableSearch</key>
- <map>
- <key>Comment</key>
- <string>Enable opening search from web link</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>EnableAppearance</key>
<map>
<key>Comment</key>
@@ -16082,17 +13843,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AllowBottomTrayButtonReordering</key>
- <map>
- <key>Comment</key>
- <string>Allow user to move and hide bottom tray buttons</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>AllowSelectAvatar</key>
<map>
<key>Comment</key>
@@ -16951,28 +14701,6 @@
<key>Value</key>
<integer>1000</integer>
</map>
- <key>FMODExStreamBufferSize</key>
- <map>
- <key>Comment</key>
- <string>Sets the streaming buffer size (in milliseconds) for FMOD Ex or FMOD Studio</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>7000</integer>
- </map>
- <key>DisablePrecacheDelayAfterTeleporting</key>
- <map>
- <key>Comment</key>
- <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>VersionChannelName</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 63608cdbf8..d1dab94a76 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -397,8 +397,18 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \
# Other shortcuts
SetOutPath "$INSTDIR"
-CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
+
+Push $0
+${GetParameters} $COMMANDLINE
+${GetOptionsS} $COMMANDLINE "/marker" $0
+# Returns error if option does not exist
+IfErrors 0 DESKTOP_SHORTCUT_DONE
+ # "/marker" is set by updater, do not recreate desktop shortcut
+ CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
+
+DESKTOP_SHORTCUT_DONE:
+Pop $0
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 8977b145d1..b51bf132f4 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1932,7 +1932,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
}
else
{
- target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
+ LLCachedControl<F32> dynamic_camera_strength(gSavedSettings, "DynamicCameraStrength");
+ target_lag = vel * dynamic_camera_strength / 30.f;
}
mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp
index 799060eeab..0b72f1ee4d 100644
--- a/indra/newview/llagentpicksinfo.cpp
+++ b/indra/newview/llagentpicksinfo.cpp
@@ -49,10 +49,10 @@ public:
void sendAgentPicksRequest()
{
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(gAgent.getID());
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgent.getID());
}
- typedef boost::function<void(LLAvatarPicks*)> server_respond_callback_t;
+ typedef boost::function<void(LLAvatarData*)> server_respond_callback_t;
void setServerRespondCallback(const server_respond_callback_t& cb)
{
@@ -61,10 +61,10 @@ public:
virtual void processProperties(void* data, EAvatarProcessorType type)
{
- if(APT_PICKS == type)
+ if(APT_PROPERTIES == type)
{
- LLAvatarPicks* picks = static_cast<LLAvatarPicks*>(data);
- if(picks && gAgent.getID() == picks->target_id)
+ LLAvatarData* picks = static_cast<LLAvatarData*>(data);
+ if(picks && gAgent.getID() == picks->avatar_id)
{
if(mServerRespondCallback)
{
@@ -115,7 +115,7 @@ bool LLAgentPicksInfo::isPickLimitReached()
return getNumberOfPicks() >= getMaxNumberOfPicks();
}
-void LLAgentPicksInfo::onServerRespond(LLAvatarPicks* picks)
+void LLAgentPicksInfo::onServerRespond(LLAvatarData* picks)
{
if(!picks)
{
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index 21df036cb7..56e7bd0775 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -29,7 +29,7 @@
#include "llsingleton.h"
-struct LLAvatarPicks;
+struct LLAvatarData;
/**
* Class that provides information about Agent Picks
@@ -74,7 +74,7 @@ public:
void decrementNumberOfPicks() { --mNumberOfPicks; }
- void onServerRespond(LLAvatarPicks* picks);
+ void onServerRespond(LLAvatarData* picks);
private:
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index debf93dccd..51e259992d 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -168,6 +168,7 @@ void LLAppCoreHttp::init()
}
else
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS("Init") << "Missing CA File; should be at " << ca_file << LL_ENDL;
}
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 4c3a9229d2..fa0dee3ef9 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1399,7 +1399,7 @@ const std::string LLAppearanceMgr::sExpectedTextureName = "OutfitPreview";
const LLUUID LLAppearanceMgr::getCOF() const
{
- return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ return mCOFID;
}
S32 LLAppearanceMgr::getCOFVersion() const
@@ -1415,6 +1415,11 @@ S32 LLAppearanceMgr::getCOFVersion() const
}
}
+void LLAppearanceMgr::initCOFID()
+{
+ mCOFID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+}
+
const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
{
const LLUUID& current_outfit_cat = getCOF();
@@ -3763,6 +3768,14 @@ LLSD LLAppearanceMgr::dumpCOF() const
return result;
}
+void LLAppearanceMgr::cleanup()
+{
+ mIsInUpdateAppearanceFromCOF = false;
+ mOutstandingAppearanceBakeRequest = false;
+ mRerequestAppearanceBake = false;
+ mCOFID.setNull();
+}
+
// static
void LLAppearanceMgr::onIdle(void *)
{
@@ -4131,7 +4144,7 @@ void LLAppearanceMgr::wearBaseOutfit()
updateCOF(base_outfit_id);
}
-void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, nullary_func_t post_update_func)
{
LL_DEBUGS("UIUsage") << "removeItemsFromAvatar" << LL_ENDL;
LLUIUsage::instance().logCommand("Avatar.RemoveItem");
@@ -4141,7 +4154,7 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
return;
}
- LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+ LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy(true, true, post_update_func);
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
const LLUUID& id_to_remove = *it;
@@ -4160,11 +4173,11 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
}
}
-void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove, nullary_func_t post_update_func)
{
uuid_vec_t ids_to_remove;
ids_to_remove.push_back(id_to_remove);
- removeItemsFromAvatar(ids_to_remove);
+ removeItemsFromAvatar(ids_to_remove, post_update_func);
}
@@ -4401,20 +4414,45 @@ BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
return FALSE;
}
-BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
+bool LLAppearanceMgr::getIsInCOF(const LLInventoryObject* obj) const
+{
+ const LLUUID& cof = getCOF();
+ if (obj->getUUID() == cof)
+ return true;
+ if (obj && obj->getParentUUID() == cof)
+ return true;
+ return false;
+}
+
+bool LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
{
- if (!getIsInCOF(obj_id)) return FALSE;
+ if (!getIsInCOF(obj_id)) return false;
// If a non-link somehow ended up in COF, allow deletion.
const LLInventoryObject *obj = gInventory.getObject(obj_id);
if (obj && !obj->getIsLinkType())
{
- return FALSE;
+ return false;
}
// For now, don't allow direct deletion from the COF. Instead, force users
// to choose "Detach" or "Take Off".
- return TRUE;
+ return true;
+}
+
+bool LLAppearanceMgr::getIsProtectedCOFItem(const LLInventoryObject* obj) const
+{
+ if (!getIsInCOF(obj)) return false;
+
+ // If a non-link somehow ended up in COF, allow deletion.
+ if (obj && !obj->getIsLinkType())
+ {
+ return false;
+ }
+
+ // For now, don't allow direct deletion from the COF. Instead, force users
+ // to choose "Detach" or "Take Off".
+ return true;
}
class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index da29ceee3a..551185e33f 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -111,9 +111,11 @@ public:
// Find the Current Outfit folder.
const LLUUID getCOF() const;
S32 getCOFVersion() const;
+ void initCOFID();
// Debugging - get truncated LLSD summary of COF contents.
LLSD dumpCOF() const;
+ void cleanup();
// Finds the folder link to the currently worn outfit
const LLViewerInventoryItem *getBaseOutfitLink();
@@ -195,8 +197,8 @@ public:
bool updateBaseOutfit();
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
- void removeItemsFromAvatar(const uuid_vec_t& item_ids);
- void removeItemFromAvatar(const LLUUID& item_id);
+ void removeItemsFromAvatar(const uuid_vec_t& item_ids, nullary_func_t post_update_func = no_op);
+ void removeItemFromAvatar(const LLUUID& item_id, nullary_func_t post_update_func = no_op);
void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel);
@@ -276,6 +278,7 @@ private:
attachments_changed_signal_t mAttachmentsChangeSignal;
LLUUID mCOFImageID;
+ LLUUID mCOFID;
std::unique_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
@@ -290,8 +293,10 @@ private:
public:
// Is this in the COF?
BOOL getIsInCOF(const LLUUID& obj_id) const;
- // Is this in the COF and can the user delete it from the COF?
- BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
+ bool getIsInCOF(const LLInventoryObject* obj) const;
+ // Is this in the COF and can the user delete it from the COF?
+ bool getIsProtectedCOFItem(const LLUUID& obj_id) const;
+ bool getIsProtectedCOFItem(const LLInventoryObject* obj) const;
// Outfits will prioritize textures with such name to use for preview in gallery
static const std::string sExpectedTextureName;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4a43133ff6..38888b4424 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -362,7 +362,6 @@ BOOL gRandomizeFramerate = FALSE;
BOOL gPeriodicSlowFrame = FALSE;
BOOL gCrashOnStartup = FALSE;
-BOOL gLLErrorActivated = FALSE;
BOOL gLogoutInProgress = FALSE;
BOOL gSimulateMemLeak = FALSE;
@@ -527,13 +526,6 @@ bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
// or for things that are performance critical. JC
static void settings_to_globals()
{
- LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad");
- BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall");
- BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight");
-
- MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight");
- MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth");
-
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
#if LL_DARWIN
@@ -2253,9 +2245,6 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);
#endif
- //Set the ErrorActivated global so we know to create a marker file
- gLLErrorActivated = true;
-
gDebugInfo["FatalMessage"] = error_string;
// We're not already crashing -- we simply *intend* to crash. Since we
// haven't actually trashed anything yet, we can afford to write the whole
@@ -2264,6 +2253,14 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
}
}
+void errorMSG(const std::string& title_string, const std::string& message_string)
+{
+ if (!message_string.empty())
+ {
+ OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);
+ }
+}
+
void LLAppViewer::initLoggingAndGetLastDuration()
{
//
@@ -2275,6 +2272,8 @@ void LLAppViewer::initLoggingAndGetLastDuration()
LLError::addGenericRecorder(&errorCallback);
//LLError::setTimeFunction(getRuntime);
+ LLError::LLUserWarningMsg::setHandler(errorMSG);
+
if (mSecondInstance)
{
@@ -2412,6 +2411,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
{ // failed to load
if(file.required)
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL;
return false;
}
@@ -2510,6 +2510,7 @@ bool LLAppViewer::initConfiguration()
if (!success)
{
LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL;
+ LLError::LLUserWarningMsg::showMissingFiles();
if (gDirUtilp->fileExists(settings_file_list))
{
LL_ERRS() << "Cannot load default configuration file settings_files.xml. "
@@ -2533,6 +2534,7 @@ bool LLAppViewer::initConfiguration()
if (!mSettingsLocationList->validateBlock())
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL;
}
@@ -2967,6 +2969,8 @@ bool LLAppViewer::initConfiguration()
LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key));
}
+ LLError::LLUserWarningMsg::setOutOfMemoryStrings(LLTrans::getString("MBOutOfMemoryTitle"), LLTrans::getString("MBOutOfMemoryErr"));
+
return true; // Config was successful.
}
@@ -3004,6 +3008,7 @@ void LLAppViewer::initStrings()
// initial check to make sure files are there failed
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Viewer failed to find localization and UI files."
<< " Please reinstall viewer from https://secondlife.com/support/downloads"
<< " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
@@ -4291,7 +4296,8 @@ bool LLAppViewer::initCache()
LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
- LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion());
+ const U32 CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS = 128;
+ LLVOCache::getInstance()->initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS_FOR_OBJECTS, getObjectCacheVersion());
return true;
}
@@ -4310,6 +4316,7 @@ void LLAppViewer::loadKeyBindings()
key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
if (!gViewerInput.loadBindingsXML(key_bindings_file))
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
}
}
@@ -5400,6 +5407,14 @@ void LLAppViewer::forceErrorLLError()
LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
}
+void LLAppViewer::forceErrorLLErrorMsg()
+{
+ LLError::LLUserWarningMsg::show("Deliberate error");
+ // Note: under debug this will show a message as well,
+ // but release won't show anything and will quit silently
+ LL_ERRS() << "This is a deliberate llerror with a message" << LL_ENDL;
+}
+
void LLAppViewer::forceErrorBreakpoint()
{
LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 6d1496d517..77a1cdb485 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -152,6 +152,7 @@ public:
// LLAppViewer testing helpers.
// *NOTE: These will potentially crash the viewer. Only for debugging.
virtual void forceErrorLLError();
+ virtual void forceErrorLLErrorMsg();
virtual void forceErrorBreakpoint();
virtual void forceErrorBadMemoryAccess();
virtual void forceErrorInfiniteLoop();
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 44bf698caa..52bec5d434 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -245,7 +245,7 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
// messages. People API already hits the user table.
LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
app->addObserver(mAvatarId, this);
- app->sendAvatarPropertiesRequest(mAvatarId);
+ app->sendAvatarLegacyPropertiesRequest(mAvatarId);
}
else if (gAgentID == mAvatarId)
{
@@ -299,9 +299,15 @@ bool LLAvatarIconCtrl::updateFromCache()
//virtual
void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
{
- if (APT_PROPERTIES == type)
+ // Both APT_PROPERTIES_LEGACY and APT_PROPERTIES have icon data.
+ // 'Legacy' is cheaper to request so LLAvatarIconCtrl issues that,
+ // but own icon should track any source for the sake of timely updates.
+ //
+ // If this needs to change, make sure to update onCommitProfileImage
+ // to issue right kind of request
+ if (APT_PROPERTIES_LEGACY == type)
{
- LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ LLAvatarLegacyData* avatar_data = static_cast<LLAvatarLegacyData*>(data);
if (avatar_data)
{
if (avatar_data->avatar_id != mAvatarId)
@@ -313,6 +319,20 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
updateFromCache();
}
}
+ else if (APT_PROPERTIES == type)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ if (avatar_data)
+ {
+ if (avatar_data->avatar_id != mAvatarId)
+ {
+ return;
+ }
+
+ LLAvatarIconIDCache::getInstance()->add(mAvatarId, avatar_data->image_id);
+ updateFromCache();
+ }
+ }
}
void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index dd0d06a8c8..bed8887ce1 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -52,24 +52,23 @@ LLAvatarPropertiesProcessor::~LLAvatarPropertiesProcessor()
void LLAvatarPropertiesProcessor::addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
{
+ if (!observer)
+ return;
+
// Check if that observer is already in mObservers for that avatar_id
- observer_multimap_t::iterator it;
+ using pair = std::pair<LLUUID, LLAvatarPropertiesObserver*>;
+ observer_multimap_t::iterator begin = mObservers.begin();
+ observer_multimap_t::iterator end = mObservers.end();
+ observer_multimap_t::iterator it = std::find_if(begin, end, [&](const pair& p)
+ {
+ return p.first == avatar_id && p.second == observer;
+ });
// IAN BUG this should update the observer's UUID if this is a dupe - sent to PE
- it = mObservers.find(avatar_id);
- while (it != mObservers.end())
+ if (it == end)
{
- if (it->second == observer)
- {
- return;
- }
- else
- {
- ++it;
- }
+ mObservers.emplace(avatar_id, observer);
}
-
- mObservers.insert(std::pair<LLUUID, LLAvatarPropertiesObserver*>(avatar_id, observer));
}
void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer)
@@ -79,19 +78,18 @@ void LLAvatarPropertiesProcessor::removeObserver(const LLUUID& avatar_id, LLAvat
return;
}
- observer_multimap_t::iterator it;
- it = mObservers.find(avatar_id);
- while (it != mObservers.end())
- {
- if (it->second == observer)
- {
- mObservers.erase(it);
- break;
- }
- else
+ // Check if that observer is in mObservers for that avatar_id
+ using pair = std::pair<LLUUID, LLAvatarPropertiesObserver*>;
+ observer_multimap_t::iterator begin = mObservers.begin();
+ observer_multimap_t::iterator end = mObservers.end();
+ observer_multimap_t::iterator it = std::find_if(begin, end, [&](const pair& p)
{
- ++it;
- }
+ return p.first == avatar_id && p.second == observer;
+ });
+
+ if (it != end)
+ {
+ mObservers.erase(it);
}
}
@@ -116,32 +114,30 @@ void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarPr
return;
}
- std::string cap;
-
- switch (type)
+ // Try to send HTTP request if cap_url is available
+ if (type == APT_PROPERTIES)
{
- case APT_PROPERTIES:
- // indicate we're going to make a request
- sendAvatarPropertiesRequestMessage(avatar_id);
- // can use getRegionCapability("AgentProfile"), but it is heavy
- // initAgentProfileCapRequest(avatar_id, cap);
- break;
- case APT_PICKS:
- case APT_GROUPS:
- case APT_NOTES:
- if (cap.empty())
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (!cap_url.empty())
{
- // indicate we're going to make a request
- sendGenericRequest(avatar_id, type, method);
+ initAgentProfileCapRequest(avatar_id, cap_url, type);
}
else
{
- initAgentProfileCapRequest(avatar_id, cap);
+ // Don't sent UDP request for APT_PROPERTIES
+ LL_WARNS() << "No cap_url for APT_PROPERTIES, request for " << avatar_id << " is not sent" << LL_ENDL;
}
- break;
- default:
+ return;
+ }
+
+ // Send UDP request
+ if (type == APT_PROPERTIES_LEGACY)
+ {
+ sendAvatarPropertiesRequestMessage(avatar_id);
+ }
+ else
+ {
sendGenericRequest(avatar_id, type, method);
- break;
}
}
@@ -150,33 +146,29 @@ void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EA
// indicate we're going to make a request
addPendingRequest(avatar_id, type);
- std::vector<std::string> strings;
- strings.push_back(avatar_id.asString());
+ std::vector<std::string> strings{ avatar_id.asString() };
send_generic_message(method, strings);
}
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id)
{
- addPendingRequest(avatar_id, APT_PROPERTIES);
+ addPendingRequest(avatar_id, APT_PROPERTIES_LEGACY);
LLMessageSystem *msg = gMessageSystem;
msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_AgentID, gAgentID);
+ msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
msg->addUUIDFast(_PREHASH_AvatarID, avatar_id);
gAgent.sendReliableMessage();
}
-void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url)
+void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url, EAvatarProcessorType type)
{
- addPendingRequest(avatar_id, APT_PROPERTIES);
- addPendingRequest(avatar_id, APT_PICKS);
- addPendingRequest(avatar_id, APT_GROUPS);
- addPendingRequest(avatar_id, APT_NOTES);
+ addPendingRequest(avatar_id, type);
LLCoros::instance().launch("requestAgentUserInfoCoro",
- boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id));
+ [cap_url, avatar_id, type]() { requestAvatarPropertiesCoro(cap_url, avatar_id, type); });
}
void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id)
@@ -184,19 +176,9 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avat
sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
}
-void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
+void LLAvatarPropertiesProcessor::sendAvatarLegacyPropertiesRequest(const LLUUID& avatar_id)
{
- sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
-}
-
-void LLAvatarPropertiesProcessor::sendAvatarNotesRequest(const LLUUID& avatar_id)
-{
- sendGenericRequest(avatar_id, APT_NOTES, "avatarnotesrequest");
-}
-
-void LLAvatarPropertiesProcessor::sendAvatarGroupsRequest(const LLUUID& avatar_id)
-{
- sendGenericRequest(avatar_id, APT_GROUPS, "avatargroupsrequest");
+ sendRequest(avatar_id, APT_PROPERTIES_LEGACY, "AvatarPropertiesRequest");
}
void LLAvatarPropertiesProcessor::sendAvatarTexturesRequest(const LLUUID& avatar_id)
@@ -211,42 +193,6 @@ void LLAvatarPropertiesProcessor::sendAvatarClassifiedsRequest(const LLUUID& ava
sendGenericRequest(avatar_id, APT_CLASSIFIEDS, "avatarclassifiedsrequest");
}
-void LLAvatarPropertiesProcessor::sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props)
-{
- if (!gAgent.isInitialized() || (gAgent.getID() == LLUUID::null))
- {
- LL_WARNS() << "Sending avatarinfo update DENIED - invalid agent" << LL_ENDL;
- return;
- }
-
- LL_WARNS() << "Sending avatarinfo update. This trims profile descriptions!!!" << LL_ENDL;
-
- // This value is required by sendAvatarPropertiesUpdate method.
- //A profile should never be mature. (From the original code)
- BOOL mature = FALSE;
-
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessageFast (_PREHASH_AvatarPropertiesUpdate);
- msg->nextBlockFast (_PREHASH_AgentData);
- msg->addUUIDFast (_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast (_PREHASH_SessionID, gAgent.getSessionID() );
- msg->nextBlockFast (_PREHASH_PropertiesData);
-
- msg->addUUIDFast (_PREHASH_ImageID, avatar_props->image_id);
- msg->addUUIDFast (_PREHASH_FLImageID, avatar_props->fl_image_id);
- msg->addStringFast (_PREHASH_AboutText, avatar_props->about_text);
- msg->addStringFast (_PREHASH_FLAboutText, avatar_props->fl_about_text);
-
- msg->addBOOL(_PREHASH_AllowPublish, avatar_props->allow_publish);
- msg->addBOOL(_PREHASH_MaturePublish, mature);
- msg->addString(_PREHASH_ProfileURL, avatar_props->profile_url);
-
- gAgent.sendReliableMessage();
-}
-
-
-
//static
std::string LLAvatarPropertiesProcessor::accountType(const LLAvatarData* avatar_data)
{
@@ -271,19 +217,21 @@ std::string LLAvatarPropertiesProcessor::accountType(const LLAvatarData* avatar_
std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_data)
{
// Special accounts like M Linden don't have payment info revealed.
- if (!avatar_data->caption_text.empty()) return "";
+ if (!avatar_data->caption_text.empty())
+ return "";
// Linden employees don't have payment info revealed
- const S32 LINDEN_EMPLOYEE_INDEX = 3;
- if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return "";
+ constexpr S32 LINDEN_EMPLOYEE_INDEX = 3;
+ if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX)
+ return "";
- BOOL transacted = (avatar_data->flags & AVATAR_TRANSACTED);
- BOOL identified = (avatar_data->flags & AVATAR_IDENTIFIED);
+ bool transacted = (avatar_data->flags & AVATAR_TRANSACTED);
+ bool identified = (avatar_data->flags & AVATAR_IDENTIFIED);
// Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations
//BOOL age_verified = (avatar_data->flags & AVATAR_AGEVERIFIED);
const char* payment_text;
- if(transacted)
+ if (transacted)
{
payment_text = "PaymentInfoUsed";
}
@@ -302,18 +250,22 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_
bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data)
{
// Special accounts like M Linden don't have payment info revealed.
- if (!avatar_data->caption_text.empty()) return true;
+ if (!avatar_data->caption_text.empty())
+ return true;
// Linden employees don't have payment info revealed
- const S32 LINDEN_EMPLOYEE_INDEX = 3;
- if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true;
+ constexpr S32 LINDEN_EMPLOYEE_INDEX = 3;
+ if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX)
+ return true;
return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
}
// static
-void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id)
+void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_url, LLUUID avatar_id, EAvatarProcessorType type)
{
+ LLAvatarPropertiesProcessor& inst = instance();
+
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestAvatarPropertiesCoro", httpPolicy));
@@ -323,104 +275,104 @@ void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_ur
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
httpOpts->setFollowRedirects(true);
- std::string finalUrl = cap_url + "/" + agent_id.asString();
+ std::string finalUrl = cap_url + "/" + avatar_id.asString();
LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
+ // Response is being processed, no longer pending is required
+ inst.removePendingRequest(avatar_id, type);
+
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status
|| !result.has("id")
- || agent_id != result["id"].asUUID())
+ || avatar_id != result["id"].asUUID())
{
- LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
- LLAvatarPropertiesProcessor* self = getInstance();
- self->removePendingRequest(agent_id, APT_PROPERTIES);
- self->removePendingRequest(agent_id, APT_PICKS);
- self->removePendingRequest(agent_id, APT_GROUPS);
- self->removePendingRequest(agent_id, APT_NOTES);
+ LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << avatar_id
+ << (!status ? " (no HTTP status)" : !result.has("id") ? " (no result.id)" :
+ std::string(" (result.id=") + result["id"].asUUID().asString() + ")")
+ << LL_ENDL;
return;
}
- // Avatar Data
-
LLAvatarData avatar_data;
+
std::string birth_date;
- avatar_data.agent_id = agent_id;
- avatar_data.avatar_id = agent_id;
+ avatar_data.agent_id = gAgentID;
+ avatar_data.avatar_id = avatar_id;
avatar_data.image_id = result["sl_image_id"].asUUID();
avatar_data.fl_image_id = result["fl_image_id"].asUUID();
avatar_data.partner_id = result["partner_id"].asUUID();
avatar_data.about_text = result["sl_about_text"].asString();
avatar_data.fl_about_text = result["fl_about_text"].asString();
avatar_data.born_on = result["member_since"].asDate();
- avatar_data.profile_url = getProfileURL(agent_id.asString());
+ // TODO: SL-20163 Remove the "has" check when SRV-684 is done
+ // and the field "hide_age" is included to the http response
+ inst.mIsHideAgeSupportedByServer = result.has("hide_age");
+ avatar_data.hide_age = inst.isHideAgeSupportedByServer() && result["hide_age"].asBoolean();
+ avatar_data.profile_url = getProfileURL(avatar_id.asString());
+ avatar_data.customer_type = result["customer_type"].asString();
+ avatar_data.notes = result["notes"].asString();
avatar_data.flags = 0;
- avatar_data.caption_index = 0;
-
- LLAvatarPropertiesProcessor* self = getInstance();
- // Request processed, no longer pending
- self->removePendingRequest(agent_id, APT_PROPERTIES);
- self->notifyObservers(agent_id, &avatar_data, APT_PROPERTIES);
-
- // Picks
-
- LLSD picks_array = result["picks"];
- LLAvatarPicks avatar_picks;
- avatar_picks.agent_id = agent_id; // Not in use?
- avatar_picks.target_id = agent_id;
-
- for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ if (result["online"].asBoolean())
{
- const LLSD& pick_data = *it;
- avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ avatar_data.flags |= AVATAR_ONLINE;
+ }
+ if (result["allow_publish"].asBoolean())
+ {
+ avatar_data.flags |= AVATAR_ALLOW_PUBLISH;
+ }
+ if (result["identified"].asBoolean())
+ {
+ avatar_data.flags |= AVATAR_IDENTIFIED;
+ }
+ if (result["transacted"].asBoolean())
+ {
+ avatar_data.flags |= AVATAR_TRANSACTED;
}
- // Request processed, no longer pending
- self->removePendingRequest(agent_id, APT_PICKS);
- self->notifyObservers(agent_id, &avatar_picks, APT_PICKS);
+ avatar_data.caption_index = 0;
+ if (result.has("charter_member")) // won't be present if "caption" is set
+ {
+ avatar_data.caption_index = result["charter_member"].asInteger();
+ }
+ else if (result.has("caption"))
+ {
+ avatar_data.caption_text = result["caption"].asString();
+ }
// Groups
-
LLSD groups_array = result["groups"];
- LLAvatarGroups avatar_groups;
- avatar_groups.agent_id = agent_id; // Not in use?
- avatar_groups.avatar_id = agent_id; // target_id
-
for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
{
const LLSD& group_info = *it;
- LLAvatarGroups::LLGroupData group_data;
+ LLAvatarData::LLGroupData group_data;
group_data.group_powers = 0; // Not in use?
group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
group_data.group_id = group_info["id"].asUUID();
group_data.group_name = group_info["name"].asString();
group_data.group_insignia_id = group_info["image_id"].asUUID();
- avatar_groups.group_list.push_back(group_data);
+ avatar_data.group_list.push_back(group_data);
}
- self->removePendingRequest(agent_id, APT_GROUPS);
- self->notifyObservers(agent_id, &avatar_groups, APT_GROUPS);
-
- // Notes
- LLAvatarNotes avatar_notes;
-
- avatar_notes.agent_id = agent_id;
- avatar_notes.target_id = agent_id;
- avatar_notes.notes = result["notes"].asString();
+ // Picks
+ LLSD picks_array = result["picks"];
+ for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
+ {
+ const LLSD& pick_data = *it;
+ avatar_data.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
+ }
- // Request processed, no longer pending
- self->removePendingRequest(agent_id, APT_NOTES);
- self->notifyObservers(agent_id, &avatar_notes, APT_NOTES);
+ inst.notifyObservers(avatar_id, &avatar_data, type);
}
-void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
+void LLAvatarPropertiesProcessor::processAvatarLegacyPropertiesReply(LLMessageSystem* msg, void**)
{
- LLAvatarData avatar_data;
+ LLAvatarLegacyData avatar_data;
std::string birth_date;
msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, avatar_data.agent_id);
@@ -434,51 +386,23 @@ void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem*
msg->getString( _PREHASH_PropertiesData, _PREHASH_ProfileURL, avatar_data.profile_url);
msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_Flags, avatar_data.flags);
-
LLDateUtil::dateFromPDTString(avatar_data.born_on, birth_date);
avatar_data.caption_index = 0;
S32 charter_member_size = 0;
charter_member_size = msg->getSize(_PREHASH_PropertiesData, _PREHASH_CharterMember);
- if(1 == charter_member_size)
+ if (1 == charter_member_size)
{
msg->getBinaryData(_PREHASH_PropertiesData, _PREHASH_CharterMember, &avatar_data.caption_index, 1);
}
- else if(1 < charter_member_size)
+ else if (1 < charter_member_size)
{
msg->getString(_PREHASH_PropertiesData, _PREHASH_CharterMember, avatar_data.caption_text);
}
LLAvatarPropertiesProcessor* self = getInstance();
// Request processed, no longer pending
- self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES);
- self->notifyObservers(avatar_data.avatar_id,&avatar_data,APT_PROPERTIES);
-}
-
-void LLAvatarPropertiesProcessor::processAvatarInterestsReply(LLMessageSystem* msg, void**)
-{
-/*
- AvatarInterestsReply is automatically sent by the server in response to the
- AvatarPropertiesRequest sent when the panel is opened (in addition to the AvatarPropertiesReply message).
- If the interests panel is no longer part of the design (?) we should just register the message
- to a handler function that does nothing.
- That will suppress the warnings and be compatible with old server versions.
- WARNING: LLTemplateMessageReader::decodeData: Message from 216.82.37.237:13000 with no handler function received: AvatarInterestsReply
-*/
-
- LLInterestsData interests_data;
-
- msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AgentID, interests_data.agent_id );
- msg->getUUIDFast( _PREHASH_AgentData, _PREHASH_AvatarID, interests_data.avatar_id );
- msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_WantToMask, interests_data.want_to_mask );
- msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_WantToText, interests_data.want_to_text );
- msg->getU32Fast( _PREHASH_PropertiesData, _PREHASH_SkillsMask, interests_data.skills_mask );
- msg->getStringFast( _PREHASH_PropertiesData, _PREHASH_SkillsText, interests_data.skills_text );
- msg->getString( _PREHASH_PropertiesData, _PREHASH_LanguagesText, interests_data.languages_text );
-
- LLAvatarPropertiesProcessor* self = getInstance();
- // Request processed, no longer pending
- self->removePendingRequest(interests_data.avatar_id, APT_INTERESTS_INFO);
- self->notifyObservers(interests_data.avatar_id, &interests_data, APT_INTERESTS_INFO);
+ self->removePendingRequest(avatar_data.avatar_id, APT_PROPERTIES_LEGACY);
+ self->notifyObservers(avatar_data.avatar_id, &avatar_data, APT_PROPERTIES_LEGACY);
}
void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem* msg, void**)
@@ -497,7 +421,7 @@ void LLAvatarPropertiesProcessor::processAvatarClassifiedsReply(LLMessageSystem*
msg->getUUID(_PREHASH_Data, _PREHASH_ClassifiedID, data.classified_id, n);
msg->getString(_PREHASH_Data, _PREHASH_Name, data.name, n);
- classifieds.classifieds_list.push_back(data);
+ classifieds.classifieds_list.emplace_back(data);
}
LLAvatarPropertiesProcessor* self = getInstance();
@@ -534,44 +458,6 @@ void LLAvatarPropertiesProcessor::processClassifiedInfoReply(LLMessageSystem* ms
self->notifyObservers(c_info.creator_id, &c_info, APT_CLASSIFIED_INFO);
}
-
-void LLAvatarPropertiesProcessor::processAvatarNotesReply(LLMessageSystem* msg, void**)
-{
- LLAvatarNotes avatar_notes;
-
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_notes.agent_id);
- msg->getUUID(_PREHASH_Data, _PREHASH_TargetID, avatar_notes.target_id);
- msg->getString(_PREHASH_Data, _PREHASH_Notes, avatar_notes.notes);
-
- LLAvatarPropertiesProcessor* self = getInstance();
- // Request processed, no longer pending
- self->removePendingRequest(avatar_notes.target_id, APT_NOTES);
- self->notifyObservers(avatar_notes.target_id,&avatar_notes,APT_NOTES);
-}
-
-void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg, void**)
-{
- LLAvatarPicks avatar_picks;
- msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
- msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
-
- S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
- for (int block = 0; block < block_count; ++block)
- {
- LLUUID pick_id;
- std::string pick_name;
-
- msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block);
- msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block);
-
- avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name));
- }
- LLAvatarPropertiesProcessor* self = getInstance();
- // Request processed, no longer pending
- self->removePendingRequest(avatar_picks.target_id, APT_PICKS);
- self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS);
-}
-
void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**)
{
LLPickData pick_data;
@@ -602,46 +488,18 @@ void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, voi
self->notifyObservers(pick_data.creator_id, &pick_data, APT_PICK_INFO);
}
-void LLAvatarPropertiesProcessor::processAvatarGroupsReply(LLMessageSystem* msg, void**)
-{
- LLAvatarGroups avatar_groups;
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, avatar_groups.agent_id );
- msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_groups.avatar_id );
-
- S32 group_count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
- for(S32 i = 0; i < group_count; ++i)
- {
- LLAvatarGroups::LLGroupData group_data;
-
- msg->getU64( _PREHASH_GroupData, _PREHASH_GroupPowers, group_data.group_powers, i );
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupTitle, group_data.group_title, i );
- msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupID, group_data.group_id, i);
- msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, group_data.group_name, i );
- msg->getUUIDFast( _PREHASH_GroupData, _PREHASH_GroupInsigniaID, group_data.group_insignia_id, i );
-
- avatar_groups.group_list.push_back(group_data);
- }
-
- LLAvatarPropertiesProcessor* self = getInstance();
- self->removePendingRequest(avatar_groups.avatar_id, APT_GROUPS);
- self->notifyObservers(avatar_groups.avatar_id,&avatar_groups,APT_GROUPS);
-}
-
-void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type)
+void LLAvatarPropertiesProcessor::notifyObservers(const LLUUID& id, void* data, EAvatarProcessorType type)
{
// Copy the map (because observers may delete themselves when updated?)
LLAvatarPropertiesProcessor::observer_multimap_t observers = mObservers;
- observer_multimap_t::iterator oi = observers.begin();
- observer_multimap_t::iterator end = observers.end();
- for (; oi != end; ++oi)
+ for (const auto& [agent_id, observer] : observers)
{
// only notify observers for the same agent, or if the observer
// didn't know the agent ID and passed a NULL id.
- const LLUUID &agent_id = oi->first;
if (agent_id == id || agent_id.isNull())
{
- oi->second->processProperties(data,type);
+ observer->processProperties(data, type);
}
}
}
@@ -655,8 +513,8 @@ void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32
// setup message header
msg->newMessageFast(_PREHASH_GrantUserRights);
msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID(_PREHASH_AgentID, gAgentID);
+ msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
msg->nextBlockFast(_PREHASH_Rights);
msg->addUUID(_PREHASH_AgentRelated, avatar_id);
@@ -666,34 +524,13 @@ void LLAvatarPropertiesProcessor::sendFriendRights(const LLUUID& avatar_id, S32
}
}
-void LLAvatarPropertiesProcessor::sendNotes(const LLUUID& avatar_id, const std::string notes)
-{
- if(!avatar_id.isNull())
- {
- LLMessageSystem* msg = gMessageSystem;
-
- // setup message header
- msg->newMessageFast(_PREHASH_AvatarNotesUpdate);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
-
- msg->nextBlockFast(_PREHASH_Data);
- msg->addUUID(_PREHASH_TargetID, avatar_id);
- msg->addString(_PREHASH_Notes, notes);
-
- gAgent.sendReliableMessage();
- }
-}
-
-
void LLAvatarPropertiesProcessor::sendPickDelete( const LLUUID& pick_id )
{
LLMessageSystem* msg = gMessageSystem;
msg->newMessage(_PREHASH_PickDelete);
msg->nextBlock(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID(_PREHASH_AgentID, gAgentID);
+ msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
msg->nextBlock(_PREHASH_Data);
msg->addUUID(_PREHASH_PickID, pick_id);
gAgent.sendReliableMessage();
@@ -709,8 +546,8 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
msg->newMessage(_PREHASH_ClassifiedDelete);
msg->nextBlock(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID(_PREHASH_AgentID, gAgentID);
+ msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
msg->nextBlock(_PREHASH_Data);
msg->addUUID(_PREHASH_ClassifiedID, classified_id);
@@ -718,39 +555,17 @@ void LLAvatarPropertiesProcessor::sendClassifiedDelete(const LLUUID& classified_
gAgent.sendReliableMessage();
}
-void LLAvatarPropertiesProcessor::sendInterestsInfoUpdate(const LLInterestsData* interests_data)
-{
- if(!interests_data)
- {
- return;
- }
-
- LLMessageSystem* msg = gMessageSystem;
-
- msg->newMessage(_PREHASH_AvatarInterestsUpdate);
- msg->nextBlockFast( _PREHASH_AgentData);
- msg->addUUIDFast( _PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast( _PREHASH_SessionID, gAgent.getSessionID() );
- msg->nextBlockFast( _PREHASH_PropertiesData);
- msg->addU32Fast( _PREHASH_WantToMask, interests_data->want_to_mask);
- msg->addStringFast( _PREHASH_WantToText, interests_data->want_to_text);
- msg->addU32Fast( _PREHASH_SkillsMask, interests_data->skills_mask);
- msg->addStringFast( _PREHASH_SkillsText, interests_data->skills_text);
- msg->addString( _PREHASH_LanguagesText, interests_data->languages_text);
-
- gAgent.sendReliableMessage();
-}
-
void LLAvatarPropertiesProcessor::sendPickInfoUpdate(const LLPickData* new_pick)
{
- if (!new_pick) return;
+ if (!new_pick)
+ return;
LLMessageSystem* msg = gMessageSystem;
msg->newMessage(_PREHASH_PickInfoUpdate);
msg->nextBlock(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID(_PREHASH_AgentID, gAgentID);
+ msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
msg->nextBlock(_PREHASH_Data);
msg->addUUID(_PREHASH_PickID, new_pick->pick_id);
@@ -787,8 +602,8 @@ void LLAvatarPropertiesProcessor::sendClassifiedInfoUpdate(const LLAvatarClassif
msg->newMessage(_PREHASH_ClassifiedInfoUpdate);
msg->nextBlock(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID(_PREHASH_AgentID, gAgentID);
+ msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
msg->nextBlock(_PREHASH_Data);
msg->addUUID(_PREHASH_ClassifiedID, c_data->classified_id);
@@ -809,9 +624,7 @@ void LLAvatarPropertiesProcessor::sendPickInfoRequest(const LLUUID& creator_id,
{
// Must ask for a pick based on the creator id because
// the pick database is distributed to the inventory cluster. JC
- std::vector<std::string> request_params;
- request_params.push_back(creator_id.asString() );
- request_params.push_back(pick_id.asString() );
+ std::vector<std::string> request_params{ creator_id.asString(), pick_id.asString() };
send_generic_message("pickinforequest", request_params);
}
@@ -822,8 +635,8 @@ void LLAvatarPropertiesProcessor::sendClassifiedInfoRequest(const LLUUID& classi
msg->newMessage(_PREHASH_ClassifiedInfoRequest);
msg->nextBlock(_PREHASH_AgentData);
- msg->addUUID(_PREHASH_AgentID, gAgent.getID());
- msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUID(_PREHASH_AgentID, gAgentID);
+ msg->addUUID(_PREHASH_SessionID, gAgentSessionID);
msg->nextBlock(_PREHASH_Data);
msg->addUUID(_PREHASH_ClassifiedID, classified_id);
@@ -840,7 +653,7 @@ bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAva
if (it == mRequestTimestamps.end()) return false;
// We found a request, check if it has timed out
- U32 now = time(NULL);
+ U32 now = time(nullptr);
const U32 REQUEST_EXPIRE_SECS = 5;
U32 expires = it->second + REQUEST_EXPIRE_SECS;
@@ -854,7 +667,7 @@ bool LLAvatarPropertiesProcessor::isPendingRequest(const LLUUID& avatar_id, EAva
void LLAvatarPropertiesProcessor::addPendingRequest(const LLUUID& avatar_id, EAvatarProcessorType type)
{
timestamp_map_t::key_type key = std::make_pair(avatar_id, type);
- U32 now = time(NULL);
+ U32 now = time(nullptr);
// Add or update existing (expired) request
mRequestTimestamps[ key ] = now;
}
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index 10cde35f9c..99ed110487 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -50,54 +50,71 @@ class LLMessageSystem;
enum EAvatarProcessorType
{
- APT_PROPERTIES,
- APT_NOTES,
- APT_GROUPS,
- APT_PICKS,
+ APT_PROPERTIES_LEGACY, // APT_PROPERTIES via udp request (Truncates data!!!)
+ APT_PROPERTIES, // APT_PROPERTIES via http request
APT_PICK_INFO,
APT_TEXTURES,
- APT_INTERESTS_INFO,
APT_CLASSIFIEDS,
APT_CLASSIFIED_INFO
};
-struct LLInterestsData
+// legacy data is supposed to match AvatarPropertiesReply,
+// but it is obsolete, fields like about_text will truncate
+// data, if you need them, use AgenProfile cap.
+// Todo: remove it once once icon ids get moved elsewhere,
+// since AgentProfile is too large for bulk icon requests
+struct LLAvatarLegacyData
{
- LLUUID agent_id;
- LLUUID avatar_id; //target id
- U32 want_to_mask;
- std::string want_to_text;
- U32 skills_mask;
- std::string skills_text;
- std::string languages_text;
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ LLUUID image_id;
+ LLUUID fl_image_id;
+ LLUUID partner_id;
+ std::string about_text;
+ std::string fl_about_text;
+ LLDate born_on;
+ std::string profile_url;
+ U8 caption_index;
+ std::string caption_text;
+ std::string customer_type;
+ U32 flags;
};
struct LLAvatarData
{
- LLUUID agent_id;
- LLUUID avatar_id; //target id
- LLUUID image_id;
- LLUUID fl_image_id;
- LLUUID partner_id;
- std::string about_text;
- std::string fl_about_text;
- LLDate born_on;
- std::string profile_url;
- U8 caption_index;
- std::string caption_text;
+ LLUUID agent_id;
+ LLUUID avatar_id; //target id
+ LLUUID image_id;
+ LLUUID fl_image_id;
+ LLUUID partner_id;
+ std::string about_text;
+ std::string fl_about_text;
+ LLDate born_on;
+ std::string profile_url;
+ U8 caption_index;
+ std::string caption_text;
std::string customer_type;
- U32 flags;
- BOOL allow_publish;
+ U32 flags;
+ bool hide_age;
+ std::string notes;
+
+ struct LLGroupData;
+ typedef std::list<LLGroupData> group_list_t;
+ group_list_t group_list;
+
+ typedef std::pair<LLUUID, std::string> pick_data_t;
+ typedef std::list< pick_data_t> picks_list_t;
+ picks_list_t picks_list;
};
-struct LLAvatarPicks
+struct LLAvatarData::LLGroupData
{
- LLUUID agent_id;
- LLUUID target_id; //target id
-
- typedef std::pair<LLUUID,std::string> pick_data_t;
- typedef std::list< pick_data_t> picks_list_t;
- picks_list_t picks_list;
+ U64 group_powers;
+ BOOL accept_notices;
+ std::string group_title;
+ LLUUID group_id;
+ std::string group_name;
+ LLUUID group_insignia_id;
};
struct LLPickData
@@ -121,36 +138,6 @@ struct LLPickData
//used only in write (update) requests
LLUUID session_id;
-
-};
-
-struct LLAvatarNotes
-{
- LLUUID agent_id;
- LLUUID target_id; //target id
- std::string notes;
-};
-
-struct LLAvatarGroups
-{
- LLUUID agent_id;
- LLUUID avatar_id; //target id
- BOOL list_in_profile;
-
- struct LLGroupData;
- typedef std::list<LLGroupData> group_list_t;
-
- group_list_t group_list;
-
- struct LLGroupData
- {
- U64 group_powers;
- BOOL accept_notices;
- std::string group_title;
- LLUUID group_id;
- std::string group_name;
- LLUUID group_insignia_id;
- };
};
struct LLAvatarClassifieds
@@ -211,9 +198,7 @@ public:
// Request various types of avatar data. Duplicate requests will be
// suppressed while waiting for a response from the network.
void sendAvatarPropertiesRequest(const LLUUID& avatar_id);
- void sendAvatarPicksRequest(const LLUUID& avatar_id);
- void sendAvatarNotesRequest(const LLUUID& avatar_id);
- void sendAvatarGroupsRequest(const LLUUID& avatar_id);
+ void sendAvatarLegacyPropertiesRequest(const LLUUID& avatar_id);
void sendAvatarTexturesRequest(const LLUUID& avatar_id);
void sendAvatarClassifiedsRequest(const LLUUID& avatar_id);
@@ -222,21 +207,17 @@ public:
void sendClassifiedInfoRequest(const LLUUID& classified_id);
- void sendAvatarPropertiesUpdate(const LLAvatarData* avatar_props);
-
void sendPickInfoUpdate(const LLPickData* new_pick);
void sendClassifiedInfoUpdate(const LLAvatarClassifiedInfo* c_data);
void sendFriendRights(const LLUUID& avatar_id, S32 rights);
- void sendNotes(const LLUUID& avatar_id, const std::string notes);
-
void sendPickDelete(const LLUUID& pick_id);
void sendClassifiedDelete(const LLUUID& classified_id);
- void sendInterestsInfoUpdate(const LLInterestsData* interests_data);
+ bool isHideAgeSupportedByServer() { return mIsHideAgeSupportedByServer; }
// Returns translated, human readable string for account type, such
// as "Resident" or "Linden Employee". Used for profiles, inspectors.
@@ -249,30 +230,23 @@ public:
static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
- static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID agent_id);
-
- static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
+ static void requestAvatarPropertiesCoro(std::string cap_url, LLUUID avatar_id, EAvatarProcessorType type);
- static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
+ // Processing of UDP variant of properties, truncates certain fields!
+ static void processAvatarLegacyPropertiesReply(LLMessageSystem* msg, void**);
static void processAvatarClassifiedsReply(LLMessageSystem* msg, void**);
static void processClassifiedInfoReply(LLMessageSystem* msg, void**);
- static void processAvatarGroupsReply(LLMessageSystem* msg, void**);
-
- static void processAvatarNotesReply(LLMessageSystem* msg, void**);
-
- static void processAvatarPicksReply(LLMessageSystem* msg, void**);
-
static void processPickInfoReply(LLMessageSystem* msg, void**);
protected:
- void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
+ void sendRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
void sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method);
void sendAvatarPropertiesRequestMessage(const LLUUID& avatar_id);
- void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url);
+ void initAgentProfileCapRequest(const LLUUID& avatar_id, const std::string& cap_url, EAvatarProcessorType type);
void notifyObservers(const LLUUID& id,void* data, EAvatarProcessorType type);
@@ -302,6 +276,9 @@ protected:
// Map avatar_id+request_type -> U32 timestamp in seconds
typedef std::map< std::pair<LLUUID, EAvatarProcessorType>, U32> timestamp_map_t;
timestamp_map_t mRequestTimestamps;
+
+ // Is returned by isHideAgeSupportedByServer()
+ bool mIsHideAgeSupportedByServer { false };
};
#endif // LL_LLAVATARPROPERTIESPROCESSOR_H
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index a6c9a41fa4..b95b971890 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -339,6 +339,7 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio
}
catch (std::bad_alloc&)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
}
}
@@ -370,6 +371,7 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
}
catch (std::bad_alloc&)
{
+ LLError::LLUserWarningMsg::showOutOfMemory();
LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL;
}
}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 9e7a8ba95c..934b852a41 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -88,7 +88,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
{
// creating params for a channel
LLScreenChannelBase::Params p;
- p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
+ p.id = NOTIFICATION_CHANNEL_UUID;
p.channel_align = CA_RIGHT;
p.toast_align = NA_TOP;
@@ -108,7 +108,7 @@ void LLChannelManager::onLoginCompleted()
if (!channel) continue;
// don't calc notifications for Nearby Chat
- if(channel->getChannelID() == LLUUID(gSavedSettings.getString("NearByChatChannelUUID")))
+ if(channel->getChannelID() == NEARBY_CHAT_CHANNEL_UUID)
{
continue;
}
@@ -130,7 +130,7 @@ void LLChannelManager::onLoginCompleted()
{
// create a channel for the StartUp Toast
LLScreenChannelBase::Params p;
- p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
+ p.id = STARTUP_CHANNEL_UUID;
p.channel_align = CA_RIGHT;
mStartUpChannel = createChannel(p);
@@ -143,9 +143,8 @@ void LLChannelManager::onLoginCompleted()
gViewerWindow->getRootView()->addChild(mStartUpChannel);
// init channel's position and size
- S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ mStartUpChannel->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLFloaterNotificationsTabbed::onStartUpToastClick, LLFloaterNotificationsTabbed::getInstance(), _2, _3, _4));
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
@@ -164,7 +163,7 @@ void LLChannelManager::onStartUpToastClose()
{
mStartUpChannel->setVisible(FALSE);
mStartUpChannel->closeStartUpToast();
- removeChannelByID(LLUUID(gSavedSettings.getString("StartUpChannelUUID")));
+ removeChannelByID(STARTUP_CHANNEL_UUID);
mStartUpChannel = NULL;
}
@@ -258,12 +257,12 @@ LLNotificationsUI::LLScreenChannel* LLChannelManager::getNotificationScreenChann
{
LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
(LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ findChannelByID(NOTIFICATION_CHANNEL_UUID));
if (channel == NULL)
{
- LL_WARNS() << "Can't find screen channel by NotificationChannelUUID" << LL_ENDL;
- llassert(!"Can't find screen channel by NotificationChannelUUID");
+ LL_WARNS() << "Can't find screen channel by Notification Channel UUID" << LL_ENDL;
+ llassert(!"Can't find screen channel by Notification Channel UUID");
}
return channel;
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index aa2ba752b7..b138db48b5 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -142,7 +142,7 @@ protected:
registrar.add("Attachment.Touch", boost::bind(handleMultiple, handle_attachment_touch, mUUIDs));
registrar.add("Attachment.Edit", boost::bind(handleMultiple, handle_item_edit, mUUIDs));
- registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+ registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op));
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
enable_registrar.add("Attachment.OnEnable", boost::bind(&CofAttachmentContextMenu::onEnable, this, _2));
@@ -195,7 +195,7 @@ protected:
LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
LLUUID selected_id = mUUIDs.back();
- registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+ registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op));
registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));
registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index eb2c156ca5..320806d78d 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -66,6 +66,7 @@ namespace
{
const std::string QUEUE_EVENTPUMP_NAME("ScriptActionQueue");
+ const F32 QUEUE_INVENTORY_FETCH_TIMEOUT = 300.f;
// ObjectIventoryFetcher is an adapter between the LLVOInventoryListener::inventoryChanged
// callback mechanism and the LLEventPump coroutine architecture allowing the
@@ -359,8 +360,6 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
// Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle.
// which is caught in objectScriptProcessingQueueCoro
bool monocompile = floater->mMono;
- F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout");
-
// Initial test to see if we can (or should) attempt to compile the script.
LLInventoryItem *item = dynamic_cast<LLInventoryItem *>(inventory);
@@ -385,7 +384,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
LLExperienceCache::instance().fetchAssociatedExperience(inventory->getParentUUID(), inventory->getUUID(),
boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _1));
- result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
+ result = llcoro::suspendUntilEventOnWithTimeout(pump, QUEUE_INVENTORY_FETCH_TIMEOUT,
LLSDMap("timeout", LLSD::Boolean(true)));
floater.check();
@@ -435,7 +434,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
&LLFloaterCompileQueue::handleScriptRetrieval,
&userData);
- result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout,
+ result = llcoro::suspendUntilEventOnWithTimeout(pump, QUEUE_INVENTORY_FETCH_TIMEOUT,
LLSDMap("timeout", LLSD::Boolean(true)));
}
@@ -481,7 +480,7 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
- result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true)));
+ result = llcoro::suspendUntilEventOnWithTimeout(pump, QUEUE_INVENTORY_FETCH_TIMEOUT, LLSDMap("timeout", LLSD::Boolean(true)));
floater.check();
@@ -736,8 +735,6 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L
// Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle.
// This is expected if the dialog closes.
LLEventMailDrop maildrop(QUEUE_EVENTPUMP_NAME, true);
- F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout");
-
try
{
@@ -759,7 +756,7 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L
args["[OBJECT_NAME]"] = (*itObj).mObjectName;
floater->addStringMessage(floater->getString("LoadingObjInv", args));
- LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, fetch_timeout,
+ LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, QUEUE_INVENTORY_FETCH_TIMEOUT,
LLSDMap("timeout", LLSD::Boolean(true)));
if (result.has("timeout"))
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 7def9c045f..d5886b4ece 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -99,21 +99,6 @@ LLVOAvatar *LLControlAvatar::getAttachedAvatar()
void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_scale_fixup) const
{
-
- F32 max_legal_offset = MAX_LEGAL_OFFSET;
- if (gSavedSettings.getControl("AnimatedObjectsMaxLegalOffset"))
- {
- max_legal_offset = gSavedSettings.getF32("AnimatedObjectsMaxLegalOffset");
- }
- max_legal_offset = llmax(max_legal_offset,0.f);
-
- F32 max_legal_size = MAX_LEGAL_SIZE;
- if (gSavedSettings.getControl("AnimatedObjectsMaxLegalSize"))
- {
- max_legal_size = gSavedSettings.getF32("AnimatedObjectsMaxLegalSize");
- }
- max_legal_size = llmax(max_legal_size, 1.f);
-
new_pos_fixup = LLVector3();
new_scale_fixup = 1.0f;
LLVector3 vol_pos = mRootVolp->getRenderPosition();
@@ -138,9 +123,9 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_
{
LLVector3 pos_box_offset = point_to_box_offset(vol_pos, unshift_extents);
F32 offset_dist = pos_box_offset.length();
- if (offset_dist > max_legal_offset && offset_dist > 0.f)
+ if (offset_dist > MAX_LEGAL_OFFSET && offset_dist > 0.f)
{
- F32 target_dist = (offset_dist - max_legal_offset);
+ F32 target_dist = (offset_dist - MAX_LEGAL_OFFSET);
new_pos_fixup = (target_dist/offset_dist)*pos_box_offset;
}
if (new_pos_fixup != mPositionConstraintFixup)
@@ -153,11 +138,11 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_
}
}
- if (box_size/mScaleConstraintFixup > max_legal_size)
+ if (box_size/mScaleConstraintFixup > MAX_LEGAL_SIZE)
{
- new_scale_fixup = mScaleConstraintFixup*max_legal_size/box_size;
+ new_scale_fixup = mScaleConstraintFixup* MAX_LEGAL_SIZE /box_size;
LL_DEBUGS("ConstraintFix") << getFullname() << " scale fix, box_size " << box_size << " fixup "
- << mScaleConstraintFixup << " max legal " << max_legal_size
+ << mScaleConstraintFixup << " max legal " << MAX_LEGAL_SIZE
<< " -> new scale " << new_scale_fixup << LL_ENDL;
}
}
@@ -202,8 +187,7 @@ void LLControlAvatar::matchVolumeTransform()
mRoot->setWorldRotation(obj_rot * joint_rot);
setRotation(mRoot->getRotation());
- F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale");
- setGlobalScale(global_scale * mScaleConstraintFixup);
+ setGlobalScale(mScaleConstraintFixup);
}
else
{
@@ -253,8 +237,7 @@ void LLControlAvatar::matchVolumeTransform()
}
mRoot->setPosition(vol_pos + mPositionConstraintFixup);
- F32 global_scale = gSavedSettings.getF32("AnimatedObjectsGlobalScale");
- setGlobalScale(global_scale * mScaleConstraintFixup);
+ setGlobalScale(mScaleConstraintFixup);
}
}
}
@@ -379,6 +362,7 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
void LLControlAvatar::markDead()
{
+ mRootVolp = NULL;
super::markDead();
mControlAVBridge = NULL;
}
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 0cbfad8b73..5f7d2fb765 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -82,7 +82,7 @@ public:
virtual BOOL isItemRenameable() const { return TRUE; }
virtual BOOL renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return TRUE; }
virtual BOOL isItemMovable( void ) const { return FALSE; }
- virtual BOOL isItemRemovable( void ) const { return FALSE; }
+ virtual BOOL isItemRemovable(bool check_worn = true) const { return FALSE; }
virtual BOOL isItemInTrash( void) const { return FALSE; }
virtual BOOL removeItem() { return FALSE; }
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index edc7bdef5f..709ba34008 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -2104,7 +2104,7 @@ void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environ
{
LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
}
- else if (LLApp::isExiting())
+ else if (LLApp::isExiting() || gDisconnected)
{
return;
}
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 4ad136e13a..27b28681e0 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -627,6 +627,9 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
switch(filter)
{
case FFLOAD_ALL:
+ case FFLOAD_EXE:
+ allowedv->push_back("app");
+ allowedv->push_back("exe");
allowedv->push_back("wav");
allowedv->push_back("bvh");
allowedv->push_back("anim");
@@ -647,9 +650,6 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
allowedv->push_back("tpic");
allowedv->push_back("png");
break;
- case FFLOAD_EXE:
- allowedv->push_back("app");
- allowedv->push_back("exe");
break;
case FFLOAD_WAV:
allowedv->push_back("wav");
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 2422596f60..7b91d31d02 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -107,15 +107,11 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
mCloseOnSelect(FALSE),
mExcludeAgentFromSearchResults(FALSE),
mContextConeOpacity (0.f),
- mContextConeInAlpha(0.f),
- mContextConeOutAlpha(0.f),
- mContextConeFadeTime(0.f)
+ mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA),
+ mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA),
+ mContextConeFadeTime(CONTEXT_CONE_FADE_TIME)
{
mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
-
- mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
- mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
- mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
BOOL LLFloaterAvatarPicker::postBuild()
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index ba91277c79..1672969e82 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -102,9 +102,9 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
mActive ( TRUE ),
mCanApplyImmediately ( show_apply_immediate ),
mContextConeOpacity ( 0.f ),
- mContextConeInAlpha ( 0.f ),
- mContextConeOutAlpha ( 0.f ),
- mContextConeFadeTime ( 0.f )
+ mContextConeInAlpha (CONTEXT_CONE_IN_ALPHA),
+ mContextConeOutAlpha (CONTEXT_CONE_OUT_ALPHA),
+ mContextConeFadeTime (CONTEXT_CONE_FADE_TIME)
{
buildFromFile ( "floater_color_picker.xml");
@@ -116,10 +116,6 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
mApplyImmediateCheck->setEnabled(FALSE);
mApplyImmediateCheck->set(FALSE);
}
-
- mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
- mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
- mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
LLFloaterColorPicker::~LLFloaterColorPicker()
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 580a3f2610..97327da81a 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -37,13 +37,14 @@
const std::string LL_FCP_COMPLETE_NAME("complete_name");
const std::string LL_FCP_ACCOUNT_NAME("user_name");
+const S32 CONVERSATION_HISTORY_PAGE_SIZE = 100;
LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
: LLFloater(session_id),
mChatHistory(NULL),
mSessionID(session_id.asUUID()),
mCurrentPage(0),
- mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
+ mPageSize(CONVERSATION_HISTORY_PAGE_SIZE),
mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
mCompleteName(session_id[LL_FCP_COMPLETE_NAME]),
mMutex(),
diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp
index c64ee5a69c..6b21e0f3a5 100644
--- a/indra/newview/llfloaterenvironmentadjust.cpp
+++ b/indra/newview/llfloaterenvironmentadjust.cpp
@@ -116,7 +116,7 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()
getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setAllowNoTexture(TRUE);
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId());
- getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture")));
+ getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(DEFAULT_BLANK_NORMAL_TEXTURE);
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onWaterMapChanged(); });
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
diff --git a/indra/newview/llfloaterexperiencepicker.cpp b/indra/newview/llfloaterexperiencepicker.cpp
index c642da7b83..fe7854b3a5 100644
--- a/indra/newview/llfloaterexperiencepicker.cpp
+++ b/indra/newview/llfloaterexperiencepicker.cpp
@@ -88,13 +88,10 @@ LLFloaterExperiencePicker::LLFloaterExperiencePicker( const LLSD& key )
:LLFloater(key)
,mSearchPanel(NULL)
,mContextConeOpacity(0.f)
- ,mContextConeInAlpha(0.f)
- ,mContextConeOutAlpha(0.f)
- ,mContextConeFadeTime(0.f)
+ ,mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA)
+ ,mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA)
+ ,mContextConeFadeTime(CONTEXT_CONE_FADE_TIME)
{
- mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
- mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
- mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
LLFloaterExperiencePicker::~LLFloaterExperiencePicker()
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index bb4cc9bca3..80dd1c8566 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -260,7 +260,8 @@ void LLFloaterIMNearbyChat::loadHistory()
void LLFloaterIMNearbyChat::removeScreenChat()
{
- LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+ LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+ LLNotificationsUI::NEARBY_CHAT_CHANNEL_UUID);
if(chat_channel)
{
chat_channel->removeToastsFromChannel();
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 4cd91c53d8..be731c8043 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -459,7 +459,7 @@ LLFloaterIMNearbyChatHandler::LLFloaterIMNearbyChatHandler()
{
// Getting a Channel for our notifications
LLFloaterIMNearbyChatScreenChannel::Params p;
- p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
+ p.id = NEARBY_CHAT_CHANNEL_UUID;
LLFloaterIMNearbyChatScreenChannel* channel = new LLFloaterIMNearbyChatScreenChannel(p);
LLFloaterIMNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index ee9dc35283..5ac7b4a654 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -651,7 +651,7 @@ void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock)
// update notification channel state
LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
(LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID));
if(!isChatMultiTab())
{
@@ -687,7 +687,7 @@ void LLFloaterIMSession::setVisible(BOOL visible)
{
LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
(LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID));
LLFloaterIMSessionTab::setVisible(visible);
@@ -865,7 +865,7 @@ void LLFloaterIMSession::updateMessages()
// remove embedded notification from channel
LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
(LLNotificationsUI::LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID));
if (getVisible())
{
// toast will be automatically closed since it is not storable toast
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 558b14bba7..d3add020cf 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -250,6 +250,13 @@ void LLFloaterJoystick::refresh()
initFromSettings();
}
+bool LLFloaterJoystick::addDeviceCallback(std::string &name, LLSD& value, void* userdata)
+{
+ LLFloaterJoystick * floater = (LLFloaterJoystick*)userdata;
+ floater->mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
+ return false; // keep searching
+}
+
void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
{
mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
@@ -264,19 +271,21 @@ void LLFloaterJoystick::refreshListOfDevices()
mHasDeviceList = false;
+ void* win_calback = nullptr;
// di8_devices_callback callback is immediate and happens in scope of getInputDevices()
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
- void* callback = &di8_list_devices_callback;
+ win_calback = di8_list_devices_callback;
+#elif LL_DARWIN
+ U32 device_type = 0;
#else
- // MAC doesn't support device search yet
- // On MAC there is an ndof_idsearch and it is possible to specify product
- // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ // On MAC it is possible to specify product
+ // and manufacturer in NDOF_Device for
+ // ndof_init_first to pick specific device
U32 device_type = 0;
- void* callback = NULL;
#endif
- if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this))
+ if (gViewerWindow->getWindow()->getInputDevices(device_type, addDeviceCallback, win_calback, this))
{
mHasDeviceList = true;
}
@@ -418,10 +427,11 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
joystick->toggleFlycam();
}
}
-
- std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString();
- gSavedSettings.setString("JoystickDeviceUUID", device_id);
- LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL;
+
+ LLViewerJoystick::getInstance()->saveDeviceIdToSettings();
+
+ std::string device_string = LLViewerJoystick::getInstance()->getDeviceUUIDString();
+ LL_DEBUGS("Joystick") << "Selected " << device_string << " as joystick." << LL_ENDL;
self->refreshListOfDevices();
}
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index 1d46efd3f6..ff889c804b 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -46,6 +46,7 @@ public:
virtual void draw();
static void setSNDefaults();
+ static bool addDeviceCallback(std::string &name, LLSD& value, void* userdata);
void addDevice(std::string &name, LLSD& value);
protected:
diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp
index d1679fd936..2ff6c5618c 100644
--- a/indra/newview/llfloaternotificationstabbed.cpp
+++ b/indra/newview/llfloaternotificationstabbed.cpp
@@ -154,7 +154,7 @@ LLPanel * LLFloaterNotificationsTabbed::findItemByID(const LLUUID& id, std::stri
void LLFloaterNotificationsTabbed::initChannel()
{
LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
- LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID);
mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
if(NULL == mChannel)
{
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index aa723eb3a8..59edb6f357 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -367,9 +367,9 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
{
- if ( APT_PROPERTIES == type )
+ if ( APT_PROPERTIES_LEGACY == type )
{
- const LLAvatarData* pAvatarData = static_cast<const LLAvatarData*>( pData );
+ const LLAvatarLegacyData* pAvatarData = static_cast<const LLAvatarLegacyData*>( pData );
if (pAvatarData && (gAgent.getID() == pAvatarData->avatar_id) && (pAvatarData->avatar_id != LLUUID::null))
{
mAllowPublish = (bool)(pAvatarData->flags & AVATAR_ALLOW_PUBLISH);
@@ -509,9 +509,7 @@ BOOL LLFloaterPreference::postBuild()
void LLFloaterPreference::updateDeleteTranscriptsButton()
{
- std::vector<std::string> list_of_transcriptions_file_names;
- LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
- getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+ getChild<LLButton>("delete_transcripts")->setEnabled(LLLogChat::transcriptFilesExist());
}
void LLFloaterPreference::onDoNotDisturbResponseChanged()
@@ -676,7 +674,6 @@ void LLFloaterPreference::cancel()
void LLFloaterPreference::onOpen(const LLSD& key)
{
-
// this variable and if that follows it are used to properly handle do not disturb mode response message
static bool initialized = FALSE;
// if user is logged in and we haven't initialized do not disturb mode response yet, do it
@@ -703,7 +700,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
(gAgent.isMature() || gAgent.isGodlike());
LLComboBox* maturity_combo = getChild<LLComboBox>("maturity_desired_combobox");
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest( gAgent.getID() );
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarLegacyPropertiesRequest( gAgent.getID() );
if (can_choose_maturity)
{
// if they're not adult or a god, they shouldn't see the adult selection, so delete it
diff --git a/indra/newview/llfloaterprofiletexture.cpp b/indra/newview/llfloaterprofiletexture.cpp
index bf1f56a6d1..a78df1015a 100644
--- a/indra/newview/llfloaterprofiletexture.cpp
+++ b/indra/newview/llfloaterprofiletexture.cpp
@@ -139,6 +139,13 @@ void LLFloaterProfileTexture::draw()
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, owner);
+ if (mImage.notNull())
+ {
+ // Pump the texture priority
+ mImage->addTextureStats(MAX_IMAGE_AREA);
+ mImage->setKnownDrawSize(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT, LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
+ }
+
LLFloater::draw();
}
@@ -176,6 +183,8 @@ void LLFloaterProfileTexture::loadAsset(const LLUUID &image_id)
mImageID = image_id;
mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
mImageOldBoostLevel = mImage->getBoostLevel();
+ mImage->setKnownDrawSize(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT, LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT);
+ mImage->forceToSaveRawImage(0);
if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)
{
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 37ae80fa8f..a6ab61cbb9 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -48,12 +48,6 @@ public:
LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& tokens, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
{
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch"))
- {
- LLNotificationsUtil::add("NoSearch", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
const size_t parts = tokens.size();
// get the (optional) category for the search
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index c8559fc9d3..5d72f8e3bf 100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -146,12 +146,6 @@ public:
const std::string& grid,
LLMediaCtrl* web)
{
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableWorldMap"))
- {
- LLNotificationsUtil::add("NoWorldMap", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
if (params.size() == 0)
{
// support the secondlife:///app/worldmap SLapp
@@ -207,12 +201,6 @@ public:
const std::string& grid,
LLMediaCtrl* web)
{
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableWorldMap"))
- {
- LLNotificationsUtil::add("NoWorldMap", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
//Make sure we have some parameters
if (params.size() == 0)
{
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index c0f773968d..6c6d302599 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -58,6 +58,9 @@
// Longest time, in seconds, to wait for all animations to stop playing
const F32 MAX_WAIT_ANIM_SECS = 30.f;
+// Longest time, in seconds, to wait for a key release.
+// This should be relatively long, but not too long. 10 minutes is enough
+const F32 MAX_WAIT_KEY_SECS = 60.f * 10.f;
// Lightweight constructor.
// init() does the heavy lifting.
@@ -528,12 +531,13 @@ void LLGestureMgr::replaceGesture(const LLUUID& item_id, const LLUUID& new_asset
LLGestureMgr::instance().replaceGesture(base_item_id, gesture, new_asset_id);
}
-void LLGestureMgr::playGesture(LLMultiGesture* gesture)
+void LLGestureMgr::playGesture(LLMultiGesture* gesture, bool fromKeyPress)
{
if (!gesture) return;
// Reset gesture to first step
gesture->mCurrentStep = 0;
+ gesture->mTriggeredByKey = fromKeyPress;
// Add to list of playing
gesture->mPlaying = TRUE;
@@ -731,7 +735,8 @@ BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask)
if (!gesture) continue;
if (gesture->mKey == key
- && gesture->mMask == mask)
+ && gesture->mMask == mask
+ && gesture->mWaitingKeyRelease == FALSE)
{
matching.push_back(gesture);
}
@@ -744,13 +749,38 @@ BOOL LLGestureMgr::triggerGesture(KEY key, MASK mask)
LLMultiGesture* gesture = matching[random];
- playGesture(gesture);
+ playGesture(gesture, TRUE);
return TRUE;
}
return FALSE;
}
+BOOL LLGestureMgr::triggerGestureRelease(KEY key, MASK mask)
+{
+ std::vector <LLMultiGesture *> matching;
+ item_map_t::iterator it;
+
+ // collect matching gestures
+ for (it = mActive.begin(); it != mActive.end(); ++it)
+ {
+ LLMultiGesture* gesture = (*it).second;
+
+ // asset data might not have arrived yet
+ if (!gesture) continue;
+
+ if (gesture->mKey == key
+ && gesture->mMask == mask)
+ {
+ gesture->mKeyReleased = TRUE;
+ }
+ }
+
+ //If we found one, block. Otherwise tell them it's free to go.
+ return matching.size() > 0;
+}
+
+
S32 LLGestureMgr::getPlayingCount() const
{
return mPlaying.size();
@@ -899,6 +929,32 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
continue;
}
+ // If we're waiting a fixed amount of time, check for timer
+ // expiration.
+ if (gesture->mWaitingKeyRelease)
+ {
+ // We're waiting for a certain amount of time to pass
+ if (gesture->mKeyReleased)
+ {
+ // wait is done, continue execution
+ gesture->mWaitingKeyRelease = FALSE;
+ gesture->mCurrentStep++;
+ }
+ else if (gesture->mWaitTimer.getElapsedTimeF32() > MAX_WAIT_KEY_SECS)
+ {
+ LL_INFOS("GestureMgr") << "Waited too long for key release, continuing gesture."
+ << LL_ENDL;
+ gesture->mWaitingKeyRelease = FALSE;
+ gesture->mCurrentStep++;
+ }
+ else
+ {
+ // we're waiting, so execution is done for now
+ waiting = TRUE;
+ }
+ continue;
+ }
+
// If we're waiting on our animations to stop, poll for
// completion.
if (gesture->mWaitingAnimations)
@@ -1015,7 +1071,17 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
case STEP_WAIT:
{
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
- if (wait_step->mFlags & WAIT_FLAG_TIME)
+ if (gesture->mTriggeredByKey // Only wait here IF we were triggered by a key!
+ && gesture->mWaitingKeyRelease == FALSE // We can only do this once! Prevent gestures infinitely running
+ && wait_step->mFlags & WAIT_FLAG_KEY_RELEASE)
+ {
+ // Lets wait for the key release first so we don't hold up re-presses
+ gesture->mWaitingKeyRelease = TRUE;
+ gesture->mKeyReleased = FALSE;
+ // Use the wait timer as a deadlock breaker for key release waits.
+ gesture->mWaitTimer.reset();
+ }
+ else if (wait_step->mFlags & WAIT_FLAG_TIME)
{
gesture->mWaitingTimer = TRUE;
gesture->mWaitTimer.reset();
@@ -1023,8 +1089,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
else if (wait_step->mFlags & WAIT_FLAG_ALL_ANIM)
{
gesture->mWaitingAnimations = TRUE;
- // Use the wait timer as a deadlock breaker for animation
- // waits.
+ // Use the wait timer as a deadlock breaker for animation waits.
gesture->mWaitTimer.reset();
}
else
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 7c8e8279c2..e805c91145 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -102,7 +102,10 @@ public:
const item_map_t& getActiveGestures() const { return mActive; }
// Force a gesture to be played, for example, if it is being
// previewed.
- void playGesture(LLMultiGesture* gesture);
+ void playGesture(LLMultiGesture* gesture, bool fromKeyPress);
+ void playGesture(LLMultiGesture* gesture) {
+ playGesture(gesture, FALSE);
+ }
void playGesture(const LLUUID& item_id);
// Stop all requested or playing anims for this gesture
@@ -118,10 +121,14 @@ public:
{
mCallbackMap[inv_item_id] = cb;
}
- // Trigger the first gesture that matches this key.
+ // Trigger a random gesture that matches this key.
// Returns TRUE if it finds a gesture bound to that key.
BOOL triggerGesture(KEY key, MASK mask);
+ // Trigger release wait on all gestures that matches this key.
+ // Returns TRUE if it finds a gesture bound to that key.
+ BOOL triggerGestureRelease(KEY key, MASK mask);
+
// Trigger all gestures referenced as substrings in this string
BOOL triggerAndReviseString(const std::string &str, std::string *revised_string = NULL);
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 380e49c320..00d472215f 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -89,12 +89,6 @@ public:
return true;
}
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo"))
- {
- LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
if (tokens.size() < 1)
{
return false;
@@ -373,7 +367,16 @@ void LLGroupActions::processLeaveGroupDataResponse(const LLUUID group_id)
args["GROUP"] = gdatap->mName;
LLSD payload;
payload["group_id"] = group_id;
- LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
+ if (gdatap->mMembershipFee > 0)
+ {
+ args["COST"] = gdatap->mMembershipFee;
+ LLNotificationsUtil::add("GroupLeaveConfirmMember", args, payload, onLeaveGroup);
+ }
+ else
+ {
+ LLNotificationsUtil::add("GroupLeaveConfirmMemberNoFee", args, payload, onLeaveGroup);
+ }
+
}
// static
@@ -405,7 +408,7 @@ void LLGroupActions::inspect(const LLUUID& group_id)
}
// static
-void LLGroupActions::show(const LLUUID& group_id)
+void LLGroupActions::show(const LLUUID &group_id, bool expand_notices_tab)
{
if (group_id.isNull())
return;
@@ -413,6 +416,10 @@ void LLGroupActions::show(const LLUUID& group_id)
LLSD params;
params["group_id"] = group_id;
params["open_tab_name"] = "panel_group_info_sidetray";
+ if (expand_notices_tab)
+ {
+ params["action"] = "show_notices";
+ }
LLFloaterSidePanelContainer::showPanel("people", "panel_group_info_sidetray", params);
LLFloater *floater = LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("people");
diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h
index afc4686dd7..44513199c1 100644
--- a/indra/newview/llgroupactions.h
+++ b/indra/newview/llgroupactions.h
@@ -57,7 +57,7 @@ public:
/**
* Show group information panel.
*/
- static void show(const LLUUID& group_id);
+ static void show(const LLUUID& group_id, bool expand_notices_tab = false);
/**
* Show group inspector floater.
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 32af2592d3..14310536b2 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -303,6 +303,7 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
item->getChildView("info_btn")->setVisible( false);
item->getChildView("profile_btn")->setVisible( false);
+ item->getChildView("notices_btn")->setVisible(false);
item->setGroupIconVisible(mShowIcons);
if (!mShowIcons)
{
@@ -403,6 +404,7 @@ mGroupIcon(NULL),
mGroupNameBox(NULL),
mInfoBtn(NULL),
mProfileBtn(NULL),
+mNoticesBtn(NULL),
mVisibilityHideBtn(NULL),
mVisibilityShowBtn(NULL),
mGroupID(LLUUID::null),
@@ -435,6 +437,9 @@ BOOL LLGroupListItem::postBuild()
mProfileBtn = getChild<LLButton>("profile_btn");
mProfileBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onProfileBtnClick(); });
+ mNoticesBtn = getChild<LLButton>("notices_btn");
+ mNoticesBtn->setClickedCallback([this](LLUICtrl *, const LLSD &) { onNoticesBtnClick(); });
+
mVisibilityHideBtn = findChild<LLButton>("visibility_hide_btn");
if (mVisibilityHideBtn)
{
@@ -470,13 +475,17 @@ void LLGroupListItem::onMouseEnter(S32 x, S32 y, MASK mask)
{
mInfoBtn->setVisible(true);
mProfileBtn->setVisible(true);
- if (mForAgent && mVisibilityHideBtn)
+ if (mForAgent)
{
LLGroupData agent_gdatap;
if (gAgent.getGroupData(mGroupID, agent_gdatap))
{
- mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
- mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ if (mVisibilityHideBtn)
+ {
+ mVisibilityHideBtn->setVisible(agent_gdatap.mListInProfile);
+ mVisibilityShowBtn->setVisible(!agent_gdatap.mListInProfile);
+ }
+ mNoticesBtn->setVisible(true);
}
}
}
@@ -489,6 +498,7 @@ void LLGroupListItem::onMouseLeave(S32 x, S32 y, MASK mask)
getChildView("hovered_icon")->setVisible( false);
mInfoBtn->setVisible(false);
mProfileBtn->setVisible(false);
+ mNoticesBtn->setVisible(false);
if (mVisibilityHideBtn)
{
mVisibilityHideBtn->setVisible(false);
@@ -583,6 +593,11 @@ void LLGroupListItem::onProfileBtnClick()
LLGroupActions::show(mGroupID);
}
+void LLGroupListItem::onNoticesBtnClick()
+{
+ LLGroupActions::show(mGroupID, true);
+}
+
void LLGroupListItem::onVisibilityBtnClick(bool new_visibility)
{
LLGroupData agent_gdatap;
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 5cbabb712f..1bc2caff33 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -123,6 +123,7 @@ private:
void setBold(bool bold);
void onInfoBtnClick();
void onProfileBtnClick();
+ void onNoticesBtnClick();
void onVisibilityBtnClick(bool new_visibility);
LLTextBox* mGroupNameBox;
@@ -130,6 +131,7 @@ private:
LLGroupIconCtrl* mGroupIcon;
LLButton* mInfoBtn;
LLButton* mProfileBtn;
+ LLButton* mNoticesBtn;
LLButton* mVisibilityHideBtn;
LLButton* mVisibilityShowBtn;
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 0fa3dc1110..99be4dc92b 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -54,9 +54,8 @@ LLIMHandler::~LLIMHandler()
//--------------------------------------------------------------------------
void LLIMHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound);
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 61a01d7418..17a28e84bb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -581,6 +581,12 @@ void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from,
return;
}
+ if (LLApp::isExiting() || gDisconnected)
+ {
+ LL_DEBUGS("ChatHistory") << "Ignoring chat history response, shutting down" << LL_ENDL;
+ return;
+ }
+
// Add history to IM session
LLSD history = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
@@ -3915,6 +3921,12 @@ public:
const LLSD& context,
const LLSD& input) const
{
+ if (LLApp::isExiting() || gDisconnected)
+ {
+ LL_DEBUGS("ChatHistory") << "Ignoring ChatterBox session, Shutting down" << LL_ENDL;
+ return;
+ }
+
LLSD body;
LLUUID temp_session_id;
LLUUID session_id;
diff --git a/indra/newview/llinspect.cpp b/indra/newview/llinspect.cpp
index f382b5985f..0da0609ff7 100644
--- a/indra/newview/llinspect.cpp
+++ b/indra/newview/llinspect.cpp
@@ -45,8 +45,8 @@ LLInspect::~LLInspect()
// virtual
void LLInspect::draw()
{
- static LLCachedControl<F32> FADE_TIME(*LLUI::getInstance()->mSettingGroups["config"], "InspectorFadeTime", 1.f);
- static LLCachedControl<F32> STAY_TIME(*LLUI::getInstance()->mSettingGroups["config"], "InspectorShowTime", 1.f);
+ const F32 FADE_TIME = 0.5f;
+ const F32 STAY_TIME = 3.f;
if (mOpenTimer.getStarted())
{
LLFloater::draw();
@@ -59,7 +59,7 @@ void LLInspect::draw()
}
else if (mCloseTimer.getStarted())
{
- F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME(), 1.f, 0.f);
+ F32 alpha = clamp_rescale(mCloseTimer.getElapsedTimeF32(), 0.f, FADE_TIME, 1.f, 0.f);
LLViewDrawContext context(alpha);
LLFloater::draw();
if (mCloseTimer.getElapsedTimeF32() > FADE_TIME)
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index b11c440015..ca18dc343d 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -261,12 +261,15 @@ void LLInspectAvatar::requestUpdate()
void LLInspectAvatar::processAvatarData(LLAvatarData* data)
{
LLStringUtil::format_map_t args;
- {
- std::string birth_date = LLTrans::getString("AvatarBirthDateFormat");
- LLStringUtil::format(birth_date, LLSD().with("datetime", (S32) data->born_on.secondsSinceEpoch()));
- args["[BORN_ON]"] = birth_date;
- }
- args["[AGE]"] = LLDateUtil::ageFromDate(data->born_on, LLDate::now());
+
+ std::string birth_date = LLTrans::getString(data->hide_age ?
+ "AvatarBirthDateFormatShort" :
+ "AvatarBirthDateFormatFull");
+ LLStringUtil::format(birth_date, LLSD().with("datetime", (S32)data->born_on.secondsSinceEpoch()));
+ args["[BORN_ON]"] = birth_date;
+ args["[AGE]"] = data->hide_age ?
+ LLStringUtilBase<char>::null :
+ LLDateUtil::ageFromDate(data->born_on, LLDate::now());
args["[SL_PROFILE]"] = data->about_text;
args["[RW_PROFILE"] = data->fl_about_text;
args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(data);
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index 6f93a78ca6..21cdde0bea 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -60,8 +60,8 @@ private:
LLInspectToast::LLInspectToast(const LLSD& notification_id) :
LLInspect(LLSD()), mPanel(NULL)
{
- LLScreenChannelBase* channel = LLChannelManager::getInstance()->findChannelByID(
- LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLScreenChannelBase* channel = LLChannelManager::getInstance()->findChannelByID(
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID);
mScreenChannel = dynamic_cast<LLScreenChannel*>(channel);
if(NULL == mScreenChannel)
{
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 932a0316dd..988dffc8a5 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -90,6 +90,7 @@
void copy_slurl_to_clipboard_callback_inv(const std::string& slurl);
const F32 SOUND_GAIN = 1.0f;
+const F32 FOLDER_LOADING_MESSAGE_DELAY = 0.5f; // Seconds to wait before showing the LOADING... text in folder views
using namespace LLOldEvents;
@@ -308,9 +309,9 @@ void LLInvFVBridge::setCreationDate(time_t creation_date_utc)
// Can be destroyed (or moved to trash)
-BOOL LLInvFVBridge::isItemRemovable() const
+BOOL LLInvFVBridge::isItemRemovable(bool check_worn) const
{
- return get_is_item_removable(getInventoryModel(), mUUID);
+ return get_is_item_removable(getInventoryModel(), mUUID, check_worn);
}
// Can be moved to another folder
@@ -772,9 +773,6 @@ void hide_context_entries(LLMenuGL& menu,
bool found = false;
- std::string myinput;
- std::vector<std::string> mylist{ "a", "b", "c" };
-
menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name);
if (itor2 != entries_to_show.end())
{
@@ -874,7 +872,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
items.push_back(std::string("Cut"));
- if (!isItemMovable() || !isItemRemovable())
+ if (!isItemMovable() || !canMenuCut())
{
disabled_items.push_back(std::string("Cut"));
}
@@ -923,7 +921,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if(!single_folder_root)
{
items.push_back(std::string("Cut"));
- if (!isItemMovable() || !isItemRemovable())
+ if (!isItemMovable() || !canMenuCut())
{
disabled_items.push_back(std::string("Cut"));
}
@@ -1068,7 +1066,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items,
items.push_back(std::string("Delete"));
- if (!isItemRemovable() || isPanelActive("Favorite Items"))
+ if (isPanelActive("Favorite Items") || !canMenuDelete())
{
disabled_items.push_back(std::string("Delete"));
}
@@ -1224,6 +1222,16 @@ void LLInvFVBridge::addLinkReplaceMenuOption(menuentry_vec_t& items, menuentry_v
}
}
+bool LLInvFVBridge::canMenuDelete()
+{
+ return isItemRemovable(false);
+}
+
+bool LLInvFVBridge::canMenuCut()
+{
+ return isItemRemovable(true);
+}
+
// *TODO: remove this
BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
{
@@ -1778,7 +1786,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
}
else if ("show_in_main_panel" == action)
{
- LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, mUUID, TRUE);
+ LLInventoryPanel::openInventoryPanelAndSetSelection(true, mUUID, true);
return;
}
else if ("cut" == action)
@@ -2412,48 +2420,19 @@ void LLFolderBridge::update()
}
}
-
-// Iterate through a folder's children to determine if
-// all the children are removable.
-class LLIsItemRemovable : public LLFolderViewFunctor
-{
-public:
- LLIsItemRemovable() : mPassed(TRUE) {}
- virtual void doFolder(LLFolderViewFolder* folder)
- {
- mPassed &= folder->getViewModelItem()->isItemRemovable();
- }
- virtual void doItem(LLFolderViewItem* item)
- {
- mPassed &= item->getViewModelItem()->isItemRemovable();
- }
- BOOL mPassed;
-};
-
// Can be destroyed (or moved to trash)
-BOOL LLFolderBridge::isItemRemovable() const
+BOOL LLFolderBridge::isItemRemovable(bool check_worn) const
{
- if (!get_is_category_removable(getInventoryModel(), mUUID))
+ if (!get_is_category_and_children_removable(getInventoryModel(), mUUID, check_worn))
{
return FALSE;
}
- LLInventoryPanel* panel = mInventoryPanel.get();
- LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getItemByID(mUUID) : NULL);
- if (folderp)
- {
- LLIsItemRemovable folder_test;
- folderp->applyFunctorToChildren(folder_test);
- if (!folder_test.mPassed)
- {
- return FALSE;
- }
- }
-
- if (isMarketplaceListingsFolder() && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID)))
- {
- return FALSE;
- }
+ if (isMarketplaceListingsFolder()
+ && (!LLMarketplaceData::instance().isSLMDataFetched() || LLMarketplaceData::instance().getActivationState(mUUID)))
+ {
+ return FALSE;
+ }
return TRUE;
}
@@ -3409,7 +3388,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
}
else if ("show_in_main_panel" == action)
{
- LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, mUUID, TRUE);
+ LLInventoryPanel::openInventoryPanelAndSetSelection(true, mUUID, true);
return;
}
else if ("cut" == action)
@@ -4383,6 +4362,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back("New Settings");
}
}
+ else
+ {
+ items.push_back(std::string("New Listing Folder"));
+ }
if (menu_items_added)
{
items.push_back(std::string("Create Separator"));
@@ -4524,7 +4507,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
return;
}
- if (!isItemRemovable())
+ if (!canMenuDelete())
{
disabled_items.push_back(std::string("Delete"));
}
@@ -4895,6 +4878,192 @@ void LLFolderBridge::modifyOutfit(BOOL append)
}
}
+//static
+void LLFolderBridge::onCanDeleteIdle(void* user_data)
+{
+ LLFolderBridge* self = (LLFolderBridge*)user_data;
+
+ // we really need proper onidle mechanics that returns available time
+ const F32 EXPIRY_SECONDS = 0.008f;
+ LLTimer timer;
+ timer.setTimerExpirySec(EXPIRY_SECONDS);
+
+ LLInventoryModel* model = self->getInventoryModel();
+ if (model)
+ {
+ switch (self->mCanDeleteFolderState)
+ {
+ case CDS_INIT_FOLDER_CHECK:
+ // Can still be expensive, split it further?
+ model->collectDescendents(
+ self->mUUID,
+ self->mFoldersToCheck,
+ self->mItemsToCheck,
+ LLInventoryModel::EXCLUDE_TRASH);
+ self->mCanDeleteFolderState = CDS_PROCESSING_ITEMS;
+ break;
+
+ case CDS_PROCESSING_ITEMS:
+ while (!timer.hasExpired() && !self->mItemsToCheck.empty())
+ {
+ LLViewerInventoryItem* item = self->mItemsToCheck.back().get();
+ if (item)
+ {
+ if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item))
+ {
+ if (get_is_item_worn(item))
+ {
+ // At the moment we disable 'cut' if category has worn items (do we need to?)
+ // but allow 'delete' to happen since it will prompt user to detach
+ self->mCanCut = false;
+ }
+ }
+
+ if (!item->getIsLinkType() && get_is_item_worn(item))
+ {
+ self->mCanCut = false;
+ }
+ }
+ self->mItemsToCheck.pop_back();
+ }
+ self->mCanDeleteFolderState = CDS_PROCESSING_FOLDERS;
+ break;
+ case CDS_PROCESSING_FOLDERS:
+ {
+ const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
+ LLViewerInventoryCategory* outfit_linked_category = base_outfit_link ? base_outfit_link->getLinkedCategory() : nullptr;
+
+ while (!timer.hasExpired() && !self->mFoldersToCheck.empty())
+ {
+ LLViewerInventoryCategory* cat = self->mFoldersToCheck.back().get();
+ if (cat)
+ {
+ const LLFolderType::EType folder_type = cat->getPreferredType();
+ if (LLFolderType::lookupIsProtectedType(folder_type))
+ {
+ self->mCanCut = false;
+ self->mCanDelete = false;
+ self->completeDeleteProcessing();
+ break;
+ }
+
+ // Can't delete the outfit that is currently being worn.
+ if (folder_type == LLFolderType::FT_OUTFIT)
+ {
+ if (cat == outfit_linked_category)
+ {
+ self->mCanCut = false;
+ self->mCanDelete = false;
+ self->completeDeleteProcessing();
+ break;
+ }
+ }
+ }
+ self->mFoldersToCheck.pop_back();
+ }
+ }
+ self->mCanDeleteFolderState = CDS_DONE;
+ break;
+ case CDS_DONE:
+ self->completeDeleteProcessing();
+ break;
+ }
+ }
+}
+
+bool LLFolderBridge::canMenuDelete()
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (!model) return false;
+ LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
+ if (!category)
+ {
+ return false;
+ }
+
+ S32 version = category->getVersion();
+ if (mLastCheckedVersion == version)
+ {
+ return mCanDelete;
+ }
+
+ initCanDeleteProcessing(model, version);
+ return false;
+}
+
+bool LLFolderBridge::canMenuCut()
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (!model) return false;
+ LLViewerInventoryCategory* category = (LLViewerInventoryCategory*)model->getCategory(mUUID);
+ if (!category)
+ {
+ return false;
+ }
+
+ S32 version = category->getVersion();
+ if (mLastCheckedVersion == version)
+ {
+ return mCanCut;
+ }
+
+ initCanDeleteProcessing(model, version);
+ return false;
+}
+
+void LLFolderBridge::initCanDeleteProcessing(LLInventoryModel* model, S32 version)
+{
+ if (mCanDeleteFolderState == CDS_DONE
+ || mInProgressVersion != version)
+ {
+ if (get_is_category_removable(model, mUUID))
+ {
+ // init recursive check of content
+ mInProgressVersion = version;
+ mCanCut = true;
+ mCanDelete = true;
+ mCanDeleteFolderState = CDS_INIT_FOLDER_CHECK;
+ mFoldersToCheck.clear();
+ mItemsToCheck.clear();
+ gIdleCallbacks.addFunction(onCanDeleteIdle, this);
+ }
+ else
+ {
+ // no check needed
+ mCanDelete = false;
+ mCanCut = false;
+ mLastCheckedVersion = version;
+ mCanDeleteFolderState = CDS_DONE;
+ mFoldersToCheck.clear();
+ mItemsToCheck.clear();
+ }
+ }
+}
+
+void LLFolderBridge::completeDeleteProcessing()
+{
+ LLInventoryModel* model = getInventoryModel();
+ LLViewerInventoryCategory* category = model ? (LLViewerInventoryCategory*)model->getCategory(mUUID) : nullptr;
+ if (model && category && category->getVersion() == mInProgressVersion)
+ {
+ mLastCheckedVersion = mInProgressVersion;
+ mCanDeleteFolderState = CDS_DONE;
+ gIdleCallbacks.deleteFunction(onCanDeleteIdle, this);
+ }
+ else
+ {
+ mCanDelete = false;
+ mCanCut = false;
+ mLastCheckedVersion = LLViewerInventoryCategory::VERSION_UNKNOWN;
+ mCanDeleteFolderState = CDS_DONE;
+ }
+
+ if (mRoot)
+ {
+ mRoot->updateMenu();
+ }
+}
+
// +=================================================+
// | LLMarketplaceFolderBridge |
@@ -4938,9 +5107,7 @@ LLUIImagePtr LLMarketplaceFolderBridge::getMarketplaceFolderIcon(BOOL is_open) c
std::string LLMarketplaceFolderBridge::getLabelSuffix() const
{
- static LLCachedControl<F32> folder_loading_message_delay(gSavedSettings, "FolderLoadingMessageWaitTime", 0.5f);
-
- if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= folder_loading_message_delay())
+ if (mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= FOLDER_LOADING_MESSAGE_DELAY)
{
return llformat(" ( %s ) ", LLTrans::getString("LoadingData").c_str());
}
@@ -5058,6 +5225,27 @@ void drop_to_favorites_cb(const LLUUID& id, LLPointer<LLInventoryCallback> cb1,
cb2->fire(id);
}
+LLFolderBridge::LLFolderBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid)
+ : LLInvFVBridge(inventory, root, uuid)
+ , mCallingCards(FALSE)
+ , mWearables(FALSE)
+ , mIsLoading(false)
+ , mShowDescendantsCount(false)
+ , mCanDeleteFolderState(CDS_DONE)
+ , mLastCheckedVersion(S32_MIN)
+ , mInProgressVersion(S32_MIN)
+ , mCanDelete(false)
+ , mCanCut(false)
+{
+}
+
+LLFolderBridge::~LLFolderBridge()
+{
+ gIdleCallbacks.deleteFunction(onCanDeleteIdle, this);
+}
+
void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb)
{
// use callback to rearrange favorite landmarks after adding
@@ -6651,6 +6839,26 @@ LLInventoryObject* LLObjectBridge::getObject() const
return object;
}
+LLViewerInventoryItem* LLObjectBridge::getItem() const
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (model)
+ {
+ return model->getItem(mUUID);
+ }
+ return NULL;
+}
+
+LLViewerInventoryCategory* LLObjectBridge::getCategory() const
+{
+ LLInventoryModel* model = getInventoryModel();
+ if (model)
+ {
+ return model->getCategory(mUUID);
+ }
+ return NULL;
+}
+
// virtual
void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
{
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 3cbbd68e51..8bdb76cdef 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -114,7 +114,7 @@ public:
virtual BOOL isItemRenameable() const { return TRUE; }
virtual BOOL isMultiPreviewAllowed() { return TRUE; }
//virtual BOOL renameItem(const std::string& new_name) {}
- virtual BOOL isItemRemovable() const;
+ virtual BOOL isItemRemovable(bool check_worn = true) const;
virtual BOOL isItemMovable() const;
virtual BOOL isItemInTrash() const;
virtual bool isItemInOutfits() const;
@@ -162,6 +162,9 @@ protected:
virtual void addLinkReplaceMenuOption(menuentry_vec_t& items,
menuentry_vec_t& disabled_items);
+ virtual bool canMenuDelete();
+ virtual bool canMenuCut();
+
protected:
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
@@ -272,14 +275,10 @@ class LLFolderBridge : public LLInvFVBridge
public:
LLFolderBridge(LLInventoryPanel* inventory,
LLFolderView* root,
- const LLUUID& uuid)
- : LLInvFVBridge(inventory, root, uuid),
- mCallingCards(FALSE),
- mWearables(FALSE),
- mIsLoading(false),
- mShowDescendantsCount(false)
- {}
-
+ const LLUUID& uuid);
+
+ ~LLFolderBridge();
+
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL);
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg, BOOL is_link = FALSE, BOOL user_confirm = TRUE, LLPointer<LLInventoryCallback> cb = NULL);
void callback_dropItemIntoFolder(const LLSD& notification, const LLSD& response, LLInventoryItem* inv_item);
@@ -321,7 +320,7 @@ public:
void* cargo_data,
std::string& tooltip_msg);
- virtual BOOL isItemRemovable() const;
+ virtual BOOL isItemRemovable(bool check_worn = true) const;
virtual BOOL isItemMovable() const ;
virtual BOOL isUpToDate() const;
virtual bool isItemCopyable(bool can_copy_as_link = true) const;
@@ -392,6 +391,31 @@ protected:
LLTimer mTimeSinceRequestStart;
std::string mMessage;
LLRootHandle<LLFolderBridge> mHandle;
+
+private:
+ // checking if folder is cutable or deletable is expensive,
+ // cache values and split check over frames
+ static void onCanDeleteIdle(void* user_data);
+ void initCanDeleteProcessing(LLInventoryModel* model, S32 version);
+ void completeDeleteProcessing();
+ bool canMenuDelete();
+ bool canMenuCut();
+
+ enum ECanDeleteState
+ {
+ CDS_INIT_FOLDER_CHECK,
+ CDS_PROCESSING_ITEMS,
+ CDS_PROCESSING_FOLDERS,
+ CDS_DONE,
+ };
+
+ ECanDeleteState mCanDeleteFolderState;
+ LLInventoryModel::cat_array_t mFoldersToCheck;
+ LLInventoryModel::item_array_t mItemsToCheck;
+ S32 mLastCheckedVersion;
+ S32 mInProgressVersion;
+ bool mCanDelete;
+ bool mCanCut;
};
class LLTextureBridge : public LLItemBridge
@@ -524,6 +548,8 @@ public:
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual BOOL renameItem(const std::string& new_name);
LLInventoryObject* getObject() const;
+ LLViewerInventoryItem* getItem() const;
+ LLViewerInventoryCategory* getCategory() const;
protected:
static LLUUID sContextMenuItemID; // Only valid while the context menu is open.
U32 mAttachPt;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 4aeacae6ed..97568fede1 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -579,9 +579,8 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id)
return FALSE;
}
-BOOL get_is_item_worn(const LLUUID& id)
+BOOL get_is_item_worn(const LLUUID& id, const LLViewerInventoryItem* item)
{
- const LLViewerInventoryItem* item = gInventory.getItem(id);
if (!item)
return FALSE;
@@ -619,6 +618,21 @@ BOOL get_is_item_worn(const LLUUID& id)
return FALSE;
}
+BOOL get_is_item_worn(const LLUUID& id)
+{
+ const LLViewerInventoryItem* item = gInventory.getItem(id);
+ return get_is_item_worn(id, item);
+}
+
+BOOL get_is_item_worn(const LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return FALSE;
+ }
+ return get_is_item_worn(item->getUUID(), item);
+}
+
BOOL get_can_item_be_worn(const LLUUID& id)
{
const LLViewerInventoryItem* item = gInventory.getItem(id);
@@ -682,39 +696,39 @@ BOOL get_can_item_be_worn(const LLUUID& id)
return FALSE;
}
-BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
+bool get_is_item_removable(const LLInventoryModel* model, const LLUUID& id, bool check_worn)
{
if (!model)
{
- return FALSE;
+ return false;
}
// Can't delete an item that's in the library.
if (!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
{
- return FALSE;
+ return false;
}
// Disable delete from COF folder; have users explicitly choose "detach/take off",
// unless the item is not worn but in the COF (i.e. is bugged).
- if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id))
+ const LLViewerInventoryItem* obj = model->getItem(id);
+ if (LLAppearanceMgr::instance().getIsProtectedCOFItem(obj))
{
- if (get_is_item_worn(id))
+ if (get_is_item_worn(id, obj))
{
- return FALSE;
+ return false;
}
}
- const LLInventoryObject *obj = model->getItem(id);
if (obj && obj->getIsLinkType())
{
- return TRUE;
+ return true;
}
- if (get_is_item_worn(id))
+ if (check_worn && get_is_item_worn(id, obj))
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
bool get_is_item_editable(const LLUUID& inv_item_id)
@@ -805,6 +819,74 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
return TRUE;
}
+bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUID& folder_id, bool check_worn)
+{
+ if (!get_is_category_removable(model, folder_id))
+ {
+ return false;
+ }
+
+ const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id))
+ {
+ return false;
+ }
+
+ LLInventoryModel::cat_array_t cat_array;
+ LLInventoryModel::item_array_t item_array;
+ model->collectDescendents(
+ folder_id,
+ cat_array,
+ item_array,
+ LLInventoryModel::EXCLUDE_TRASH);
+
+ if (check_worn)
+ {
+ for (LLInventoryModel::item_array_t::value_type& item : item_array)
+ {
+ // Disable delete/cut from COF folder; have users explicitly choose "detach/take off",
+ // unless the item is not worn but in the COF (i.e. is bugged).
+ if (item)
+ {
+ if (LLAppearanceMgr::instance().getIsProtectedCOFItem(item))
+ {
+ if (get_is_item_worn(item))
+ {
+ return false;
+ }
+ }
+
+ if (!item->getIsLinkType() && get_is_item_worn(item))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
+ LLViewerInventoryCategory* outfit_linked_category = base_outfit_link ? base_outfit_link->getLinkedCategory() : nullptr;
+ for (LLInventoryModel::cat_array_t::value_type& cat : cat_array)
+ {
+ const LLFolderType::EType folder_type = cat->getPreferredType();
+ if (LLFolderType::lookupIsProtectedType(folder_type))
+ {
+ return false;
+ }
+
+ // Can't delete the outfit that is currently being worn.
+ if (folder_type == LLFolderType::FT_OUTFIT)
+ {
+ if (cat == outfit_linked_category)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
{
if (!model)
@@ -2759,7 +2841,7 @@ bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventory
{
if (item)
{
- return !get_is_item_removable(&gInventory, item->getUUID());
+ return !get_is_item_removable(&gInventory, item->getUUID(), true);
}
if (cat)
{
@@ -3024,6 +3106,8 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
{
const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
bool marketplacelistings_item = false;
+ bool has_worn = false;
+ bool needs_replacement = false;
LLAllDescendentsPassedFilter f;
for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(); (it != selected_items.end()) && (f.allDescendentsPassedFilter()); ++it)
{
@@ -3032,14 +3116,69 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
folder->applyFunctorRecursively(f);
}
LLFolderViewModelItemInventory * viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
- if (viewModel && gInventory.isObjectDescendentOf(viewModel->getUUID(), marketplacelistings_id))
+ LLUUID obj_id = viewModel->getUUID();
+ if (viewModel && gInventory.isObjectDescendentOf(obj_id, marketplacelistings_id))
{
marketplacelistings_item = true;
break;
}
+
+ LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+ if (cat)
+ {
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(obj_id, categories, items, FALSE);
+
+ for (LLInventoryModel::item_array_t::value_type& item : items)
+ {
+ if (get_is_item_worn(item))
+ {
+ has_worn = true;
+ LLWearableType::EType type = item->getWearableType();
+ if (type == LLWearableType::WT_SHAPE
+ || type == LLWearableType::WT_SKIN
+ || type == LLWearableType::WT_HAIR
+ || type == LLWearableType::WT_EYES)
+ {
+ needs_replacement = true;
+ break;
+ }
+ }
+ }
+ if (needs_replacement)
+ {
+ break;
+ }
+ }
+ LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+ if (item && get_is_item_worn(item))
+ {
+ has_worn = true;
+ LLWearableType::EType type = item->getWearableType();
+ if (type == LLWearableType::WT_SHAPE
+ || type == LLWearableType::WT_SKIN
+ || type == LLWearableType::WT_HAIR
+ || type == LLWearableType::WT_EYES)
+ {
+ needs_replacement = true;
+ break;
+ }
+ }
}
// Fall through to the generic confirmation if the user choose to ignore the specialized one
- if ( (!f.allDescendentsPassedFilter()) && !marketplacelistings_item && (!LLNotifications::instance().getIgnored("DeleteFilteredItems")) )
+ if (needs_replacement)
+ {
+ LLNotificationsUtil::add("CantDeleteRequiredClothing");
+ }
+ else if (has_worn)
+ {
+ LLSD payload;
+ payload["has_worn"] = true;
+ LLNotificationsUtil::add("DeleteWornItems", LLSD(), payload, boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle()));
+ }
+ else if ( (!f.allDescendentsPassedFilter()) && !marketplacelistings_item && (!LLNotifications::instance().getIgnored("DeleteFilteredItems")) )
{
LLNotificationsUtil::add("DeleteFilteredItems", LLSD(), LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root->getHandle()));
}
@@ -3362,11 +3501,81 @@ void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, con
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0 && !root.isDead() && !root.get()->isDead())
{
+ bool has_worn = notification["payload"]["has_worn"].asBoolean();
LLFolderView* folder_root = root.get();
//Need to remove item from DND before item is removed from root folder view
//because once removed from root folder view the item is no longer a selected item
removeItemFromDND(folder_root);
- folder_root->removeSelectedItems();
+
+ // removeSelectedItems will change selection, collect worn items beforehand
+ uuid_vec_t worn;
+ uuid_vec_t item_deletion_list;
+ uuid_vec_t cat_deletion_list;
+ if (has_worn)
+ {
+ //Get selected items
+ LLFolderView::selected_items_t selectedItems = folder_root->getSelectedItems();
+
+ //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification
+ //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
+ for (LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+ {
+ LLFolderViewModelItemInventory* viewModel = dynamic_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem());
+
+ LLUUID obj_id = viewModel->getUUID();
+ LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+ bool cat_has_worn = false;
+ if (cat)
+ {
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(obj_id, categories, items, FALSE);
+
+ for (LLInventoryModel::item_array_t::value_type& item : items)
+ {
+ if (get_is_item_worn(item))
+ {
+ worn.push_back(item->getUUID());
+ cat_has_worn = true;
+ }
+ }
+ if (cat_has_worn)
+ {
+ cat_deletion_list.push_back(obj_id);
+ }
+ }
+ LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+ if (item && get_is_item_worn(item))
+ {
+ worn.push_back(obj_id);
+ item_deletion_list.push_back(obj_id);
+ }
+ }
+ }
+
+ // removeSelectedItems will check if items are worn before deletion,
+ // don't 'unwear' yet to prevent race conditions from unwearing
+ // and removing simultaneously
+ folder_root->removeSelectedItems();
+
+ // unwear then delete the rest
+ if (!worn.empty())
+ {
+ // should fire once after every item gets detached
+ LLAppearanceMgr::instance().removeItemsFromAvatar(worn,
+ [item_deletion_list, cat_deletion_list]()
+ {
+ for (const LLUUID& id : item_deletion_list)
+ {
+ remove_inventory_item(id, NULL);
+ }
+ for (const LLUUID& id : cat_deletion_list)
+ {
+ remove_inventory_category(id, NULL);
+ }
+ });
+ }
// Update the marketplace listings that have been affected by the operation
updateMarketplaceFolders();
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 925217dda3..deacaced42 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -47,17 +47,19 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id);
// Is this item or its baseitem is worn, attached, etc...
BOOL get_is_item_worn(const LLUUID& id);
+BOOL get_is_item_worn(const LLViewerInventoryItem* item);
// Could this item be worn (correct type + not already being worn)
BOOL get_can_item_be_worn(const LLUUID& id);
-BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id);
+bool get_is_item_removable(const LLInventoryModel* model, const LLUUID& id, bool check_worn);
// Performs the appropiate edit action (if one exists) for this item
bool get_is_item_editable(const LLUUID& inv_item_id);
void handle_item_edit(const LLUUID& inv_item_id);
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
+bool get_is_category_and_children_removable(LLInventoryModel* model, const LLUUID& folder_id, bool check_worn);
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 68581d04eb..c8e2090192 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -1435,7 +1435,7 @@ void LLInventoryGallery::onFocusReceived()
LLInventoryGalleryItem* focus_item = NULL;
for (const LLUUID& id : mSelectedItemIDs)
{
- if (mItemMap[id])
+ if (mItemMap[id] && !mItemMap[id]->isHidden())
{
focus_item = mItemMap[id];
focus_item->setSelected(true);
@@ -1668,6 +1668,45 @@ void LLInventoryGallery::cut()
mFilterSubString.clear();
}
+
+
+bool is_category_removable(const LLUUID& folder_id, bool check_worn)
+{
+ if (!get_is_category_removable(&gInventory, folder_id))
+ {
+ return false;
+ }
+
+ // check children
+ LLInventoryModel::cat_array_t* cat_array;
+ LLInventoryModel::item_array_t* item_array;
+ gInventory.getDirectDescendentsOf(folder_id, cat_array, item_array);
+
+ for (LLInventoryModel::item_array_t::value_type& item : *item_array)
+ {
+ if (!get_is_item_removable(&gInventory, item->getUUID(), check_worn))
+ {
+ return false;
+ }
+ }
+
+ for (LLInventoryModel::cat_array_t::value_type& cat : *cat_array)
+ {
+ if (!is_category_removable(cat->getUUID(), check_worn))
+ {
+ return false;
+ }
+ }
+
+ const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id))
+ {
+ return false;
+ }
+
+ return true;
+}
+
BOOL LLInventoryGallery::canCut() const
{
if (!getVisible() || !getEnabled() || mSelectedItemIDs.empty())
@@ -1680,12 +1719,12 @@ BOOL LLInventoryGallery::canCut() const
LLViewerInventoryCategory* cat = gInventory.getCategory(id);
if (cat)
{
- if (!get_is_category_removable(&gInventory, id))
+ if (!get_is_category_and_children_removable(&gInventory, id, true))
{
return FALSE;
}
}
- else if (!get_is_item_removable(&gInventory, id))
+ else if (!get_is_item_removable(&gInventory, id, true))
{
return FALSE;
}
@@ -1864,42 +1903,149 @@ void LLInventoryGallery::onDelete(const LLSD& notification, const LLSD& response
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
- for (const LLUUID& id : selected_ids)
+ bool has_worn = notification["payload"]["has_worn"].asBoolean();
+ uuid_vec_t worn;
+ uuid_vec_t item_deletion_list;
+ uuid_vec_t cat_deletion_list;
+ for (const LLUUID& obj_id : selected_ids)
{
- LLInventoryObject* obj = gInventory.getObject(id);
- if (!obj)
- {
- return;
- }
- if (obj->getType() == LLAssetType::AT_CATEGORY)
+ LLViewerInventoryCategory* cat = gInventory.getCategory(obj_id);
+ if (cat)
{
- if (get_is_category_removable(&gInventory, id))
+ bool cat_has_worn = false;
+ if (has_worn)
{
- gInventory.removeCategory(id);
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(obj_id, categories, items, FALSE);
+
+ for (LLInventoryModel::item_array_t::value_type& item : items)
+ {
+ if (get_is_item_worn(item))
+ {
+ worn.push_back(item->getUUID());
+ cat_has_worn = true;
+ }
+ }
+ }
+ if (cat_has_worn)
+ {
+ cat_deletion_list.push_back(obj_id);
+ }
+ else
+ {
+ gInventory.removeCategory(obj_id);
}
}
- else
+ LLViewerInventoryItem* item = gInventory.getItem(obj_id);
+ if (item)
{
- if (get_is_item_removable(&gInventory, id))
+ if (has_worn && get_is_item_worn(item))
+ {
+ worn.push_back(item->getUUID());
+ item_deletion_list.push_back(item->getUUID());
+ }
+ else
{
- gInventory.removeItem(id);
+ gInventory.removeItem(obj_id);
}
}
}
+
+ if (!worn.empty())
+ {
+ // should fire once after every item gets detached
+ LLAppearanceMgr::instance().removeItemsFromAvatar(worn,
+ [item_deletion_list, cat_deletion_list]()
+ {
+ for (const LLUUID& id : item_deletion_list)
+ {
+ remove_inventory_item(id, NULL);
+ }
+ for (const LLUUID& id : cat_deletion_list)
+ {
+ remove_inventory_category(id, NULL);
+ }
+ });
+ }
}
}
void LLInventoryGallery::deleteSelection()
{
- if (!LLInventoryAction::sDeleteConfirmationDisplayed) // ask for the confirmation at least once per session
+ bool has_worn = false;
+ bool needs_replacement = false;
+ for (const LLUUID& id : mSelectedItemIDs)
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(id);
+ if (cat)
+ {
+ LLInventoryModel::cat_array_t categories;
+ LLInventoryModel::item_array_t items;
+
+ gInventory.collectDescendents(id, categories, items, FALSE);
+
+ for (LLInventoryModel::item_array_t::value_type& item : items)
+ {
+ if (get_is_item_worn(item))
+ {
+ has_worn = true;
+ LLWearableType::EType type = item->getWearableType();
+ if (type == LLWearableType::WT_SHAPE
+ || type == LLWearableType::WT_SKIN
+ || type == LLWearableType::WT_HAIR
+ || type == LLWearableType::WT_EYES)
+ {
+ needs_replacement = true;
+ break;
+ }
+ }
+ }
+ if (needs_replacement)
+ {
+ break;
+ }
+ }
+
+ LLViewerInventoryItem* item = gInventory.getItem(id);
+ if (item && get_is_item_worn(item))
+ {
+ has_worn = true;
+ LLWearableType::EType type = item->getWearableType();
+ if (type == LLWearableType::WT_SHAPE
+ || type == LLWearableType::WT_SKIN
+ || type == LLWearableType::WT_HAIR
+ || type == LLWearableType::WT_EYES)
+ {
+ needs_replacement = true;
+ break;
+ }
+ }
+ }
+
+ if (needs_replacement)
+ {
+ LLNotificationsUtil::add("CantDeleteRequiredClothing");
+ }
+ else if (has_worn)
{
- LLNotifications::instance().setIgnored("DeleteItems", false);
- LLInventoryAction::sDeleteConfirmationDisplayed = true;
+ LLSD payload;
+ payload["has_worn"] = true;
+ LLNotificationsUtil::add("DeleteWornItems", LLSD(), payload, boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs));
}
+ else
+ {
+ if (!LLInventoryAction::sDeleteConfirmationDisplayed) // ask for the confirmation at least once per session
+ {
+ LLNotifications::instance().setIgnored("DeleteItems", false);
+ LLInventoryAction::sDeleteConfirmationDisplayed = true;
+ }
- LLSD args;
- args["QUESTION"] = LLTrans::getString("DeleteItem");
- LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs));
+ LLSD args;
+ args["QUESTION"] = LLTrans::getString("DeleteItem");
+ LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryGallery::onDelete, _1, _2, mSelectedItemIDs));
+ }
}
bool LLInventoryGallery::canDeleteSelection()
@@ -1925,7 +2071,7 @@ bool LLInventoryGallery::canDeleteSelection()
return false;
}
}
- else if (!get_is_item_removable(&gInventory, id))
+ else if (!get_is_item_removable(&gInventory, id, true))
{
return false;
}
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index 5f4b816b99..4b47346473 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -495,7 +495,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
}
}
items.push_back(std::string("Purge Item"));
- if (is_folder && !get_is_category_removable(&gInventory, selected_id))
+ if (is_folder && !get_is_category_and_children_removable(&gInventory, selected_id, true))
{
disabled_items.push_back(std::string("Purge Item"));
}
@@ -542,11 +542,16 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
}
items.push_back(std::string("Cut"));
items.push_back(std::string("Delete"));
- if(!get_is_category_removable(&gInventory, selected_id))
+
+ if(!get_is_category_and_children_removable(&gInventory, selected_id, false))
{
disabled_items.push_back(std::string("Delete"));
disabled_items.push_back(std::string("Cut"));
}
+ else if (!get_is_category_and_children_removable(&gInventory, selected_id, true))
+ {
+ disabled_items.push_back(std::string("Cut"));
+ }
if(!is_inbox)
{
@@ -577,11 +582,15 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
{
items.push_back(std::string("Delete"));
}
- if(!get_is_item_removable(&gInventory, selected_id))
+ if (!get_is_item_removable(&gInventory, selected_id, false))
{
disabled_items.push_back(std::string("Delete"));
disabled_items.push_back(std::string("Cut"));
}
+ else if(!get_is_item_removable(&gInventory, selected_id, true))
+ {
+ disabled_items.push_back(std::string("Cut"));
+ }
if (selected_item && (selected_item->getInventoryType() != LLInventoryType::IT_CALLINGCARD) && !is_inbox && selected_item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
{
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 23129f7d44..cac859387c 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -240,7 +240,7 @@ void LLInventoryItemsList::refresh()
case REFRESH_LIST_SORT:
{
// Filter, sort, rearrange and notify parent about shape changes
- filterItems();
+ filterItems(true, true);
if (mAddedItems.size() == 0)
{
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index ce41105f98..5b83298bb9 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -51,20 +51,20 @@ public:
/**
* Let list know items need to be refreshed in next doIdle()
*/
- void setNeedsRefresh(bool needs_refresh){ mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; }
+ void setNeedsRefresh(bool needs_refresh) { mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; }
- U32 getNeedsRefresh(){ return mRefreshState; }
+ U32 getNeedsRefresh() { return mRefreshState; }
/**
* Sets the flag indicating that the list needs to be refreshed even if it is
* not currently visible.
*/
- void setForceRefresh(bool force_refresh){ mForceRefresh = force_refresh; }
+ void setForceRefresh(bool force_refresh) { mForceRefresh = force_refresh; }
/**
* If refreshes when invisible.
*/
- bool getForceRefresh(){ return mForceRefresh; }
+ bool getForceRefresh() { return mForceRefresh; }
virtual bool selectItemByValue(const LLSD& value, bool select = true);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 05aa2e423f..eebc79c1c6 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1744,12 +1744,10 @@ void LLInventoryModel::changeItemParent(LLViewerInventoryItem* item,
<< " from " << make_inventory_info(item->getParentUUID())
<< " to " << make_inventory_info(new_parent_id) << LL_ENDL;
- LLInventoryModel::update_list_t update;
- LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
- update.push_back(new_folder);
- accountForUpdate(update);
+ LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(), -1);
+ accountForUpdate(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1, false);
+ accountForUpdate(new_folder);
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
new_item->setParent(new_parent_id);
@@ -1779,12 +1777,10 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat,
<< " from " << make_inventory_info(cat->getParentUUID())
<< " to " << make_inventory_info(new_parent_id) << LL_ENDL;
- LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate old_folder(cat->getParentUUID(), -1);
- update.push_back(old_folder);
- LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
- update.push_back(new_folder);
- accountForUpdate(update);
+ accountForUpdate(old_folder);
+ LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1, false);
+ accountForUpdate(new_folder);
LLPointer<LLViewerInventoryCategory> new_cat = new LLViewerInventoryCategory(cat);
new_cat->setParent(new_parent_id);
@@ -2542,7 +2538,10 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const
{
descendents_actual += update.mDescendentDelta;
cat->setDescendentCount(descendents_actual);
- cat->setVersion(++version);
+ if (update.mChangeVersion)
+ {
+ cat->setVersion(++version);
+ }
LL_DEBUGS(LOG_INV) << "accounted: '" << cat->getName() << "' "
<< version << " with " << descendents_actual
<< " descendents." << LL_ENDL;
@@ -2570,7 +2569,7 @@ void LLInventoryModel::accountForUpdate(const LLCategoryUpdate& update) const
}
void LLInventoryModel::accountForUpdate(
- const LLInventoryModel::update_list_t& update)
+ const LLInventoryModel::update_list_t& update) const
{
update_list_t::const_iterator it = update.begin();
update_list_t::const_iterator end = update.end();
@@ -2581,7 +2580,7 @@ void LLInventoryModel::accountForUpdate(
}
void LLInventoryModel::accountForUpdate(
- const LLInventoryModel::update_map_t& update)
+ const LLInventoryModel::update_map_t& update) const
{
LLCategoryUpdate up;
update_map_t::const_iterator it = update.begin();
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 69d987cabd..41faafa6bb 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -511,12 +511,14 @@ public:
// Represents the number of items added or removed from a category.
struct LLCategoryUpdate
{
- LLCategoryUpdate() : mDescendentDelta(0) {}
- LLCategoryUpdate(const LLUUID& category_id, S32 delta) :
+ LLCategoryUpdate() : mDescendentDelta(0), mChangeVersion(true) {}
+ LLCategoryUpdate(const LLUUID& category_id, S32 delta, bool change_version = true) :
mCategoryID(category_id),
- mDescendentDelta(delta) {}
+ mDescendentDelta(delta),
+ mChangeVersion(change_version) {}
LLUUID mCategoryID;
S32 mDescendentDelta;
+ bool mChangeVersion;
};
typedef std::vector<LLCategoryUpdate> update_list_t;
@@ -534,8 +536,8 @@ public:
// Call when there are category updates. Call them *before* the
// actual update so the method can do descendent accounting correctly.
void accountForUpdate(const LLCategoryUpdate& update) const;
- void accountForUpdate(const update_list_t& updates);
- void accountForUpdate(const update_map_t& updates);
+ void accountForUpdate(const update_list_t& updates) const;
+ void accountForUpdate(const update_map_t& updates) const;
// Return (yes/no/maybe) child status of category children.
EHasChildren categoryHasChildren(const LLUUID& cat_id) const;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 154d8e2e18..ab04a8589a 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1887,46 +1887,52 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
}
//static
-void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id, BOOL use_main_panel, BOOL take_keyboard_focus, BOOL reset_filter)
+void LLInventoryPanel::openInventoryPanelAndSetSelection(bool auto_open, const LLUUID& obj_id,
+ bool use_main_panel, bool take_keyboard_focus, bool reset_filter)
{
LLSidepanelInventory* sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
sidepanel_inventory->showInventoryPanel();
- bool in_inbox = (gInventory.isObjectDescendentOf(obj_id, gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX)));
-
- if (!in_inbox && (use_main_panel || !sidepanel_inventory->getMainInventoryPanel()->isRecentItemsPanelSelected()))
+ LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+ bool in_inbox = gInventory.isObjectDescendentOf(obj_id, cat_id);
+ if (!in_inbox && use_main_panel)
{
sidepanel_inventory->selectAllItemsPanel();
}
- LLFloater* inventory_floater = LLFloaterSidePanelContainer::getTopmostInventoryFloater();
- if(!auto_open && inventory_floater && inventory_floater->getVisible())
+ if (!auto_open)
{
- LLSidepanelInventory *inventory_panel = inventory_floater->findChild<LLSidepanelInventory>("main_panel");
- LLPanelMainInventory* main_panel = inventory_panel->getMainInventoryPanel();
- if(main_panel->isSingleFolderMode() && main_panel->isGalleryViewMode())
+ LLFloater* inventory_floater = LLFloaterSidePanelContainer::getTopmostInventoryFloater();
+ if (inventory_floater && inventory_floater->getVisible())
{
- LL_DEBUGS("Inventory") << "Opening gallery panel for item" << obj_id << LL_ENDL;
- main_panel->setGallerySelection(obj_id);
- return;
+ LLSidepanelInventory *inventory_panel = inventory_floater->findChild<LLSidepanelInventory>("main_panel");
+ LLPanelMainInventory* main_panel = inventory_panel->getMainInventoryPanel();
+ if (main_panel->isSingleFolderMode() && main_panel->isGalleryViewMode())
+ {
+ LL_DEBUGS("Inventory") << "Opening gallery panel for item" << obj_id << LL_ENDL;
+ main_panel->setGallerySelection(obj_id);
+ return;
+ }
}
}
- LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
- if (main_inventory && main_inventory->isSingleFolderMode()
- && use_main_panel)
+ if (use_main_panel)
{
- const LLInventoryObject *obj = gInventory.getObject(obj_id);
- if (obj)
+ LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
+ if (main_inventory && main_inventory->isSingleFolderMode())
{
- LL_DEBUGS("Inventory") << "Opening main inventory panel for item" << obj_id << LL_ENDL;
- main_inventory->setSingleFolderViewRoot(obj->getParentUUID(), false);
- main_inventory->setGallerySelection(obj_id);
- return;
+ const LLInventoryObject *obj = gInventory.getObject(obj_id);
+ if (obj)
+ {
+ LL_DEBUGS("Inventory") << "Opening main inventory panel for item" << obj_id << LL_ENDL;
+ main_inventory->setSingleFolderViewRoot(obj->getParentUUID(), false);
+ main_inventory->setGallerySelection(obj_id);
+ return;
+ }
}
}
- LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
+ LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
if (active_panel)
{
LL_DEBUGS("Messaging", "Inventory") << "Highlighting" << obj_id << LL_ENDL;
@@ -1938,11 +1944,8 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
if (in_inbox)
{
-
- LLInventoryPanel * inventory_panel = NULL;
sidepanel_inventory->openInbox();
- inventory_panel = sidepanel_inventory->getInboxPanel();
-
+ LLInventoryPanel* inventory_panel = sidepanel_inventory->getInboxPanel();
if (inventory_panel)
{
inventory_panel->setSelection(obj_id, take_keyboard_focus);
@@ -1967,7 +1970,6 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
void LLInventoryPanel::setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id)
{
-
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
{
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index b68433bab0..97300596f9 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -244,12 +244,12 @@ public:
// "Auto_open" determines if we open an inventory panel if none are open.
static LLInventoryPanel *getActiveInventoryPanel(BOOL auto_open = TRUE);
- static void openInventoryPanelAndSetSelection(BOOL auto_open,
+ static void openInventoryPanelAndSetSelection(bool auto_open,
const LLUUID& obj_id,
- BOOL use_main_panel = FALSE,
- BOOL take_keyboard_focus = TAKE_FOCUS_YES,
- BOOL reset_filter = FALSE);
- static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id);
+ bool use_main_panel = false,
+ bool take_keyboard_focus = true,
+ bool reset_filter = false);
+ static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id);
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
void removeItemID(const LLUUID& id);
LLFolderViewItem* getItemByID(const LLUUID& id);
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 9fa35e3bd9..eb1bb9aca4 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -230,10 +230,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
// Can't access old mTextEntry fields as they are protected, so lets build new params
// That is C&P from LLComboBox::createLineEditor function
- static LLUICachedControl<S32> drop_shadow_button ("DropShadowButton", 0);
S32 arrow_width = mArrowImage ? mArrowImage->getWidth() : 0;
LLRect text_entry_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
- text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * drop_shadow_button;
+ text_entry_rect.mRight -= llmax(8,arrow_width) + 2 * BTN_DROP_SHADOW;
LLLineEditor::Params params = p.combo_editor;
params.rect(text_entry_rect);
@@ -708,7 +707,7 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
value["item_type"] = LANDMARK;
value["AssetUUID"] = landmark_items[i]->getAssetUUID();
- add(landmark_items[i]->getName(), value);
+ addLocationHistoryEntry(landmark_items[i]->getName(), value);
}
//Let's add teleport history items
@@ -733,7 +732,7 @@ void LLLocationInputCtrl::onLocationPrearrange(const LLSD& data)
std::string region_name = result->mTitle.substr(0, result->mTitle.find(','));
//TODO*: add Surl to teleportitem or parse region name from title
value["tooltip"] = LLSLURL(region_name, result->mGlobalPos).getSLURLString();
- add(result->getTitle(), value);
+ addLocationHistoryEntry(result->getTitle(), value);
}
result = std::find_if(result + 1, th_items.end(), boost::bind(
&LLLocationInputCtrl::findTeleportItemsByTitle, this,
@@ -986,6 +985,17 @@ void LLLocationInputCtrl::positionMaturityButton()
mMaturityButton->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad);
}
+void LLLocationInputCtrl::addLocationHistoryEntry(const std::string& title, const LLSD& value)
+{
+ // SL-20286 : Duplication of autocomplete results occurs when entering some search queries in the navigation bar
+ // Exclude visual duplicates (items with the same titles) in the dropdown list
+ LLScrollListItem* item = mList->getItemByLabel(title);
+ if (!item)
+ {
+ add(title, value);
+ }
+}
+
void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter)
{
LLLocationHistory::location_list_t filtered_items;
@@ -1010,7 +1020,7 @@ void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter)
//location history can contain only typed locations
value["item_type"] = TYPED_REGION_SLURL;
value["global_pos"] = it->mGlobalPos.getValue();
- add(it->getLocation(), value);
+ addLocationHistoryEntry(it->getLocation(), value);
}
}
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index af2a9f6afd..cbc05602ce 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -145,6 +145,7 @@ private:
void refreshMaturityButton();
void positionMaturityButton();
+ void addLocationHistoryEntry(const std::string& title, const LLSD& value);
void rebuildLocationHistory(const std::string& filter = LLStringUtil::null);
bool findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter);
void setText(const LLStringExplicit& text);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 052ac50185..5f3ad7c58f 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -651,6 +651,27 @@ std::string LLLogChat::oldLogFileName(std::string filename)
return scanResult;
}
+bool LLLogChat::transcriptFilesExist()
+{
+ std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+ // get Users log directory
+ std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
+
+ // add final OS dependent delimiter
+ dirname += gDirUtilp->getDirDelimiter();
+
+ LLDirIterator iter(dirname, pattern);
+ std::string filename;
+ while (iter.next(filename))
+ {
+ std::string fullname = gDirUtilp->add(dirname, filename);
+ if (isTranscriptFileFound(fullname))
+ {
+ return true;
+ }
+ }
+ return false;
+}
// static
void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions)
{
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 5dce8ab1d2..9e2e060de2 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -103,6 +103,7 @@ public:
const std::string& from,
const LLUUID& from_id,
const std::string& line);
+ static bool transcriptFilesExist();
static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions);
static void getListOfTranscriptFiles(std::vector<std::string>& list);
static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 01d6469010..48fd946a21 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1360,7 +1360,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL;
+ LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL;
return false;
}
LLMeshRepository::sCacheBytesRead += size;
@@ -1473,7 +1473,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL;
+ LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL;
return false;
}
LLMeshRepository::sCacheBytesRead += size;
@@ -1575,7 +1575,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL;
+ LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL;
return false;
}
file.read(buffer, size);
@@ -1770,7 +1770,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
U8* buffer = new(std::nothrow) U8[size];
if (!buffer)
{
- LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL;
+ LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL;
// todo: for now it will result in indefinite constant retries, should result in timeout
// or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point)
return false;
@@ -5503,7 +5503,7 @@ void on_new_single_inventory_upload_complete(
}
else
{
- LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, server_response["new_inventory_item"].asUUID(), TRUE, TAKE_FOCUS_NO, TRUE);
+ LLInventoryPanel::openInventoryPanelAndSetSelection(true, server_response["new_inventory_item"].asUUID(), true, false, true);
}
// restore keyboard focus
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index f5ee1171d9..61448828d1 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -352,10 +352,9 @@ void LLNavigationBar::draw()
{
if (isBackgroundVisible())
{
- static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
static LLUIColor color_drop_shadow = LLUIColorTable::instance().getColor("ColorDropShadow");
gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0,
- color_drop_shadow, drop_shadow_floater );
+ color_drop_shadow, DROP_SHADOW_FLOATER);
}
LLPanel::draw();
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 90b9cdc133..df8ab84663 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -46,7 +46,7 @@ LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notif
mIsModal(is_modal)
{
LLScreenChannelBase::Params p;
- p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
+ p.id = ALERT_CHANNEL_UUID;
p.display_toasts_always = true;
p.toast_align = NA_CENTRE;
p.channel_align = CA_CENTRE;
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index f87ebf219b..3c3d96f72c 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -56,9 +56,8 @@ LLGroupHandler::~LLGroupHandler()
//--------------------------------------------------------------------------
void LLGroupHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound);
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 3f22467544..0e7222838d 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -63,8 +63,7 @@ LLOfferHandler::~LLOfferHandler()
void LLOfferHandler::initChannel()
{
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound);
+ mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index bb39d8f362..2f7dfa8e77 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -61,9 +61,8 @@ LLScriptHandler::~LLScriptHandler()
//--------------------------------------------------------------------------
void LLScriptHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound);
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 91f93067de..dc24e651cb 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -60,9 +60,8 @@ LLTipHandler::~LLTipHandler()
//--------------------------------------------------------------------------
void LLTipHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
- S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
- mChannel.get()->init(channel_right_bound - channel_width, channel_right_bound);
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ mChannel.get()->init(channel_right_bound - NOTIFY_BOX_WIDTH, channel_right_bound);
}
//--------------------------------------------------------------------------
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index de988555c5..e621c32911 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -433,8 +433,7 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
}
void LLOutfitGallery::reArrangeRows(S32 row_diff)
-{
-
+{
std::vector<LLOutfitGalleryItem*> buf_items = mItems;
for (std::vector<LLOutfitGalleryItem*>::const_reverse_iterator it = buf_items.rbegin(); it != buf_items.rend(); ++it)
{
@@ -446,16 +445,24 @@ void LLOutfitGallery::reArrangeRows(S32 row_diff)
}
mHiddenItems.clear();
- mItemsInRow+= row_diff;
+ mItemsInRow += row_diff;
updateGalleryWidth();
std::sort(buf_items.begin(), buf_items.end(), compareGalleryItem);
-
+
+ std::string cur_filter = getFilterSubString();
+ LLStringUtil::toUpper(cur_filter);
+
for (std::vector<LLOutfitGalleryItem*>::const_iterator it = buf_items.begin(); it != buf_items.end(); ++it)
{
- (*it)->setHidden(false);
- applyFilter(*it,sFilterSubString);
+ std::string outfit_name = (*it)->getItemName();
+ LLStringUtil::toUpper(outfit_name);
+
+ bool hidden = (std::string::npos == outfit_name.find(cur_filter));
+ (*it)->setHidden(hidden);
+
addToGallery(*it);
}
+
updateMessageVisibility();
}
@@ -725,9 +732,9 @@ LLOutfitGallery::~LLOutfitGallery()
}
}
-void LLOutfitGallery::setFilterSubString(const std::string& string)
+// virtual
+void LLOutfitGallery::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
{
- sFilterSubString = string;
reArrangeRows();
}
@@ -743,20 +750,6 @@ void LLOutfitGallery::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id)
}
}
-void LLOutfitGallery::applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring)
-{
- if (!item) return;
-
- std::string outfit_name = item->getItemName();
- LLStringUtil::toUpper(outfit_name);
-
- std::string cur_filter = filter_substring;
- LLStringUtil::toUpper(cur_filter);
-
- bool hidden = (std::string::npos == outfit_name.find(cur_filter));
- item->setHidden(hidden);
-}
-
void LLOutfitGallery::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
{
}
@@ -904,11 +897,11 @@ bool LLOutfitGallery::hasDefaultImage(const LLUUID& outfit_cat_id)
void LLOutfitGallery::updateMessageVisibility()
{
- if(mItems.empty())
+ if (mItems.empty())
{
mMessageTextBox->setVisible(TRUE);
mScrollPanel->setVisible(FALSE);
- std::string message = sFilterSubString.empty()? getString("no_outfits_msg") : getString("no_matched_outfits_msg");
+ std::string message = getString(getFilterSubString().empty() ? "no_outfits_msg" : "no_matched_outfits_msg");
mMessageTextBox->setValue(message);
}
else
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 9915752962..f2366e6494 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -90,7 +90,7 @@ public:
void wearSelectedOutfit();
- /*virtual*/ void setFilterSubString(const std::string& string);
+ /*virtual*/ void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string);
/*virtual*/ void getCurrentCategories(uuid_vec_t& vcur);
/*virtual*/ void updateAddedCategory(LLUUID cat_id);
@@ -117,8 +117,6 @@ protected:
/*virtual*/ void onExpandAllFolders() {}
/*virtual*/ LLOutfitListGearMenuBase* createGearMenu();
- void applyFilter(LLOutfitGalleryItem* item, const std::string& filter_substring);
-
private:
LLUUID getPhotoAssetId(const LLUUID& outfit_id);
LLUUID getDefaultPhoto();
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 5c7792b0df..27d73fc4ae 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -188,7 +188,7 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
list->setCommitCallback(boost::bind(&LLOutfitsList::onListSelectionChange, this, _1));
// Setting list refresh callback to apply filter on list change.
- list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onFilteredWearableItemsListRefresh, this, _1));
+ list->setRefreshCompleteCallback(boost::bind(&LLOutfitsList::onRefreshComplete, this, _1));
list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3));
@@ -199,19 +199,17 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id)
// Further list updates will be triggered by the category observer.
list->updateList(cat_id);
- // If filter is currently applied we store the initial tab state and
- // open it to show matched items if any.
- if (!sFilterSubString.empty())
+ // If filter is currently applied we store the initial tab state.
+ if (!getFilterSubString().empty())
{
tab->notifyChildren(LLSD().with("action", "store_state"));
- tab->setDisplayChildren(true);
// Setting mForceRefresh flag will make the list refresh its contents
// even if it is not currently visible. This is required to apply the
// filter to the newly added list.
list->setForceRefresh(true);
- list->setFilterSubString(sFilterSubString);
+ list->setFilterSubString(getFilterSubString(), false);
}
}
@@ -314,14 +312,6 @@ void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid)
}
// virtual
-void LLOutfitsList::setFilterSubString(const std::string& string)
-{
- applyFilter(string);
-
- sFilterSubString = string;
-}
-
-// virtual
bool LLOutfitListBase::isActionEnabled(const LLSD& userdata)
{
if (mSelectedOutfitUUID.isNull()) return false;
@@ -494,9 +484,9 @@ void LLOutfitsList::restoreOutfitSelection(LLAccordionCtrlTab* tab, const LLUUID
}
}
-void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
+void LLOutfitsList::onRefreshComplete(LLUICtrl* ctrl)
{
- if (!ctrl || sFilterSubString.empty())
+ if (!ctrl || getFilterSubString().empty())
return;
for (outfits_map_t::iterator
@@ -510,57 +500,50 @@ void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
if (list != ctrl) continue;
- applyFilterToTab(iter->first, tab, sFilterSubString);
+ applyFilterToTab(iter->first, tab, getFilterSubString());
}
}
-void LLOutfitsList::applyFilter(const std::string& new_filter_substring)
+// virtual
+void LLOutfitsList::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
{
- mAccordion->setFilterSubString(new_filter_substring);
+ mAccordion->setFilterSubString(new_string);
- for (outfits_map_t::iterator
- iter = mOutfitsMap.begin(),
- iter_end = mOutfitsMap.end();
- iter != iter_end; ++iter)
+ outfits_map_t::iterator iter = mOutfitsMap.begin(), iter_end = mOutfitsMap.end();
+ while (iter != iter_end)
{
- LLAccordionCtrlTab* tab = iter->second;
+ const LLUUID& category_id = iter->first;
+ LLAccordionCtrlTab* tab = iter++->second;
if (!tab) continue;
- bool more_restrictive = sFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, sFilterSubString.size()).compare(sFilterSubString);
-
- // Restore tab visibility in case of less restrictive filter
- // to compare it with updated string if it was previously hidden.
- if (!more_restrictive)
- {
- tab->setVisible(TRUE);
- }
-
LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
if (list)
{
- list->setFilterSubString(new_filter_substring);
+ list->setFilterSubString(new_string, tab->getDisplayChildren());
}
- if(sFilterSubString.empty() && !new_filter_substring.empty())
+ if (old_string.empty())
{
- //store accordion tab state when filter is not empty
- tab->notifyChildren(LLSD().with("action","store_state"));
+ // Store accordion tab state when filter is not empty
+ tab->notifyChildren(LLSD().with("action", "store_state"));
}
- if (!new_filter_substring.empty())
+ if (!new_string.empty())
{
- applyFilterToTab(iter->first, tab, new_filter_substring);
+ applyFilterToTab(category_id, tab, new_string);
}
else
{
- // restore tab title when filter is empty
+ tab->setVisible(TRUE);
+
+ // Restore tab title when filter is empty
tab->setTitle(tab->getTitle());
- //restore accordion state after all those accodrion tab manipulations
- tab->notifyChildren(LLSD().with("action","restore_state"));
+ // Restore accordion state after all those accodrion tab manipulations
+ tab->notifyChildren(LLSD().with("action", "restore_state"));
// Try restoring the tab selection.
- restoreOutfitSelection(tab, iter->first);
+ restoreOutfitSelection(tab, category_id);
}
}
@@ -586,11 +569,11 @@ void LLOutfitsList::applyFilterToTab(
if (std::string::npos == title.find(cur_filter))
{
- // hide tab if its title doesn't pass filter
- // and it has no visible items
+ // Hide tab if its title doesn't pass filter
+ // and it has no matched items
tab->setVisible(list->hasMatchedItems());
- // remove title highlighting because it might
+ // Remove title highlighting because it might
// have been previously highlighted by less restrictive filter
tab->setTitle(tab->getTitle());
@@ -602,18 +585,6 @@ void LLOutfitsList::applyFilterToTab(
// Try restoring the tab selection.
restoreOutfitSelection(tab, category_id);
}
-
- if (tab->getVisible())
- {
- // Open tab if it has passed the filter.
- tab->setDisplayChildren(true);
- }
- else
- {
- // Set force refresh flag to refresh not visible list
- // when some changes occur in it.
- list->setForceRefresh(true);
- }
}
bool LLOutfitsList::canWearSelected()
@@ -698,11 +669,10 @@ void LLOutfitsList::onCOFChanged()
// These links UUIDs are not the same UUIDs that we have in each wearable items list.
// So we collect base items' UUIDs to find them or links that point to them in wearable
// items lists and update their worn state there.
- for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
- iter != item_array.end();
- ++iter)
+ LLInventoryModel::item_array_t::const_iterator array_iter = item_array.begin(), array_end = item_array.end();
+ while (array_iter < array_end)
{
- vnew.push_back((*iter)->getLinkedUUID());
+ vnew.push_back((*(array_iter++))->getLinkedUUID());
}
// We need to update only items that were added or removed from COF.
@@ -711,20 +681,20 @@ void LLOutfitsList::onCOFChanged()
// Store the ids of items currently linked from COF.
mCOFLinkedItems = vnew;
- for (outfits_map_t::iterator iter = mOutfitsMap.begin();
- iter != mOutfitsMap.end();
- ++iter)
+ // Append removed ids to added ids because we should update all of them.
+ vadded.reserve(vadded.size() + vremoved.size());
+ vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
+ vremoved.clear();
+
+ outfits_map_t::iterator map_iter = mOutfitsMap.begin(), map_end = mOutfitsMap.end();
+ while (map_iter != map_end)
{
- LLAccordionCtrlTab* tab = iter->second;
+ LLAccordionCtrlTab* tab = (map_iter++)->second;
if (!tab) continue;
LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
if (!list) continue;
- // Append removed ids to added ids because we should update all of them.
- vadded.reserve(vadded.size() + vremoved.size());
- vadded.insert(vadded.end(), vremoved.begin(), vremoved.end());
-
// Every list updates the labels of changed items or
// the links that point to these items.
list->updateChangedItems(vadded);
@@ -835,7 +805,6 @@ void LLOutfitListBase::onOpen(const LLSD& info)
// arrive.
category->fetch();
refreshList(outfits);
- highlightBaseOutfit();
mIsInitialized = true;
}
@@ -843,6 +812,9 @@ void LLOutfitListBase::onOpen(const LLSD& info)
void LLOutfitListBase::refreshList(const LLUUID& category_id)
{
+ bool wasNull = mRefreshListState.CategoryUUID.isNull();
+ mRefreshListState.CategoryUUID.setNull();
+
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
@@ -855,27 +827,81 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
LLInventoryModel::EXCLUDE_TRASH,
is_category);
- uuid_vec_t vadded;
- uuid_vec_t vremoved;
+ // Memorize item names for each UUID
+ std::map<LLUUID, std::string> names;
+ for (const LLPointer<LLViewerInventoryCategory>& cat : cat_array)
+ {
+ names.emplace(std::make_pair(cat->getUUID(), cat->getName()));
+ }
+
+ // Fill added and removed items vectors.
+ mRefreshListState.Added.clear();
+ mRefreshListState.Removed.clear();
+ computeDifference(cat_array, mRefreshListState.Added, mRefreshListState.Removed);
+ // Sort added items vector by item name.
+ std::sort(mRefreshListState.Added.begin(), mRefreshListState.Added.end(),
+ [names](const LLUUID& a, const LLUUID& b)
+ {
+ return LLStringUtil::compareDict(names.at(a), names.at(b)) < 0;
+ });
+ // Initialize iterators for added and removed items vectors.
+ mRefreshListState.AddedIterator = mRefreshListState.Added.begin();
+ mRefreshListState.RemovedIterator = mRefreshListState.Removed.begin();
+
+ LL_INFOS() << "added: " << mRefreshListState.Added.size() <<
+ ", removed: " << mRefreshListState.Removed.size() <<
+ ", changed: " << gInventory.getChangedIDs().size() <<
+ LL_ENDL;
+
+ mRefreshListState.CategoryUUID = category_id;
+ if (wasNull)
+ {
+ gIdleCallbacks.addFunction(onIdle, this);
+ }
+}
+
+// static
+void LLOutfitListBase::onIdle(void* userdata)
+{
+ LLOutfitListBase* self = (LLOutfitListBase*)userdata;
- // Create added and removed items vectors.
- computeDifference(cat_array, vadded, vremoved);
+ self->onIdleRefreshList();
+}
+
+void LLOutfitListBase::onIdleRefreshList()
+{
+ if (mRefreshListState.CategoryUUID.isNull())
+ return;
+
+ const F64 MAX_TIME = 0.05f;
+ F64 curent_time = LLTimer::getTotalSeconds();
+ const F64 end_time = curent_time + MAX_TIME;
// Handle added tabs.
- for (uuid_vec_t::const_iterator iter = vadded.begin();
- iter != vadded.end();
- ++iter)
+ while (mRefreshListState.AddedIterator < mRefreshListState.Added.end())
{
- const LLUUID cat_id = (*iter);
+ const LLUUID cat_id = (*mRefreshListState.AddedIterator++);
updateAddedCategory(cat_id);
+
+ curent_time = LLTimer::getTotalSeconds();
+ if (curent_time >= end_time)
+ return;
}
+ mRefreshListState.Added.clear();
+ mRefreshListState.AddedIterator = mRefreshListState.Added.end();
// Handle removed tabs.
- for (uuid_vec_t::const_iterator iter = vremoved.begin(); iter != vremoved.end(); ++iter)
+ while (mRefreshListState.RemovedIterator < mRefreshListState.Removed.end())
{
- const LLUUID cat_id = (*iter);
+ const LLUUID cat_id = (*mRefreshListState.RemovedIterator++);
updateRemovedCategory(cat_id);
+
+ curent_time = LLTimer::getTotalSeconds();
+ if (curent_time >= end_time)
+ return;
}
+ mRefreshListState.Removed.clear();
+ mRefreshListState.RemovedIterator = mRefreshListState.Removed.end();
// Get changed items from inventory model and update outfit tabs
// which might have been renamed.
@@ -888,9 +914,9 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
if (!cat)
{
LLInventoryObject* obj = gInventory.getObject(*items_iter);
- if(!obj || (obj->getType() != LLAssetType::AT_CATEGORY))
+ if (!obj || (obj->getType() != LLAssetType::AT_CATEGORY))
{
- return;
+ break;
}
cat = (LLViewerInventoryCategory*)obj;
}
@@ -900,6 +926,12 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id)
}
sortOutfits();
+ highlightBaseOutfit();
+
+ gIdleCallbacks.deleteFunction(onIdle, this);
+ mRefreshListState.CategoryUUID.setNull();
+
+ LL_INFOS() << "done" << LL_ENDL;
}
void LLOutfitListBase::computeDifference(
@@ -936,7 +968,6 @@ void LLOutfitListBase::highlightBaseOutfit()
mHighlightedOutfitUUID = base_id;
onHighlightBaseOutfit(base_id, prev_id);
}
-
}
void LLOutfitListBase::removeSelected()
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 66b3165169..43c3ba75b5 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -116,8 +116,20 @@ protected:
void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response);
virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0;
+ static void onIdle(void* userdata);
+ void onIdleRefreshList();
+
+ struct
+ {
+ LLUUID CategoryUUID;
+ uuid_vec_t Added;
+ uuid_vec_t Removed;
+ uuid_vec_t::const_iterator AddedIterator;
+ uuid_vec_t::const_iterator RemovedIterator;
+ } mRefreshListState;
+
bool mIsInitialized;
- LLInventoryCategoriesObserver* mCategoriesObserver;
+ LLInventoryCategoriesObserver* mCategoriesObserver;
LLUUID mSelectedOutfitUUID;
// id of currently highlited outfit
LLUUID mHighlightedOutfitUUID;
@@ -225,7 +237,7 @@ public:
//void performAction(std::string action);
- /*virtual*/ void setFilterSubString(const std::string& string);
+ /*virtual*/ void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string);
/*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const;
@@ -295,12 +307,7 @@ private:
* Called upon list refresh event to update tab visibility depending on
* the results of applying filter to the title and list items of the tab.
*/
- void onFilteredWearableItemsListRefresh(LLUICtrl* ctrl);
-
- /**
- * Highlights filtered items and hides tabs which haven't passed filter.
- */
- void applyFilter(const std::string& new_filter_substring);
+ void onRefreshComplete(LLUICtrl* ctrl);
/**
* Applies filter to the given tab
diff --git a/indra/newview/llpanelappearancetab.cpp b/indra/newview/llpanelappearancetab.cpp
index 8fa8867c69..16bd8a1380 100644
--- a/indra/newview/llpanelappearancetab.cpp
+++ b/indra/newview/llpanelappearancetab.cpp
@@ -28,12 +28,35 @@
#include "llpanelappearancetab.h"
-
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llviewerinventory.h"
-//virtual
+std::string LLPanelAppearanceTab::sRecentFilterSubString;
+
+void LLPanelAppearanceTab::setFilterSubString(const std::string& new_string)
+{
+ if (new_string != mFilterSubString)
+ {
+ std::string old_string = mFilterSubString;
+ mFilterSubString = new_string;
+ onFilterSubStringChanged(mFilterSubString, old_string);
+ }
+
+ sRecentFilterSubString = new_string;
+}
+
+void LLPanelAppearanceTab::checkFilterSubString()
+{
+ if (sRecentFilterSubString != mFilterSubString)
+ {
+ std::string old_string = mFilterSubString;
+ mFilterSubString = sRecentFilterSubString;
+ onFilterSubStringChanged(mFilterSubString, old_string);
+ }
+}
+
+// virtual
bool LLPanelAppearanceTab::canTakeOffSelected()
{
uuid_vec_t selected_uuids;
diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h
index 2ed6b00497..e81394dd3c 100644
--- a/indra/newview/llpanelappearancetab.h
+++ b/indra/newview/llpanelappearancetab.h
@@ -35,13 +35,17 @@ public:
LLPanelAppearanceTab() : LLPanel() {}
virtual ~LLPanelAppearanceTab() {}
- virtual void setFilterSubString(const std::string& string) = 0;
+ void setFilterSubString(const std::string& new_string);
+
+ void checkFilterSubString();
+
+ virtual void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string) = 0;
virtual bool isActionEnabled(const LLSD& userdata) = 0;
virtual void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const {}
- static const std::string& getFilterSubString() { return sFilterSubString; }
+ const std::string& getFilterSubString() { return mFilterSubString; }
protected:
@@ -50,7 +54,10 @@ protected:
*/
bool canTakeOffSelected();
- static std::string sFilterSubString;
+private:
+ std::string mFilterSubString;
+
+ static std::string sRecentFilterSubString;
};
#endif //LL_LLPANELAPPEARANCETAB_H
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index ff33efe4aa..3f2dc5a415 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -127,6 +127,54 @@ void LLPanelProfileTab::setApplyProgress(bool started)
}
}
+static void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data, std::function<void(bool)> callback)
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ httpOpts->setFollowRedirects(true);
+
+ std::string finalUrl = cap_url + "/" + agent_id.asString();
+
+ LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ if (!status)
+ {
+ LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL;
+ }
+
+ if (callback)
+ {
+ callback(status);
+ }
+}
+
+bool LLPanelProfileTab::saveAgentUserInfoCoro(std::string name, LLSD value, std::function<void(bool)> callback) const
+{
+ std::string cap_url = gAgent.getRegionCapability("AgentProfile");
+ if (cap_url.empty())
+ {
+ LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ return false;
+ }
+
+ LLCoros::instance().launch("putAgentUserInfoCoro",
+ boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with(name, value), callback));
+
+ return true;
+}
+
LLPanelProfilePropertiesProcessorTab::LLPanelProfilePropertiesProcessorTab()
: LLPanelProfileTab()
{
@@ -152,3 +200,13 @@ void LLPanelProfilePropertiesProcessorTab::setAvatarId(const LLUUID & avatar_id)
LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), this);
}
}
+
+void LLPanelProfilePropertiesProcessorTab::updateData()
+{
+ LLUUID avatar_id = getAvatarId();
+ if (!getStarted() && avatar_id.notNull())
+ {
+ setIsLoading();
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(getAvatarId());
+ }
+}
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index f182660c8e..ec620b39e1 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -92,17 +92,17 @@ public:
/**
* Returns avatar ID.
*/
- virtual const LLUUID& getAvatarId() { return mAvatarId; }
+ virtual const LLUUID& getAvatarId() const { return mAvatarId; }
/**
* Sends update data request to server.
*/
- virtual void updateData() {};
+ virtual void updateData(){};
/**
* Clears panel data if viewing avatar info for first time and sends update data request.
*/
- virtual void onOpen(const LLSD& key);
+ virtual void onOpen(const LLSD& key) override;
/**
* Clears all data received from server.
@@ -133,6 +133,8 @@ protected:
const bool getSelfProfile() const { return mSelfProfile; }
+ bool saveAgentUserInfoCoro(std::string name, LLSD value, std::function<void(bool)> callback = nullptr) const;
+
public:
void setIsLoading() { mLoadingState = PROFILE_LOADING; }
void resetLoading() { mLoadingState = PROFILE_INIT; }
@@ -158,12 +160,14 @@ public:
LLPanelProfilePropertiesProcessorTab();
~LLPanelProfilePropertiesProcessorTab();
- /*virtual*/ void setAvatarId(const LLUUID& avatar_id);
+ void setAvatarId(const LLUUID& avatar_id) override;
+
+ void updateData() override;
/**
* Processes data received from server via LLAvatarPropertiesObserver.
*/
- virtual void processProperties(void* data, EAvatarProcessorType type) = 0;
+ virtual void processProperties(void* data, EAvatarProcessorType type) override = 0;
};
#endif // LL_LLPANELAVATAR_H
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 183000ceac..e926ed2b3c 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -104,6 +104,11 @@ LLPanelClassifiedInfo::LLPanelClassifiedInfo()
LLPanelClassifiedInfo::~LLPanelClassifiedInfo()
{
sAllPanels.remove(this);
+
+ if (getAvatarId().notNull())
+ {
+ LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), this);
+ }
}
BOOL LLPanelClassifiedInfo::postBuild()
diff --git a/indra/newview/llpaneleditwater.cpp b/indra/newview/llpaneleditwater.cpp
index a09964e17d..fc9ca4e47e 100644
--- a/indra/newview/llpaneleditwater.cpp
+++ b/indra/newview/llpaneleditwater.cpp
@@ -89,7 +89,7 @@ BOOL LLPanelSettingsWaterMainTab::postBuild()
getChild<LLUICtrl>(FIELD_WATER_UNDERWATER_MOD)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onFogUnderWaterChanged(); });
mTxtNormalMap->setDefaultImageAssetID(LLSettingsWater::GetDefaultWaterNormalAssetId());
- mTxtNormalMap->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" )));
+ mTxtNormalMap->setBlankImageAssetID(DEFAULT_BLANK_NORMAL_TEXTURE);
mTxtNormalMap->setCommitCallback([this](LLUICtrl *, const LLSD &) { onNormalMapChanged(); });
getChild<LLUICtrl>(FIELD_WATER_WAVE2_XY)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSmallWaveChanged(); });
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 5f8071d3eb..366e1f6b47 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -336,7 +336,7 @@ BOOL LLPanelFace::postBuild()
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
- mTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectTexture" )));
+ mTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_TEXTURE);
mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
@@ -353,7 +353,7 @@ BOOL LLPanelFace::postBuild()
mShinyTextureCtrl = getChild<LLTextureCtrl>("shinytexture control");
if(mShinyTextureCtrl)
{
- mShinyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectSpecularTexture" )));
+ mShinyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_SPECULAR_TEXTURE);
mShinyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitSpecularTexture, this, _2) );
mShinyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelSpecularTexture, this, _2) );
mShinyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectSpecularTexture, this, _2) );
@@ -370,8 +370,8 @@ BOOL LLPanelFace::postBuild()
mBumpyTextureCtrl = getChild<LLTextureCtrl>("bumpytexture control");
if(mBumpyTextureCtrl)
{
- mBumpyTextureCtrl->setDefaultImageAssetID(LLUUID( gSavedSettings.getString( "DefaultObjectNormalTexture" )));
- mBumpyTextureCtrl->setBlankImageAssetID(LLUUID( gSavedSettings.getString( "DefaultBlankNormalTexture" )));
+ mBumpyTextureCtrl->setDefaultImageAssetID(DEFAULT_OBJECT_NORMAL_TEXTURE);
+ mBumpyTextureCtrl->setBlankImageAssetID(DEFAULT_BLANK_NORMAL_TEXTURE);
mBumpyTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitNormalTexture, this, _2) );
mBumpyTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelNormalTexture, this, _2) );
mBumpyTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectNormalTexture, this, _2) );
@@ -4413,7 +4413,7 @@ void LLPanelFace::onCopyTexture()
LLUUID id = mat_data["NormMap"].asUUID();
if (id.notNull() && !get_can_copy_texture(id))
{
- mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["NormMap"] = DEFAULT_OBJECT_TEXTURE;
mat_data["NormMapNoCopy"] = true;
}
@@ -4423,7 +4423,7 @@ void LLPanelFace::onCopyTexture()
LLUUID id = mat_data["SpecMap"].asUUID();
if (id.notNull() && !get_can_copy_texture(id))
{
- mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture"));
+ mat_data["SpecMap"] = DEFAULT_OBJECT_TEXTURE;
mat_data["SpecMapNoCopy"] = true;
}
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index ab255d5215..0ab0d85c78 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -134,6 +134,15 @@ void LLPanelGroup::onOpen(const LLSD& key)
if(panel_notices)
panel_notices->refreshNotices();
}
+ if (str_action == "show_notices")
+ {
+ setGroupID(group_id);
+
+ LLAccordionCtrl *tab_ctrl = getChild<LLAccordionCtrl>("groups_accordion");
+ tab_ctrl->collapseAllTabs();
+ getChild<LLAccordionCtrlTab>("group_notices_tab")->setDisplayChildren(true);
+ tab_ctrl->arrange();
+ }
}
@@ -264,8 +273,15 @@ void LLPanelGroup::onBtnGroupChatClicked(void* user_data)
void LLPanelGroup::onBtnJoin()
{
- LL_DEBUGS() << "joining group: " << mID << LL_ENDL;
- LLGroupActions::join(mID);
+ if (LLGroupActions::isInGroup(mID))
+ {
+ LLGroupActions::leave(mID);
+ }
+ else
+ {
+ LL_DEBUGS() << "joining group: " << mID << LL_ENDL;
+ LLGroupActions::join(mID);
+ }
}
void LLPanelGroup::changed(LLGroupChange gc)
@@ -303,12 +319,17 @@ void LLPanelGroup::update(LLGroupChange gc)
LLGroupData agent_gdatap;
bool is_member = gAgent.getGroupData(mID,agent_gdatap) || gAgent.isGodlikeWithoutAdminMenuFakery();
- bool join_btn_visible = !is_member && gdatap->mOpenEnrollment;
+ bool join_btn_visible = is_member || gdatap->mOpenEnrollment;
mButtonJoin->setVisible(join_btn_visible);
mJoinText->setVisible(join_btn_visible);
- if(join_btn_visible)
+ if (is_member)
+ {
+ mJoinText->setValue(getString("group_member"));
+ mButtonJoin->setLabel(getString("leave_txt"));
+ }
+ else if(join_btn_visible)
{
LLStringUtil::format_map_t string_args;
std::string fee_buff;
@@ -323,6 +344,7 @@ void LLPanelGroup::update(LLGroupChange gc)
fee_buff = getString("group_join_free", string_args);
}
mJoinText->setValue(fee_buff);
+ mButtonJoin->setLabel(getString("join_txt"));
}
}
}
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 82f880c9ee..a38e27b16b 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -250,6 +250,7 @@ BOOL LLPanelGroupNotices::postBuild()
mNoticesList = getChild<LLScrollListCtrl>("notice_list",recurse);
mNoticesList->setCommitOnSelectionChange(TRUE);
mNoticesList->setCommitCallback(onSelectNotice, this);
+ mNoticesList->sortByColumn("date", false);
mBtnNewMessage = getChild<LLButton>("create_new_notice",recurse);
mBtnNewMessage->setClickedCallback(onClickNewMessage, this);
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 0704fc881d..94f1b252dd 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -244,7 +244,7 @@ BOOL LLPanelObject::postBuild()
mCtrlSculptTexture = getChild<LLTextureCtrl>("sculpt texture control");
if (mCtrlSculptTexture)
{
- mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
+ mCtrlSculptTexture->setDefaultImageAssetID(SCULPT_DEFAULT_TEXTURE);
mCtrlSculptTexture->setCommitCallback( boost::bind(&LLPanelObject::onCommitSculpt, this, _2 ));
mCtrlSculptTexture->setOnCancelCallback( boost::bind(&LLPanelObject::onCancelSculpt, this, _2 ));
mCtrlSculptTexture->setOnSelectCallback( boost::bind(&LLPanelObject::onSelectSculpt, this, _2 ));
@@ -2024,7 +2024,7 @@ void LLPanelObject::onCancelSculpt(const LLSD& data)
if(mSculptTextureRevert == LLUUID::null)
{
- mSculptTextureRevert = LLUUID(SCULPT_DEFAULT_TEXTURE);
+ mSculptTextureRevert = SCULPT_DEFAULT_TEXTURE;
}
mTextureCtrl->setImageAssetID(mSculptTextureRevert);
@@ -2267,7 +2267,7 @@ void LLPanelObject::onCopyParams()
}
else
{
- mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE);
+ mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE;
}
mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index f3a41f2e25..e5ae282235 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -130,7 +130,7 @@ public:
virtual BOOL isItemRenameable() const;
virtual BOOL renameItem(const std::string& new_name);
virtual BOOL isItemMovable() const;
- virtual BOOL isItemRemovable() const;
+ virtual BOOL isItemRemovable(bool check_worn = true) const;
virtual BOOL removeItem();
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
virtual void move(LLFolderViewModelItem* parent_listener);
@@ -336,7 +336,7 @@ BOOL LLTaskInvFVBridge::isItemMovable() const
return TRUE;
}
-BOOL LLTaskInvFVBridge::isItemRemovable() const
+BOOL LLTaskInvFVBridge::isItemRemovable(bool check_worn) const
{
const LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
if(object
@@ -588,7 +588,7 @@ public:
virtual BOOL isItemRenameable() const;
// virtual BOOL isItemCopyable() const { return FALSE; }
virtual BOOL renameItem(const std::string& new_name);
- virtual BOOL isItemRemovable() const;
+ virtual BOOL isItemRemovable(bool check_worn = true) const;
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
virtual bool hasChildren() const;
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
@@ -648,7 +648,7 @@ BOOL LLTaskCategoryBridge::renameItem(const std::string& new_name)
return FALSE;
}
-BOOL LLTaskCategoryBridge::isItemRemovable() const
+BOOL LLTaskCategoryBridge::isItemRemovable(bool check_worn) const
{
return FALSE;
}
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 4a755a6e93..c7ae4eb0d9 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -733,7 +733,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
if (mSearchString == "")
{
mInventoryItemsPanel->setFilterSubString(LLStringUtil::null);
- mWearableItemsList->setFilterSubString(LLStringUtil::null);
+ mWearableItemsList->setFilterSubString(LLStringUtil::null, true);
// re-open folders that were initially open
mSavedFolderState->setApply(TRUE);
mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -763,8 +763,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
// set new filter string
mInventoryItemsPanel->setFilterSubString(mSearchString);
- mWearableItemsList->setFilterSubString(mSearchString);
-
+ mWearableItemsList->setFilterSubString(mSearchString, true);
}
void LLPanelOutfitEdit::onPlusBtnClicked(void)
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index d8c34d5c40..af06de379d 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -28,19 +28,19 @@
#include "llpaneloutfitsinventory.h"
-#include "llnotificationsutil.h"
-#include "lltabcontainer.h"
-
+#include "llagentwearables.h"
+#include "llappearancemgr.h"
#include "llfloatersidepanelcontainer.h"
#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
-#include "llagentwearables.h"
-#include "llappearancemgr.h"
-#include "lloutfitobserver.h"
+#include "llnotificationsutil.h"
#include "lloutfitgallery.h"
+#include "lloutfitobserver.h"
#include "lloutfitslist.h"
+#include "llpanelappearancetab.h"
#include "llpanelwearing.h"
#include "llsidepanelappearance.h"
+#include "lltabcontainer.h"
#include "llviewercontrol.h"
#include "llviewerfoldertype.h"
@@ -159,25 +159,12 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
{
if (!mActivePanel) return;
- mFilterSubString = string;
-
- if (string == "")
- {
- mActivePanel->setFilterSubString(LLStringUtil::null);
- }
-
if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
{
llassert(false); // this should have been done on startup
LLInventoryModelBackgroundFetch::instance().start();
}
- if (mActivePanel->getFilterSubString().empty() && string.empty())
- {
- // current filter and new filter empty, do nothing
- return;
- }
-
// set new filter string
mActivePanel->setFilterSubString(string);
}
@@ -302,6 +289,7 @@ bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
{
return mActivePanel && mActivePanel->isActionEnabled(userdata);
}
+
// List Commands //
//////////////////////////////////////////////////////////////////////////////////
@@ -330,7 +318,7 @@ void LLPanelOutfitsInventory::onTabChange()
mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel());
if (!mActivePanel) return;
- mActivePanel->setFilterSubString(mFilterSubString);
+ mActivePanel->checkFilterSubString();
mActivePanel->onOpen(LLSD());
updateVerbs();
@@ -357,8 +345,6 @@ bool LLPanelOutfitsInventory::isOutfitsGalleryPanelActive() const
return mActivePanel->getName() == OUTFIT_GALLERY_TAB_NAME;
}
-
-
void LLPanelOutfitsInventory::setWearablesLoading(bool val)
{
updateVerbs();
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 50d7074d4b..91873a427a 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -66,7 +66,6 @@ protected:
private:
LLTabContainer* mAppearanceTabs;
- std::string mFilterSubString;
//////////////////////////////////////////////////////////////////////////////////
// tab panels //
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index ffbed778c1..55ddeed4ec 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -102,216 +102,6 @@ static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage";
//////////////////////////////////////////////////////////////////////////
-void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("request_avatar_properties_coro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders;
-
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- httpOpts->setFollowRedirects(true);
-
- std::string finalUrl = cap_url + "/" + agent_id.asString();
-
- LLSD result = httpAdapter->getAndSuspend(httpRequest, finalUrl, httpOpts, httpHeaders);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Result: " << httpResults << LL_ENDL;
-
- if (!status
- || !result.has("id")
- || agent_id != result["id"].asUUID())
- {
- LL_WARNS("AvatarProperties") << "Failed to get agent information for id " << agent_id << LL_ENDL;
- return;
- }
-
- LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", agent_id));
- if (!floater_profile)
- {
- // floater is dead, so panels are dead as well
- return;
- }
-
- LLPanel *panel = floater_profile->findChild<LLPanel>(PANEL_PROFILE_VIEW, TRUE);
- LLPanelProfile *panel_profile = dynamic_cast<LLPanelProfile*>(panel);
- if (!panel_profile)
- {
- LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL;
- return;
- }
-
-
- // Avatar Data
-
- LLAvatarData *avatar_data = &panel_profile->mAvatarData;
- std::string birth_date;
-
- avatar_data->agent_id = agent_id;
- avatar_data->avatar_id = agent_id;
- avatar_data->image_id = result["sl_image_id"].asUUID();
- avatar_data->fl_image_id = result["fl_image_id"].asUUID();
- avatar_data->partner_id = result["partner_id"].asUUID();
- avatar_data->about_text = result["sl_about_text"].asString();
- avatar_data->fl_about_text = result["fl_about_text"].asString();
- avatar_data->born_on = result["member_since"].asDate();
- avatar_data->profile_url = getProfileURL(agent_id.asString());
- avatar_data->customer_type = result["customer_type"].asString();
-
- avatar_data->flags = 0;
-
- if (result["online"].asBoolean())
- {
- avatar_data->flags |= AVATAR_ONLINE;
- }
- if (result["allow_publish"].asBoolean())
- {
- avatar_data->flags |= AVATAR_ALLOW_PUBLISH;
- }
- if (result["identified"].asBoolean())
- {
- avatar_data->flags |= AVATAR_IDENTIFIED;
- }
- if (result["transacted"].asBoolean())
- {
- avatar_data->flags |= AVATAR_TRANSACTED;
- }
-
- avatar_data->caption_index = 0;
- if (result.has("charter_member")) // won't be present if "caption" is set
- {
- avatar_data->caption_index = result["charter_member"].asInteger();
- }
- else if (result.has("caption"))
- {
- avatar_data->caption_text = result["caption"].asString();
- }
-
- panel = floater_profile->findChild<LLPanel>(PANEL_SECONDLIFE, TRUE);
- LLPanelProfileSecondLife *panel_sl = dynamic_cast<LLPanelProfileSecondLife*>(panel);
- if (panel_sl)
- {
- panel_sl->processProfileProperties(avatar_data);
- }
-
- panel = floater_profile->findChild<LLPanel>(PANEL_WEB, TRUE);
- LLPanelProfileWeb *panel_web = dynamic_cast<LLPanelProfileWeb*>(panel);
- if (panel_web)
- {
- panel_web->setLoaded();
- }
-
- panel = floater_profile->findChild<LLPanel>(PANEL_FIRSTLIFE, TRUE);
- LLPanelProfileFirstLife *panel_first = dynamic_cast<LLPanelProfileFirstLife*>(panel);
- if (panel_first)
- {
- panel_first->processProperties(avatar_data);
- }
-
- // Picks
-
- LLSD picks_array = result["picks"];
- LLAvatarPicks avatar_picks;
- avatar_picks.agent_id = agent_id; // Not in use?
- avatar_picks.target_id = agent_id;
-
- for (LLSD::array_const_iterator it = picks_array.beginArray(); it != picks_array.endArray(); ++it)
- {
- const LLSD& pick_data = *it;
- avatar_picks.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString());
- }
-
- panel = floater_profile->findChild<LLPanel>(PANEL_PICKS, TRUE);
- LLPanelProfilePicks *panel_picks = dynamic_cast<LLPanelProfilePicks*>(panel);
- if (panel_picks)
- {
- // Refresh pick limit before processing
- LLAgentPicksInfo::getInstance()->onServerRespond(&avatar_picks);
- panel_picks->processProperties(&avatar_picks);
- }
-
- // Groups
-
- LLSD groups_array = result["groups"];
- LLAvatarGroups avatar_groups;
- avatar_groups.agent_id = agent_id; // Not in use?
- avatar_groups.avatar_id = agent_id; // target_id
-
- for (LLSD::array_const_iterator it = groups_array.beginArray(); it != groups_array.endArray(); ++it)
- {
- const LLSD& group_info = *it;
- LLAvatarGroups::LLGroupData group_data;
- group_data.group_powers = 0; // Not in use?
- group_data.group_title = group_info["name"].asString(); // Missing data, not in use?
- group_data.group_id = group_info["id"].asUUID();
- group_data.group_name = group_info["name"].asString();
- group_data.group_insignia_id = group_info["image_id"].asUUID();
-
- avatar_groups.group_list.push_back(group_data);
- }
-
- if (panel_sl)
- {
- panel_sl->processGroupProperties(&avatar_groups);
- }
-
- // Notes
- LLAvatarNotes avatar_notes;
-
- avatar_notes.agent_id = agent_id;
- avatar_notes.target_id = agent_id;
- avatar_notes.notes = result["notes"].asString();
-
- panel = floater_profile->findChild<LLPanel>(PANEL_NOTES, TRUE);
- LLPanelProfileNotes *panel_notes = dynamic_cast<LLPanelProfileNotes*>(panel);
- if (panel_notes)
- {
- panel_notes->processProperties(&avatar_notes);
- }
-}
-
-//TODO: changes take two minutes to propagate!
-// Add some storage that holds updated data for two minutes
-// for new instances to reuse the data
-// Profile data is only relevant to own avatar, but notes
-// are for everybody (no onger an issue?)
-void put_avatar_properties_coro(std::string cap_url, LLUUID agent_id, LLSD data, std::function<void(bool)> callback)
-{
- LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
- LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
- httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("put_avatar_properties_coro", httpPolicy));
- LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
- LLCore::HttpHeaders::ptr_t httpHeaders;
-
- LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
- httpOpts->setFollowRedirects(true);
-
- std::string finalUrl = cap_url + "/" + agent_id.asString();
-
- LLSD result = httpAdapter->putAndSuspend(httpRequest, finalUrl, data, httpOpts, httpHeaders);
-
- LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
-
- if (!status)
- {
- LL_WARNS("AvatarProperties") << "Failed to put agent information " << data << " for id " << agent_id << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("AvatarProperties") << "Agent id: " << agent_id << " Data: " << data << " Result: " << httpResults << LL_ENDL;
- }
-
- if (callback)
- {
- callback(status);
- }
-}
-
LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::string path_to_image, LLHandle<LLPanel> *handle)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
@@ -348,7 +138,6 @@ LLUUID post_profile_image(std::string cap_url, const LLSD &first_data, std::stri
}
// Upload the image
-
LLCore::HttpRequest::ptr_t uploaderhttpRequest(new LLCore::HttpRequest);
LLCore::HttpHeaders::ptr_t uploaderhttpHeaders(new LLCore::HttpHeaders);
LLCore::HttpOptions::ptr_t uploaderhttpOpts(new LLCore::HttpOptions);
@@ -898,11 +687,12 @@ void LLFloaterProfilePermissions::onCancel()
// LLPanelProfileSecondLife
LLPanelProfileSecondLife::LLPanelProfileSecondLife()
- : LLPanelProfileTab()
+ : LLPanelProfilePropertiesProcessorTab()
, mAvatarNameCacheConnection()
, mHasUnsavedDescriptionChanges(false)
, mWaitingForImageUpload(false)
, mAllowPublish(false)
+ , mHideAge(false)
{
}
@@ -928,6 +718,7 @@ BOOL LLPanelProfileSecondLife::postBuild()
{
mGroupList = getChild<LLGroupList>("group_list");
mShowInSearchCombo = getChild<LLComboBox>("show_in_search");
+ mHideAgeCombo = getChild<LLComboBox>("hide_age");
mSecondLifePic = getChild<LLThumbnailCtrl>("2nd_life_pic");
mSecondLifePicLayout = getChild<LLPanel>("image_panel");
mDescriptionEdit = getChild<LLTextEditor>("sl_description_edit");
@@ -942,6 +733,7 @@ BOOL LLPanelProfileSecondLife::postBuild()
mCantEditObjectsIcon = getChild<LLIconCtrl>("cant_edit_objects");
mShowInSearchCombo->setCommitCallback([this](LLUICtrl*, void*) { onShowInSearchCallback(); }, nullptr);
+ mHideAgeCombo->setCommitCallback([this](LLUICtrl*, void*) { onHideAgeCallback(); }, nullptr);
mGroupList->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { LLPanelProfileSecondLife::openGroupProfile(); });
mGroupList->setReturnCallback([this](LLUICtrl*, const LLSD&) { LLPanelProfileSecondLife::openGroupProfile(); });
mSaveDescriptionChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr);
@@ -1012,26 +804,6 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key)
mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2));
}
-void LLPanelProfileSecondLife::updateData()
-{
- LLUUID avatar_id = getAvatarId();
- if (!getStarted() && avatar_id.notNull())
- {
- setIsLoading();
-
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("requestAgentUserInfoCoro",
- boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
- }
- else
- {
- LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL;
- }
- }
-}
-
void LLPanelProfileSecondLife::refreshName()
{
if (!mAvatarNameCacheConnection.connected())
@@ -1075,6 +847,18 @@ void LLPanelProfileSecondLife::resetData()
childSetVisible("partner_spacer_layout", TRUE);
}
+void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PROPERTIES == type)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ if (avatar_data && getAvatarId() == avatar_data->avatar_id)
+ {
+ processProfileProperties(avatar_data);
+ }
+ }
+}
+
void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
{
const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
@@ -1094,22 +878,18 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat
fillAccountStatus(avatar_data);
- setLoaded();
-}
-
-void LLPanelProfileSecondLife::processGroupProperties(const LLAvatarGroups* avatar_groups)
-{
-
- LLAvatarGroups::group_list_t::const_iterator it = avatar_groups->group_list.begin();
- const LLAvatarGroups::group_list_t::const_iterator it_end = avatar_groups->group_list.end();
+ LLAvatarData::group_list_t::const_iterator it = avatar_data->group_list.begin();
+ const LLAvatarData::group_list_t::const_iterator it_end = avatar_data->group_list.end();
for (; it_end != it; ++it)
{
- LLAvatarGroups::LLGroupData group_data = *it;
+ LLAvatarData::LLGroupData group_data = *it;
mGroups[group_data.group_name] = group_data.group_id;
}
mGroupList->setGroups(mGroups);
+
+ setLoaded();
}
void LLPanelProfileSecondLife::openGroupProfile()
@@ -1216,7 +996,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
// and to make sure icons in text will be up to date
LLAvatarIconIDCache::getInstance()->add(avatar_data->avatar_id, avatar_data->image_id);
- fillAgeData(avatar_data->born_on);
+ fillAgeData(avatar_data);
setDescriptionText(avatar_data->about_text);
@@ -1251,7 +1031,7 @@ void LLPanelProfileSecondLife::fillCommonData(const LLAvatarData* avatar_data)
if (getSelfProfile())
{
mAllowPublish = avatar_data->flags & AVATAR_ALLOW_PUBLISH;
- mShowInSearchCombo->setValue((BOOL)mAllowPublish);
+ mShowInSearchCombo->setValue(mAllowPublish ? TRUE : FALSE);
}
}
@@ -1376,21 +1156,47 @@ void LLPanelProfileSecondLife::fillRightsData()
}
}
-void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on)
+void LLPanelProfileSecondLife::fillAgeData(const LLAvatarData* avatar_data)
{
// Date from server comes already converted to stl timezone,
// so display it as an UTC + 0
- std::string name_and_date = getString("date_format");
+ bool hide_age = avatar_data->hide_age && !getSelfProfile();
+ std::string name_and_date = getString(hide_age ? "date_format_short" : "date_format_full");
LLSD args_name;
- args_name["datetime"] = (S32)born_on.secondsSinceEpoch();
+ args_name["datetime"] = (S32)avatar_data->born_on.secondsSinceEpoch();
LLStringUtil::format(name_and_date, args_name);
getChild<LLUICtrl>("sl_birth_date")->setValue(name_and_date);
- std::string register_date = getString("age_format");
- LLSD args_age;
- args_age["[AGE]"] = LLDateUtil::ageFromDate(born_on, LLDate::now());
- LLStringUtil::format(register_date, args_age);
- getChild<LLUICtrl>("user_age")->setValue(register_date);
+ LLUICtrl* userAgeCtrl = getChild<LLUICtrl>("user_age");
+ if (hide_age)
+ {
+ userAgeCtrl->setVisible(FALSE);
+ }
+ else
+ {
+ std::string register_date = getString("age_format");
+ LLSD args_age;
+ args_age["[AGE]"] = LLDateUtil::ageFromDate(avatar_data->born_on, LLDate::now());
+ LLStringUtil::format(register_date, args_age);
+ userAgeCtrl->setValue(register_date);
+ }
+
+ BOOL showHideAgeCombo = FALSE;
+ if (getSelfProfile())
+ {
+ if (LLAvatarPropertiesProcessor::getInstance()->isHideAgeSupportedByServer())
+ {
+ F64 birth = avatar_data->born_on.secondsSinceEpoch();
+ F64 now = LLDate::now().secondsSinceEpoch();
+ if (now - birth > 365 * 24 * 60 * 60)
+ {
+ mHideAge = avatar_data->hide_age;
+ mHideAgeCombo->setValue(mHideAge ? TRUE : FALSE);
+ showHideAgeCombo = TRUE;
+ }
+ }
+ }
+ mHideAgeCombo->setVisible(showHideAgeCombo);
}
void LLPanelProfileSecondLife::onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep)
@@ -1465,7 +1271,7 @@ void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id)
LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
}
- LLPanelProfileTab::setAvatarId(avatar_id);
+ LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id);
if (LLAvatarActions::isFriend(getAvatarId()))
{
@@ -1507,6 +1313,10 @@ void LLPanelProfileSecondLife::setLoaded()
if (getSelfProfile())
{
mShowInSearchCombo->setEnabled(TRUE);
+ if (mHideAgeCombo->getVisible())
+ {
+ mHideAgeCombo->setEnabled(TRUE);
+ }
mDescriptionEdit->setEnabled(TRUE);
}
}
@@ -1834,39 +1644,28 @@ void LLPanelProfileSecondLife::onSetDescriptionDirty()
void LLPanelProfileSecondLife::onShowInSearchCallback()
{
- S32 value = mShowInSearchCombo->getValue().asInteger();
- if (mAllowPublish == (bool)value)
- {
+ bool value = mShowInSearchCombo->getValue().asInteger();
+ if (value == mAllowPublish)
return;
- }
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- mAllowPublish = value;
- LLSD data;
- data["allow_publish"] = mAllowPublish;
- LLCoros::instance().launch("putAgentUserInfoCoro",
- boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), data, nullptr));
- }
- else
- {
- LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
- }
+
+ mAllowPublish = value;
+ saveAgentUserInfoCoro("allow_publish", value);
+}
+
+void LLPanelProfileSecondLife::onHideAgeCallback()
+{
+ bool value = mHideAgeCombo->getValue().asInteger();
+ if (value == mHideAge)
+ return;
+
+ mHideAge = value;
+ saveAgentUserInfoCoro("hide_age", value);
}
void LLPanelProfileSecondLife::onSaveDescriptionChanges()
{
mDescriptionText = mDescriptionEdit->getValue().asString();
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("putAgentUserInfoCoro",
- boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText), nullptr));
- }
- else
- {
- LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
- }
+ saveAgentUserInfoCoro("sl_about_text", mDescriptionText);
mSaveDescriptionChanges->setEnabled(FALSE);
mDiscardDescriptionChanges->setEnabled(FALSE);
@@ -2000,55 +1799,44 @@ void LLPanelProfileSecondLife::onShowTexturePicker()
void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id)
{
if (mImageId == id)
- {
return;
- }
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
+ std::function<void(bool)> callback = [id](bool result)
{
- std::function<void(bool)> callback = [id](bool result)
+ if (result)
{
- if (result)
- {
- LLAvatarIconIDCache::getInstance()->add(gAgentID, id);
- // Should trigger callbacks in icon controls
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID);
- }
- };
- LLSD params;
- params["sl_image_id"] = id;
- LLCoros::instance().launch("putAgentUserInfoCoro",
- boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params, callback));
+ LLAvatarIconIDCache::getInstance()->add(gAgentID, id);
+ // Should trigger callbacks in icon controls (or request Legacy)
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(gAgentID);
+ }
+ };
+
+ if (!saveAgentUserInfoCoro("sl_image_id", id, callback))
+ return;
- mImageId = id;
+ mImageId = id;
+ if (mImageId == LLUUID::null)
+ {
+ mSecondLifePic->setValue("Generic_Person_Large");
+ }
+ else
+ {
+ mSecondLifePic->setValue(mImageId);
+ }
+
+ LLFloater *floater = mFloaterProfileTextureHandle.get();
+ if (floater)
+ {
+ LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
if (mImageId == LLUUID::null)
{
- mSecondLifePic->setValue("Generic_Person_Large");
+ texture_view->resetAsset();
}
else
{
- mSecondLifePic->setValue(mImageId);
- }
-
- LLFloater *floater = mFloaterProfileTextureHandle.get();
- if (floater)
- {
- LLFloaterProfileTexture * texture_view = dynamic_cast<LLFloaterProfileTexture*>(floater);
- if (mImageId == LLUUID::null)
- {
- texture_view->resetAsset();
- }
- else
- {
- texture_view->loadAsset(mImageId);
- }
+ texture_view->loadAsset(mImageId);
}
}
- else
- {
- LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
- }
}
//////////////////////////////////////////////////////////////////////////
@@ -2179,6 +1967,8 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e
LLStringUtil::format_map_t args;
args["[TIME]"] = llformat("%.2f", mPerformanceTimer.getElapsedTimeF32());
childSetValue("status_text", LLSD( getString("LoadTime", args)) );
+
+ setLoaded();
}
break;
@@ -2194,7 +1984,7 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e
//////////////////////////////////////////////////////////////////////////
LLPanelProfileFirstLife::LLPanelProfileFirstLife()
- : LLPanelProfileTab()
+ : LLPanelProfilePropertiesProcessorTab()
, mHasUnsavedChanges(false)
{
}
@@ -2345,34 +2135,22 @@ void LLPanelProfileFirstLife::onRemovePhoto()
void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id)
{
if (mImageId == id)
- {
return;
- }
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLSD params;
- params["fl_image_id"] = id;
- LLCoros::instance().launch("putAgentUserInfoCoro",
- boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), params, nullptr));
-
- mImageId = id;
- if (mImageId.notNull())
- {
- mPicture->setValue(mImageId);
- }
- else
- {
- mPicture->setValue("Generic_Person_Large");
- }
+ if (!saveAgentUserInfoCoro("fl_image_id", id))
+ return;
- mRemovePhoto->setEnabled(mImageId.notNull());
+ mImageId = id;
+ if (mImageId.notNull())
+ {
+ mPicture->setValue(mImageId);
}
else
{
- LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
+ mPicture->setValue("Generic_Person_Large");
}
+
+ mRemovePhoto->setEnabled(mImageId.notNull());
}
void LLPanelProfileFirstLife::setDescriptionText(const std::string &text)
@@ -2395,16 +2173,7 @@ void LLPanelProfileFirstLife::onSetDescriptionDirty()
void LLPanelProfileFirstLife::onSaveDescriptionChanges()
{
mCurrentDescription = mDescriptionEdit->getValue().asString();
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("putAgentUserInfoCoro",
- boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription), nullptr));
- }
- else
- {
- LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
- }
+ saveAgentUserInfoCoro("fl_about_text", mCurrentDescription);
mSaveChanges->setEnabled(FALSE);
mDiscardChanges->setEnabled(FALSE);
@@ -2416,6 +2185,18 @@ void LLPanelProfileFirstLife::onDiscardDescriptionChanges()
setDescriptionText(mCurrentDescription);
}
+void LLPanelProfileFirstLife::processProperties(void* data, EAvatarProcessorType type)
+{
+ if (APT_PROPERTIES == type)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ if (avatar_data && getAvatarId() == avatar_data->avatar_id)
+ {
+ processProperties(avatar_data);
+ }
+ }
+}
+
void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data)
{
setDescriptionText(avatar_data->fl_about_text);
@@ -2464,7 +2245,7 @@ void LLPanelProfileFirstLife::setLoaded()
//////////////////////////////////////////////////////////////////////////
LLPanelProfileNotes::LLPanelProfileNotes()
-: LLPanelProfileTab()
+: LLPanelProfilePropertiesProcessorTab()
, mHasUnsavedChanges(false)
{
@@ -2474,22 +2255,6 @@ LLPanelProfileNotes::~LLPanelProfileNotes()
{
}
-void LLPanelProfileNotes::updateData()
-{
- LLUUID avatar_id = getAvatarId();
- if (!getStarted() && avatar_id.notNull())
- {
- setIsLoading();
-
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("requestAgentUserInfoCoro",
- boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
- }
- }
-}
-
void LLPanelProfileNotes::commitUnsavedChanges()
{
if (mHasUnsavedChanges)
@@ -2538,16 +2303,7 @@ void LLPanelProfileNotes::onSetNotesDirty()
void LLPanelProfileNotes::onSaveNotesChanges()
{
mCurrentNotes = mNotesEditor->getValue().asString();
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("putAgentUserInfoCoro",
- boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("notes", mCurrentNotes), nullptr));
- }
- else
- {
- LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL;
- }
+ saveAgentUserInfoCoro("notes", mCurrentNotes);
mSaveChanges->setEnabled(FALSE);
mDiscardChanges->setEnabled(FALSE);
@@ -2559,9 +2315,21 @@ void LLPanelProfileNotes::onDiscardNotesChanges()
setNotesText(mCurrentNotes);
}
-void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes)
+void LLPanelProfileNotes::processProperties(void* data, EAvatarProcessorType type)
{
- setNotesText(avatar_notes->notes);
+ if (APT_PROPERTIES == type)
+ {
+ LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+ if (avatar_data && getAvatarId() == avatar_data->avatar_id)
+ {
+ processProperties(avatar_data);
+ }
+ }
+}
+
+void LLPanelProfileNotes::processProperties(const LLAvatarData* avatar_data)
+{
+ setNotesText(avatar_data->notes);
mNotesEditor->setEnabled(TRUE);
setLoaded();
}
@@ -2572,14 +2340,6 @@ void LLPanelProfileNotes::resetData()
setNotesText(std::string());
}
-void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id)
-{
- if (avatar_id.notNull())
- {
- LLPanelProfileTab::setAvatarId(avatar_id);
- }
-}
-
//////////////////////////////////////////////////////////////////////////
// LLPanelProfile
@@ -2656,12 +2416,7 @@ void LLPanelProfile::updateData()
mPanelFirstlife->setIsLoading();
mPanelNotes->setIsLoading();
- std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP);
- if (!cap_url.empty())
- {
- LLCoros::instance().launch("requestAgentUserInfoCoro",
- boost::bind(request_avatar_properties_coro, cap_url, avatar_id));
- }
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(getAvatarId());
}
}
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index 11632a10ae..221a576a65 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -68,7 +68,7 @@ class LLViewerFetchedTexture;
* Panel for displaying Avatar's second life related info.
*/
class LLPanelProfileSecondLife
- : public LLPanelProfileTab
+ : public LLPanelProfilePropertiesProcessorTab
, public LLFriendObserver
, public LLVoiceClientStatusObserver
{
@@ -93,10 +93,6 @@ public:
void resetData() override;
- /**
- * Sends update data request to server.
- */
- void updateData() override;
void refreshName();
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
@@ -107,7 +103,7 @@ public:
bool hasUnsavedChanges() override;
void commitUnsavedChanges() override;
- friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
+ void processProperties(void* data, EAvatarProcessorType type) override;
protected:
/**
@@ -116,11 +112,6 @@ protected:
void processProfileProperties(const LLAvatarData* avatar_data);
/**
- * Processes group related data received from server.
- */
- void processGroupProperties(const LLAvatarGroups* avatar_groups);
-
- /**
* Fills common for Avatar profile and My Profile fields.
*/
void fillCommonData(const LLAvatarData* avatar_data);
@@ -143,7 +134,7 @@ protected:
/**
* Fills user name, display name, age.
*/
- void fillAgeData(const LLDate &born_on);
+ void fillAgeData(const LLAvatarData* avatar_data);
void onImageLoaded(BOOL success, LLViewerFetchedTexture *imagep);
static void onImageLoaded(BOOL success,
@@ -179,6 +170,7 @@ private:
void setDescriptionText(const std::string &text);
void onSetDescriptionDirty();
void onShowInSearchCallback();
+ void onHideAgeCallback();
void onSaveDescriptionChanges();
void onDiscardDescriptionChanges();
void onShowAgentPermissionsDialog();
@@ -193,6 +185,7 @@ private:
LLGroupList* mGroupList;
LLComboBox* mShowInSearchCombo;
+ LLComboBox* mHideAgeCombo;
LLThumbnailCtrl* mSecondLifePic;
LLPanel* mSecondLifePicLayout;
LLTextEditor* mDescriptionEdit;
@@ -214,6 +207,7 @@ private:
bool mVoiceStatus;
bool mWaitingForImageUpload;
bool mAllowPublish;
+ bool mHideAge;
std::string mDescriptionText;
LLUUID mImageId;
@@ -247,8 +241,6 @@ public:
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
- friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
-
protected:
void onCommitLoad(LLUICtrl* ctrl);
@@ -267,7 +259,7 @@ private:
* Panel for displaying Avatar's first life related info.
*/
class LLPanelProfileFirstLife
- : public LLPanelProfileTab
+ : public LLPanelProfilePropertiesProcessorTab
{
public:
LLPanelProfileFirstLife();
@@ -277,6 +269,7 @@ public:
BOOL postBuild() override;
+ void processProperties(void* data, EAvatarProcessorType type) override;
void processProperties(const LLAvatarData* avatar_data);
void resetData() override;
@@ -287,8 +280,6 @@ public:
bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
void commitUnsavedChanges() override;
- friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
-
protected:
void setLoaded() override;
@@ -320,24 +311,21 @@ protected:
* Panel for displaying Avatar's notes and modifying friend's rights.
*/
class LLPanelProfileNotes
- : public LLPanelProfileTab
+ : public LLPanelProfilePropertiesProcessorTab
{
public:
LLPanelProfileNotes();
/*virtual*/ ~LLPanelProfileNotes();
- void setAvatarId(const LLUUID& avatar_id) override;
-
void onOpen(const LLSD& key) override;
BOOL postBuild() override;
- void processProperties(LLAvatarNotes* avatar_notes);
+ void processProperties(void* data, EAvatarProcessorType type) override;
+ void processProperties(const LLAvatarData* avatar_data);
void resetData() override;
- void updateData() override;
-
bool hasUnsavedChanges() override { return mHasUnsavedChanges; }
void commitUnsavedChanges() override;
@@ -384,10 +372,6 @@ public:
void showClassified(const LLUUID& classified_id = LLUUID::null, bool edit = false);
void createClassified();
- LLAvatarData getAvatarData() { return mAvatarData; };
-
- friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
-
private:
void onTabChange();
@@ -398,13 +382,6 @@ private:
LLPanelProfileFirstLife* mPanelFirstlife;
LLPanelProfileNotes* mPanelNotes;
LLTabContainer* mTabContainer;
-
- // Todo: due to server taking minutes to update this needs a more long term storage
- // to reuse recently saved values if user opens floater again
- // Storage implementation depends onto how a cap will be implemented, if cap will be
- // enought to fully update LLAvatarPropertiesProcessor, then this storage can be
- // implemented there.
- LLAvatarData mAvatarData;
};
#endif //LL_LLPANELPROFILE_H
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
index ff3f654d0e..4128c5745f 100644
--- a/indra/newview/llpanelprofilepicks.cpp
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -98,12 +98,6 @@ public:
return true;
}
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
- {
- LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
// handle app/pick/create urls first
if (params.size() == 1 && params[0].asString() == "create")
{
@@ -296,17 +290,21 @@ void LLPanelProfilePicks::callbackDeletePick(const LLSD& notification, const LLS
void LLPanelProfilePicks::processProperties(void* data, EAvatarProcessorType type)
{
- if (APT_PICKS == type)
+ if (APT_PROPERTIES == type)
{
- LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
- if (avatar_picks && getAvatarId() == avatar_picks->target_id)
+ LLAvatarData* avatar_picks = static_cast<LLAvatarData*>(data);
+ if (avatar_picks && getAvatarId() == avatar_picks->avatar_id)
{
+ if (getSelfProfile())
+ {
+ LLAgentPicksInfo::getInstance()->onServerRespond(avatar_picks);
+ }
processProperties(avatar_picks);
}
}
}
-void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
+void LLPanelProfilePicks::processProperties(const LLAvatarData* avatar_picks)
{
LLUUID selected_id = mPickToSelectOnLoad;
bool has_selection = false;
@@ -324,7 +322,7 @@ void LLPanelProfilePicks::processProperties(const LLAvatarPicks* avatar_picks)
mTabContainer->deleteAllTabs();
- LLAvatarPicks::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
+ LLAvatarData::picks_list_t::const_iterator it = avatar_picks->picks_list.begin();
for (; avatar_picks->picks_list.end() != it; ++it)
{
LLUUID pick_id = it->first;
@@ -428,7 +426,7 @@ void LLPanelProfilePicks::updateData()
{
setIsLoading();
- LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(avatar_id);
+ LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id);
}
if (!getIsLoaded())
{
diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h
index f84463cc9b..79a5ace865 100644
--- a/indra/newview/llpanelprofilepicks.h
+++ b/indra/newview/llpanelprofilepicks.h
@@ -58,7 +58,7 @@ public:
void selectPick(const LLUUID& pick_id);
void processProperties(void* data, EAvatarProcessorType type) override;
- void processProperties(const LLAvatarPicks* avatar_picks);
+ void processProperties(const LLAvatarData* avatar_picks);
void resetData() override;
@@ -77,8 +77,6 @@ public:
bool hasUnsavedChanges() override;
void commitUnsavedChanges() override;
- friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id);
-
private:
void onClickNewBtn();
void onClickDelete();
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 5242c4fef9..35eba16afe 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -110,9 +110,9 @@ protected:
registrar.add("Wearing.EditOutfit", boost::bind(&edit_outfit));
registrar.add("Wearing.ShowOriginal", boost::bind(show_item_original, mUUIDs.front()));
registrar.add("Wearing.TakeOff",
- boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op));
registrar.add("Wearing.Detach",
- boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op));
LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");
updateMenuItemsVisibility(menu);
@@ -209,8 +209,6 @@ protected:
//////////////////////////////////////////////////////////////////////////
-std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null;
-
static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing");
LLPanelWearing::LLPanelWearing()
@@ -328,10 +326,11 @@ void LLPanelWearing::startUpdateTimer()
}
// virtual
-void LLPanelWearing::setFilterSubString(const std::string& string)
+void LLPanelWearing::onFilterSubStringChanged(const std::string& new_string, const std::string& old_string)
{
- sFilterSubString = string;
- mCOFItemsList->setFilterSubString(sFilterSubString);
+ mCOFItemsList->setFilterSubString(new_string, true);
+
+ mAccordionCtrl->arrange();
}
// virtual
diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h
index 18e543eec6..2f3f14956a 100644
--- a/indra/newview/llpanelwearing.h
+++ b/indra/newview/llpanelwearing.h
@@ -61,7 +61,7 @@ public:
/*virtual*/ void onOpen(const LLSD& info);
- /*virtual*/ void setFilterSubString(const std::string& string);
+ /*virtual*/ void onFilterSubStringChanged(const std::string& new_string, const std::string& old_string);
/*virtual*/ bool isActionEnabled(const LLSD& userdata);
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9bf771db8a..ec537e216b 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -115,7 +115,7 @@ void LLPersistentNotificationStorage::loadNotifications()
using namespace LLNotificationsUI;
LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
- findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ findChannelByID(LLNotificationsUI::NOTIFICATION_CHANNEL_UUID));
LLNotifications& instance = LLNotifications::instance();
S32 processed_notifications = 0;
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index 30d0a22ef0..1fcc456d62 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -254,8 +254,6 @@ void LLPresetsManager::getControlNames(std::vector<std::string>& names)
// From panel_preferences_move.xml
("CameraAngle")
("CameraOffsetScale")
- ("EditCameraMovement")
- ("AppearanceCameraMovement")
// From llagentcamera.cpp
("CameraOffsetBuild")
("TrackFocusObject")
@@ -460,6 +458,9 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
LL_DEBUGS() << "attempting to load preset '"<<name<<"' from '"<<full_path<<"'" << LL_ENDL;
+ bool appearance_camera_movement = gSavedSettings.getBOOL("AppearanceCameraMovement");
+ bool edit_camera_movement = gSavedSettings.getBOOL("EditCameraMovement");
+
mIgnoreChangedSignal = true;
if(gSavedSettings.loadFromFile(full_path, false, true) > 0)
{
@@ -479,6 +480,16 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
{
gSavedSettings.setString("PresetCameraActive", name);
triggerChangeCameraSignal();
+
+ //SL-20277 old preset files may contain settings that should be ignored when loading camera presets
+ if (appearance_camera_movement != (bool)gSavedSettings.getBOOL("AppearanceCameraMovement"))
+ {
+ gSavedSettings.setBOOL("AppearanceCameraMovement", appearance_camera_movement);
+ }
+ if (edit_camera_movement != (bool)gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ gSavedSettings.setBOOL("EditCameraMovement", edit_camera_movement);
+ }
}
}
else
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 544ff8b5dc..0b0d5d10cd 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -433,6 +433,11 @@ BOOL LLPreviewGesture::postBuild()
edit->setIgnoreTab(TRUE);
mChatEditor = edit;
+ check = getChild<LLCheckBoxCtrl>( "wait_key_release_check");
+ check->setVisible(FALSE);
+ check->setCommitCallback(onCommitWait, this);
+ mWaitKeyReleaseCheck = check;
+
check = getChild<LLCheckBoxCtrl>( "wait_anim_check");
check->setVisible(FALSE);
check->setCommitCallback(onCommitWait, this);
@@ -638,6 +643,7 @@ void LLPreviewGesture::refresh()
mAnimationRadio->setEnabled(FALSE);
mSoundCombo->setEnabled(FALSE);
mChatEditor->setEnabled(FALSE);
+ mWaitKeyReleaseCheck->setEnabled(FALSE);
mWaitAnimCheck->setEnabled(FALSE);
mWaitTimeCheck->setEnabled(FALSE);
mWaitTimeEditor->setEnabled(FALSE);
@@ -660,6 +666,7 @@ void LLPreviewGesture::refresh()
mAnimationRadio->setEnabled(modifiable);
mSoundCombo->setEnabled(modifiable);
mChatEditor->setEnabled(modifiable);
+ mWaitKeyReleaseCheck->setEnabled(modifiable);
mWaitAnimCheck->setEnabled(modifiable);
mWaitTimeCheck->setEnabled(modifiable);
mWaitTimeEditor->setEnabled(modifiable);
@@ -695,6 +702,7 @@ void LLPreviewGesture::refresh()
mAnimationRadio->setVisible(FALSE);
mSoundCombo->setVisible(FALSE);
mChatEditor->setVisible(FALSE);
+ mWaitKeyReleaseCheck->setVisible(FALSE);
mWaitAnimCheck->setVisible(FALSE);
mWaitTimeCheck->setVisible(FALSE);
mWaitTimeEditor->setVisible(FALSE);
@@ -739,6 +747,8 @@ void LLPreviewGesture::refresh()
{
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
optionstext = getString("step_wait");
+ mWaitKeyReleaseCheck->setVisible(TRUE);
+ mWaitKeyReleaseCheck->set(wait_step->mFlags & WAIT_FLAG_KEY_RELEASE);
mWaitAnimCheck->setVisible(TRUE);
mWaitAnimCheck->set(wait_step->mFlags & WAIT_FLAG_ALL_ANIM);
mWaitTimeCheck->setVisible(TRUE);
@@ -1518,6 +1528,7 @@ void LLPreviewGesture::onCommitWait(LLUICtrl* ctrl, void* data)
LLGestureStepWait* wait_step = (LLGestureStepWait*)step;
U32 flags = 0x0;
+ if (self->mWaitKeyReleaseCheck->get()) flags |= WAIT_FLAG_KEY_RELEASE;
if (self->mWaitAnimCheck->get()) flags |= WAIT_FLAG_ALL_ANIM;
if (self->mWaitTimeCheck->get()) flags |= WAIT_FLAG_TIME;
wait_step->mFlags = flags;
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index f5c47d71b8..d0fddaf49a 100644
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -154,6 +154,7 @@ private:
LLComboBox* mAnimationCombo;
LLComboBox* mSoundCombo;
LLLineEditor* mChatEditor;
+ LLCheckBoxCtrl* mWaitKeyReleaseCheck;
LLCheckBoxCtrl* mWaitAnimCheck;
LLCheckBoxCtrl* mWaitTimeCheck;
LLLineEditor* mWaitTimeEditor;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 17f2970f99..ea3aa58f94 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -170,8 +170,9 @@ void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
void LLScreenChannelBase::updateRect()
{
+ const S32 CHANNEL_BOTTOM_PANEL_MARGIN = 35;
S32 channel_top = getChannelRect().mTop;
- S32 channel_bottom = getChannelRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+ S32 channel_bottom = getChannelRect().mBottom + CHANNEL_BOTTOM_PANEL_MARGIN;
S32 channel_left = getRect().mLeft;
S32 channel_right = getRect().mRight;
setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index e5f4807ab7..d66c8afc22 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -34,6 +34,12 @@
namespace LLNotificationsUI
{
+ const LLUUID ALERT_CHANNEL_UUID("F3E07BC8-A973-476D-8C7F-F3B7293975D1");
+ const LLUUID NOTIFICATION_CHANNEL_UUID("AEED3193-8709-4693-8558-7452CCA97AE5");
+ const LLUUID NEARBY_CHAT_CHANNEL_UUID("E1158BD6-661C-4981-9DAD-4DCBFF062502");
+ const LLUUID STARTUP_CHANNEL_UUID("B56AF90D-6684-48E4-B1E4-722D3DEB2CB6");
+
+ const S32 NOTIFY_BOX_WIDTH = 305;
typedef enum e_notification_toast_alignment
{
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 6a27ff3047..66ee016191 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -335,7 +335,7 @@ void LLScriptFloater::hideToastsIfNeeded()
// find channel
LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->findChannelByID(
- LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID));
// update notification channel state
if(channel)
{
diff --git a/indra/newview/llsearchhistory.cpp b/indra/newview/llsearchhistory.cpp
index 449e0080f0..66e377cb8d 100644
--- a/indra/newview/llsearchhistory.cpp
+++ b/indra/newview/llsearchhistory.cpp
@@ -75,6 +75,17 @@ bool LLSearchHistory::save()
{
// build filename for each user
std::string resolved_filename = getHistoryFilePath();
+
+ // delete the file if it is empty or contains only empty entries
+ if (std::find_if(mSearchHistory.begin(), mSearchHistory.end(), [](const LLSearchHistoryItem& x)
+ {
+ return !x.search_query.empty();
+ }) == mSearchHistory.end())
+ {
+ remove(resolved_filename.c_str());
+ return true;
+ }
+
// open a file for writing
llofstream file(resolved_filename.c_str());
if (!file.is_open())
diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp
index 74844a80e8..dbab7e53b6 100644
--- a/indra/newview/llsetkeybinddialog.cpp
+++ b/indra/newview/llsetkeybinddialog.cpp
@@ -74,13 +74,10 @@ LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key)
pUpdater(NULL),
mLastMaskKey(0),
mContextConeOpacity(0.f),
- mContextConeInAlpha(0.f),
- mContextConeOutAlpha(0.f),
- mContextConeFadeTime(0.f)
+ mContextConeInAlpha(CONTEXT_CONE_IN_ALPHA),
+ mContextConeOutAlpha(CONTEXT_CONE_OUT_ALPHA),
+ mContextConeFadeTime(CONTEXT_CONE_FADE_TIME)
{
- mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
- mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
- mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
}
LLSetKeyBindDialog::~LLSetKeyBindDialog()
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index fe61b7a02a..ad8e1a6506 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -74,6 +74,32 @@ LLSidepanelTaskInfo* LLSidepanelTaskInfo::sActivePanel = NULL;
static LLPanelInjector<LLSidepanelTaskInfo> t_task_info("sidepanel_task_info");
+static std::string click_action_to_string_value(U8 click_action)
+{
+ switch (click_action)
+ {
+ case CLICK_ACTION_TOUCH:
+ return "Touch";
+ case CLICK_ACTION_SIT:
+ return "Sit";
+ case CLICK_ACTION_BUY:
+ return "Buy";
+ case CLICK_ACTION_PAY:
+ return "Pay";
+ case CLICK_ACTION_OPEN:
+ return "Open";
+ case CLICK_ACTION_ZOOM:
+ return "Zoom";
+ case CLICK_ACTION_DISABLED:
+ return "None";
+ case CLICK_ACTION_IGNORE:
+ return "Ignore";
+ default:
+ return "Touch";
+ }
+ return "Touch";
+}
+
// Default constructor
LLSidepanelTaskInfo::LLSidepanelTaskInfo()
: mVisibleDebugPermissions(true) // space was allocated by default
@@ -891,11 +917,7 @@ void LLSidepanelTaskInfo::refresh()
U8 click_action = 0;
if (LLSelectMgr::getInstance()->selectionGetClickAction(&click_action))
{
- LLComboBox* ComboClickAction = getChild<LLComboBox>("clickaction");
- if (ComboClickAction)
- {
- ComboClickAction->setCurrentByIndex((S32)click_action);
- }
+ getChild<LLComboBox>("clickaction")->setValue(click_action_to_string_value(click_action));
}
getChildView("label click action")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
@@ -1152,6 +1174,8 @@ static U8 string_value_to_click_action(std::string p_value)
return CLICK_ACTION_ZOOM;
if (p_value == "None")
return CLICK_ACTION_DISABLED;
+ if (p_value == "Ignore")
+ return CLICK_ACTION_IGNORE;
return CLICK_ACTION_TOUCH;
}
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index a3a8247268..e43fb993ce 100644
--- a/indra/newview/llslurl.cpp
+++ b/indra/newview/llslurl.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file llurlsimstring.cpp (was llsimurlstring.cpp)
* @brief Handles "SLURL fragments" like Ahern/123/45 for
* startup processing, login screen, prefs, etc.
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,7 +36,7 @@
#include "curl/curl.h"
const char* LLSLURL::SLURL_HTTP_SCHEME = "http";
const char* LLSLURL::SLURL_HTTPS_SCHEME = "https";
-const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";
+const char* LLSLURL::SLURL_SECONDLIFE_SCHEME = "secondlife";
const char* LLSLURL::SLURL_SECONDLIFE_PATH = "secondlife";
const char* LLSLURL::SLURL_COM = "slurl.com";
// For DnD - even though www.slurl.com redirects to slurl.com in a browser, you can copy and drag
@@ -54,473 +54,469 @@ const char* LLSLURL::SIM_LOCATION_LAST = "last";
// resolve a simstring from a slurl
LLSLURL::LLSLURL(const std::string& slurl)
{
- // by default we go to agni.
- mType = INVALID;
-
- if(slurl == SIM_LOCATION_HOME)
- {
- mType = HOME_LOCATION;
- }
- else if(slurl.empty() || (slurl == SIM_LOCATION_LAST))
- {
- mType = LAST_LOCATION;
- }
- else
- {
- LLURI slurl_uri;
- // parse the slurl as a uri
- if(slurl.find(':') == std::string::npos)
- {
- // There may be no scheme ('secondlife:' etc.) passed in. In that case
- // we want to normalize the slurl by putting the appropriate scheme
- // in front of the slurl. So, we grab the appropriate slurl base
- // from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or
- // https://<hostname>/region/ for Standalone grid (the word region, not the region name)
- // these slurls are typically passed in from the 'starting location' box on the login panel,
- // where the user can type in <regionname>/<x>/<y>/<z>
- std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
-
- // the slurl that was passed in might have a prepended /, or not. So,
- // we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z>
- // or some such.
-
- if(slurl[0] == '/')
- {
- fixed_slurl += slurl.substr(1);
- }
- else
- {
- fixed_slurl += slurl;
- }
- // We then load the slurl into a LLURI form
- slurl_uri = LLURI(fixed_slurl);
- }
- else
- {
- // as we did have a scheme, implying a URI style slurl, we
- // simply parse it as a URI
- slurl_uri = LLURI(slurl);
- }
-
- LLSD path_array = slurl_uri.pathArray();
-
- // determine whether it's a maingrid URI or an Standalone/open style URI
- // by looking at the scheme. If it's a 'secondlife:' slurl scheme or
- // 'sl:' scheme, we know it's maingrid
-
- // At the end of this if/else block, we'll have determined the grid,
- // and the slurl type (APP or LOCATION)
- if(slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
- {
- // parse a maingrid style slurl. We know the grid is maingrid
- // so grab it.
- // A location slurl for maingrid (with the special schemes) can be in the form
- // secondlife://<regionname>/<x>/<y>/<z>
- // or
- // secondlife://<Grid>/secondlife/<region>/<x>/<y>/<z>
- // where if grid is empty, it specifies Agni
-
- // An app style slurl for maingrid can be
- // secondlife://<Grid>/app/<app parameters>
- // where an empty grid implies Agni
-
- // we'll start by checking the top of the 'path' which will be
- // either 'app', 'secondlife', or <x>.
-
- // default to maingrid
-
- mGrid = MAINGRID;
-
- if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) ||
- (path_array[0].asString() == LLSLURL::SLURL_APP_PATH))
- {
- // it's in the form secondlife://<grid>/(app|secondlife)
- // so parse the grid name to derive the grid ID
- if (!slurl_uri.hostName().empty())
- {
- mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName());
- }
- else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
- {
- // If the slurl is in the form secondlife:///secondlife/<region> form,
- // then we are in fact on maingrid.
- mGrid = MAINGRID;
- }
- else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
- {
- // for app style slurls, where no grid name is specified, assume the currently
- // selected or logged in grid.
- mGrid = LLGridManager::getInstance()->getGridId();
- }
-
- if(mGrid.empty())
- {
- // we couldn't find the grid in the grid manager, so bail
- LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL;
- return;
- }
- // set the type as appropriate.
- if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
- {
- mType = LOCATION;
- }
- else
- {
- mType = APP;
- }
- path_array.erase(0);
- }
- else
- {
- if(slurl_uri.hostName() == LLSLURL::SLURL_APP_PATH)
+ // by default we go to agni.
+ mType = INVALID;
+
+ if (slurl.empty() || (slurl == SIM_LOCATION_LAST))
+ {
+ mType = LAST_LOCATION;
+ }
+ else if (slurl == SIM_LOCATION_HOME)
+ {
+ mType = HOME_LOCATION;
+ }
+ else
+ {
+ LLURI slurl_uri;
+ // parse the slurl as a uri
+ if (slurl.find(':') == std::string::npos)
+ {
+ // There may be no scheme ('secondlife:' etc.) passed in. In that case
+ // we want to normalize the slurl by putting the appropriate scheme
+ // in front of the slurl. So, we grab the appropriate slurl base
+ // from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or
+ // https://<hostname>/region/ for Standalone grid (the word region, not the region name)
+ // these slurls are typically passed in from the 'starting location' box on the login panel,
+ // where the user can type in <regionname>/<x>/<y>/<z>
+ std::string fixed_slurl = LLGridManager::getInstance()->getSLURLBase();
+
+ // the slurl that was passed in might have a prepended /, or not. So,
+ // we strip off the prepended '/' so we don't end up with http://slurl.com/secondlife/<region>/<x>/<y>/<z>
+ // or some such.
+
+ if (slurl[0] == '/')
+ {
+ fixed_slurl += slurl.substr(1);
+ }
+ else
+ {
+ fixed_slurl += slurl;
+ }
+ // We then load the slurl into a LLURI form
+ slurl_uri = LLURI(fixed_slurl);
+ }
+ else
+ {
+ // as we did have a scheme, implying a URI style slurl, we
+ // simply parse it as a URI
+ slurl_uri = LLURI(slurl);
+ }
+
+ LLSD path_array = slurl_uri.pathArray();
+
+ // determine whether it's a maingrid URI or an Standalone/open style URI
+ // by looking at the scheme. If it's a 'secondlife:' slurl scheme or
+ // 'sl:' scheme, we know it's maingrid
+
+ // At the end of this if/else block, we'll have determined the grid,
+ // and the slurl type (APP or LOCATION)
+ if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME)
+ {
+ if (path_array.size() == 0
+ && slurl_uri.authority().empty()
+ && slurl_uri.escapedQuery().empty())
+ {
+ mType = EMPTY;
+ // um, we need a path...
+ return;
+ }
+
+ // parse a maingrid style slurl. We know the grid is maingrid
+ // so grab it.
+ // A location slurl for maingrid (with the special schemes) can be in the form
+ // secondlife://<regionname>/<x>/<y>/<z>
+ // or
+ // secondlife://<Grid>/secondlife/<region>/<x>/<y>/<z>
+ // where if grid is empty, it specifies Agni
+
+ // An app style slurl for maingrid can be
+ // secondlife://<Grid>/app/<app parameters>
+ // where an empty grid implies Agni
+
+ // we'll start by checking the top of the 'path' which will be
+ // either 'app', 'secondlife', or <x>.
+
+ // default to maingrid
+
+ mGrid = MAINGRID;
+
+ if ((path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH) ||
+ (path_array[0].asString() == LLSLURL::SLURL_APP_PATH))
+ {
+ // it's in the form secondlife://<grid>/(app|secondlife)
+ // so parse the grid name to derive the grid ID
+ if (!slurl_uri.hostName().empty())
+ {
+ mGrid = LLGridManager::getInstance()->getGridId(slurl_uri.hostName());
+ }
+ else if(path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
+ {
+ // If the slurl is in the form secondlife:///secondlife/<region> form,
+ // then we are in fact on maingrid.
+ mGrid = MAINGRID;
+ }
+ else if(path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
+ {
+ // for app style slurls, where no grid name is specified, assume the currently
+ // selected or logged in grid.
+ mGrid = LLGridManager::getInstance()->getGridId();
+ }
+
+ if (mGrid.empty())
+ {
+ // we couldn't find the grid in the grid manager, so bail
+ LL_WARNS("AppInit")<<"unable to find grid"<<LL_ENDL;
+ return;
+ }
+ // set the type as appropriate.
+ if (path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH)
+ {
+ mType = LOCATION;
+ }
+ else
+ {
+ mType = APP;
+ }
+ path_array.erase(0);
+ }
+ else
+ {
+ if (slurl_uri.hostName() == LLSLURL::SLURL_APP_PATH)
{
mType = APP;
}
else
{
// it wasn't a /secondlife/<region> or /app/<params>, so it must be secondlife://<region>
- // therefore the hostname will be the region name, and it's a location type
- mType = LOCATION;
- // 'normalize' it so the region name is in fact the head of the path_array
- path_array.insert(0, slurl_uri.hostName());
+ // therefore the hostname will be the region name, and it's a location type
+ mType = LOCATION;
+ // 'normalize' it so the region name is in fact the head of the path_array
+ path_array.insert(0, slurl_uri.hostName());
+ }
+ }
+ }
+ else if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
+ (slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
+ (slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
+ {
+ // We're dealing with either a Standalone style slurl or slurl.com slurl
+ if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
+ (slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
+ (slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
+ {
+ // slurl.com implies maingrid
+ mGrid = MAINGRID;
+ }
+ else
+ {
+ // Don't try to match any old http://<host>/ URL as a SLurl.
+ // SLE SLurls will have the grid hostname in the URL, so only
+ // match http URLs if the hostname matches the grid hostname
+ // (or its a slurl.com or maps.secondlife.com URL).
+ if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME ||
+ slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) &&
+ slurl_uri.hostName() != LLGridManager::getInstance()->getGrid())
+ {
+ return;
}
- }
- }
- else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) ||
- (slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) ||
- (slurl_uri.scheme() == LLSLURL::SLURL_X_GRID_LOCATION_INFO_SCHEME))
- {
- // We're dealing with either a Standalone style slurl or slurl.com slurl
- if ((slurl_uri.hostName() == LLSLURL::SLURL_COM) ||
- (slurl_uri.hostName() == LLSLURL::WWW_SLURL_COM) ||
- (slurl_uri.hostName() == LLSLURL::MAPS_SECONDLIFE_COM))
- {
- // slurl.com implies maingrid
- mGrid = MAINGRID;
- }
- else
- {
- // Don't try to match any old http://<host>/ URL as a SLurl.
- // SLE SLurls will have the grid hostname in the URL, so only
- // match http URLs if the hostname matches the grid hostname
- // (or its a slurl.com or maps.secondlife.com URL).
- if ((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME ||
- slurl_uri.scheme() == LLSLURL::SLURL_HTTPS_SCHEME) &&
- slurl_uri.hostName() != LLGridManager::getInstance()->getGrid())
- {
- return;
- }
-
- // As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style
- // urls are properly formed, unlike the stinky maingrid style
- mGrid = slurl_uri.hostName();
- }
- if (path_array.size() == 0)
- {
- // um, we need a path...
- return;
- }
-
- // we need to normalize the urls so
- // the path portion starts with the 'command' that we want to do
- // it can either be region or app.
- if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) ||
- (path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH))
- {
- // strip off 'region' or 'secondlife'
- path_array.erase(0);
- // it's a location
- mType = LOCATION;
- }
- else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
- {
- mType = APP;
- path_array.erase(0);
- // leave app appended.
- }
- else
- {
- // not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL
- return;
- }
- }
- else
- {
- // invalid scheme, so bail
- return;
- }
-
-
- if(path_array.size() == 0)
- {
- // we gotta have some stuff after the specifier as to whether it's a region or command
- return;
- }
-
- // now that we know whether it's an app slurl or a location slurl,
- // parse the slurl into the proper data structures.
- if(mType == APP)
- {
- // grab the app command type and strip it (could be a command to jump somewhere,
- // or whatever )
- mAppCmd = path_array[0].asString();
- path_array.erase(0);
-
- // Grab the parameters
- mAppPath = path_array;
- // and the query
- mAppQuery = slurl_uri.query();
- mAppQueryMap = slurl_uri.queryMap();
- return;
- }
- else if(mType == LOCATION)
- {
- // at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z
- // are collectively optional
- // are optional
-
- mRegion = LLURI::unescape(path_array[0].asString());
-
- if(LLStringUtil::containsNonprintable(mRegion))
- {
- LLStringUtil::stripNonprintable(mRegion);
- }
-
- path_array.erase(0);
-
- // parse the x, y, and optionally z
- if(path_array.size() >= 2)
- {
-
- mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
- if((F32(mPosition[VX]) < 0.f) ||
- (mPosition[VX] > REGION_WIDTH_METERS) ||
- (F32(mPosition[VY]) < 0.f) ||
- (mPosition[VY] > REGION_WIDTH_METERS) ||
- (F32(mPosition[VZ]) < 0.f) ||
- (mPosition[VZ] > REGION_HEIGHT_METERS))
- {
- mType = INVALID;
- return;
- }
-
- }
- else
- {
- // if x, y and z were not fully passed in, go to the middle of the region.
- // teleport will adjust the actual location to make sure you're on the ground
- // and such
- mPosition = LLVector3(REGION_WIDTH_METERS/2, REGION_WIDTH_METERS/2, 0);
- }
- }
- }
-}
+ // As it's a Standalone grid/open, we will always have a hostname, as Standalone/open style
+ // urls are properly formed, unlike the stinky maingrid style
+ mGrid = slurl_uri.hostName();
+ }
+ if (path_array.size() == 0)
+ {
+ // um, we need a path...
+ return;
+ }
+
+ // we need to normalize the urls so
+ // the path portion starts with the 'command' that we want to do
+ // it can either be region or app.
+ if ((path_array[0].asString() == LLSLURL::SLURL_REGION_PATH) ||
+ (path_array[0].asString() == LLSLURL::SLURL_SECONDLIFE_PATH))
+ {
+ // strip off 'region' or 'secondlife'
+ path_array.erase(0);
+ // it's a location
+ mType = LOCATION;
+ }
+ else if (path_array[0].asString() == LLSLURL::SLURL_APP_PATH)
+ {
+ mType = APP;
+ path_array.erase(0);
+ // leave app appended.
+ }
+ else
+ {
+ // not a valid https/http/x-grid-location-info slurl, so it'll likely just be a URL
+ return;
+ }
+ }
+ else
+ {
+ // invalid scheme, so bail
+ return;
+ }
+
+ if (path_array.size() == 0)
+ {
+ // we gotta have some stuff after the specifier as to whether it's a region or command
+ return;
+ }
+
+ // now that we know whether it's an app slurl or a location slurl,
+ // parse the slurl into the proper data structures.
+ if (mType == APP)
+ {
+ // grab the app command type and strip it (could be a command to jump somewhere,
+ // or whatever )
+ mAppCmd = path_array[0].asString();
+ path_array.erase(0);
+
+ // Grab the parameters
+ mAppPath = path_array;
+ // and the query
+ mAppQuery = slurl_uri.query();
+ mAppQueryMap = slurl_uri.queryMap();
+ return;
+ }
+ else if (mType == LOCATION)
+ {
+ // at this point, head of the path array should be [ <region>, <x>, <y>, <z> ] where x, y and z
+ // are collectively optional
+ // are optional
+
+ mRegion = LLURI::unescape(path_array[0].asString());
+
+ if (LLStringUtil::containsNonprintable(mRegion))
+ {
+ LLStringUtil::stripNonprintable(mRegion);
+ }
+
+ path_array.erase(0);
+
+ // parse the x, y, and optionally z
+ if (path_array.size() >= 2)
+ {
+ mPosition = LLVector3(path_array); // this construction handles LLSD without all components (values default to 0.f)
+ if ((F32(mPosition[VX]) < 0.f) || (mPosition[VX] > REGION_WIDTH_METERS) ||
+ (F32(mPosition[VY]) < 0.f) || (mPosition[VY] > REGION_WIDTH_METERS) ||
+ (F32(mPosition[VZ]) < 0.f) || (mPosition[VZ] > REGION_HEIGHT_METERS))
+ {
+ mType = INVALID;
+ return;
+ }
+ }
+ else
+ {
+ // if x, y and z were not fully passed in, go to the middle of the region.
+ // teleport will adjust the actual location to make sure you're on the ground
+ // and such
+ mPosition = LLVector3(REGION_WIDTH_METERS / 2, REGION_WIDTH_METERS / 2, 0);
+ }
+ }
+ }
+}
// Create a slurl for the middle of the region
-LLSLURL::LLSLURL(const std::string& grid,
- const std::string& region)
+LLSLURL::LLSLURL(const std::string& grid, const std::string& region)
{
- mGrid = grid;
- mRegion = region;
- mType = LOCATION;
- mPosition = LLVector3((F64)REGION_WIDTH_METERS/2, (F64)REGION_WIDTH_METERS/2, 0);
+ mGrid = grid;
+ mRegion = region;
+ mType = LOCATION;
+ mPosition = LLVector3((F64)REGION_WIDTH_METERS / 2, (F64)REGION_WIDTH_METERS / 2, 0);
}
-
-
// create a slurl given the position. The position will be modded with the region
// width handling global positions as well
-LLSLURL::LLSLURL(const std::string& grid,
- const std::string& region,
- const LLVector3& position)
+LLSLURL::LLSLURL(const std::string& grid,
+ const std::string& region,
+ const LLVector3& position)
{
- mGrid = grid;
- mRegion = region;
- S32 x = ll_round( (F32)fmod( position[VX], (F32)REGION_WIDTH_METERS ) );
- S32 y = ll_round( (F32)fmod( position[VY], (F32)REGION_WIDTH_METERS ) );
- S32 z = ll_round( (F32)position[VZ] );
- mType = LOCATION;
- mPosition = LLVector3(x, y, z);
+ mGrid = grid;
+ mRegion = region;
+ S32 x = ll_round((F32)fmod(position[VX], (F32)REGION_WIDTH_METERS));
+ S32 y = ll_round((F32)fmod(position[VY], (F32)REGION_WIDTH_METERS));
+ S32 z = ll_round((F32)position[VZ]);
+ mType = LOCATION;
+ mPosition = LLVector3(x, y, z);
}
-
// create a simstring
-LLSLURL::LLSLURL(const std::string& region,
- const LLVector3& position)
+LLSLURL::LLSLURL(const std::string& region,
+ const LLVector3& position)
{
- *this = LLSLURL(LLGridManager::getInstance()->getGridId(),
- region, position);
+ *this = LLSLURL(LLGridManager::getInstance()->getGridId(), region, position);
}
// create a slurl from a global position
-LLSLURL::LLSLURL(const std::string& grid,
- const std::string& region,
- const LLVector3d& global_position)
+LLSLURL::LLSLURL(const std::string& grid,
+ const std::string& region,
+ const LLVector3d& global_position)
{
- *this = LLSLURL(LLGridManager::getInstance()->getGridId(grid),
- region, LLVector3(global_position.mdV[VX],
- global_position.mdV[VY],
- global_position.mdV[VZ]));
+ *this = LLSLURL(LLGridManager::getInstance()->getGridId(grid), region,
+ LLVector3(global_position.mdV[VX], global_position.mdV[VY], global_position.mdV[VZ]));
}
// create a slurl from a global position
-LLSLURL::LLSLURL(const std::string& region,
- const LLVector3d& global_position)
+LLSLURL::LLSLURL(const std::string& region,
+ const LLVector3d& global_position)
{
- *this = LLSLURL(LLGridManager::getInstance()->getGridId(),
- region, global_position);
+ *this = LLSLURL(LLGridManager::getInstance()->getGridId(),
+ region, global_position);
}
LLSLURL::LLSLURL(const std::string& command, const LLUUID&id, const std::string& verb)
{
- mType = APP;
- mAppCmd = command;
- mAppPath = LLSD::emptyArray();
- mAppPath.append(LLSD(id));
- mAppPath.append(LLSD(verb));
+ mType = APP;
+ mAppCmd = command;
+ mAppPath = LLSD::emptyArray();
+ mAppPath.append(LLSD(id));
+ mAppPath.append(LLSD(verb));
}
-
std::string LLSLURL::getSLURLString() const
{
- switch(mType)
- {
- case HOME_LOCATION:
- return SIM_LOCATION_HOME;
- case LAST_LOCATION:
- return SIM_LOCATION_LAST;
- case LOCATION:
- {
- // lookup the grid
- S32 x = ll_round( (F32)mPosition[VX] );
- S32 y = ll_round( (F32)mPosition[VY] );
- S32 z = ll_round( (F32)mPosition[VZ] );
- return LLGridManager::getInstance()->getSLURLBase(mGrid) +
- LLURI::escape(mRegion) + llformat("/%d/%d/%d",x,y,z);
- }
- case APP:
- {
- std::ostringstream app_url;
- app_url << LLGridManager::getInstance()->getAppSLURLBase() << "/" << mAppCmd;
- for(LLSD::array_const_iterator i = mAppPath.beginArray();
- i != mAppPath.endArray();
- i++)
- {
- app_url << "/" << i->asString();
- }
- if(mAppQuery.length() > 0)
- {
- app_url << "?" << mAppQuery;
- }
- return app_url.str();
- }
- default:
- LL_WARNS("AppInit") << "Unexpected SLURL type for SLURL string" << (int)mType << LL_ENDL;
- return std::string();
- }
+ switch (mType)
+ {
+ case HOME_LOCATION:
+ return SIM_LOCATION_HOME;
+ case LAST_LOCATION:
+ return SIM_LOCATION_LAST;
+ case LOCATION:
+ {
+ // lookup the grid
+ S32 x = ll_round((F32)mPosition[VX]);
+ S32 y = ll_round((F32)mPosition[VY]);
+ S32 z = ll_round((F32)mPosition[VZ]);
+ return LLGridManager::getInstance()->getSLURLBase(mGrid) +
+ LLURI::escape(mRegion) + llformat("/%d/%d/%d", x, y, z);
+ }
+ case APP:
+ {
+ std::ostringstream app_url;
+ app_url << LLGridManager::getInstance()->getAppSLURLBase() << "/" << mAppCmd;
+ for (LLSD::array_const_iterator i = mAppPath.beginArray();
+ i != mAppPath.endArray();
+ i++)
+ {
+ app_url << "/" << i->asString();
+ }
+ if (mAppQuery.length() > 0)
+ {
+ app_url << "?" << mAppQuery;
+ }
+ return app_url.str();
+ }
+ default:
+ LL_WARNS("AppInit") << "Unexpected SLURL type for SLURL string" << (int)mType << LL_ENDL;
+ return std::string();
+ }
}
std::string LLSLURL::getLoginString() const
{
-
- std::stringstream unescaped_start;
- switch(mType)
- {
- case LOCATION:
- unescaped_start << "uri:"
- << mRegion << "&"
- << ll_round(mPosition[0]) << "&"
- << ll_round(mPosition[1]) << "&"
- << ll_round(mPosition[2]);
- break;
- case HOME_LOCATION:
- unescaped_start << "home";
- break;
- case LAST_LOCATION:
- unescaped_start << "last";
- break;
- default:
- LL_WARNS("AppInit") << "Unexpected SLURL type ("<<(int)mType <<")for login string"<< LL_ENDL;
- break;
- }
- return xml_escape_string(unescaped_start.str());
+ std::stringstream unescaped_start;
+ switch (mType)
+ {
+ case LOCATION:
+ unescaped_start << "uri:"
+ << mRegion << "&"
+ << ll_round(mPosition[0]) << "&"
+ << ll_round(mPosition[1]) << "&"
+ << ll_round(mPosition[2]);
+ break;
+ case HOME_LOCATION:
+ unescaped_start << "home";
+ break;
+ case LAST_LOCATION:
+ unescaped_start << "last";
+ break;
+ default:
+ LL_WARNS("AppInit") << "Unexpected SLURL type (" << (int)mType << ")for login string" << LL_ENDL;
+ break;
+ }
+ return xml_escape_string(unescaped_start.str());
}
-bool LLSLURL::operator==(const LLSLURL& rhs)
+bool LLSLURL::operator ==(const LLSLURL& rhs)
{
- if(rhs.mType != mType) return false;
- switch(mType)
- {
- case LOCATION:
- return ((mGrid == rhs.mGrid) &&
- (mRegion == rhs.mRegion) &&
- (mPosition == rhs.mPosition));
- case APP:
- return getSLURLString() == rhs.getSLURLString();
-
- case HOME_LOCATION:
- case LAST_LOCATION:
- return true;
- default:
- return false;
- }
+ if (rhs.mType != mType)
+ return false;
+
+ switch (mType)
+ {
+ case LOCATION:
+ return (mGrid == rhs.mGrid) &&
+ (mRegion == rhs.mRegion) &&
+ (mPosition == rhs.mPosition);
+
+ case APP:
+ return getSLURLString() == rhs.getSLURLString();
+
+ case HOME_LOCATION:
+ case LAST_LOCATION:
+ return true;
+
+ default:
+ return false;
+ }
}
bool LLSLURL::operator !=(const LLSLURL& rhs)
{
- return !(*this == rhs);
+ return !(*this == rhs);
}
std::string LLSLURL::getLocationString() const
{
- return llformat("%s/%d/%d/%d",
- mRegion.c_str(),
- (int)ll_round(mPosition[0]),
- (int)ll_round(mPosition[1]),
- (int)ll_round(mPosition[2]));
+ return llformat("%s/%d/%d/%d",
+ mRegion.c_str(),
+ (int)ll_round(mPosition[0]),
+ (int)ll_round(mPosition[1]),
+ (int)ll_round(mPosition[2]));
}
// static
-const std::string LLSLURL::typeName[NUM_SLURL_TYPES] =
+const std::string LLSLURL::typeName[NUM_SLURL_TYPES] =
{
- "INVALID",
- "LOCATION",
- "HOME_LOCATION",
- "LAST_LOCATION",
- "APP",
- "HELP"
+ "INVALID",
+ "LOCATION",
+ "HOME_LOCATION",
+ "LAST_LOCATION",
+ "APP",
+ "HELP",
+ "EMPTY"
};
-
+
std::string LLSLURL::getTypeString(SLURL_TYPE type)
{
- std::string name;
- if ( type >= INVALID && type < NUM_SLURL_TYPES )
- {
- name = LLSLURL::typeName[type];
- }
- else
- {
- name = llformat("Out of Range (%d)",type);
- }
- return name;
+ std::string name;
+ if (type >= INVALID && type < NUM_SLURL_TYPES)
+ {
+ name = LLSLURL::typeName[type];
+ }
+ else
+ {
+ name = llformat("Out of Range (%d)", type);
+ }
+ return name;
}
-
std::string LLSLURL::asString() const
{
std::ostringstream result;
result
- << " mType: " << LLSLURL::getTypeString(mType)
- << " mGrid: " + getGrid()
- << " mRegion: " + getRegion()
- << " mPosition: " << mPosition
- << " mAppCmd:" << getAppCmd()
- << " mAppPath:" + getAppPath().asString()
- << " mAppQueryMap:" + getAppQueryMap().asString()
- << " mAppQuery: " + getAppQuery()
- ;
-
+ << " mType: " << LLSLURL::getTypeString(mType)
+ << " mGrid: " + getGrid()
+ << " mRegion: " + getRegion()
+ << " mPosition: " << mPosition
+ << " mAppCmd:" << getAppCmd()
+ << " mAppPath:" + getAppPath().asString()
+ << " mAppQueryMap:" + getAppQueryMap().asString()
+ << " mAppQuery: " + getAppQuery()
+ ;
+
return result.str();
}
-
diff --git a/indra/newview/llslurl.h b/indra/newview/llslurl.h
index b86cf7949b..6132a4a8b0 100644
--- a/indra/newview/llslurl.h
+++ b/indra/newview/llslurl.h
@@ -52,13 +52,14 @@ public:
static const char* SLURL_REGION_PATH;
// if you modify this enumeration, update typeName as well
- enum SLURL_TYPE {
- INVALID,
+ enum SLURL_TYPE {
+ INVALID,
LOCATION,
HOME_LOCATION,
LAST_LOCATION,
APP,
HELP,
+ EMPTY,
NUM_SLURL_TYPES // must be last
};
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 931880a475..2ecdf75e29 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1322,17 +1322,8 @@ void drawBox(const LLVector4a& c, const LLVector4a& r)
void drawBoxOutline(const LLVector3& pos, const LLVector3& size)
{
-
- llassert(pos.isFinite());
- llassert(size.isFinite());
-
- llassert(!llisnan(pos.mV[0]));
- llassert(!llisnan(pos.mV[1]));
- llassert(!llisnan(pos.mV[2]));
-
- llassert(!llisnan(size.mV[0]));
- llassert(!llisnan(size.mV[1]));
- llassert(!llisnan(size.mV[2]));
+ if (!pos.isFinite() || !size.isFinite())
+ return;
LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1));
LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1));
@@ -1607,6 +1598,8 @@ bool check_rigged_group(LLDrawable* drawable)
if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group)
{
+ LL_WARNS() << "[root->isState(LLDrawable::RIGGED) and root->getSpatialGroup() != group] is true"
+ " (" << root->getSpatialGroup() << " != " << group << ")" << LL_ENDL;
llassert(false);
return false;
}
@@ -1616,8 +1609,10 @@ bool check_rigged_group(LLDrawable* drawable)
{
for (auto& face : root->getFaces())
{
- if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ if ((S32)face->getDrawOrderIndex() <= last_draw_index)
{
+ LL_WARNS() << "[(S32)face->getDrawOrderIndex() <= last_draw_index] is true"
+ " (" << (S32)face->getDrawOrderIndex() << " <= " << last_draw_index << ")" << LL_ENDL;
llassert(false);
return false;
}
@@ -1631,17 +1626,21 @@ bool check_rigged_group(LLDrawable* drawable)
{
for (auto& face : child->mDrawable->getFaces())
{
- if ((S32) face->getDrawOrderIndex() <= last_draw_index)
+ if ((S32)face->getDrawOrderIndex() <= last_draw_index)
{
+ LL_WARNS() << "[(S32)face->getDrawOrderIndex() <= last_draw_index] is true"
+ " (" << (S32)face->getDrawOrderIndex() << " <= " << last_draw_index << ")" << LL_ENDL;
llassert(false);
return false;
}
last_draw_index = face->getDrawOrderIndex();
}
}
-
+
if (child->mDrawable->getSpatialGroup() != group)
{
+ LL_WARNS() << "[child->mDrawable->getSpatialGroup() != group] is true"
+ " (" << child->mDrawable->getSpatialGroup() << " != " << group << ")" << LL_ENDL;
llassert(false);
return false;
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d0b76848f7..09917c921f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1964,8 +1964,10 @@ bool idle_startup()
display_startup();
return FALSE;
}
+
LLInventoryModelBackgroundFetch::instance().start();
- LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ LLAppearanceMgr::instance().initCOFID();
+ LLUUID cof_id = LLAppearanceMgr::instance().getCOF();
LLViewerInventoryCategory* cof = gInventory.getCategory(cof_id);
if (cof
&& cof->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
@@ -2276,7 +2278,7 @@ bool idle_startup()
static LLFrameTimer wearables_timer;
const F32 wearables_time = wearables_timer.getElapsedTimeF32();
- static LLCachedControl<F32> max_wearables_time(gSavedSettings, "ClothingLoadingDelay");
+ const F32 MAX_WEARABLES_TIME = 10.f;
if (!gAgent.isOutfitChosen() && isAgentAvatarValid())
{
@@ -2295,7 +2297,7 @@ bool idle_startup()
display_startup();
- if (gAgent.isOutfitChosen() && (wearables_time > max_wearables_time))
+ if (gAgent.isOutfitChosen() && (wearables_time > MAX_WEARABLES_TIME))
{
if (gInventory.isInventoryUsable())
{
@@ -2682,18 +2684,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
LLViewerParcelMgr::processParcelDwellReply);
msg->setHandlerFunc("AvatarPropertiesReply",
- &LLAvatarPropertiesProcessor::processAvatarPropertiesReply);
- msg->setHandlerFunc("AvatarInterestsReply",
- &LLAvatarPropertiesProcessor::processAvatarInterestsReply);
- msg->setHandlerFunc("AvatarGroupsReply",
- &LLAvatarPropertiesProcessor::processAvatarGroupsReply);
- // ratings deprecated
- //msg->setHandlerFuncFast(_PREHASH_AvatarStatisticsReply,
- // LLPanelAvatar::processAvatarStatisticsReply);
- msg->setHandlerFunc("AvatarNotesReply",
- &LLAvatarPropertiesProcessor::processAvatarNotesReply);
- msg->setHandlerFunc("AvatarPicksReply",
- &LLAvatarPropertiesProcessor::processAvatarPicksReply);
+ &LLAvatarPropertiesProcessor::processAvatarLegacyPropertiesReply);
msg->setHandlerFunc("AvatarClassifiedReply",
&LLAvatarPropertiesProcessor::processAvatarClassifiedsReply);
@@ -2850,6 +2841,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
// Initiate creation of COF, since we're also bypassing that.
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_CURRENT_OUTFIT);
+ LLAppearanceMgr::getInstance()->initCOFID();
ESex gender;
if (gender_name == "male")
@@ -3005,6 +2997,7 @@ void reset_login()
gAgent.cleanup();
gSky.cleanup(); // mVOSkyp is an inworld object.
LLWorld::getInstance()->resetClass();
+ LLAppearanceMgr::getInstance()->cleanup();
if ( gViewerWindow )
{ // Hide menus and normal buttons
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 8f64cff47c..db6d822186 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -127,8 +127,8 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
//---------------------------------------------------------------------------------
void LLSysWellWindow::initChannel()
{
- LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
- LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+ LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID);
mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
if(NULL == mChannel)
{
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 28e01c6c21..91e2c054fc 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -82,10 +82,10 @@
//static
bool get_is_predefined_texture(LLUUID asset_id)
{
- if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture"))
- || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID"))
- || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID"))
- || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE))
+ if (asset_id == DEFAULT_OBJECT_TEXTURE
+ || asset_id == UI_IMAGE_WHITE
+ || asset_id == UI_IMAGE_INVISIBLE
+ || asset_id == SCULPT_DEFAULT_TEXTURE)
{
return true;
}
@@ -1625,8 +1625,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
// Default of defaults is white image for diff tex
//
- LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) );
- setBlankImageAssetID( whiteImage );
+ setBlankImageAssetID(UI_IMAGE_WHITE);
setAllowNoTexture(p.allow_no_texture);
setCanApplyImmediately(p.can_apply_immediately);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 7a96eea60d..810e1d2395 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -72,6 +72,13 @@ enum LLPickerSource
PICKER_UNKNOWN, // on cancel, default ids
};
+const LLUUID DEFAULT_BLANK_NORMAL_TEXTURE("5b53359e-59dd-d8a2-04c3-9e65134da47a");
+const LLUUID DEFAULT_OBJECT_NORMAL_TEXTURE("85f28839-7a1c-b4e3-d71d-967792970a7b");
+const LLUUID DEFAULT_OBJECT_SPECULAR_TEXTURE("87e0e8f7-8729-1ea8-cfc9-8915773009db");
+const LLUUID DEFAULT_OBJECT_TEXTURE("89556747-24cb-43ed-920b-47caed15465f");
+const LLUUID UI_IMAGE_WHITE("5748decc-f629-461c-9a36-a35a221fe21f");
+const LLUUID UI_IMAGE_INVISIBLE("89556747-24cb-43ed-920b-47caed15465f");
+
//////////////////////////////////////////////////////////////////////////////////////////
// LLTextureCtrl
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 62703e3499..badae2ab53 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -424,14 +424,12 @@ void LLAvatarTexBar::draw()
text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
line_num++;
}
- const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
LLColor4 header_color(1.f, 1.f, 1.f, 0.9f);
- const std::string texture_timeout_str = texture_timeout ? llformat("%d",texture_timeout) : "Disabled";
const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled";
- std::string header_text = llformat("[ Timeout('AvatarBakedTextureUploadTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());
+ std::string header_text = llformat("[ Timeout:60 ] [ LOD_Override('TextureDiscardLevel'):%s ]", override_tex_discard_level_str.c_str());
LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, l_offset, v_offset + line_height*line_num,
header_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
line_num++;
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 8bf078477a..27208e05f1 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -90,6 +90,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
std::string edit_text_contents;
S32 edit_text_max_chars = 0;
bool is_password = false;
+ bool allow_emoji = false;
LLToastPanel::setBackgroundVisible(FALSE);
LLToastPanel::setBackgroundOpaque(TRUE);
@@ -134,6 +135,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
edit_text_contents = (*it)["value"].asString();
edit_text_name = (*it)["name"].asString();
edit_text_max_chars = (*it)["max_length_chars"].asInteger();
+ allow_emoji = (*it)["allow_emoji"].asBoolean();
}
else if (type == "password")
{
@@ -292,6 +294,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight());
mLineEditor->setRect(leditor_rect);
mLineEditor->setMaxTextChars(edit_text_max_chars);
+ mLineEditor->setAllowEmoji(allow_emoji);
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
@@ -497,10 +500,9 @@ void LLToastAlertPanel::draw()
}
static LLUIColor shadow_color = LLUIColorTable::instance().getColor("ColorDropShadow");
- static LLUICachedControl<S32> shadow_lines ("DropShadowFloater", 5);
gl_drop_shadow( 0, LLToastPanel::getRect().getHeight(), LLToastPanel::getRect().getWidth(), 0,
- shadow_color, shadow_lines);
+ shadow_color, DROP_SHADOW_FLOATER);
LLToastPanel::draw();
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index e7f96239fd..dadeb03fe5 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -301,12 +301,10 @@ void LLToolDragAndDrop::setDragStart(S32 x, S32 y)
BOOL LLToolDragAndDrop::isOverThreshold(S32 x,S32 y)
{
- static LLCachedControl<S32> drag_and_drop_threshold(gSavedSettings,"DragAndDropDistanceThreshold", 3);
-
S32 mouse_delta_x = x - mDragStartX;
S32 mouse_delta_y = y - mDragStartY;
- return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > drag_and_drop_threshold * drag_and_drop_threshold;
+ return (mouse_delta_x * mouse_delta_x) + (mouse_delta_y * mouse_delta_y) > DRAG_N_DROP_DISTANCE_THRESHOLD * DRAG_N_DROP_DISTANCE_THRESHOLD;
}
void LLToolDragAndDrop::beginDrag(EDragAndDropType type,
@@ -569,12 +567,13 @@ BOOL LLToolDragAndDrop::handleKey(KEY key, MASK mask)
BOOL LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask)
{
+ const F32 DRAG_N_DROP_TOOLTIP_DELAY = 0.10000000149f;
if (!mToolTipMsg.empty())
{
LLToolTipMgr::instance().unblockToolTips();
LLToolTipMgr::instance().show(LLToolTip::Params()
.message(mToolTipMsg)
- .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" )));
+ .delay_time(DRAG_N_DROP_TOOLTIP_DELAY));
return TRUE;
}
return FALSE;
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index d99c0ba2a6..e937c499ae 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -223,6 +223,13 @@ BOOL LLVisualParamHint::render()
LLVector3 target_pos = target_joint_pos + (target_offset * avatar_rotation);
F32 cam_angle_radians = mVisualParam->getCameraAngle() * DEG_TO_RAD;
+
+ static LLCachedControl<bool> auto_camera_position(gSavedSettings, "AppearanceCameraMovement");
+ if (!auto_camera_position)
+ {
+ cam_angle_radians += F_PI;
+ }
+
LLVector3 camera_snapshot_offset(
mVisualParam->getCameraDistance() * cosf( cam_angle_radians ),
mVisualParam->getCameraDistance() * sinf( cam_angle_radians ),
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 83a707472e..cf3b714c49 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -86,8 +86,8 @@ LLToolPie::LLToolPie()
mMouseSteerX(-1),
mMouseSteerY(-1),
mClickAction(0),
- mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
- mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ),
+ mClickActionBuyEnabled( TRUE ),
+ mClickActionPayEnabled( TRUE ),
mDoubleClickTimer()
{
}
@@ -756,8 +756,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
{
S32 delta_x = x - mMouseDownX;
S32 delta_y = y - mMouseDownY;
- S32 threshold = gSavedSettings.getS32("DragAndDropDistanceThreshold");
- if (delta_x * delta_x + delta_y * delta_y > threshold * threshold)
+ if (delta_x * delta_x + delta_y * delta_y > DRAG_N_DROP_DISTANCE_THRESHOLD * DRAG_N_DROP_DISTANCE_THRESHOLD)
{
startCameraSteering();
steerCameraWithMouse(x, y);
@@ -1089,6 +1088,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
final_name = LLTrans::getString("TooltipPerson");;
}
+ const F32 INSPECTOR_TOOLTIP_DELAY = 0.35f;
+
LLInspector::Params p;
p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>());
p.message(final_name);
@@ -1096,7 +1097,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
p.click_callback(boost::bind(showAvatarInspector, hover_object->getID()));
p.visible_time_near(6.f);
p.visible_time_far(3.f);
- p.delay_time(gSavedSettings.getF32("AvatarInspectorTooltipDelay"));
+ p.delay_time(INSPECTOR_TOOLTIP_DELAY);
p.wrap(false);
LLToolTipMgr::instance().show(p);
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 76fb138768..07ea8a4ec6 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -134,6 +134,11 @@ bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl,
LLMediaCtrl* web,
bool trusted_browser)
{
+ // SL-20422 : Clicking the "Bring it back" link on Aditi displays a teleport alert
+ // Stop further processing empty urls like [secondlife:/// Bring it back.]
+ if (slurl.getType() == LLSLURL::EMPTY)
+ return true;
+
const bool right_click = false;
return dispatchCore(slurl, nav_type, right_click, web, trusted_browser);
}
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index a2b0b04092..e2e321af0d 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -931,7 +931,7 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti
// Show the preview panel for textures and sounds to let
// user know that the image (or snapshot) arrived intact.
LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(FALSE);
- LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, serverInventoryItem, FALSE, TAKE_FOCUS_NO, (panel == NULL));
+ LLInventoryPanel::openInventoryPanelAndSetSelection(true, serverInventoryItem, false, false, !panel);
// restore keyboard focus
gFocusMgr.setKeyboardFocus(focus);
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 6a0edbecb1..48499f0da8 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -48,6 +48,8 @@
#include "llstreamingaudio.h"
/////////////////////////////////////////////////////////
+const U32 FMODEX_DECODE_BUFFER_SIZE = 1000; // in milliseconds
+const U32 FMODEX_STREAM_BUFFER_SIZE = 7000; // in milliseconds
LLViewerAudio::LLViewerAudio() :
mDone(true),
@@ -116,7 +118,7 @@ void LLViewerAudio::startInternetStreamWithAutoFade(const std::string &streamURI
LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
if (stream && stream->supportsAdjustableBufferSizes())
- stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"), gSavedSettings.getU32("FMODExDecodeBufferSize"));
+ stream->setBufferSizes(FMODEX_STREAM_BUFFER_SIZE, FMODEX_DECODE_BUFFER_SIZE);
gAudiop->startInternetStream(mNextStreamURI);
}
@@ -183,7 +185,7 @@ bool LLViewerAudio::onIdleUpdate()
LL_DEBUGS("AudioEngine") << "Audio fade in: " << mNextStreamURI << LL_ENDL;
LLStreamingAudioInterface *stream = gAudiop->getStreamingAudioImpl();
if(stream && stream->supportsAdjustableBufferSizes())
- stream->setBufferSizes(gSavedSettings.getU32("FMODExStreamBufferSize"),gSavedSettings.getU32("FMODExDecodeBufferSize"));
+ stream->setBufferSizes(FMODEX_STREAM_BUFFER_SIZE, FMODEX_DECODE_BUFFER_SIZE);
gAudiop->startInternetStream(mNextStreamURI);
}
@@ -418,12 +420,19 @@ void audio_update_volume(bool force_update)
gAudiop->setMasterGain ( master_volume );
- gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
+ const F32 AUDIO_LEVEL_DOPPLER = 1.f;
+ gAudiop->setDopplerFactor(AUDIO_LEVEL_DOPPLER);
- if(!LLViewerCamera::getInstance()->cameraUnderWater())
- gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
+ if(!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ const F32 AUDIO_LEVEL_ROLLOFF = 1.f;
+ gAudiop->setRolloffFactor(AUDIO_LEVEL_ROLLOFF);
+ }
else
- gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelUnderwaterRolloff"));
+ {
+ const F32 AUDIO_LEVEL_UNDERWATER_ROLLOFF = 5.f;
+ gAudiop->setRolloffFactor(AUDIO_LEVEL_UNDERWATER_ROLLOFF);
+ }
gAudiop->setMuted(mute_audio || progress_view_visible);
@@ -532,8 +541,8 @@ void audio_update_wind(bool force_update)
// whereas steady-state avatar walk velocity is only 3.2 m/s.
// Without this the world feels desolate on first login when you are
// standing still.
- static LLUICachedControl<F32> wind_level("AudioLevelWind", 0.5f);
- LLVector3 scaled_wind_vec = gWindVec * wind_level;
+ const F32 WIND_LEVEL = 0.5f;
+ LLVector3 scaled_wind_vec = gWindVec * WIND_LEVEL;
// Mix in the avatar's motion, subtract because when you walk north,
// the apparent wind moves south.
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 7738cb904e..4f83f2cc9f 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -345,15 +345,6 @@ static bool handleChatFontSizeChanged(const LLSD& newvalue)
return true;
}
-static bool handleChatPersistTimeChanged(const LLSD& newvalue)
-{
- if(gConsole)
- {
- gConsole->setLinePersistTime((F32) newvalue.asReal());
- }
- return true;
-}
-
static bool handleConsoleMaxLinesChanged(const LLSD& newvalue)
{
if(gConsole)
@@ -630,6 +621,18 @@ void handleUserTargetDrawDistanceChanged(const LLSD& newValue)
LLPerfStats::tunables.userTargetDrawDistance = newval;
}
+void handleUserMinDrawDistanceChanged(const LLSD &newValue)
+{
+ const auto newval = gSavedSettings.getF32("AutoTuneRenderFarClipMin");
+ LLPerfStats::tunables.userMinDrawDistance = newval;
+}
+
+void handleUserTargetReflectionsChanged(const LLSD& newValue)
+{
+ const auto newval = gSavedSettings.getS32("UserTargetReflections");
+ LLPerfStats::tunables.userTargetReflections = newval;
+}
+
void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled");
@@ -728,7 +731,6 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
- setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged);
setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged);
@@ -739,9 +741,6 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged);
- setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged);
- setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged);
- setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged);
@@ -827,6 +826,7 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderAvatarMaxART", handleRenderAvatarMaxARTChanged);
setting_setup_signal_listener(gSavedSettings, "PerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged);
+ setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipMin", handleUserMinDrawDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
setting_setup_signal_listener(gSavedSettings, "TuningFPSStrategy", handleFPSTuningStrategyChanged);
@@ -853,8 +853,6 @@ DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"];
DECL_LLCC(LLSD, test_llsd);
-static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hahahahahha", "Not the real comment");
-
void test_cached_control()
{
#define do { TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL; } while(0)
@@ -871,8 +869,6 @@ void test_cached_control()
TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f));
TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255));
//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd);
-
- if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL;
}
#endif // TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index a936012781..dc05914662 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -214,11 +214,11 @@ void display_update_camera()
void display_stats()
{
LL_PROFILE_ZONE_SCOPED
- F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency");
- if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq)
+ const F32 FPS_LOG_FREQUENCY = 10.f;
+ if (gRecentFPSTime.getElapsedTimeF32() >= FPS_LOG_FREQUENCY)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS");
- F32 fps = gRecentFrameCount / fps_log_freq;
+ F32 fps = gRecentFrameCount / FPS_LOG_FREQUENCY;
LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL;
gRecentFrameCount = 0;
gRecentFPSTime.reset();
@@ -233,8 +233,8 @@ void display_stats()
LLMemory::logMemoryInfo(TRUE) ;
gRecentMemoryTime.reset();
}
- F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency");
- if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq)
+ const F32 ASSET_STORAGE_LOG_FREQUENCY = 60.f;
+ if (gAssetStorageLogTime.getElapsedTimeF32() >= ASSET_STORAGE_LOG_FREQUENCY)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage");
gAssetStorageLogTime.reset();
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index e35cb26ce1..4577f71061 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -227,8 +227,18 @@ std::string string_from_guid(const GUID &guid)
return res;
}
+#elif LL_DARWIN
+
+bool macos_devices_callback(std::string &product_name, LLSD &data, void* userdata)
+{
+ std::string product = data["product"].asString();
+
+ return LLViewerJoystick::getInstance()->initDevice(nullptr, product, data);
+}
+
#endif
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::updateEnabled(bool autoenable)
{
@@ -365,25 +375,48 @@ void LLViewerJoystick::init(bool autoenable)
{
if (mNdofDev)
{
+ U32 device_type = 0;
+ void* win_callback = nullptr;
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback;
// di8_devices_callback callback is immediate and happens in scope of getInputDevices()
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
- U32 device_type = DI8DEVCLASS_GAMECTRL;
- void* callback = &di8_devices_callback;
-#else
- // MAC doesn't support device search yet
- // On MAC there is an ndof_idsearch and it is possible to specify product
- // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
- U32 device_type = 0;
- void* callback = NULL;
+ device_type = DI8DEVCLASS_GAMECTRL;
+ win_callback = &di8_devices_callback;
+#elif LL_DARWIN
+ osx_callback = macos_devices_callback;
+
+ if (mLastDeviceUUID.isMap())
+ {
+ std::string manufacturer = mLastDeviceUUID["manufacturer"].asString();
+ std::string product = mLastDeviceUUID["product"].asString();
+
+ strncpy(mNdofDev->manufacturer, manufacturer.c_str(), sizeof(mNdofDev->manufacturer));
+ strncpy(mNdofDev->product, product.c_str(), sizeof(mNdofDev->product));
+
+ if (ndof_init_first(mNdofDev, nullptr))
+ {
+ mDriverState = JDS_INITIALIZING;
+ // Saved device no longer exist
+ // No device found
+ LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
+ }
+ else
+ {
+ mDriverState = JDS_INITIALIZED;
+ }
+ }
#endif
- if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ if (mDriverState != JDS_INITIALIZED)
{
- LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
- // Failed to gather devices from windows, init first suitable one
- mLastDeviceUUID = LLSD();
- void *preffered_device = NULL;
- initDevice(preffered_device);
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
+ {
+ LL_INFOS("Joystick") << "Failed to gather input devices. Falling back to ndof's init" << LL_ENDL;
+ // Failed to gather devices, init first suitable one
+ mLastDeviceUUID = LLSD();
+ void *preffered_device = NULL;
+ initDevice(preffered_device);
+ }
}
if (mDriverState == JDS_INITIALIZING)
@@ -438,27 +471,49 @@ void LLViewerJoystick::initDevice(LLSD &guid)
{
#if LIB_NDOF
mLastDeviceUUID = guid;
-
+ U32 device_type = 0;
+ void* win_callback = nullptr;
+ std::function<bool(std::string&, LLSD&, void*)> osx_callback;
+ mDriverState = JDS_INITIALIZING;
+
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
- U32 device_type = DI8DEVCLASS_GAMECTRL;
- void* callback = &di8_devices_callback;
-#else
- // MAC doesn't support device search yet
- // On MAC there is an ndof_idsearch and it is possible to specify product
- // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
- U32 device_type = 0;
- void* callback = NULL;
+ device_type = DI8DEVCLASS_GAMECTRL;
+ win_callback = &di8_devices_callback;
+#elif LL_DARWIN
+ osx_callback = macos_devices_callback;
+ if (mLastDeviceUUID.isMap())
+ {
+ std::string manufacturer = mLastDeviceUUID["manufacturer"].asString();
+ std::string product = mLastDeviceUUID["product"].asString();
+
+ strncpy(mNdofDev->manufacturer, manufacturer.c_str(), sizeof(mNdofDev->manufacturer));
+ strncpy(mNdofDev->product, product.c_str(), sizeof(mNdofDev->product));
+
+ if (ndof_init_first(mNdofDev, nullptr))
+ {
+ mDriverState = JDS_INITIALIZING;
+ // Saved device no longer exist
+ // Np other device present
+ LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
+ }
+ else
+ {
+ mDriverState = JDS_INITIALIZED;
+ }
+ }
#endif
- mDriverState = JDS_INITIALIZING;
- if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ if (mDriverState != JDS_INITIALIZED)
{
- LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
- // Failed to gather devices from windows, init first suitable one
- void *preffered_device = NULL;
- mLastDeviceUUID = LLSD();
- initDevice(preffered_device);
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
+ {
+ LL_INFOS("Joystick") << "Failed to gather input devices. Falling back to ndof's init" << LL_ENDL;
+ // Failed to gather devices from window, init first suitable one
+ void *preffered_device = NULL;
+ mLastDeviceUUID = LLSD();
+ initDevice(preffered_device);
+ }
}
if (mDriverState == JDS_INITIALIZING)
@@ -469,19 +524,37 @@ void LLViewerJoystick::initDevice(LLSD &guid)
#endif
}
-void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid)
+bool LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid)
{
#if LIB_NDOF
mLastDeviceUUID = guid;
-
+
+#if LL_DARWIN
+ if (guid.isMap())
+ {
+ std::string manufacturer = mLastDeviceUUID["manufacturer"].asString();
+ std::string product = mLastDeviceUUID["product"].asString();
+
+ strncpy(mNdofDev->manufacturer, manufacturer.c_str(), sizeof(mNdofDev->manufacturer));
+ strncpy(mNdofDev->product, product.c_str(), sizeof(mNdofDev->product));
+ }
+ else
+ {
+ mNdofDev->product[0] = '\0';
+ mNdofDev->manufacturer[0] = '\0';
+ }
+#else
strncpy(mNdofDev->product, name.c_str(), sizeof(mNdofDev->product));
mNdofDev->manufacturer[0] = '\0';
+#endif
- initDevice(preffered_device);
+ return initDevice(preffered_device);
+#else
+ return false;
#endif
}
-void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */)
+bool LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */)
{
#if LIB_NDOF
// Different joysticks will return different ranges of raw values.
@@ -511,8 +584,10 @@ void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE
else
{
mDriverState = JDS_INITIALIZED;
+ return true;
}
#endif
+ return false;
}
// -----------------------------------------------------------------------------
@@ -1320,6 +1395,8 @@ bool LLViewerJoystick::isDeviceUUIDSet()
#if LL_WINDOWS && !LL_MESA_HEADLESS
// for ease of comparison and to dial less with platform specific variables, we store id as LLSD binary
return mLastDeviceUUID.isBinary();
+#elif LL_DARWIN
+ return mLastDeviceUUID.isMap();
#else
return false;
#endif
@@ -1346,19 +1423,48 @@ std::string LLViewerJoystick::getDeviceUUIDString()
{
return std::string();
}
+#elif LL_DARWIN
+ if (mLastDeviceUUID.isMap())
+ {
+ std::string manufacturer = mLastDeviceUUID["manufacturer"].asString();
+ std::string product = mLastDeviceUUID["product"].asString();
+ return manufacturer + ":" + product;
+ }
+ else
+ {
+ return std::string();
+ }
#else
return std::string();
- // return mLastDeviceUUID;
+#endif
+}
+
+void LLViewerJoystick::saveDeviceIdToSettings()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // can't save as binary directly,
+ // someone editing the xml will corrupt it
+ // so convert to string first
+ std::string device_string = getDeviceUUIDString();
+ gSavedSettings.setLLSD("JoystickDeviceUUID", LLSD(device_string));
+#else
+ LLSD device_id = getDeviceUUID();
+ gSavedSettings.setLLSD("JoystickDeviceUUID", device_id);
#endif
}
void LLViewerJoystick::loadDeviceIdFromSettings()
{
+ LLSD dev_id = gSavedSettings.getLLSD("JoystickDeviceUUID");
#if LL_WINDOWS && !LL_MESA_HEADLESS
// We can't save binary data to gSavedSettings, somebody editing the file will corrupt it,
// so _GUID data gets converted to string (we probably can convert it to LLUUID with memcpy)
// and here we need to convert it back to binary from string
- std::string device_string = gSavedSettings.getString("JoystickDeviceUUID");
+ std::string device_string;
+ if (dev_id.isString())
+ {
+ device_string = dev_id.asString();
+ }
if (device_string.empty())
{
mLastDeviceUUID = LLSD();
@@ -1372,10 +1478,22 @@ void LLViewerJoystick::loadDeviceIdFromSettings()
LLSD::Binary data; //just an std::vector
data.resize(size);
memcpy(&data[0], &guid /*POD _GUID*/, size);
- // We store this data in LLSD since LLSD is versatile and will be able to handle both GUID2
- // and any data MAC will need for device selection
+ // We store this data in LLSD since it can handle both GUID2 and long
mLastDeviceUUID = LLSD(data);
}
+#elif LL_DARWIN
+ if (!dev_id.isMap())
+ {
+ mLastDeviceUUID = LLSD();
+ }
+ else
+ {
+ std::string manufacturer = mLastDeviceUUID["manufacturer"].asString();
+ std::string product = mLastDeviceUUID["product"].asString();
+ LL_DEBUGS("Joystick") << "Looking for device by manufacturer: " << manufacturer << " and product: " << product << LL_ENDL;
+ // We store this data in LLSD since it can handle both GUID2 and long
+ mLastDeviceUUID = dev_id;
+ }
#else
mLastDeviceUUID = LLSD();
//mLastDeviceUUID = gSavedSettings.getLLSD("JoystickDeviceUUID");
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 3b4f898710..33579f544c 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -30,6 +30,9 @@
#include "stdtypes.h"
#if LIB_NDOF
+#if LL_DARWIN
+#define TARGET_OS_MAC 1
+#endif
#include "ndofdev_external.h"
#else
#define NDOF_Device void
@@ -52,8 +55,8 @@ class LLViewerJoystick : public LLSingleton<LLViewerJoystick>
public:
void init(bool autoenable);
void initDevice(LLSD &guid);
- void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
- void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
+ bool initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
+ bool initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
void terminate();
void updateStatus();
@@ -76,6 +79,7 @@ public:
LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search
std::string getDeviceUUIDString(); // converted readable value for settings
std::string getDescription();
+ void saveDeviceIdToSettings();
protected:
void updateEnabled(bool autoenable);
@@ -103,7 +107,11 @@ private:
bool mCameraUpdated;
bool mOverrideCamera;
U32 mJoystickRun;
- LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device
+
+ // Windows: _GUID as U8 binary map
+ // MacOS: long as an U8 binary map
+ // Else: integer 1 for no device/ndof's default device
+ LLSD mLastDeviceUUID;
static F32 sLastDelta[7];
static F32 sDelta[7];
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 9db9d97ddc..c6d6b625a3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -289,6 +289,7 @@ void handle_disconnect_viewer(void *);
void force_error_breakpoint(void *);
void force_error_llerror(void *);
+void force_error_llerror_msg(void*);
void force_error_bad_memory_access(void *);
void force_error_infinite_loop(void *);
void force_error_software_exception(void *);
@@ -2376,6 +2377,15 @@ class LLAdvancedForceErrorLlerror : public view_listener_t
}
};
+class LLAdvancedForceErrorLlerrorMsg: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_llerror_msg(NULL);
+ return true;
+ }
+};
+
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -7255,37 +7265,70 @@ class LLAttachmentDetach : public view_listener_t
{
// Called when the user clicked on an object attached to them
// and selected "Detach".
- LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLViewerObject *object = selection->getPrimaryObject();
if (!object)
{
LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
return true;
}
- LLViewerObject *parent = (LLViewerObject*)object->getParent();
- while (parent)
- {
- if(parent->isAvatar())
- {
- break;
- }
- object = parent;
- parent = (LLViewerObject*)parent->getParent();
- }
+ struct f: public LLSelectedObjectFunctor
+ {
+ f() : mAvatarsInSelection(false) {}
+ virtual bool apply(LLViewerObject* objectp)
+ {
+ if (!objectp)
+ {
+ return false;
+ }
- if (!object)
- {
- LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
- return true;
- }
+ if (objectp->isAvatar())
+ {
+ mAvatarsInSelection = true;
+ return false;
+ }
- if (object->isAvatar())
- {
- LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
- return true;
- }
+ LLViewerObject* parent = (LLViewerObject*)objectp->getParent();
+ while (parent)
+ {
+ if (parent->isAvatar())
+ {
+ break;
+ }
+ objectp = parent;
+ parent = (LLViewerObject*)parent->getParent();
+ }
- LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
+ // std::set to avoid dupplicate 'roots' from linksets
+ mRemoveSet.insert(objectp->getAttachmentItemID());
+
+ return true;
+ }
+ bool mAvatarsInSelection;
+ uuid_set_t mRemoveSet;
+ } func;
+ // Probbly can run applyToRootObjects instead,
+ // but previous version of this code worked for any selected object
+ selection->applyToObjects(&func);
+
+ if (func.mAvatarsInSelection)
+ {
+ // Not possible under normal circumstances
+ // Either avatar selection is ON or has to do with animeshes
+ // Better stop this than mess something
+ LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
+ return true;
+ }
+
+ if (func.mRemoveSet.empty())
+ {
+ LL_WARNS() << "handle_detach() - no valid attachments in selection to detach" << LL_ENDL;
+ return true;
+ }
+
+ uuid_vec_t detach_list(func.mRemoveSet.begin(), func.mRemoveSet.end());
+ LLAppearanceMgr::instance().removeItemsFromAvatar(detach_list);
return true;
}
@@ -8355,6 +8398,11 @@ void force_error_llerror(void *)
LLAppViewer::instance()->forceErrorLLError();
}
+void force_error_llerror_msg(void*)
+{
+ LLAppViewer::instance()->forceErrorLLErrorMsg();
+}
+
void force_error_bad_memory_access(void *)
{
LLAppViewer::instance()->forceErrorBadMemoryAccess();
@@ -9593,6 +9641,7 @@ void initialize_menus()
// Advanced > Debugging
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
+ view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ada898b98c..0ee5b8f454 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1563,15 +1563,22 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
}
else
{
- // Highlight item
- const BOOL auto_open =
- gSavedSettings.getBOOL("ShowInInventory") && // don't open if showininventory is false
- !from_name.empty(); // don't open if it's not from anyone.
- if(auto_open)
+ // Highlight item
+ bool show_in_inventory = gSavedSettings.get<bool>("ShowInInventory");
+ bool auto_open =
+ show_in_inventory && // don't open if ShowInInventory is FALSE
+ !from_name.empty(); // don't open if it's not from anyone
+
+ // SL-20419 : Don't change active tab if floater is visible
+ LLFloater* instance = LLFloaterReg::findInstance("inventory");
+ bool use_main_panel = instance && instance->getVisible();
+
+ if (auto_open)
{
LLFloaterReg::showInstance("inventory");
}
- LLInventoryPanel::openInventoryPanelAndSetSelection(auto_open, obj_id, true);
+
+ LLInventoryPanel::openInventoryPanelAndSetSelection(auto_open, obj_id, use_main_panel);
}
}
}
@@ -1647,8 +1654,9 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
const LLUUID& blocked_id;
};
- LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
- gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
+ LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID,
+ OfferMatcher(blocked_id));
}
@@ -5768,8 +5776,9 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name)
const LLUUID& blocked_id;
};
- LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(LLUUID(
- gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(task_id));
+ LLNotificationsUI::LLChannelManager::getInstance()->killToastsFromChannel(
+ LLNotificationsUI::NOTIFICATION_CHANNEL_UUID,
+ OfferMatcher(task_id));
}
static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index d4346ee2d9..6b2f093bcc 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3189,7 +3189,6 @@ void LLViewerObject::unlinkControlAvatar()
if (mControlAvatar)
{
mControlAvatar->markForDeath();
- mControlAvatar->mRootVolp = NULL;
mControlAvatar = NULL;
}
}
@@ -3961,20 +3960,13 @@ F32 LLViewerObject::recursiveGetEstTrianglesMax() const
S32 LLViewerObject::getAnimatedObjectMaxTris() const
{
S32 max_tris = 0;
- if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits"))
+ if (gAgent.getRegion())
{
- max_tris = S32_MAX;
- }
- else
- {
- if (gAgent.getRegion())
+ LLSD features;
+ gAgent.getRegion()->getSimulatorFeatures(features);
+ if (features.has("AnimatedObjects"))
{
- LLSD features;
- gAgent.getRegion()->getSimulatorFeatures(features);
- if (features.has("AnimatedObjects"))
- {
- max_tris = features["AnimatedObjects"]["AnimatedObjectMaxTris"].asInteger();
- }
+ max_tris = features["AnimatedObjects"]["AnimatedObjectMaxTris"].asInteger();
}
}
return max_tris;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 15accd0547..c5426c9382 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1526,6 +1526,12 @@ void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
// static
void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user)
{
+ if (LLApp::isExiting() || gDisconnected)
+ {
+ LL_DEBUGS("ParcelMgr") << "Ignoring parcel properties, shutting down" << LL_ENDL;
+ return;
+ }
+
S32 request_result;
S32 sequence_id;
BOOL snap_selection = FALSE;
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 785c84c38d..5a2b7e4c2f 100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -50,18 +50,15 @@
#include "pipeline.h"
-const U8 OVERLAY_IMG_COMPONENTS = 4;
+static const U8 OVERLAY_IMG_COMPONENTS = 4;
+static const F32 LINE_WIDTH = 0.0625f;
LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters)
: mRegion( region ),
mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ),
mDirty( FALSE ),
mTimeSinceLastUpdate(),
- mOverlayTextureIdx(-1),
- mVertexCount(0),
- mVertexArray(NULL),
- mColorArray(NULL)
-// mTexCoordArray(NULL),
+ mOverlayTextureIdx(-1)
{
// Create a texture to hold color information.
// 4 components
@@ -99,17 +96,6 @@ LLViewerParcelOverlay::~LLViewerParcelOverlay()
{
delete[] mOwnership;
mOwnership = NULL;
-
- delete[] mVertexArray;
- mVertexArray = NULL;
-
- delete[] mColorArray;
- mColorArray = NULL;
-
-// JC No textures.
-// delete mTexCoordArray;
-// mTexCoordArray = NULL;
-
mImageRaw = NULL;
}
@@ -312,7 +298,6 @@ F32 LLViewerParcelOverlay::getOwnedRatio() const
}
return (F32)total / (F32)size;
-
}
//---------------------------------------------------------------------------
@@ -329,14 +314,13 @@ F32 LLViewerParcelOverlay::getOwnedRatio() const
// Note: Assumes that the ownership array and
void LLViewerParcelOverlay::updateOverlayTexture()
{
- if (mOverlayTextureIdx < 0 && mDirty)
- {
- mOverlayTextureIdx = 0;
- }
if (mOverlayTextureIdx < 0)
{
- return;
+ if (!mDirty)
+ return;
+ mOverlayTextureIdx = 0;
}
+
const LLColor4U avail = LLUIColorTable::instance().getColor("PropertyColorAvail").get();
const LLColor4U owned = LLUIColorTable::instance().getColor("PropertyColorOther").get();
const LLColor4U group = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
@@ -441,38 +425,44 @@ void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay)
setDirty();
}
-
void LLViewerParcelOverlay::updatePropertyLines()
{
- if (!gSavedSettings.getBOOL("ShowPropertyLines"))
+ static LLCachedControl<bool> show(gSavedSettings, "ShowPropertyLines");
+
+ if (!show)
return;
-
- S32 row, col;
-
- const LLColor4U self_coloru = LLUIColorTable::instance().getColor("PropertyColorSelf").get();
- const LLColor4U other_coloru = LLUIColorTable::instance().getColor("PropertyColorOther").get();
- const LLColor4U group_coloru = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
- const LLColor4U for_sale_coloru = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
- const LLColor4U auction_coloru = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
-
- // Build into dynamic arrays, then copy into static arrays.
- std::vector<LLVector3> new_vertex_array;
- new_vertex_array.reserve(256);
- std::vector<LLColor4U> new_color_array;
- new_color_array.reserve(256);
- std::vector<LLVector2> new_coord_array;
- new_coord_array.reserve(256);
-
- U8 overlay = 0;
- BOOL add_edge = FALSE;
+
+ LLColor4U colors[PARCEL_COLOR_MASK + 1];
+ colors[PARCEL_SELF] = LLUIColorTable::instance().getColor("PropertyColorSelf").get();
+ colors[PARCEL_OWNED] = LLUIColorTable::instance().getColor("PropertyColorOther").get();
+ colors[PARCEL_GROUP] = LLUIColorTable::instance().getColor("PropertyColorGroup").get();
+ colors[PARCEL_FOR_SALE] = LLUIColorTable::instance().getColor("PropertyColorForSale").get();
+ colors[PARCEL_AUCTION] = LLUIColorTable::instance().getColor("PropertyColorAuction").get();
+
+ mEdges.clear();
+
const F32 GRID_STEP = PARCEL_GRID_STEP_METERS;
const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
- for (row = 0; row < GRIDS_PER_EDGE; row++)
+ for (S32 row = 0; row < GRIDS_PER_EDGE; row++)
{
- for (col = 0; col < GRIDS_PER_EDGE; col++)
+ for (S32 col = 0; col < GRIDS_PER_EDGE; col++)
{
- overlay = mOwnership[row*GRIDS_PER_EDGE+col];
+ U8 overlay = mOwnership[row*GRIDS_PER_EDGE+col];
+ S32 colorIndex = overlay & PARCEL_COLOR_MASK;
+ switch(colorIndex)
+ {
+ case PARCEL_SELF:
+ case PARCEL_GROUP:
+ case PARCEL_OWNED:
+ case PARCEL_FOR_SALE:
+ case PARCEL_AUCTION:
+ break;
+ default:
+ continue;
+ }
+
+ const LLColor4U& color = colors[colorIndex];
F32 left = col*GRID_STEP;
F32 right = left+GRID_STEP;
@@ -483,259 +473,41 @@ void LLViewerParcelOverlay::updatePropertyLines()
// West edge
if (overlay & PARCEL_WEST_LINE)
{
- switch(overlay & PARCEL_COLOR_MASK)
- {
- case PARCEL_SELF:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, WEST, self_coloru);
- break;
- case PARCEL_GROUP:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, WEST, group_coloru);
- break;
- case PARCEL_OWNED:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, WEST, other_coloru);
- break;
- case PARCEL_FOR_SALE:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, WEST, for_sale_coloru);
- break;
- case PARCEL_AUCTION:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, WEST, auction_coloru);
- break;
- default:
- break;
- }
+ addPropertyLine(left, bottom, 0, 1, LINE_WIDTH, 0, color);
}
// East edge
- if (col < GRIDS_PER_EDGE-1)
- {
- U8 east_overlay = mOwnership[row*GRIDS_PER_EDGE+col+1];
- add_edge = east_overlay & PARCEL_WEST_LINE;
- }
- else
- {
- add_edge = TRUE;
- }
-
- if (add_edge)
+ if (col == GRIDS_PER_EDGE - 1 || mOwnership[row * GRIDS_PER_EDGE + col + 1] & PARCEL_WEST_LINE)
{
- switch(overlay & PARCEL_COLOR_MASK)
- {
- case PARCEL_SELF:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- right, bottom, EAST, self_coloru);
- break;
- case PARCEL_GROUP:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- right, bottom, EAST, group_coloru);
- break;
- case PARCEL_OWNED:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- right, bottom, EAST, other_coloru);
- break;
- case PARCEL_FOR_SALE:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- right, bottom, EAST, for_sale_coloru);
- break;
- case PARCEL_AUCTION:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- right, bottom, EAST, auction_coloru);
- break;
- default:
- break;
- }
+ addPropertyLine(right, bottom, 0, 1, -LINE_WIDTH, 0, color);
}
// South edge
if (overlay & PARCEL_SOUTH_LINE)
{
- switch(overlay & PARCEL_COLOR_MASK)
- {
- case PARCEL_SELF:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, SOUTH, self_coloru);
- break;
- case PARCEL_GROUP:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, SOUTH, group_coloru);
- break;
- case PARCEL_OWNED:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, SOUTH, other_coloru);
- break;
- case PARCEL_FOR_SALE:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, SOUTH, for_sale_coloru);
- break;
- case PARCEL_AUCTION:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, bottom, SOUTH, auction_coloru);
- break;
- default:
- break;
- }
+ addPropertyLine(left, bottom, 1, 0, 0, LINE_WIDTH, color);
}
-
// North edge
- if (row < GRIDS_PER_EDGE-1)
- {
- U8 north_overlay = mOwnership[(row+1)*GRIDS_PER_EDGE+col];
- add_edge = north_overlay & PARCEL_SOUTH_LINE;
- }
- else
+ if (row == GRIDS_PER_EDGE - 1 || mOwnership[(row + 1) * GRIDS_PER_EDGE + col] & PARCEL_SOUTH_LINE)
{
- add_edge = TRUE;
+ addPropertyLine(left, top, 1, 0, 0, -LINE_WIDTH, color);
}
-
- if (add_edge)
- {
- switch(overlay & PARCEL_COLOR_MASK)
- {
- case PARCEL_SELF:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, top, NORTH, self_coloru);
- break;
- case PARCEL_GROUP:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, top, NORTH, group_coloru);
- break;
- case PARCEL_OWNED:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, top, NORTH, other_coloru);
- break;
- case PARCEL_FOR_SALE:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, top, NORTH, for_sale_coloru);
- break;
- case PARCEL_AUCTION:
- addPropertyLine(new_vertex_array, new_color_array, new_coord_array,
- left, top, NORTH, auction_coloru);
- break;
- default:
- break;
- }
- }
- }
- }
-
- // Now copy into static arrays for faster rendering.
- // Attempt to recycle old arrays if possible to avoid memory
- // shuffling.
- S32 new_vertex_count = new_vertex_array.size();
-
- if (!(mVertexArray && mColorArray && new_vertex_count == mVertexCount))
- {
- // ...need new arrays
- delete[] mVertexArray;
- mVertexArray = NULL;
- delete[] mColorArray;
- mColorArray = NULL;
-
- mVertexCount = new_vertex_count;
-
- if (new_vertex_count > 0)
- {
- mVertexArray = new F32[3 * mVertexCount];
- mColorArray = new U8 [4 * mVertexCount];
}
}
-
- // Copy the new data into the arrays
- S32 i;
- F32* vertex = mVertexArray;
- for (i = 0; i < mVertexCount; i++)
- {
- const LLVector3& point = new_vertex_array.at(i);
- *vertex = point.mV[VX];
- vertex++;
- *vertex = point.mV[VY];
- vertex++;
- *vertex = point.mV[VZ];
- vertex++;
- }
-
- U8* colorp = mColorArray;
- for (i = 0; i < mVertexCount; i++)
- {
- const LLColor4U& color = new_color_array.at(i);
- *colorp = color.mV[VRED];
- colorp++;
- *colorp = color.mV[VGREEN];
- colorp++;
- *colorp = color.mV[VBLUE];
- colorp++;
- *colorp = color.mV[VALPHA];
- colorp++;
- }
// Everything's clean now
mDirty = FALSE;
}
-
-void LLViewerParcelOverlay::addPropertyLine(
- std::vector<LLVector3>& vertex_array,
- std::vector<LLColor4U>& color_array,
- std::vector<LLVector2>& coord_array,
- const F32 start_x, const F32 start_y,
- const U32 edge,
- const LLColor4U& color)
+void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F32 dy, F32 tick_dx, F32 tick_dy, const LLColor4U& color)
{
- LLColor4U underwater( color );
- underwater.mV[VALPHA] /= 2;
-
- vertex_array.reserve(16);
- color_array.reserve(16);
- coord_array.reserve(16);
-
LLSurface& land = mRegion->getLand();
+ F32 water_z = land.getWaterHeight();
- F32 dx;
- F32 dy;
- F32 tick_dx;
- F32 tick_dy;
- //const F32 LINE_WIDTH = 0.125f;
- const F32 LINE_WIDTH = 0.0625f;
-
- switch(edge)
- {
- case WEST:
- dx = 0.f;
- dy = 1.f;
- tick_dx = LINE_WIDTH;
- tick_dy = 0.f;
- break;
-
- case EAST:
- dx = 0.f;
- dy = 1.f;
- tick_dx = -LINE_WIDTH;
- tick_dy = 0.f;
- break;
-
- case NORTH:
- dx = 1.f;
- dy = 0.f;
- tick_dx = 0.f;
- tick_dy = -LINE_WIDTH;
- break;
-
- case SOUTH:
- dx = 1.f;
- dy = 0.f;
- tick_dx = 0.f;
- tick_dy = LINE_WIDTH;
- break;
-
- default:
- LL_ERRS() << "Invalid edge in addPropertyLine" << LL_ENDL;
- return;
- }
+ mEdges.resize(mEdges.size() + 1);
+ Edge& edge = mEdges.back();
+ edge.color = color;
F32 outside_x = start_x;
F32 outside_y = start_y;
@@ -744,14 +516,31 @@ void LLViewerParcelOverlay::addPropertyLine(
F32 inside_y = start_y + tick_dy;
F32 inside_z = 0.f;
+ auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part)
+ {
+ F32 new_x = start.mV[0] + (x - start.mV[0]) * part;
+ F32 new_y = start.mV[1] + (y - start.mV[1]) * part;
+ F32 new_z = start.mV[2] + (z - start.mV[2]) * part;
+ edge.vertices.emplace_back(new_x, new_y, new_z);
+ };
+
+ auto checkForSplit = [&]()
+ {
+ const LLVector3& last_outside = edge.vertices.back();
+ F32 z0 = last_outside.mV[2];
+ F32 z1 = outside_z;
+ if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z))
+ return;
+ F32 part = (water_z - z0) / (z1 - z0);
+ const LLVector3& last_inside = edge.vertices[edge.vertices.size() - 2];
+ split(last_inside, inside_x, inside_y, inside_z, part);
+ split(last_outside, outside_x, outside_y, outside_z, part);
+ };
+
// First part, only one vertex
outside_z = land.resolveHeightRegion( outside_x, outside_y );
- if (outside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
- coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
+ edge.vertices.emplace_back(outside_x, outside_y, outside_z);
inside_x += dx * LINE_WIDTH;
inside_y += dy * LINE_WIDTH;
@@ -763,17 +552,8 @@ void LLViewerParcelOverlay::addPropertyLine(
inside_z = land.resolveHeightRegion( inside_x, inside_y );
outside_z = land.resolveHeightRegion( outside_x, outside_y );
- if (inside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- if (outside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) );
- vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
-
- coord_array.push_back( LLVector2(outside_x - start_x, 1.f) );
- coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
+ edge.vertices.emplace_back(inside_x, inside_y, inside_z);
+ edge.vertices.emplace_back(outside_x, outside_y, outside_z);
inside_x += dx * (dx - LINE_WIDTH);
inside_y += dy * (dy - LINE_WIDTH);
@@ -782,24 +562,16 @@ void LLViewerParcelOverlay::addPropertyLine(
outside_y += dy * (dy - LINE_WIDTH);
// Middle part, full width
- S32 i;
const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS );
- for (i = 1; i < GRID_STEP; i++)
+ for (S32 i = 1; i < GRID_STEP; i++)
{
inside_z = land.resolveHeightRegion( inside_x, inside_y );
outside_z = land.resolveHeightRegion( outside_x, outside_y );
- if (inside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- if (outside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) );
- vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
+ checkForSplit();
- coord_array.push_back( LLVector2(outside_x - start_x, 1.f) );
- coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
+ edge.vertices.emplace_back(inside_x, inside_y, inside_z);
+ edge.vertices.emplace_back(outside_x, outside_y, outside_z);
inside_x += dx;
inside_y += dy;
@@ -818,20 +590,10 @@ void LLViewerParcelOverlay::addPropertyLine(
inside_z = land.resolveHeightRegion( inside_x, inside_y );
outside_z = land.resolveHeightRegion( outside_x, outside_y );
- if (inside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- if (outside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- vertex_array.push_back( LLVector3(inside_x, inside_y, inside_z) );
- vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
-
- coord_array.push_back( LLVector2(outside_x - start_x, 1.f) );
- coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
+ checkForSplit();
- inside_x += dx * LINE_WIDTH;
- inside_y += dy * LINE_WIDTH;
+ edge.vertices.emplace_back(inside_x, inside_y, inside_z);
+ edge.vertices.emplace_back(outside_x, outside_y, outside_z);
outside_x += dx * LINE_WIDTH;
outside_y += dy * LINE_WIDTH;
@@ -839,14 +601,9 @@ void LLViewerParcelOverlay::addPropertyLine(
// Last edge is not drawn to the edge
outside_z = land.resolveHeightRegion( outside_x, outside_y );
- if (outside_z > 20.f) color_array.push_back( color );
- else color_array.push_back( underwater );
-
- vertex_array.push_back( LLVector3(outside_x, outside_y, outside_z) );
- coord_array.push_back( LLVector2(outside_x - start_x, 0.f) );
+ edge.vertices.emplace_back(outside_x, outside_y, outside_z);
}
-
void LLViewerParcelOverlay::setDirty()
{
mDirty = TRUE;
@@ -882,18 +639,15 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update)
}
}
-S32 LLViewerParcelOverlay::renderPropertyLines ()
+void LLViewerParcelOverlay::renderPropertyLines()
{
- if (!gSavedSettings.getBOOL("ShowPropertyLines"))
- {
- return 0;
- }
- if (!mVertexArray || !mColorArray)
- {
- return 0;
- }
+ static LLCachedControl<bool> show(gSavedSettings, "ShowPropertyLines");
+
+ if (!show)
+ return;
LLSurface& land = mRegion->getLand();
+ F32 water_z = land.getWaterHeight() + 0.01f;
LLGLSUIDefault gls_ui; // called from pipeline
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -920,16 +674,11 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
- gGL.translatef( origin.mV[VX], origin.mV[VY], origin.mV[VZ] );
+ gGL.translatef(origin.mV[VX], origin.mV[VY], origin.mV[VZ]);
gGL.translatef(pull_toward_camera.mV[VX], pull_toward_camera.mV[VY],
pull_toward_camera.mV[VZ]);
- // Include +1 because vertices are fenceposts.
- // *2 because it's a quad strip
- const S32 GRID_STEP = S32( PARCEL_GRID_STEP_METERS );
- const S32 vertex_per_edge = 3 + 2 * (GRID_STEP-1) + 3;
-
// Stomp the camera into two dimensions
LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() );
@@ -939,91 +688,68 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS;
cull_plane_point += camera_region;
- LLVector3 vertex;
-
- const S32 BYTES_PER_COLOR = 4;
- const S32 FLOATS_PER_VERTEX = 3;
- //const S32 FLOATS_PER_TEX_COORD = 2;
- S32 i, j;
- S32 drawn = 0;
- F32* vertexp;
- U8* colorp;
bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build");
const F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f;
- for (i = 0; i < mVertexCount; i += vertex_per_edge)
+ for (const Edge& edge : mEdges)
{
- colorp = mColorArray + BYTES_PER_COLOR * i;
- vertexp = mVertexArray + FLOATS_PER_VERTEX * i;
-
- vertex.mV[VX] = *(vertexp);
- vertex.mV[VY] = *(vertexp+1);
- vertex.mV[VZ] = *(vertexp+2);
+ LLVector3 center = edge.vertices[edge.vertices.size() >> 1];
- if (dist_vec_squared2D(vertex, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
+ if (dist_vec_squared2D(center, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
{
continue;
}
// Destroy vertex, transform to plane-local.
- vertex -= cull_plane_point;
+ center -= cull_plane_point;
- // negative dot product means it is in back of the plane
- if ( vertex * CAMERA_AT < 0.f )
+ // Negative dot product means it is in back of the plane
+ if (center * CAMERA_AT < 0.f)
{
continue;
}
gGL.begin(LLRender::TRIANGLE_STRIP);
- for (j = 0; j < vertex_per_edge; j++)
- {
- gGL.color4ubv(colorp);
- gGL.vertex3fv(vertexp);
+ gGL.color4ubv(edge.color.mV);
- colorp += BYTES_PER_COLOR;
- vertexp += FLOATS_PER_VERTEX;
+ for (const LLVector3& vertex : edge.vertices)
+ {
+ if (render_hidden || camera_z < water_z || vertex.mV[2] >= water_z)
+ {
+ gGL.vertex3fv(vertex.mV);
+ }
+ else
+ {
+ LLVector3 visible = vertex;
+ visible.mV[2] = water_z;
+ gGL.vertex3fv(visible.mV);
+ }
}
- drawn += vertex_per_edge;
-
gGL.end();
-
+
if (render_hidden)
{
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
-
- colorp = mColorArray + BYTES_PER_COLOR * i;
- vertexp = mVertexArray + FLOATS_PER_VERTEX * i;
gGL.begin(LLRender::TRIANGLE_STRIP);
- for (j = 0; j < vertex_per_edge; j++)
- {
- U8 color[4];
- color[0] = colorp[0];
- color[1] = colorp[1];
- color[2] = colorp[2];
- color[3] = colorp[3]/4;
+ LLColor4U color = edge.color;
+ color.mV[3] /= 4;
+ gGL.color4ubv(color.mV);
- gGL.color4ubv(color);
- gGL.vertex3fv(vertexp);
-
- colorp += BYTES_PER_COLOR;
- vertexp += FLOATS_PER_VERTEX;
+ for (const LLVector3& vertex : edge.vertices)
+ {
+ gGL.vertex3fv(vertex.mV);
}
- drawn += vertex_per_edge;
-
gGL.end();
}
-
}
gGL.popMatrix();
-
- return drawn;
}
// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
@@ -1047,11 +773,9 @@ void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F3
void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
{
- if (!mOwnership)
- {
- return;
- }
- if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ static LLCachedControl<bool> show(gSavedSettings, "MiniMapShowPropertyLines");
+
+ if (!mOwnership || !show)
{
return;
}
@@ -1066,11 +790,11 @@ void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_me
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glLineWidth(1.0f);
gGL.color4fv(parcel_outline_color);
- for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
+ for (S32 i = 0; i <= GRIDS_PER_EDGE; i++)
{
const F32 bottom = region_bottom + (i * map_parcel_width);
const F32 top = bottom + map_parcel_width;
- for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
+ for (S32 j = 0; j <= GRIDS_PER_EDGE; j++)
{
const F32 left = region_left + (j * map_parcel_width);
const F32 right = left + map_parcel_width;
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index c466cc3b6b..c0d7e2a466 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -68,8 +68,8 @@ public:
F32 getOwnedRatio() const;
// Returns the number of vertices drawn
- S32 renderPropertyLines();
- void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
+ void renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@@ -83,7 +83,7 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
-
+
private:
// This is in parcel rows and columns, not grid rows and columns
// Stored in bottom three bits.
@@ -92,12 +92,7 @@ private:
U8 parcelFlags(S32 row, S32 col, U8 flags) const;
- void addPropertyLine(std::vector<LLVector3>& vertex_array,
- std::vector<LLColor4U>& color_array,
- std::vector<LLVector2>& coord_array,
- const F32 start_x, const F32 start_y,
- const U32 edge,
- const LLColor4U& color);
+ void addPropertyLine(F32 start_x, F32 start_y, F32 dx, F32 dy, F32 tick_dx, F32 tick_dy, const LLColor4U& color);
void updateOverlayTexture();
void updatePropertyLines();
@@ -120,10 +115,14 @@ private:
BOOL mDirty;
LLFrameTimer mTimeSinceLastUpdate;
S32 mOverlayTextureIdx;
-
- S32 mVertexCount;
- F32* mVertexArray;
- U8* mColorArray;
+
+ struct Edge
+ {
+ std::vector<LLVector3> vertices;
+ LLColor4U color;
+ };
+
+ std::vector<Edge> mEdges;
};
#endif
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 452dcdd8fd..3bc659060a 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1074,15 +1074,11 @@ void LLViewerRegion::setCacheID(const LLUUID& id)
mImpl->mCacheID = id;
}
-S32 LLViewerRegion::renderPropertyLines()
+void LLViewerRegion::renderPropertyLines()
{
if (mParcelOverlay)
{
- return mParcelOverlay->renderPropertyLines();
- }
- else
- {
- return 0;
+ mParcelOverlay->renderPropertyLines();
}
}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index a409d837a4..0f5ab2ae43 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -156,7 +156,7 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
- S32 renderPropertyLines();
+ void renderPropertyLines();
void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
index 4c2fbcf837..ae8163beec 100644
--- a/indra/newview/llviewertexlayer.cpp
+++ b/indra/newview/llviewertexlayer.cpp
@@ -186,11 +186,11 @@ BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const
// Update if we've hit a timeout. Unlike for uploads, we can make this timeout fairly small
// since render unnecessarily doesn't cost much.
- const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
- if (texture_timeout != 0)
+ const U32 TEXTURE_TIMEOUT = 10;
+ if (TEXTURE_TIMEOUT != 0)
{
// If we hit our timeout and have textures available at even lower resolution, then update.
- const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
+ const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= TEXTURE_TIMEOUT;
const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
if (has_lower_lod && is_update_textures_timeout) return TRUE;
}
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 9a6d40ab0a..9c4240770c 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -577,7 +577,6 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
LLHost request_from_host)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled", true);
LLPointer<LLViewerFetchedTexture> imagep ;
switch(texture_type)
@@ -623,11 +622,9 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
imagep->forceActive() ;
}
- if(fast_cache_fetching_enabled)
- {
- mFastCacheList.insert(imagep);
- imagep->setInFastCacheList(true);
- }
+ mFastCacheList.insert(imagep);
+ imagep->setInFastCacheList(true);
+
return imagep ;
}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ed671fe849..a89d535943 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2093,13 +2093,15 @@ void LLViewerWindow::initBase()
gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
+ const F32 CHAT_PERSIST_TIME = 20.f;
+
// Console
llassert( !gConsole );
LLConsole::Params cp;
cp.name("console");
cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
cp.rect(getChatConsoleRect());
- cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
+ cp.persist_time(CHAT_PERSIST_TIME);
cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
gConsole = LLUICtrlFactory::create<LLConsole>(cp);
@@ -2811,6 +2813,15 @@ BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
}
}
+ // Try for a new-format gesture
+ if (LLGestureMgr::instance().triggerGestureRelease(key, mask))
+ {
+ LL_DEBUGS() << "LLviewerWindow::handleKey new gesture release feature" << LL_ENDL;
+ LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+ return TRUE;
+ }
+ //Old format gestures do not support this, so no need to implement it.
+
// don't pass keys on to world when something in ui has focus
return gFocusMgr.childHasKeyboardFocus(mRootView)
|| LLMenuGL::getKeyboardMode()
@@ -3316,11 +3327,13 @@ void LLViewerWindow::updateUI()
if (gLoggedInTime.getStarted())
{
- if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("DestinationGuideHintTimeout"))
+ const F32 DESTINATION_GUIDE_HINT_TIMEOUT = 1200.f;
+ const F32 SIDE_PANEL_HINT_TIMEOUT = 300.f;
+ if (gLoggedInTime.getElapsedTimeF32() > DESTINATION_GUIDE_HINT_TIMEOUT)
{
LLFirstUse::notUsingDestinationGuide();
}
- if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout"))
+ if (gLoggedInTime.getElapsedTimeF32() > SIDE_PANEL_HINT_TIMEOUT)
{
LLFirstUse::notUsingSidePanel();
}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index fee00eb6f4..498bc498f1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1351,8 +1351,8 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- static LLCachedControl<S32> box_detail_cache(gSavedSettings, "AvatarBoundingBoxComplexity");
- S32 box_detail = box_detail_cache;
+ const S32 BOX_DETAIL_DEFAULT = 3;
+ S32 box_detail = BOX_DETAIL_DEFAULT;
if (getOverallAppearance() != AOA_NORMAL)
{
if (isControlAvatar())
@@ -4254,10 +4254,10 @@ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time)
LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );
- static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0);
- static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0);
+ const F32 AVATAR_PELVIS_ROTATE_THRESHOLD_SLOW = 60.0f;
+ const F32 AVATAR_PELVIS_ROTATE_THRESHOLD_FAST = 2.0f;
- F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast);
+ F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, AVATAR_PELVIS_ROTATE_THRESHOLD_SLOW, AVATAR_PELVIS_ROTATE_THRESHOLD_FAST);
if (self_in_mouselook)
{
@@ -9282,9 +9282,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
// Parse visual params, if any.
S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
- static LLCachedControl<bool> block_some_avatars(gSavedSettings, "BlockSomeAvatarAppearanceVisualParams");
- bool drop_visual_params_debug = block_some_avatars && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
- if( num_blocks > 1 && !drop_visual_params_debug)
+ if( num_blocks > 1)
{
//LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
@@ -9329,14 +9327,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
}
else
{
- if (drop_visual_params_debug)
- {
- LL_INFOS() << "Debug-faked lack of parameters on AvatarAppearance for object: " << getID() << LL_ENDL;
- }
- else
- {
- LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL;
- }
+ LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << LL_ENDL;
}
LLVisualParam* appearance_version_param = getVisualParam(11000);
diff --git a/indra/newview/llvoicecallhandler.cpp b/indra/newview/llvoicecallhandler.cpp
index 95e11abd82..c245399622 100644
--- a/indra/newview/llvoicecallhandler.cpp
+++ b/indra/newview/llvoicecallhandler.cpp
@@ -40,12 +40,6 @@ public:
bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web)
{
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableVoiceCall"))
- {
- LLNotificationsUtil::add("NoVoiceCall", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
- return true;
- }
-
//Make sure we have some parameters
if (params.size() == 0)
{
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 8681f7c14e..49c35c7ad5 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -781,35 +781,27 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)
void LLWearableItemsList::updateChangedItems(const uuid_vec_t& changed_items_uuids)
{
// nothing to update
- if (changed_items_uuids.empty()) return;
-
- typedef std::vector<LLPanel*> item_panel_list_t;
-
- item_panel_list_t items;
- getItems(items);
+ if (changed_items_uuids.empty())
+ return;
- for (item_panel_list_t::iterator items_iter = items.begin();
- items_iter != items.end();
- ++items_iter)
+ uuid_vec_t::const_iterator uuids_begin = changed_items_uuids.begin(), uuids_end = changed_items_uuids.end();
+ pairs_const_iterator_t pairs_iter = getItemPairs().begin(), pairs_end = getItemPairs().end();
+ while (pairs_iter != pairs_end)
{
- LLPanelInventoryListItemBase* item = dynamic_cast<LLPanelInventoryListItemBase*>(*items_iter);
- if (!item) continue;
+ LLPanel* panel = (*(pairs_iter++))->first;
+ LLPanelInventoryListItemBase* item = dynamic_cast<LLPanelInventoryListItemBase*>(panel);
+ if (!item)
+ continue;
LLViewerInventoryItem* inv_item = item->getItem();
- if (!inv_item) continue;
-
- LLUUID linked_uuid = inv_item->getLinkedUUID();
+ if (!inv_item)
+ continue;
- for (uuid_vec_t::const_iterator iter = changed_items_uuids.begin();
- iter != changed_items_uuids.end();
- ++iter)
- {
- if (linked_uuid == *iter)
- {
- item->setNeedsRefresh(true);
- break;
- }
- }
+ const LLUUID& linked_uuid = inv_item->getLinkedUUID();
+ if (std::find(uuids_begin, uuids_end, linked_uuid) != uuids_end)
+ {
+ item->setNeedsRefresh(true);
+ }
}
}
@@ -933,17 +925,17 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
registrar.add("Wearable.TakeOffDetach",
- boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op));
// Register handlers for clothing.
registrar.add("Clothing.TakeOff",
- boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op));
// Register handlers for body parts.
// Register handlers for attachments.
registrar.add("Attachment.Detach",
- boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
+ boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op));
registrar.add("Attachment.Touch", boost::bind(handle_attachment_touch, selected_id));
registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3a1edb0d00..5f866c0df5 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -5137,7 +5137,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
light->setSpotExponent(0.f);
light->setSpotCutoff(180.f);
}
- else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
+ else if (gAvatarBacklight)
{
LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir);
LLVector3 opposite_pos = -light_dir;
diff --git a/indra/newview/skins/default/textures/icons/Group_Notices.png b/indra/newview/skins/default/textures/icons/Group_Notices.png
new file mode 100644
index 0000000000..601502d374
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Group_Notices.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 2126db32df..45b73d0270 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -239,6 +239,8 @@ with the same filename but different name
<texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" />
<texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" />
+ <texture name="Group_Notices" file_name="icons/Group_Notices.png" preload="false" />
+
<texture name="Hand" file_name="icons/hand.png" preload="false" />
<texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
index ce788654aa..19b3c3160c 100644
--- a/indra/newview/skins/default/xui/en/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
@@ -211,22 +211,12 @@
<button.commit_callback
function="MediaBrowser.OpenWebBrowser" />
</button>
- <check_box
- control_name="UseExternalBrowser"
- follows="bottom|left"
- height="20"
- label="Always open in my web browser"
- layout="topleft"
- left_pad="5"
- name="open_always"
- top_delta="0"
- width="200" />
<button
follows="bottom|right"
height="20"
label="Close"
layout="topleft"
- left_pad="80"
+ left_pad="285"
name="close"
top_delta="0"
width="70">
diff --git a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
index c4ac936334..28b735d297 100644
--- a/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
+++ b/indra/newview/skins/default/xui/en/floater_preview_gesture.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="460"
- min_height="460"
+ height="475"
+ min_height="475"
layout="topleft"
name="gesture_preview"
help_topic="gesture_preview"
@@ -297,11 +297,20 @@
<check_box
follows="top|left"
height="20"
+ label="until key is released"
+ layout="topleft"
+ left="28"
+ name="wait_key_release_check"
+ top="330"
+ width="100" />
+ <check_box
+ follows="top|left"
+ height="20"
label="until animations are done"
layout="topleft"
left="28"
name="wait_anim_check"
- top="330"
+ top_delta="20"
width="100" />
<check_box
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/floater_region_info.xml b/indra/newview/skins/default/xui/en/floater_region_info.xml
index 3b58cd08f6..2101000294 100644
--- a/indra/newview/skins/default/xui/en/floater_region_info.xml
+++ b/indra/newview/skins/default/xui/en/floater_region_info.xml
@@ -7,14 +7,16 @@
name="regioninfo"
save_rect="true"
title="REGION/ESTATE"
- width="530">
+ width="637">
<tab_container
bottom="555"
follows="left|right|top|bottom"
layout="topleft"
- left="1"
+ left="0"
name="region_panels"
- right="-1"
- tab_position="top"
+ tab_padding_right="3"
+ tab_position="left"
+ halign="left"
+ tab_width="110"
top="20"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 0295ef8ccd..6dfc0b8f16 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -144,6 +144,14 @@
parameter="rename" />
</menu_item_call>
<menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Listing Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
label="New Outfit"
layout="topleft"
name="New Outfit">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 660f4b62c7..3a6cf2ddff 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -64,6 +64,14 @@
function="Floater.ToggleOrBringToFront"
parameter="camera" />
</menu_item_call>
+ <menu_item_call
+ label="Notifications..."
+ name="Notifications"
+ shortcut="alt|shift|N">
+ <menu_item_call.on_click
+ function="Floater.ToggleOrBringToFront"
+ parameter="notification_well_window" />
+ </menu_item_call>
<menu_item_separator/>
<menu_item_check
@@ -391,6 +399,16 @@
function="Self.EnableRemoveAllAttachments" />
</menu_item_call>
</menu>
+ <menu_item_call
+ label="Remove selected attachments"
+ layout="topleft"
+ name="Remove Selected Attachments"
+ shortcut="alt|shift|R">
+ <menu_item_call.on_click
+ function="Attachment.Detach" />
+ <menu_item_call.on_enable
+ function="Attachment.EnableDetach" />
+ </menu_item_call>
<menu_item_separator/>
<menu_item_call
label="Complete avatars..."
@@ -742,6 +760,33 @@
function="Floater.Show"
parameter="360capture" />
</menu_item_call>
+ <menu
+ create_jump_keys="true"
+ label="Zoom level"
+ name="Zoom menu"
+ tear_off="true">
+ <menu_item_call
+ label="Zoom out"
+ name="Zoom Out"
+ shortcut="control|8">
+ <menu_item_call.on_click
+ function="View.ZoomOut" />
+ </menu_item_call>
+ <menu_item_call
+ label="Default"
+ name="Zoom Default"
+ shortcut="control|9">
+ <menu_item_call.on_click
+ function="View.ZoomDefault" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom in"
+ name="Zoom In"
+ shortcut="control|0">
+ <menu_item_call.on_click
+ function="View.ZoomIn" />
+ </menu_item_call>
+ </menu>
<menu_item_separator/>
<menu_item_call
label="Place profile"
@@ -2383,29 +2428,6 @@ function="World.EnvPreset"
function="View.EnableLastChatter" />
</menu_item_call>
- <menu_item_separator/>
-
- <menu_item_call
- label="Zoom In"
- name="Zoom In"
- shortcut="control|0">
- <menu_item_call.on_click
- function="View.ZoomIn" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- name="Zoom Default"
- shortcut="control|9">
- <menu_item_call.on_click
- function="View.ZoomDefault" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Out"
- name="Zoom Out"
- shortcut="control|8">
- <menu_item_call.on_click
- function="View.ZoomOut" />
- </menu_item_call>
</menu> <!--Shortcuts-->
<menu_item_separator/>
@@ -2717,6 +2739,12 @@ function="World.EnvPreset"
function="Advanced.ForceErrorLlerror" />
</menu_item_call>
<menu_item_call
+ label="Force LLError, Message And Crash"
+ name="Force LLError And Crash">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorLlerrorMsg" />
+ </menu_item_call>
+ <menu_item_call
label="Force Bad Memory Access"
name="Force Bad Memory Access">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d642ea162c..c2c7a303f6 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4399,14 +4399,28 @@ Are you sure you want to return the selected objects to their owners? Transferab
icon="alert.tga"
name="GroupLeaveConfirmMember"
type="alert">
-You are currently a member of the group &lt;nolink&gt;[GROUP]&lt;/nolink&gt;.
-Leave Group?
+Leave the group &apos;&lt;nolink&gt;[GROUP]&lt;/nolink&gt;&apos;?
+Currently, the fee to join this &quot;group&quot; is L$ [COST].
<tag>group</tag>
<tag>confirm</tag>
<usetemplate
name="okcancelbuttons"
notext="Cancel"
- yestext="OK"/>
+ yestext="Leave"/>
+ </notification>
+
+ <notification
+ icon="alert.tga"
+ name="GroupLeaveConfirmMemberNoFee"
+ type="alert">
+Leave the group &apos;&lt;nolink&gt;[GROUP]&lt;/nolink&gt;&apos;?
+There is currently no fee to join this group.
+ <tag>group</tag>
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Leave"/>
</notification>
@@ -6169,6 +6183,33 @@ Are you sure you want to delete them?
notext="Cancel"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="DeleteWornItems"
+ type="alertmodal">
+ <unique/>
+Some item(s) you wish to delete are being worn on your avatar.
+Remove these items from your avatar?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Remove item(s) and delete"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="CantDeleteRequiredClothing"
+ type="alertmodal">
+ <unique/>
+Some item(s) you wish to delete are required clothing layers (skin, shape, hair, eyes).
+You must replace those layers before deleting them.
+ <tag>confirm</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
<notification
icon="alertmodal.tga"
@@ -6457,14 +6498,6 @@ Your trash is overflowing. This may cause problems logging in.
</notification>
<notification
- icon="notifytip.tga"
- name="InventoryLimitReachedAIS"
- type="notifytip">
-Your inventory is experiencing issues. Please, contact support.
- <tag>fail</tag>
- </notification>
-
- <notification
icon="alertmodal.tga"
name="InventoryLimitReachedAISAlert"
type="alertmodal">
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 5eafb5cdf1..472eb319bb 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -65,7 +65,7 @@ Hover your mouse over the options for more help.
width="168" />
<text
font="SansSerifMedium"
- text_color="EmphasisColor"
+ text_color="white"
type="string"
follows="left|top"
height="16"
@@ -75,14 +75,14 @@ Hover your mouse over the options for more help.
top_pad="10"
visible="true"
width="190">
- Free
+ No charge to join
</text>
<button
follows="left|top"
left_delta="0"
top_pad="6"
height="23"
- label="JOIN NOW!"
+ label="Join group"
name="btn_join"
visible="true"
width="120" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 05de249d22..d2b0eb4b7c 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -22,10 +22,10 @@ background_visible="true"
name="group_join_btn">
Join (L$[AMOUNT])
</panel.string>
- <panel.string
- name="group_join_free">
- Free
- </panel.string>
+ <panel.string name="group_join_free">No charge to join</panel.string>
+ <panel.string name="group_member">You are a member</panel.string>
+ <panel.string name="join_txt">Join group</panel.string>
+ <panel.string name="leave_txt">Leave</panel.string>
<panel
name="group_info_top"
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index e758a8ce30..c8b165e869 100644
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -49,6 +49,18 @@
value="Unknown"
width="242" />
<button
+ name="notices_btn"
+ tool_tip="Group Notices"
+ top_delta="-4"
+ left_pad="3"
+ right="-53"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Group_Notices"
+ image_unselected="Group_Notices"
+ tab_stop="false"/>
+ <button
follows="right"
height="16"
image_pressed="Info_Press"
@@ -58,7 +70,7 @@
name="info_btn"
tool_tip="More info"
tab_stop="false"
- top_delta="-2"
+ top_delta="2"
width="16" />
<!--*TODO: Should only appear on rollover-->
<button
@@ -71,6 +83,6 @@
name="profile_btn"
tab_stop="false"
tool_tip="View profile"
- top_delta="-2"
+ top_delta="0"
width="20" />
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
index b72af7221e..9e19588033 100644
--- a/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item_short.xml
@@ -54,9 +54,22 @@
use_ellipses="true"
/>
<button
+ name="notices_btn"
+ tool_tip="Group Notices"
+ top_delta="-4"
+ left_pad="3"
+ right="-80"
+ height="20"
+ width="20"
+ follows="right"
+ image_pressed="Group_Notices"
+ image_unselected="Group_Notices"
+ tab_stop="false"
+ visible="false"/>
+ <button
name="visibility_hide_btn"
tool_tip="Hide group on my profile"
- top_delta="-3"
+ top_delta="0"
left_pad="3"
right="-53"
height="20"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 4aadc0591c..5ccd1e97d2 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -219,6 +219,7 @@
tab_height="30"
tab_position="top"
tab_min_width="100"
+ use_tab_offset="true"
top="0">
<inventory_panel
bg_opaque_color="DkGray2"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
index f899f83ad4..6ae4890777 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_firstlife.xml
@@ -22,6 +22,7 @@
<thumbnail
name="real_world_pic"
image_name="Generic_Person_Large"
+ show_loading="false"
follows="top|left"
layout="topleft"
top="10"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
index fea7d1bcb8..307b7b83ef 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -5,7 +5,7 @@
top="0"
left="0"
height="480"
- width="420"
+ width="440"
follows="all"
layout="topleft"
>
@@ -14,8 +14,11 @@
so display it as an UTC+0
-->
<string
- name="date_format"
+ name="date_format_full"
value="SL birthdate: [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]" />
+ <string
+ name="date_format_short"
+ value="SL birthdate: [mth,datetime,utc] [day,datetime,utc]" />
<string
name="age_format"
value="[AGE]" />
@@ -53,7 +56,7 @@ Account: [ACCTTYPE]
top="8"
left="6"
bottom="-1"
- width="160"
+ width="180"
border_size="0"
follows="left|top|bottom"
layout="topleft"
@@ -71,6 +74,7 @@ Account: [ACCTTYPE]
<thumbnail
name="2nd_life_pic"
image_name="Generic_Person_Large"
+ show_loading="false"
layout="topleft"
follows="all"
interactable="true"
@@ -322,74 +326,81 @@ Account: [ACCTTYPE]
visible="true"/>
</layout_panel>
<layout_panel
+ name="menu_panel"
+ follows="all"
+ layout="topleft"
+ height="55"
+ auto_resize="false"
+ user_resize="false">
+ <menu_button
+ layout="topleft"
+ follows="left|top"
+ left="1"
+ top="25"
+ height="25"
+ width="176"
+ label="Actions"
+ halign="left"
+ image_unselected="DropDown_Off"
+ image_selected="DropDown_On"
+ image_pressed="DropDown_Press"
+ image_pressed_selected="DropDown_Press"
+ image_disabled="DropDown_Disabled"
+ name="agent_actions_menu"/>
+ </layout_panel>
+ <layout_panel
name="settings_panel"
follows="all"
layout="topleft"
- height="50"
+ height="70"
auto_resize="false"
user_resize="false">
<!-- only for self -->
- <text
- name="search_label"
- value="Show my profile in search:"
- top="1"
- left="6"
- right="-1"
- height="16"
- follows="left|top|right"
- layout="topleft"/>
<combo_box
name="show_in_search"
tool_tip="Let people see you in search results"
left="1"
- top="18"
- height="23"
- width="140"
+ top="5"
+ height="25"
+ width="176"
follows="left|top"
layout="topleft"
- visible="true"
enabled="false">
<combo_box.item
- name="Hide"
- label="Hide"
- value="0" />
- <combo_box.item
name="Show"
- label="Show"
+ label="Show me in search"
value="1" />
+ <combo_box.item
+ name="Hide"
+ label="Don't show me in search"
+ value="0" />
</combo_box>
- </layout_panel>
-
- <layout_panel
- name="menu_panel"
- follows="all"
- layout="topleft"
- height="55"
- auto_resize="false"
- user_resize="false"
- >
- <menu_button
- layout="topleft"
- follows="left|top"
+ <combo_box
+ name="hide_age"
+ tool_tip="Let people see your SL age"
left="1"
- top="25"
+ top="40"
height="25"
- width="140"
- label="Actions"
- halign="left"
- image_unselected="DropDown_Off"
- image_selected="DropDown_On"
- image_pressed="DropDown_Press"
- image_pressed_selected="DropDown_Press"
- image_disabled="DropDown_Disabled"
- name="agent_actions_menu" />
+ width="176"
+ follows="left|top"
+ layout="topleft"
+ enabled="false">
+ <combo_box.item
+ name="Show"
+ label="Show birthdate + SL age"
+ value="0"/>
+ <combo_box.item
+ name="Hide"
+ label="Show month + day only"
+ value="1"/>
+ </combo_box>
</layout_panel>
</layout_stack>
<layout_stack
name="main_stack"
top="8"
- left="168"
+ left="188"
bottom="-1"
right="-1"
follows="all"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index faff6185ab..65dad8bca4 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -286,13 +286,13 @@
name="Zoom"
value="Zoom" />
<combo_box.item
- label="Ignore object"
- name="Ignoreobject"
- value="Ignore" />
- <combo_box.item
label="None"
name="None"
value="None" />
+ <combo_box.item
+ label="Ignore object"
+ name="Ignoreobject"
+ value="Ignore" />
</combo_box>
<panel
border="false"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 5d33853adc..f20bdeca17 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3020,8 +3020,19 @@ Running in window.
If you continue to receive this message, contact the [SUPPORT_SITE].
</string>
+ <string name="MBOutOfMemoryTitle">Out Of Memory</string>
+ <string name="MBOutOfMemoryErr">
+ [APP_NAME]'s request for memory failed. Application can't proceed and will be closed.
- <!-- Avatar Shape Information -->
+If your computer's RAM is low, quit any heavy applications before runing Second Life, allocate a page file or reduce graphical settings like draw distance.
+ </string>
+ <string name="MBMissingFile">
+ [APP_NAME] couldn't access or find some of the files it needs and will be closed.
+
+Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall.
+ </string>
+
+ <!-- Avatar Shape Information -->
<string name="5 O'Clock Shadow">5 O'Clock Shadow</string>
<string name="All White">All White</string>
@@ -3936,7 +3947,8 @@ Abuse Report</string>
<string name="dance8">dance8</string>
<!-- birth date format shared by avatar inspector and profile panels -->
- <string name="AvatarBirthDateFormat">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string>
+ <string name="AvatarBirthDateFormatFull">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string>
+ <string name="AvatarBirthDateFormatShort">[mthnum,datetime,slt]/[day,datetime,slt]</string>
<string name="DefaultMimeType">none/none</string>
<string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string>
@@ -4001,7 +4013,8 @@ Please check http://status.secondlifegrid.net to see if there is a known problem
<string name="EmptyOutfitText">There are no items in this outfit</string>
<!-- External editor status codes -->
- <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.</string>
+ <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.
+See https://wiki.secondlife.com/wiki/LSL_Alternate_Editors</string>
<string name="ExternalEditorNotFound">Cannot find the external editor you specified.
Try enclosing path to the editor with double quotes.
(e.g. "/path to my/editor" "%s")</string>
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index eabf922875..8d21b6ed69 100644
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -187,6 +187,12 @@ namespace tut
ensure_equals("maps.secondlife.com slurl, region + coords", slurl.getSLURLString(),
"http://maps.secondlife.com/secondlife/myregion/1/2/3");
+ slurl = LLSLURL("secondlife://");
+ ensure_equals("secondlife: slurl, empty - type", slurl.getType(), LLSLURL::EMPTY);
+
+ slurl = LLSLURL("secondlife:///");
+ ensure_equals("secondlife: slurl, root - type", slurl.getType(), LLSLURL::EMPTY);
+
slurl = LLSLURL("secondlife://myregion");
ensure_equals("secondlife: slurl, region only - type", slurl.getType(), LLSLURL::LOCATION);
ensure_equals("secondlife: slurl, region only", slurl.getSLURLString(),
diff --git a/scripts/code_tools/fix_xml_indentations.py b/scripts/code_tools/fix_xml_indentations.py
new file mode 100644
index 0000000000..019f6db23c
--- /dev/null
+++ b/scripts/code_tools/fix_xml_indentations.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python3
+"""\
+
+This script formats XML files in a given directory with options for indentation and space removal.
+
+$LicenseInfo:firstyear=2023&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2023, 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$
+"""
+
+import os
+import sys
+import glob
+import io
+import xml.etree.ElementTree as ET
+
+def get_xml_declaration(file_path):
+ with open(file_path, 'r', encoding='utf-8') as file:
+ first_line = file.readline().strip()
+ if first_line.startswith('<?xml'):
+ return first_line
+ return None
+
+def parse_xml_file(file_path):
+ try:
+ tree = ET.parse(file_path)
+ return tree
+ except ET.ParseError as e:
+ print(f"Error parsing XML file {file_path}: {e}")
+ return None
+
+def indent(elem, level=0, indent_text=False, indent_tab=False):
+ indent_string = "\t" if indent_tab else " "
+ i = "\n" + level * indent_string
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + indent_string
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ indent(elem, level + 1, indent_text, indent_tab)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+ if indent_text and elem.text and not elem.text.isspace():
+ elem.text = "\n" + (level + 1) * indent_string + elem.text.strip() + "\n" + level * indent_string
+
+def save_xml(tree, file_path, xml_decl, indent_text=False, indent_tab=False, rm_space=False, rewrite_decl=False):
+ if tree is not None:
+ root = tree.getroot()
+ indent(root, indent_text=indent_text, indent_tab=indent_tab)
+ xml_string = ET.tostring(root, encoding='unicode')
+ if rm_space:
+ xml_string = xml_string.replace(' />', '/>')
+
+ xml_decl = (xml_decl if (xml_decl and not rewrite_decl)
+ else '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>')
+
+ try:
+ with io.open(file_path, 'wb') as file:
+ file.write(xml_decl.encode('utf-8'))
+ file.write('\n'.encode('utf-8'))
+ file.write(xml_string.encode('utf-8'))
+ except IOError as e:
+ print(f"Error saving file {file_path}: {e}")
+
+def process_directory(directory_path, indent_text=False, indent_tab=False, rm_space=False, rewrite_decl=False):
+ if not os.path.isdir(directory_path):
+ print(f"Directory not found: {directory_path}")
+ return
+
+ xml_files = glob.glob(os.path.join(directory_path, "*.xml"))
+ if not xml_files:
+ print(f"No XML files found in directory: {directory_path}")
+ return
+
+ for file_path in xml_files:
+ xml_decl = get_xml_declaration(file_path)
+ tree = parse_xml_file(file_path)
+ if tree is not None:
+ save_xml(tree, file_path, xml_decl, indent_text, indent_tab, rm_space, rewrite_decl)
+
+if __name__ == "__main__":
+ if len(sys.argv) < 2 or '--help' in sys.argv:
+ print("This script formats XML files in a given directory. Useful to fix XUI XMLs after processing by other tools.")
+ print("\nUsage:")
+ print(" python fix_xml_indentations.py <path/to/directory> [options]")
+ print("\nOptions:")
+ print(" --indent-text Indents text within XML tags.")
+ print(" --indent-tab Uses tabs instead of spaces for indentation.")
+ print(" --rm-space Removes spaces in self-closing tags.")
+ print(" --rewrite_decl Replaces the XML declaration line.")
+ print("\nCommon Usage:")
+ print(" To format XML files with text indentation, tab indentation, and removal of spaces in self-closing tags:")
+ print(" python fix_xml_indentations.py /path/to/xmls --indent-text --indent-tab --rm-space")
+ sys.exit(1)
+
+ directory_path = sys.argv[1]
+ indent_text = '--indent-text' in sys.argv
+ indent_tab = '--indent-tab' in sys.argv
+ rm_space = '--rm-space' in sys.argv
+ rewrite_decl = '--rewrite_decl' in sys.argv
+ process_directory(directory_path, indent_text, indent_tab, rm_space, rewrite_decl)