summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/lllineeditor.cpp27
-rw-r--r--indra/llui/lllineeditor.h4
-rw-r--r--indra/llui/lltextbase.cpp8
-rw-r--r--indra/newview/app_settings/settings.xml110
-rw-r--r--indra/newview/llavataractions.cpp13
-rw-r--r--indra/newview/llavataractions.h5
-rw-r--r--indra/newview/llchannelmanager.cpp2
-rw-r--r--indra/newview/llchiclet.cpp10
-rw-r--r--indra/newview/llfloatergodtools.cpp2
-rw-r--r--indra/newview/llfloatergroups.cpp2
-rw-r--r--indra/newview/llfloaterland.cpp7
-rw-r--r--indra/newview/llfloatermap.cpp4
-rw-r--r--indra/newview/llfloaternamedesc.cpp4
-rw-r--r--indra/newview/llfloaterproperties.cpp4
-rw-r--r--indra/newview/llfolderview.cpp2
-rw-r--r--indra/newview/llgroupactions.cpp15
-rw-r--r--indra/newview/llgroupactions.h7
-rw-r--r--indra/newview/llimfloater.cpp2
-rw-r--r--indra/newview/llimhandler.cpp2
-rw-r--r--indra/newview/llimview.cpp5110
-rw-r--r--indra/newview/llmanip.cpp4
-rw-r--r--indra/newview/llmaniprotate.cpp13
-rw-r--r--indra/newview/llmediactrl.cpp24
-rw-r--r--indra/newview/llnearbychat.cpp2
-rw-r--r--indra/newview/llnetmap.cpp12
-rw-r--r--indra/newview/llnetmap.h3
-rw-r--r--indra/newview/llnotificationalerthandler.cpp2
-rw-r--r--indra/newview/llnotificationgrouphandler.cpp2
-rw-r--r--indra/newview/llnotificationofferhandler.cpp2
-rw-r--r--indra/newview/llnotificationscripthandler.cpp2
-rw-r--r--indra/newview/llnotificationtiphandler.cpp2
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp1
-rw-r--r--indra/newview/llpanellogin.cpp4
-rw-r--r--indra/newview/llpanelpeople.cpp2
-rw-r--r--indra/newview/llpanelpermissions.cpp4
-rw-r--r--indra/newview/llpreviewanim.cpp2
-rw-r--r--indra/newview/llpreviewgesture.cpp2
-rw-r--r--indra/newview/llpreviewnotecard.cpp2
-rw-r--r--indra/newview/llpreviewscript.cpp2
-rw-r--r--indra/newview/llpreviewsound.cpp2
-rw-r--r--indra/newview/llpreviewtexture.cpp2
-rw-r--r--indra/newview/llscreenchannel.cpp6
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp4
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp4
-rw-r--r--indra/newview/llsyswellwindow.cpp2
-rw-r--r--indra/newview/lltoolfocus.cpp6
-rw-r--r--indra/newview/lltoolgrab.cpp14
-rw-r--r--indra/newview/llvieweraudio.cpp16
-rw-r--r--indra/newview/llviewercamera.cpp26
-rw-r--r--indra/newview/llviewertexturelist.cpp6
-rw-r--r--indra/newview/llviewerwindow.cpp63
-rw-r--r--indra/newview/llviewerwindow.h3
-rw-r--r--indra/newview/skins/default/textures/icons/MinusItem_Disabled.pngbin0 -> 173 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/MinusItem_Off.pngbin0 -> 178 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/MinusItem_Press.pngbin0 -> 172 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml35
-rw-r--r--indra/newview/skins/default/xui/en/floater_aaa.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_camera.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml102
-rw-r--r--indra/newview/skins/default/xui/en/floater_land_holdings.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_nearby_chat.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_perm_prefs.xml30
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_line_editor.xml13
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml8
-rw-r--r--indra/newview/skins/default/xui/en/inspect_object.xml10
-rw-r--r--indra/newview/skins/default/xui/en/menu_imchiclet_group.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml18
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml22
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml7396
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_activeim_row.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_chat_header.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_im_control_panel.xml17
-rw-r--r--indra/newview/skins/default/xui/en/panel_picks.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml30
-rw-r--r--indra/newview/skins/default/xui/en/panel_sys_well_item.xml4
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_appearance.xml4
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml10
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml6
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml12
80 files changed, 6695 insertions, 6659 deletions
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 75905d0927..c2f91ff7e0 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -84,8 +84,8 @@ void LLLineEditor::PrevalidateNamedFuncs::declareValues()
declare("non_negative_s32", LLLineEditor::prevalidateNonNegativeS32);
declare("alpha_num", LLLineEditor::prevalidateAlphaNum);
declare("alpha_num_space", LLLineEditor::prevalidateAlphaNumSpace);
- declare("printable_not_pipe", LLLineEditor::prevalidatePrintableNotPipe);
- declare("printable_no_space", LLLineEditor::prevalidatePrintableNoSpace);
+ declare("ascii_printable_no_pipe", LLLineEditor::prevalidateASCIIPrintableNoPipe);
+ declare("ascii_printable_no_space", LLLineEditor::prevalidateASCIIPrintableNoSpace);
}
LLLineEditor::Params::Params()
@@ -2186,20 +2186,28 @@ BOOL LLLineEditor::prevalidateAlphaNumSpace(const LLWString &str)
return rv;
}
+// Used for most names of things stored on the server, due to old file-formats
+// that used the pipe (|) for multiline text storage. Examples include
+// inventory item names, parcel names, object names, etc.
// static
-BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str)
+BOOL LLLineEditor::prevalidateASCIIPrintableNoPipe(const LLWString &str)
{
BOOL rv = TRUE;
S32 len = str.length();
if(len == 0) return rv;
while(len--)
{
- if('|' == str[len])
+ llwchar wc = str[len];
+ if (wc < 0x20
+ || wc > 0x7f
+ || wc == '|')
{
rv = FALSE;
break;
}
- if(!((' ' == str[len]) || LLStringOps::isAlnum((char)str[len]) || LLStringOps::isPunct((char)str[len])))
+ if(!(wc == ' '
+ || LLStringOps::isAlnum((char)wc)
+ || LLStringOps::isPunct((char)wc) ) )
{
rv = FALSE;
break;
@@ -2209,15 +2217,19 @@ BOOL LLLineEditor::prevalidatePrintableNotPipe(const LLWString &str)
}
+// Used for avatar names
// static
-BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
+BOOL LLLineEditor::prevalidateASCIIPrintableNoSpace(const LLWString &str)
{
BOOL rv = TRUE;
S32 len = str.length();
if(len == 0) return rv;
while(len--)
{
- if(LLStringOps::isSpace(str[len]))
+ llwchar wc = str[len];
+ if (wc < 0x20
+ || wc > 0x7f
+ || LLStringOps::isSpace(wc))
{
rv = FALSE;
break;
@@ -2232,6 +2244,7 @@ BOOL LLLineEditor::prevalidatePrintableNoSpace(const LLWString &str)
return rv;
}
+
// static
BOOL LLLineEditor::prevalidateASCII(const LLWString &str)
{
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index d3daa941cf..4474963b1a 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -235,8 +235,8 @@ public:
static BOOL prevalidateNonNegativeS32(const LLWString &str);
static BOOL prevalidateAlphaNum(const LLWString &str );
static BOOL prevalidateAlphaNumSpace(const LLWString &str );
- static BOOL prevalidatePrintableNotPipe(const LLWString &str);
- static BOOL prevalidatePrintableNoSpace(const LLWString &str);
+ static BOOL prevalidateASCIIPrintableNoPipe(const LLWString &str);
+ static BOOL prevalidateASCIIPrintableNoSpace(const LLWString &str);
static BOOL prevalidateASCII(const LLWString &str);
static BOOL postvalidateFloat(const std::string &str);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index caaf47240f..cd795282f9 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2380,6 +2380,14 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
// if last character is a newline, then return true, forcing line break
llwchar last_char = text[mStart + first_char + num_chars - 1];
+
+ LLUIImagePtr image = mStyle->getImage();
+ if( image.notNull())
+ {
+ width += image->getWidth();
+ height = llmax(height, image->getHeight());
+ }
+
return num_chars >= 1 && last_char == '\n';
}
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 94a2ca16f4..74ae8db0c7 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9645,116 +9645,6 @@
<key>Value</key>
<string>00000000-0000-0000-0000-000000000000</string>
</map>
- <key>UISndPieMenuAppear</key>
- <map>
- <key>Comment</key>
- <string>Sound file for opening pie menu (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>8eaed61f-92ff-6485-de83-4dcc938a478e</string>
- </map>
- <key>UISndPieMenuHide</key>
- <map>
- <key>Comment</key>
- <string>Sound file for closing pie menu (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>00000000-0000-0000-0000-000000000000</string>
- </map>
- <key>UISndPieMenuSliceHighlight0</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 0 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>d9f73cf8-17b4-6f7a-1565-7951226c305d</string>
- </map>
- <key>UISndPieMenuSliceHighlight1</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 1 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>f6ba9816-dcaf-f755-7b67-51b31b6233e5</string>
- </map>
- <key>UISndPieMenuSliceHighlight2</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 2 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>7aff2265-d05b-8b72-63c7-dbf96dc2f21f</string>
- </map>
- <key>UISndPieMenuSliceHighlight3</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 3 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>09b2184e-8601-44e2-afbb-ce37434b8ba1</string>
- </map>
- <key>UISndPieMenuSliceHighlight4</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 4 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>bbe4c7fc-7044-b05e-7b89-36924a67593c</string>
- </map>
- <key>UISndPieMenuSliceHighlight5</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 5 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>d166039b-b4f5-c2ec-4911-c85c727b016c</string>
- </map>
- <key>UISndPieMenuSliceHighlight6</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 6 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>242af82b-43c2-9a3b-e108-3b0c7e384981</string>
- </map>
- <key>UISndPieMenuSliceHighlight7</key>
- <map>
- <key>Comment</key>
- <string>Sound file for selecting pie menu item 7 (uuid for sound asset)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>String</string>
- <key>Value</key>
- <string>c1f334fb-a5be-8fe7-22b3-29631c21cf0b</string>
- </map>
<key>UISndSnapshot</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index ee4a9df15f..0844cca766 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -190,6 +190,19 @@ void LLAvatarActions::startIM(const LLUUID& id)
}
// static
+void LLAvatarActions::endIM(const LLUUID& id)
+{
+ if (id.isNull())
+ return;
+
+ LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
+ if (session_id != LLUUID::null)
+ {
+ gIMMgr->leaveSession(session_id);
+ }
+}
+
+// static
void LLAvatarActions::startCall(const LLUUID& id)
{
if (id.isNull())
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 66ea6880db..d9dab95a77 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -74,6 +74,11 @@ public:
static void startIM(const LLUUID& id);
/**
+ * End instant messaging session.
+ */
+ static void endIM(const LLUUID& id);
+
+ /**
* Start an avatar-to-avatar voice call with another user
*/
static void startCall(const LLUUID& id);
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index aa584b3ae8..94c303a30f 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -126,7 +126,7 @@ void LLChannelManager::onLoginCompleted()
gViewerWindow->getRootView()->addChild(mStartUpChannel);
// init channel's position and size
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLSysWellWindow::onStartUpToastClick, LLFloaterReg::getTypedInstance<LLSysWellWindow>("syswell_window"), _2, _3, _4));
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index caf6917d90..9845664c74 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -474,6 +474,10 @@ void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
{
LLAvatarActions::requestFriendshipDialog(other_participant_id);
}
+ else if("end" == level)
+ {
+ LLAvatarActions::endIM(other_participant_id);
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -768,12 +772,16 @@ void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
if("group chat" == level)
{
- LLGroupActions::startChat(group_id);
+ LLGroupActions::startIM(group_id);
}
else if("info" == level)
{
LLGroupActions::show(group_id);
}
+ else if("end" == level)
+ {
+ LLGroupActions::endIM(group_id);
+ }
}
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index 886f5ec924..cd3432190b 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -415,7 +415,7 @@ LLPanelRegionTools::LLPanelRegionTools()
BOOL LLPanelRegionTools::postBuild()
{
getChild<LLLineEditor>("region name")->setKeystrokeCallback(onChangeSimName, this);
- childSetPrevalidate("region name", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("region name", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
childSetPrevalidate("estate", &LLLineEditor::prevalidatePositiveS32);
childSetPrevalidate("parentestate", &LLLineEditor::prevalidatePositiveS32);
childDisable("parentestate");
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 45af515a86..7cb925bc0b 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -327,7 +327,7 @@ void LLPanelGroups::startIM()
if (group_list && (group_id = group_list->getCurrentID()).notNull())
{
- LLGroupActions::startChat(group_id);
+ LLGroupActions::startIM(group_id);
}
}
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 015a947d91..22d6098d5b 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -347,13 +347,14 @@ BOOL LLPanelLandGeneral::postBuild()
{
mEditName = getChild<LLLineEditor>("Name");
mEditName->setCommitCallback(onCommitAny, this);
- childSetPrevalidate("Name", LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("Name", LLLineEditor::prevalidateASCIIPrintableNoPipe);
mEditDesc = getChild<LLTextEditor>("Description");
mEditDesc->setCommitOnFocusLost(TRUE);
mEditDesc->setCommitCallback(onCommitAny, this);
- childSetPrevalidate("Description", LLLineEditor::prevalidatePrintableNotPipe);
-
+ // No prevalidate function - historically the prevalidate function was broken,
+ // allowing residents to put in characters like U+2661 WHITE HEART SUIT, so
+ // preserve that ability.
mTextSalePending = getChild<LLTextBox>("SalePending");
mTextOwnerLabel = getChild<LLTextBox>("Owner:");
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index 3fe711a166..d18f127f85 100644
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -83,7 +83,6 @@ BOOL LLFloaterMap::postBuild()
{
mMap = getChild<LLNetMap>("Net Map");
mMap->setScale(gSavedSettings.getF32("MiniMapScale"));
- mMap->setRotateMap(gSavedSettings.getBOOL( "MiniMapRotate" ));
mMap->setToolTipMsg(getString("ToolTipMsg"));
sendChildToBack(mMap);
@@ -178,7 +177,8 @@ void LLFloaterMap::draw()
{
F32 rotation = 0;
- if( mMap->getRotateMap() )
+ static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
+ if( rotate_map )
{
// rotate subsequent draws to agent rotation
rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index b7296518d4..810761e034 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -111,7 +111,7 @@ BOOL LLFloaterNameDesc::postBuild()
if (NameEditor)
{
NameEditor->setMaxTextLength(DB_INV_ITEM_NAME_STR_LEN);
- NameEditor->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
+ NameEditor->setPrevalidate(&LLLineEditor::prevalidateASCIIPrintableNoPipe);
}
y -= llfloor(PREVIEW_LINE_HEIGHT * 1.2f);
@@ -123,7 +123,7 @@ BOOL LLFloaterNameDesc::postBuild()
if (DescEditor)
{
DescEditor->setMaxTextLength(DB_INV_ITEM_DESC_STR_LEN);
- DescEditor->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe);
+ DescEditor->setPrevalidate(&LLLineEditor::prevalidateASCIIPrintableNoPipe);
}
y -= llfloor(PREVIEW_LINE_HEIGHT * 1.2f);
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index e0d4a59d9d..ff9002787c 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -130,9 +130,9 @@ BOOL LLFloaterProperties::postBuild()
{
// build the UI
// item name & description
- childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidateASCIIPrintableNoPipe);
getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLFloaterProperties::onCommitName,this));
- childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidateASCIIPrintableNoPipe);
getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLFloaterProperties:: onCommitDescription, this));
// Creator information
getChild<LLUICtrl>("BtnCreator")->setCommitCallback(boost::bind(&LLFloaterProperties::onClickCreator,this));
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 4192c6a586..955bc64e05 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -220,7 +220,7 @@ LLFolderView::LLFolderView(const Params& p)
params.font(getLabelFontForStyle(LLFontGL::NORMAL));
params.max_length_bytes(DB_INV_ITEM_NAME_STR_LEN);
params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
- params.prevalidate_callback(&LLLineEditor::prevalidatePrintableNotPipe);
+ params.prevalidate_callback(&LLLineEditor::prevalidateASCIIPrintableNoPipe);
params.commit_on_focus_lost(true);
params.visible(false);
mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index e60bde9fd8..f4e1951c7b 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -272,7 +272,7 @@ void LLGroupActions::closeGroup(const LLUUID& group_id)
// static
-void LLGroupActions::startChat(const LLUUID& group_id)
+void LLGroupActions::startIM(const LLUUID& group_id)
{
if (group_id.isNull())
return;
@@ -299,6 +299,19 @@ void LLGroupActions::startChat(const LLUUID& group_id)
}
// static
+void LLGroupActions::endIM(const LLUUID& group_id)
+{
+ if (group_id.isNull())
+ return;
+
+ LLUUID session_id = gIMMgr->computeSessionID(IM_SESSION_GROUP_START, group_id);
+ if (session_id != LLUUID::null)
+ {
+ gIMMgr->leaveSession(session_id);
+ }
+}
+
+// static
bool LLGroupActions::isInGroup(const LLUUID& group_id)
{
// *TODO: Move all the LLAgent group stuff into another class, such as
diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h
index 74c84d1561..9750b3e3cb 100644
--- a/indra/newview/llgroupactions.h
+++ b/indra/newview/llgroupactions.h
@@ -88,7 +88,12 @@ public:
/**
* Start group instant messaging session.
*/
- static void startChat(const LLUUID& group_id);
+ static void startIM(const LLUUID& group_id);
+
+ /**
+ * End group instant messaging session.
+ */
+ static void endIM(const LLUUID& group_id);
/// Returns if the current user is a member of the group
static bool isInGroup(const LLUUID& group_id);
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 1f80543791..dbbf98ad08 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -358,7 +358,7 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
void LLIMFloater::getAllowedRect(LLRect& rect)
{
- rect = gViewerWindow->getWorldViewRectRaw();
+ rect = gViewerWindow->getWorldViewRectScaled();
}
void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 524a889f97..c081af5879 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -58,7 +58,7 @@ LLIMHandler::~LLIMHandler()
//--------------------------------------------------------------------------
void LLIMHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index dd78bb631f..ad80e7ed61 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1,2556 +1,2556 @@
-/**
- * @file LLIMMgr.cpp
- * @brief Container for Instant Messaging
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llimview.h"
-
-#include "llfloaterreg.h"
-#include "llfontgl.h"
-#include "llrect.h"
-#include "llerror.h"
-#include "llbutton.h"
-#include "llhttpclient.h"
-#include "llsdutil_math.h"
-#include "llstring.h"
-#include "lluictrlfactory.h"
-
-#include "llagent.h"
-#include "llavatariconctrl.h"
-#include "llbottomtray.h"
-#include "llcallingcard.h"
-#include "llchat.h"
+/**
+ * @file LLIMMgr.cpp
+ * @brief Container for Instant Messaging
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llimview.h"
+
+#include "llfloaterreg.h"
+#include "llfontgl.h"
+#include "llrect.h"
+#include "llerror.h"
+#include "llbutton.h"
+#include "llhttpclient.h"
+#include "llsdutil_math.h"
+#include "llstring.h"
+#include "lluictrlfactory.h"
+
+#include "llagent.h"
+#include "llavatariconctrl.h"
+#include "llbottomtray.h"
+#include "llcallingcard.h"
+#include "llchat.h"
#include "llchiclet.h"
-#include "llresmgr.h"
-#include "llfloaterchat.h"
-#include "llfloaterchatterbox.h"
-#include "llavataractions.h"
-#include "llhttpnode.h"
-#include "llimfloater.h"
-#include "llimpanel.h"
-#include "llresizebar.h"
-#include "lltabcontainer.h"
-#include "llviewercontrol.h"
-#include "llfloater.h"
-#include "llmutelist.h"
-#include "llresizehandle.h"
-#include "llkeyboard.h"
-#include "llui.h"
-#include "llviewermenu.h"
-#include "llcallingcard.h"
-#include "lltoolbar.h"
-#include "llviewermessage.h"
-#include "llviewerwindow.h"
-#include "llnotify.h"
-#include "llviewerregion.h"
-#include "llvoicechannel.h"
-#include "lltrans.h"
-#include "llrecentpeople.h"
-#include "llsyswellwindow.h"
-
-#include "llfirstuse.h"
-#include "llagentui.h"
-
-//
-// Globals
-//
-LLIMMgr* gIMMgr = NULL;
-
-//
-// Statics
-//
-// *FIXME: make these all either UIStrings or Strings
-
-const static std::string IM_SEPARATOR(": ");
-
-
-void toast_callback(const LLSD& msg){
- // do not show toast in busy mode or it goes from agent
- if (gAgent.getBusy() || gAgent.getID() == msg["from_id"])
- {
- return;
- }
-
- // check whether incoming IM belongs to an active session or not
- if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
- {
- return;
- }
-
- // Skip toasting for system messages
- if (msg["from_id"].asUUID() == LLUUID::null)
- {
- return;
- }
-
- LLSD args;
- args["MESSAGE"] = msg["message"];
- args["TIME"] = msg["time"];
- args["FROM"] = msg["from"];
- args["FROM_ID"] = msg["from_id"];
- args["SESSION_ID"] = msg["session_id"];
-
- LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
-}
-
-void LLIMModel::setActiveSessionID(const LLUUID& session_id)
-{
- // check if such an ID really exists
- if (!findIMSession(session_id))
- {
- llwarns << "Trying to set as active a non-existent session!" << llendl;
- return;
- }
-
- mActiveSessionID = session_id;
-}
-
-LLIMModel::LLIMModel()
-{
- addNewMsgCallback(LLIMFloater::newIMCallback);
- addNewMsgCallback(toast_callback);
-}
-
-LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids)
-: mSessionID(session_id),
- mName(name),
- mType(type),
- mNumUnread(0),
- mOtherParticipantID(other_participant_id),
- mInitialTargetIDs(ids),
- mVoiceChannel(NULL),
- mSpeakers(NULL),
- mSessionInitialized(false),
- mCallBackEnabled(true),
- mTextIMPossible(true),
- mOtherParticipantIsAvatar(true)
-{
- if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
- {
- mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
- }
- else
- {
- mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
- }
- mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
-
- // All participants will be added to the list of people we've recently interacted with.
- mSpeakers->addListener(&LLRecentPeople::instance(), "add");
-
- //we need to wait for session initialization for outgoing ad-hoc and group chat session
- //correct session id for initiated ad-hoc chat will be received from the server
- if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID,
- mInitialTargetIDs, mType))
- {
- //we don't need to wait for any responses
- //so we're already initialized
- mSessionInitialized = true;
- }
-
- if (IM_NOTHING_SPECIAL == type)
- {
- mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionID);
- mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID);
- mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
- }
-
- if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
- LLLogChat::loadHistory(mName, &chatFromLogFile, (void *)this);
-}
-
-LLIMModel::LLIMSession::~LLIMSession()
-{
- delete mSpeakers;
- mSpeakers = NULL;
-
- // End the text IM session if necessary
- if(gVoiceClient && mOtherParticipantID.notNull())
- {
- switch(mType)
- {
- case IM_NOTHING_SPECIAL:
- case IM_SESSION_P2P_INVITE:
- gVoiceClient->endUserIMSession(mOtherParticipantID);
- break;
-
- default:
- // Appease the linux compiler
- break;
- }
- }
-
- // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
- mVoiceChannel->deactivate();
-
- delete mVoiceChannel;
- mVoiceChannel = NULL;
-}
-
-void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_id)
-{
- mSessionInitialized = true;
-
- if (new_session_id != mSessionID)
- {
- mSessionID = new_session_id;
- mVoiceChannel->updateSessionID(new_session_id);
- }
-}
-
-void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time)
-{
- LLSD message;
- message["from"] = from;
- message["from_id"] = from_id;
- message["message"] = utf8_text;
- message["time"] = time;
- message["index"] = (LLSD::Integer)mMsgs.size();
-
- mMsgs.push_front(message);
-
- if (mSpeakers && from_id.notNull())
- {
- mSpeakers->speakerChatted(from_id);
- mSpeakers->setSpeakerTyping(from_id, FALSE);
- }
-}
-
-void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata)
-{
- if (!userdata) return;
-
- LLIMSession* self = (LLIMSession*) userdata;
-
- if (type == LLLogChat::LOG_LINE)
- {
- self->addMessage("", LLSD(), msg["message"].asString(), "");
- }
- else if (type == LLLogChat::LOG_LLSD)
- {
- self->addMessage(msg["from"].asString(), msg["from_id"].asUUID(), msg["message"].asString(), msg["time"].asString());
- }
-}
-
-LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
-{
- return get_if_there(mId2SessionMap, session_id,
- (LLIMModel::LLIMSession*) NULL);
-}
-
-void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
- LLIMSession* session = findIMSession(old_session_id);
- if (session)
- {
- session->sessionInitReplyReceived(new_session_id);
-
- if (old_session_id != new_session_id)
- {
- mId2SessionMap.erase(old_session_id);
- mId2SessionMap[new_session_id] = session;
-
- gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
- }
-
- LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
- if (im_floater)
- {
- im_floater->sessionInitReplyReceived(new_session_id);
- }
- }
-
- //*TODO remove this "floater" stuff when Communicate Floater is gone
- LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(old_session_id);
- if (floater)
- {
- floater->sessionInitReplyReceived(new_session_id);
- }
-}
-
-void LLIMModel::testMessages()
-{
- LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9");
- LLUUID bot1_session_id;
- std::string from = "IM Tester";
-
- bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id);
- newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id);
- addMessage(bot1_session_id, from, bot1_id, "Test Message: Hi from testerbot land!");
-
- LLUUID bot2_id;
- std::string firstname[] = {"Roflcopter", "Joe"};
- std::string lastname[] = {"Linden", "Tester", "Resident", "Schmoe"};
-
- S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]);
- S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]);
-
- from = firstname[rand1] + " " + lastname[rand2];
- bot2_id.generate(from);
- LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id);
- newSession(bot2_session_id, from, IM_NOTHING_SPECIAL, bot2_id);
- addMessage(bot2_session_id, from, bot2_id, "Test Message: Hello there, I have a question. Can I bother you for a second? ");
- addMessage(bot2_session_id, from, bot2_id, "Test Message: OMGWTFBBQ.");
-}
-
-
-bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
- const LLUUID& other_participant_id, const std::vector<LLUUID>& ids)
-{
- if (findIMSession(session_id))
- {
- llwarns << "IM Session " << session_id << " already exists" << llendl;
- return false;
- }
-
- LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids);
- mId2SessionMap[session_id] = session;
-
- LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
-
- return true;
-
-}
-
-bool LLIMModel::clearSession(const LLUUID& session_id)
-{
- if (mId2SessionMap.find(session_id) == mId2SessionMap.end()) return false;
- delete (mId2SessionMap[session_id]);
- mId2SessionMap.erase(session_id);
- return true;
-}
-
-void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
-{
- LLIMSession* session = findIMSession(session_id);
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return;
- }
-
- int i = session->mMsgs.size() - start_index;
-
- for (std::list<LLSD>::iterator iter = session->mMsgs.begin();
- iter != session->mMsgs.end() && i > 0;
- iter++)
- {
- LLSD msg;
- msg = *iter;
- messages.push_back(*iter);
- i--;
- }
-
- session->mNumUnread = 0;
-
- LLSD arg;
- arg["session_id"] = session_id;
- arg["num_unread"] = 0;
- mNoUnreadMsgsSignal(arg);
-}
-
-bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
-
- LLIMSession* session = findIMSession(session_id);
-
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return false;
- }
-
- session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false)); //might want to add date separately
-
- return true;
-}
-
-bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
-{
- S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions");
- if (im_log_option != LOG_CHAT)
- {
- if(im_log_option == LOG_BOTH_TOGETHER)
- {
- LLLogChat::saveHistory(std::string("chat"), from, from_id, utf8_text);
- return true;
- }
- else
- {
- LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text);
- return true;
- }
- }
- return false;
-}
-
-bool LLIMModel::proccessOnlineOfflineNotification(
- const LLUUID& session_id,
- const std::string& utf8_text)
-{
- // Add message to old one floater
- LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
- if ( floater )
- {
- if ( !utf8_text.empty() )
- {
- floater->addHistoryLine(utf8_text, LLUIColorTable::instance().getColor("SystemChatColor"));
- }
- }
- // Add system message to history
- return addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text);
-}
-
-bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
- const std::string& utf8_text, bool log2file /* = true */) {
- LLIMSession* session = findIMSession(session_id);
-
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return false;
- }
-
- addToHistory(session_id, from, from_id, utf8_text);
- if (log2file) logToFile(session_id, from, from_id, utf8_text);
-
- session->mNumUnread++;
-
- // notify listeners
- LLSD arg;
- arg["session_id"] = session_id;
- arg["num_unread"] = session->mNumUnread;
- arg["message"] = utf8_text;
- arg["from"] = from;
- arg["from_id"] = from_id;
- arg["time"] = LLLogChat::timestamp(false);
- mNewMsgSignal(arg);
-
- return true;
-}
-
-
-const std::string& LLIMModel::getName(const LLUUID& session_id) const
-{
- LLIMSession* session = findIMSession(session_id);
-
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return LLStringUtil::null;
- }
-
- return session->mName;
-}
-
-const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
-{
- LLIMSession* session = findIMSession(session_id);
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return -1;
- }
-
- return session->mNumUnread;
-}
-
-const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
-{
- LLIMSession* session = findIMSession(session_id);
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return LLUUID::null;
- }
-
- return session->mOtherParticipantID;
-}
-
-EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
-{
- LLIMSession* session = findIMSession(session_id);
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return IM_COUNT;
- }
-
- return session->mType;
-}
-
-LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
-{
- LLIMSession* session = findIMSession(session_id);
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return NULL;
- }
-
- return session->mVoiceChannel;
-}
-
-LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
-{
- LLIMSession* session = findIMSession(session_id);
- if (!session)
- {
- llwarns << "session " << session_id << "does not exist " << llendl;
- return NULL;
- }
-
- return session->mSpeakers;
-}
-
-
-// TODO get rid of other participant ID
-void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
-{
- std::string name;
- LLAgentUI::buildFullname(name);
-
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- other_participant_id,
- name,
- std::string("typing"),
- IM_ONLINE,
- (typing ? IM_TYPING_START : IM_TYPING_STOP),
- session_id);
- gAgent.sendReliableMessage();
-}
-
-void LLIMModel::sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id)
-{
- if(session_id.notNull())
- {
- std::string name;
- LLAgentUI::buildFullname(name);
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- other_participant_id,
- name,
- LLStringUtil::null,
- IM_ONLINE,
- IM_SESSION_LEAVE,
- session_id);
- gAgent.sendReliableMessage();
- }
-}
-
-//*TODO this method is better be moved to the LLIMMgr
-void LLIMModel::sendMessage(const std::string& utf8_text,
- const LLUUID& im_session_id,
- const LLUUID& other_participant_id,
- EInstantMessage dialog)
-{
- std::string name;
- bool sent = false;
- LLAgentUI::buildFullname(name);
-
- const LLRelationship* info = NULL;
- info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
-
- U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
-
- if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
- {
- // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice.
- sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text);
- }
-
- if(!sent)
- {
- // Send message normally.
-
- // default to IM_SESSION_SEND unless it's nothing special - in
- // which case it's probably an IM to everyone.
- U8 new_dialog = dialog;
-
- if ( dialog != IM_NOTHING_SPECIAL )
- {
- new_dialog = IM_SESSION_SEND;
- }
- pack_instant_message(
- gMessageSystem,
- gAgent.getID(),
- FALSE,
- gAgent.getSessionID(),
- other_participant_id,
- name.c_str(),
- utf8_text.c_str(),
- offline,
- (EInstantMessage)new_dialog,
- im_session_id);
- gAgent.sendReliableMessage();
- }
-
- // If there is a mute list and this is not a group chat...
- if ( LLMuteList::getInstance() )
- {
- // ... the target should not be in our mute list for some message types.
- // Auto-remove them if present.
- switch( dialog )
- {
- case IM_NOTHING_SPECIAL:
- case IM_GROUP_INVITATION:
- case IM_INVENTORY_OFFERED:
- case IM_SESSION_INVITE:
- case IM_SESSION_P2P_INVITE:
- case IM_SESSION_CONFERENCE_START:
- case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing.
- case IM_LURE_USER:
- case IM_GODLIKE_LURE_USER:
- case IM_FRIENDSHIP_OFFERED:
- LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM);
- break;
- default: ; // do nothing
- }
- }
-
- if((dialog == IM_NOTHING_SPECIAL) &&
- (other_participant_id.notNull()))
- {
- // Do we have to replace the /me's here?
- std::string from;
- LLAgentUI::buildFullname(from);
- LLIMModel::getInstance()->addMessage(im_session_id, from, gAgentID, utf8_text);
-
- //local echo for the legacy communicate panel
- std::string history_echo;
- LLAgentUI::buildFullname(history_echo);
-
- history_echo += ": " + utf8_text;
-
- LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
- if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
-
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
- if (speaker_mgr)
- {
- speaker_mgr->speakerChatted(gAgentID);
- speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
- }
- }
-
- // Add the recipient to the recent people list.
- LLRecentPeople::instance().add(other_participant_id);
-}
-
-void session_starter_helper(
- const LLUUID& temp_session_id,
- const LLUUID& other_participant_id,
- EInstantMessage im_type)
-{
- LLMessageSystem *msg = gMessageSystem;
-
- msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-
- msg->nextBlockFast(_PREHASH_MessageBlock);
- msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
- msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id);
- msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
- msg->addU8Fast(_PREHASH_Dialog, im_type);
- msg->addUUIDFast(_PREHASH_ID, temp_session_id);
- msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
-
- std::string name;
- LLAgentUI::buildFullname(name);
-
- msg->addStringFast(_PREHASH_FromAgentName, name);
- msg->addStringFast(_PREHASH_Message, LLStringUtil::null);
- msg->addU32Fast(_PREHASH_ParentEstateID, 0);
- msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
- msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
-}
-
-void start_deprecated_conference_chat(
- const LLUUID& temp_session_id,
- const LLUUID& creator_id,
- const LLUUID& other_participant_id,
- const LLSD& agents_to_invite)
-{
- U8* bucket;
- U8* pos;
- S32 count;
- S32 bucket_size;
-
- // *FIX: this could suffer from endian issues
- count = agents_to_invite.size();
- bucket_size = UUID_BYTES * count;
- bucket = new U8[bucket_size];
- pos = bucket;
-
- for(S32 i = 0; i < count; ++i)
- {
- LLUUID agent_id = agents_to_invite[i].asUUID();
-
- memcpy(pos, &agent_id, UUID_BYTES);
- pos += UUID_BYTES;
- }
-
- session_starter_helper(
- temp_session_id,
- other_participant_id,
- IM_SESSION_CONFERENCE_START);
-
- gMessageSystem->addBinaryDataFast(
- _PREHASH_BinaryBucket,
- bucket,
- bucket_size);
-
- gAgent.sendReliableMessage();
-
- delete[] bucket;
-}
-
-class LLStartConferenceChatResponder : public LLHTTPClient::Responder
-{
-public:
- LLStartConferenceChatResponder(
- const LLUUID& temp_session_id,
- const LLUUID& creator_id,
- const LLUUID& other_participant_id,
- const LLSD& agents_to_invite)
- {
- mTempSessionID = temp_session_id;
- mCreatorID = creator_id;
- mOtherParticipantID = other_participant_id;
- mAgents = agents_to_invite;
- }
-
- virtual void error(U32 statusNum, const std::string& reason)
- {
- //try an "old school" way.
- if ( statusNum == 400 )
- {
- start_deprecated_conference_chat(
- mTempSessionID,
- mCreatorID,
- mOtherParticipantID,
- mAgents);
- }
-
- //else throw an error back to the client?
- //in theory we should have just have these error strings
- //etc. set up in this file as opposed to the IMMgr,
- //but the error string were unneeded here previously
- //and it is not worth the effort switching over all
- //the possible different language translations
- }
-
-private:
- LLUUID mTempSessionID;
- LLUUID mCreatorID;
- LLUUID mOtherParticipantID;
-
- LLSD mAgents;
-};
-
-// Returns true if any messages were sent, false otherwise.
-// Is sort of equivalent to "does the server need to do anything?"
-bool LLIMModel::sendStartSession(
- const LLUUID& temp_session_id,
- const LLUUID& other_participant_id,
- const std::vector<LLUUID>& ids,
- EInstantMessage dialog)
-{
- if ( dialog == IM_SESSION_GROUP_START )
- {
- session_starter_helper(
- temp_session_id,
- other_participant_id,
- dialog);
- gMessageSystem->addBinaryDataFast(
- _PREHASH_BinaryBucket,
- EMPTY_BINARY_BUCKET,
- EMPTY_BINARY_BUCKET_SIZE);
- gAgent.sendReliableMessage();
-
- return true;
- }
- else if ( dialog == IM_SESSION_CONFERENCE_START )
- {
- LLSD agents;
- for (int i = 0; i < (S32) ids.size(); i++)
- {
- agents.append(ids[i]);
- }
-
- //we have a new way of starting conference calls now
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- std::string url = region->getCapability(
- "ChatSessionRequest");
- LLSD data;
- data["method"] = "start conference";
- data["session-id"] = temp_session_id;
-
- data["params"] = agents;
-
- LLHTTPClient::post(
- url,
- data,
- new LLStartConferenceChatResponder(
- temp_session_id,
- gAgent.getID(),
- other_participant_id,
- data["params"]));
- }
- else
- {
- start_deprecated_conference_chat(
- temp_session_id,
- gAgent.getID(),
- other_participant_id,
- agents);
- }
-
- //we also need to wait for reply from the server in case of ad-hoc chat (we'll get new session id)
- return true;
- }
-
- return false;
-}
-
-// static
-void LLIMModel::sendSessionInitialized(const LLUUID &session_id)
-{
- LLIMSession* session = getInstance()->findIMSession(session_id);
- if (session)
- {
- LLSD arg;
- arg["session_id"] = session_id;
- getInstance()->mSessionInitializedSignal(arg);
- }
-}
-
-//
-// Helper Functions
-//
-
-class LLViewerChatterBoxInvitationAcceptResponder :
- public LLHTTPClient::Responder
-{
-public:
- LLViewerChatterBoxInvitationAcceptResponder(
- const LLUUID& session_id,
- LLIMMgr::EInvitationType invitation_type)
- {
- mSessionID = session_id;
- mInvitiationType = invitation_type;
- }
-
- void result(const LLSD& content)
- {
- if ( gIMMgr)
- {
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
- if (speaker_mgr)
- {
- //we've accepted our invitation
- //and received a list of agents that were
- //currently in the session when the reply was sent
- //to us. Now, it is possible that there were some agents
- //to slip in/out between when that message was sent to us
- //and now.
-
- //the agent list updates we've received have been
- //accurate from the time we were added to the session
- //but unfortunately, our base that we are receiving here
- //may not be the most up to date. It was accurate at
- //some point in time though.
- speaker_mgr->setSpeakers(content);
-
- //we now have our base of users in the session
- //that was accurate at some point, but maybe not now
- //so now we apply all of the udpates we've received
- //in case of race conditions
- speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
- }
-
- if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
- {
- gIMMgr->startCall(mSessionID);
- }
-
- if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE
- || mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
- && LLIMModel::getInstance()->findIMSession(mSessionID))
- {
- // always open IM window when connecting to voice
- LLIMFloater::show(mSessionID);
- }
-
- gIMMgr->clearPendingAgentListUpdates(mSessionID);
- gIMMgr->clearPendingInvitation(mSessionID);
- }
- }
-
- void error(U32 statusNum, const std::string& reason)
- {
- //throw something back to the viewer here?
- if ( gIMMgr )
- {
- gIMMgr->clearPendingAgentListUpdates(mSessionID);
- gIMMgr->clearPendingInvitation(mSessionID);
- if ( 404 == statusNum )
- {
- std::string error_string;
- error_string = "does not exist";
- gIMMgr->showSessionStartError(error_string, mSessionID);
- }
- }
- }
-
-private:
- LLUUID mSessionID;
- LLIMMgr::EInvitationType mInvitiationType;
-};
-
-
-// the other_participant_id is either an agent_id, a group_id, or an inventory
-// folder item_id (collection of calling cards)
-
-// static
-LLUUID LLIMMgr::computeSessionID(
- EInstantMessage dialog,
- const LLUUID& other_participant_id)
-{
- LLUUID session_id;
- if (IM_SESSION_GROUP_START == dialog)
- {
- // slam group session_id to the group_id (other_participant_id)
- session_id = other_participant_id;
- }
- else if (IM_SESSION_CONFERENCE_START == dialog)
- {
- session_id.generate();
- }
- else if (IM_SESSION_INVITE == dialog)
- {
- // use provided session id for invites
- session_id = other_participant_id;
- }
- else
- {
- LLUUID agent_id = gAgent.getID();
- if (other_participant_id == agent_id)
- {
- // if we try to send an IM to ourselves then the XOR would be null
- // so we just make the session_id the same as the agent_id
- session_id = agent_id;
- }
- else
- {
- // peer-to-peer or peer-to-asset session_id is the XOR
- session_id = other_participant_id ^ agent_id;
- }
- }
- return session_id;
-}
-
-inline LLFloater* getFloaterBySessionID(const LLUUID session_id)
-{
- LLFloater* floater = NULL;
- if ( gIMMgr )
- {
- floater = dynamic_cast < LLFloater* >
- ( gIMMgr->findFloaterBySession(session_id) );
- }
- if ( !floater )
- {
- floater = dynamic_cast < LLFloater* >
- ( LLIMFloater::findInstance(session_id) );
- }
- return floater;
-}
-
-void
-LLIMMgr::showSessionStartError(
- const std::string& error_string,
- const LLUUID session_id)
-{
- const LLFloater* floater = getFloaterBySessionID (session_id);
- if (!floater) return;
-
- LLSD args;
- args["REASON"] = LLTrans::getString(error_string);
- args["RECIPIENT"] = floater->getTitle();
-
- LLSD payload;
- payload["session_id"] = session_id;
-
- LLNotifications::instance().add(
- "ChatterBoxSessionStartError",
- args,
- payload,
- LLIMMgr::onConfirmForceCloseError);
-}
-
-void
-LLIMMgr::showSessionEventError(
- const std::string& event_string,
- const std::string& error_string,
- const LLUUID session_id)
-{
- const LLFloater* floater = getFloaterBySessionID (session_id);
- if (!floater) return;
-
- LLSD args;
- args["REASON"] =
- LLTrans::getString(error_string);
- args["EVENT"] =
- LLTrans::getString(event_string);
- args["RECIPIENT"] = floater->getTitle();
-
- LLNotifications::instance().add(
- "ChatterBoxSessionEventError",
- args);
-}
-
-void
-LLIMMgr::showSessionForceClose(
- const std::string& reason_string,
- const LLUUID session_id)
-{
- const LLFloater* floater = getFloaterBySessionID (session_id);
- if (!floater) return;
-
- LLSD args;
-
- args["NAME"] = floater->getTitle();
- args["REASON"] = LLTrans::getString(reason_string);
-
- LLSD payload;
- payload["session_id"] = session_id;
-
- LLNotifications::instance().add(
- "ForceCloseChatterBoxSession",
- args,
- payload,
- LLIMMgr::onConfirmForceCloseError);
-}
-
-//static
-bool
-LLIMMgr::onConfirmForceCloseError(
- const LLSD& notification,
- const LLSD& response)
-{
- //only 1 option really
- LLUUID session_id = notification["payload"]["session_id"];
-
- LLFloater* floater = getFloaterBySessionID (session_id);
- if ( floater )
- {
- floater->closeFloater(FALSE);
- }
- return false;
-}
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLOutgoingCallDialog
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) :
- LLDockableFloater(NULL, false, payload),
- mPayload(payload)
-{
-}
-
-void LLOutgoingCallDialog::getAllowedRect(LLRect& rect)
-{
- rect = gViewerWindow->getWorldViewRectRaw();
-}
-
-void LLOutgoingCallDialog::onOpen(const LLSD& key)
-{
- // tell the user which voice channel they are leaving
- if (!mPayload["old_channel_name"].asString().empty())
- {
- childSetTextArg("leaving", "[CURRENT_CHAT]", mPayload["old_channel_name"].asString());
- }
- else
- {
- childSetTextArg("leaving", "[CURRENT_CHAT]", getString("localchat"));
- }
-
- std::string callee_name = mPayload["session_name"].asString();
- if (callee_name == "anonymous")
- {
- callee_name = getString("anonymous");
- }
-
- setTitle(callee_name);
-
- LLSD callee_id = mPayload["other_user_id"];
- childSetTextArg("calling", "[CALLEE_NAME]", callee_name);
- childSetTextArg("connecting", "[CALLEE_NAME]", callee_name);
- LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
- icon->setValue(callee_id);
-}
-
-
-//static
-void LLOutgoingCallDialog::onCancel(void* user_data)
-{
- LLOutgoingCallDialog* self = (LLOutgoingCallDialog*)user_data;
-
- if (!gIMMgr)
- return;
-
- LLUUID session_id = self->mPayload["session_id"].asUUID();
- gIMMgr->endCall(session_id);
-
- self->closeFloater();
-}
-
-
-BOOL LLOutgoingCallDialog::postBuild()
-{
- BOOL success = LLDockableFloater::postBuild();
-
- childSetAction("Cancel", onCancel, this);
-
- // dock the dialog to the sys well, where other sys messages appear
- setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
- this, getDockTongue(), LLDockControl::TOP,
- boost::bind(&LLOutgoingCallDialog::getAllowedRect, this, _1)));
-
- return success;
-}
-
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLIncomingCallDialog
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
- LLDockableFloater(NULL, false, payload),
- mPayload(payload)
-{
-}
-
-BOOL LLIncomingCallDialog::postBuild()
-{
- LLDockableFloater::postBuild();
-
- LLSD caller_id = mPayload["caller_id"];
- EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
-
- std::string call_type = getString("VoiceInviteP2P");
- std::string caller_name = mPayload["caller_name"].asString();
- if (caller_name == "anonymous")
- {
- caller_name = getString("anonymous");
- }
-
- setTitle(caller_name + " " + call_type);
-
- // If it is not a P2P invite, then it's an AdHoc invite
- if ( type != IM_SESSION_P2P_INVITE )
- {
- call_type = getString("VoiceInviteAdHoc");
- }
-
- // check to see if this is an Avaline call
- LLUUID session_id = mPayload["session_id"].asUUID();
- bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
- childSetVisible("Start IM", is_avatar); // no IM for avaline
-
- LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
- caller_name_widget->setValue(caller_name + " " + call_type);
- LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
- icon->setValue(caller_id);
-
- childSetAction("Accept", onAccept, this);
- childSetAction("Reject", onReject, this);
- childSetAction("Start IM", onStartIM, this);
- childSetFocus("Accept");
-
- return TRUE;
-}
-
-void LLIncomingCallDialog::getAllowedRect(LLRect& rect)
-{
- rect = gViewerWindow->getWorldViewRectRaw();
-}
-
-void LLIncomingCallDialog::onOpen(const LLSD& key)
-{
- // tell the user which voice channel they would be leaving
- LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
- if (voice && !voice->getSessionName().empty())
- {
- childSetTextArg("question", "[CURRENT_CHAT]", voice->getSessionName());
- }
- else
- {
- childSetTextArg("question", "[CURRENT_CHAT]", getString("localchat"));
- }
-
- // dock the dialog to the sys well, where other sys messages appear
- setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
- this, getDockTongue(), LLDockControl::TOP,
- boost::bind(&LLIncomingCallDialog::getAllowedRect, this, _1)));
-}
-
-//static
-void LLIncomingCallDialog::onAccept(void* user_data)
-{
- LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
- self->processCallResponse(0);
- self->closeFloater();
-}
-
-//static
-void LLIncomingCallDialog::onReject(void* user_data)
-{
- LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
- self->processCallResponse(1);
- self->closeFloater();
-}
-
-//static
-void LLIncomingCallDialog::onStartIM(void* user_data)
-{
- LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
- self->processCallResponse(2);
- self->closeFloater();
-}
-
-void LLIncomingCallDialog::processCallResponse(S32 response)
-{
- if (!gIMMgr)
- return;
-
- LLUUID session_id = mPayload["session_id"].asUUID();
- EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
- LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)mPayload["inv_type"].asInteger();
- bool voice = true;
- switch(response)
- {
- case 2: // start IM: just don't start the voice chat
- {
- voice = false;
- /* FALLTHROUGH */
- }
- case 0: // accept
- {
- if (type == IM_SESSION_P2P_INVITE)
- {
- // create a normal IM session
- session_id = gIMMgr->addP2PSession(
- mPayload["session_name"].asString(),
- mPayload["caller_id"].asUUID(),
- mPayload["session_handle"].asString());
-
- if (voice)
- {
- if (gIMMgr->startCall(session_id))
- {
- // always open IM window when connecting to voice
- LLIMFloater::show(session_id);
- }
- }
-
- gIMMgr->clearPendingAgentListUpdates(session_id);
- gIMMgr->clearPendingInvitation(session_id);
- }
- else
- {
- LLUUID session_id = gIMMgr->addSession(
- mPayload["session_name"].asString(),
- type,
- session_id);
- if (session_id != LLUUID::null)
- {
- LLIMFloater::show(session_id);
- }
-
- std::string url = gAgent.getRegion()->getCapability(
- "ChatSessionRequest");
-
- if (voice)
- {
- LLSD data;
- data["method"] = "accept invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- new LLViewerChatterBoxInvitationAcceptResponder(
- session_id,
- inv_type));
- }
- }
- if (voice)
- {
- break;
- }
- }
- case 1: // decline
- {
- if (type == IM_SESSION_P2P_INVITE)
- {
- if(gVoiceClient)
- {
- std::string s = mPayload["session_handle"].asString();
- gVoiceClient->declineInvite(s);
- }
- }
- else
- {
- std::string url = gAgent.getRegion()->getCapability(
- "ChatSessionRequest");
-
- LLSD data;
- data["method"] = "decline invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- NULL);
- }
- }
-
- gIMMgr->clearPendingAgentListUpdates(session_id);
- gIMMgr->clearPendingInvitation(session_id);
- }
-}
-
-bool inviteUserResponse(const LLSD& notification, const LLSD& response)
-{
- if (!gIMMgr)
- return false;
-
- const LLSD& payload = notification["payload"];
- LLUUID session_id = payload["session_id"].asUUID();
- EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
- LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
- S32 option = LLNotification::getSelectedOption(notification, response);
- switch(option)
- {
- case 0: // accept
- {
- if (type == IM_SESSION_P2P_INVITE)
- {
- // create a normal IM session
- session_id = gIMMgr->addP2PSession(
- payload["session_name"].asString(),
- payload["caller_id"].asUUID(),
- payload["session_handle"].asString(),
- payload["session_uri"].asString());
-
- if (gIMMgr->startCall(session_id))
- {
- // always open IM window when connecting to voice
- LLIMFloater::show(session_id);
- }
-
- gIMMgr->clearPendingAgentListUpdates(session_id);
- gIMMgr->clearPendingInvitation(session_id);
- }
- else
- {
- LLUUID session_id = gIMMgr->addSession(
- payload["session_name"].asString(),
- type,
- session_id);
- if (session_id != LLUUID::null)
- {
- LLIMFloater::show(session_id);
- }
-
- std::string url = gAgent.getRegion()->getCapability(
- "ChatSessionRequest");
-
- LLSD data;
- data["method"] = "accept invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- new LLViewerChatterBoxInvitationAcceptResponder(
- session_id,
- inv_type));
- }
- }
- break;
- case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
- {
- // mute the sender of this invite
- if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID()))
- {
- LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT);
- LLMuteList::getInstance()->add(mute);
- }
- }
- /* FALLTHROUGH */
-
- case 1: // decline
- {
- if (type == IM_SESSION_P2P_INVITE)
- {
- if(gVoiceClient)
- {
- std::string s = payload["session_handle"].asString();
- gVoiceClient->declineInvite(s);
- }
- }
- else
- {
- std::string url = gAgent.getRegion()->getCapability(
- "ChatSessionRequest");
-
- LLSD data;
- data["method"] = "decline invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- NULL);
- }
- }
-
- gIMMgr->clearPendingAgentListUpdates(session_id);
- gIMMgr->clearPendingInvitation(session_id);
- break;
- }
-
- return false;
-}
-
-//
-// Member Functions
-//
-
-LLIMMgr::LLIMMgr() :
- mIMReceived(FALSE)
-{
- mPendingInvitations = LLSD::emptyMap();
- mPendingAgentListUpdates = LLSD::emptyMap();
-}
-
-// Add a message to a session.
-void LLIMMgr::addMessage(
- const LLUUID& session_id,
- const LLUUID& target_id,
- const std::string& from,
- const std::string& msg,
- const std::string& session_name,
- EInstantMessage dialog,
- U32 parent_estate_id,
- const LLUUID& region_id,
- const LLVector3& position,
- bool link_name) // If this is true, then we insert the name and link it to a profile
-{
- LLUUID other_participant_id = target_id;
-
- // don't process muted IMs
- if (LLMuteList::getInstance()->isMuted(
- other_participant_id,
- LLMute::flagTextChat) && !LLMuteList::getInstance()->isLinden(from))
- {
- return;
- }
-
- LLFloaterIMPanel* floater;
- LLUUID new_session_id = session_id;
- if (new_session_id.isNull())
- {
- //no session ID...compute new one
- new_session_id = computeSessionID(dialog, other_participant_id);
- }
-
- //*NOTE session_name is empty in case of incoming P2P sessions
- std::string fixed_session_name = from;
- if(!session_name.empty() && session_name.size()>1)
- {
- fixed_session_name = session_name;
- }
-
- bool new_session = !hasSession(new_session_id);
- if (new_session)
- {
- LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id);
- }
-
- floater = findFloaterBySession(new_session_id);
- if (!floater)
- {
- floater = findFloaterBySession(other_participant_id);
- if (floater)
- {
- llinfos << "found the IM session " << session_id
- << " by participant " << other_participant_id << llendl;
- }
- }
-
- // create IM window as necessary
- if(!floater)
- {
- floater = createFloater(
- new_session_id,
- other_participant_id,
- fixed_session_name,
- dialog,
- FALSE);
- }
-
- if (new_session)
- {
- // When we get a new IM, and if you are a god, display a bit
- // of information about the source. This is to help liaisons
- // when answering questions.
- if(gAgent.isGodlike())
- {
- // *TODO:translate (low priority, god ability)
- std::ostringstream bonus_info;
- bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + ":" + " "
- << parent_estate_id
- << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "")
- << ((parent_estate_id == 5) ? "," + LLTrans::getString ("IMTeen") : "");
-
- // once we have web-services (or something) which returns
- // information about a region id, we can print this out
- // and even have it link to map-teleport or something.
- //<< "*** region_id: " << region_id << std::endl
- //<< "*** position: " << position << std::endl;
-
- floater->addHistoryLine(bonus_info.str(), LLUIColorTable::instance().getColor("SystemChatColor"));
- LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
- }
-
- make_ui_sound("UISndNewIncomingIMSession");
- }
-
- // now add message to floater
- bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM);
- const LLColor4& color = ( is_from_system ?
- LLUIColorTable::instance().getColor("SystemChatColor") :
- LLUIColorTable::instance().getColor("IMChatColor"));
- if ( !link_name )
- {
- floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally
- }
- else
- {
- floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
- }
-
- LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
-
- if( !LLFloaterReg::instanceVisible("communicate") && !floater->getVisible())
- {
- LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance();
-
- //if the IM window is not open and the floater is not visible (i.e. not torn off)
- LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater();
-
- // select the newly added floater (or the floater with the new line added to it).
- // it should be there.
- chat_floater->selectFloater(floater);
-
- //there was a previously unseen IM, make that old tab flashing
- //it is assumed that the most recently unseen IM tab is the one current selected/active
- if ( previouslyActiveFloater && getIMReceived() )
- {
- chat_floater->setFloaterFlashing(previouslyActiveFloater, TRUE);
- }
-
- //notify of a new IM
- notifyNewIM();
- }
-}
-
-void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
-{
- LLUIString message;
-
- // null session id means near me (chat history)
- if (session_id.isNull())
- {
- message = LLTrans::getString(message_name);
- message.setArgs(args);
-
- LLChat chat(message);
- chat.mSourceType = CHAT_SOURCE_SYSTEM;
- LLFloaterChat::addChatHistory(chat);
- }
- else // going to IM session
- {
- if (hasSession(session_id))
- {
- message = LLTrans::getString(message_name + "-im");
- message.setArgs(args);
- gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
- }
- }
-}
-
-void LLIMMgr::notifyNewIM()
-{
- if(!LLFloaterReg::instanceVisible("communicate"))
- {
- mIMReceived = TRUE;
- }
-}
-
-S32 LLIMMgr::getNumberOfUnreadIM()
-{
- std::map<LLUUID, LLIMModel::LLIMSession*>::iterator it;
-
- S32 num = 0;
- for(it = LLIMModel::getInstance()->mId2SessionMap.begin(); it != LLIMModel::getInstance()->mId2SessionMap.end(); ++it)
- {
- num += (*it).second->mNumUnread;
- }
-
- return num;
-}
-
-void LLIMMgr::clearNewIMNotification()
-{
- mIMReceived = FALSE;
-}
-
-BOOL LLIMMgr::getIMReceived() const
-{
- return mIMReceived;
-}
-
-LLUUID LLIMMgr::addP2PSession(const std::string& name,
- const LLUUID& other_participant_id,
- const std::string& voice_session_handle,
- const std::string& caller_uri)
-{
- LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
- if (session_id != LLUUID::null)
- {
- LLIMFloater::show(session_id);
- }
-
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
- if (speaker_mgr)
- {
- LLVoiceChannelP2P* voice_channel = dynamic_cast<LLVoiceChannelP2P*>(speaker_mgr->getVoiceChannel());
- if (voice_channel)
- {
- voice_channel->setSessionHandle(voice_session_handle, caller_uri);
- }
- }
- return session_id;
-}
-
-// This adds a session to the talk view. The name is the local name of
-// the session, dialog specifies the type of session. If the session
-// exists, it is brought forward. Specifying id = NULL results in an
-// im session to everyone. Returns the uuid of the session.
-LLUUID LLIMMgr::addSession(
- const std::string& name,
- EInstantMessage dialog,
- const LLUUID& other_participant_id)
-{
- LLDynamicArray<LLUUID> ids;
- ids.put(other_participant_id);
- return addSession(name, dialog, other_participant_id, ids);
-}
-
-// Adds a session using the given session_id. If the session already exists
-// the dialog type is assumed correct. Returns the uuid of the session.
-LLUUID LLIMMgr::addSession(
- const std::string& name,
- EInstantMessage dialog,
- const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids)
-{
- if (0 == ids.getLength())
- {
- return LLUUID::null;
- }
-
- LLUUID session_id = computeSessionID(dialog,other_participant_id);
-
- bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
-
- if (new_session)
- {
- LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids);
- }
-
-
- //*TODO remove this "floater" thing when Communicate Floater's gone
- LLFloaterIMPanel* floater = findFloaterBySession(session_id);
- if(!floater)
- {
- // On creation, use the first element of ids as the
- // "other_participant_id"
- floater = createFloater(
- session_id,
- other_participant_id,
- name,
- dialog,
- TRUE,
- ids);
- }
-
- //we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
- if (!new_session) return session_id;
-
- noteOfflineUsers(session_id, floater, ids);
-
- // Only warn for regular IMs - not group IMs
- if( dialog == IM_NOTHING_SPECIAL )
- {
- noteMutedUsers(session_id, floater, ids);
- }
-
- return session_id;
-}
-
-bool LLIMMgr::leaveSession(const LLUUID& session_id)
-{
- LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
- if (!im_session) return false;
-
- LLIMModel::getInstance()->sendLeaveSession(session_id, im_session->mOtherParticipantID);
- gIMMgr->removeSession(session_id);
- return true;
-}
-
-// Removes data associated with a particular session specified by session_id
-void LLIMMgr::removeSession(const LLUUID& session_id)
-{
- llassert_always(hasSession(session_id));
-
- //*TODO remove this floater thing when Communicate Floater is being deleted (IB)
- LLFloaterIMPanel* floater = findFloaterBySession(session_id);
- if(floater)
- {
- mFloaters.erase(floater->getHandle());
- LLFloaterChatterBox::getInstance()->removeFloater(floater);
- }
-
- clearPendingInvitation(session_id);
- clearPendingAgentListUpdates(session_id);
-
- LLIMModel::getInstance()->clearSession(session_id);
-
- notifyObserverSessionRemoved(session_id);
-}
-
-void LLIMMgr::inviteToSession(
- const LLUUID& session_id,
- const std::string& session_name,
- const LLUUID& caller_id,
- const std::string& caller_name,
- EInstantMessage type,
- EInvitationType inv_type,
- const std::string& session_handle,
- const std::string& session_uri)
-{
- //ignore invites from muted residents
- if (LLMuteList::getInstance()->isMuted(caller_id))
- {
- return;
- }
-
- std::string notify_box_type;
-
- BOOL ad_hoc_invite = FALSE;
- if(type == IM_SESSION_P2P_INVITE)
- {
- //P2P is different...they only have voice invitations
- notify_box_type = "VoiceInviteP2P";
- }
- else if ( gAgent.isInGroup(session_id) )
- {
- //only really old school groups have voice invitations
- notify_box_type = "VoiceInviteGroup";
- }
- else if ( inv_type == INVITATION_TYPE_VOICE )
- {
- //else it's an ad-hoc
- //and a voice ad-hoc
- notify_box_type = "VoiceInviteAdHoc";
- ad_hoc_invite = TRUE;
- }
- else if ( inv_type == INVITATION_TYPE_IMMEDIATE )
- {
- notify_box_type = "InviteAdHoc";
- ad_hoc_invite = TRUE;
- }
-
- LLSD payload;
- payload["session_id"] = session_id;
- payload["session_name"] = session_name;
- payload["caller_id"] = caller_id;
- payload["caller_name"] = caller_name;
- payload["type"] = type;
- payload["inv_type"] = inv_type;
- payload["session_handle"] = session_handle;
- payload["session_uri"] = session_uri;
- payload["notify_box_type"] = notify_box_type;
-
- LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
- if (channelp && channelp->callStarted())
- {
- // you have already started a call to the other user, so just accept the invite
- LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
- return;
- }
-
- if (type == IM_SESSION_P2P_INVITE || ad_hoc_invite)
- {
- // is the inviter a friend?
- if (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)
- {
- // if not, and we are ignoring voice invites from non-friends
- // then silently decline
- if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
- {
- // invite not from a friend, so decline
- LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
- return;
- }
- }
- }
-
- if ( !mPendingInvitations.has(session_id.asString()) )
- {
- if (caller_name.empty())
- {
- gCacheName->get(caller_id, FALSE, boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3, _4));
- }
- else
- {
- if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
- {
- LLFloaterReg::showInstance("incoming_call", payload, TRUE);
- }
- else
- {
- LLSD args;
- args["NAME"] = caller_name;
- args["GROUP"] = session_name;
-
- LLNotifications::instance().add(notify_box_type, args, payload, &inviteUserResponse);
- }
- }
- mPendingInvitations[session_id.asString()] = LLSD();
- }
-}
-
-void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
-{
- payload["caller_name"] = first + " " + last;
- payload["session_name"] = payload["caller_name"].asString();
-
- std::string notify_box_type = payload["notify_box_type"].asString();
-
- if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
- {
- LLFloaterReg::showInstance("incoming_call", payload, TRUE);
- }
- else
- {
- LLSD args;
- args["NAME"] = payload["caller_name"].asString();
-
- LLNotifications::instance().add(
- payload["notify_box_type"].asString(),
- args,
- payload,
- &inviteUserResponse);
- }
-}
-
-void LLIMMgr::disconnectAllSessions()
-{
- LLFloaterIMPanel* floater = NULL;
- std::set<LLHandle<LLFloater> >::iterator handle_it;
- for(handle_it = mFloaters.begin();
- handle_it != mFloaters.end();
- )
- {
- floater = (LLFloaterIMPanel*)handle_it->get();
-
- // MUST do this BEFORE calling floater->onClose() because that may remove the item from the set, causing the subsequent increment to crash.
- ++handle_it;
-
- if (floater)
- {
- floater->setEnabled(FALSE);
- floater->closeFloater(TRUE);
- }
- }
-}
-
-
-// This method returns the im panel corresponding to the uuid
-// provided. The uuid can either be a session id or an agent
-// id. Returns NULL if there is no matching panel.
-LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id)
-{
- LLFloaterIMPanel* rv = NULL;
- std::set<LLHandle<LLFloater> >::iterator handle_it;
- for(handle_it = mFloaters.begin();
- handle_it != mFloaters.end();
- ++handle_it)
- {
- rv = (LLFloaterIMPanel*)handle_it->get();
- if(rv && session_id == rv->getSessionID())
- {
- break;
- }
- rv = NULL;
- }
- return rv;
-}
-
-
-BOOL LLIMMgr::hasSession(const LLUUID& session_id)
-{
- return LLIMModel::getInstance()->findIMSession(session_id) != NULL;
-}
-
-void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
-{
- if ( mPendingInvitations.has(session_id.asString()) )
- {
- mPendingInvitations.erase(session_id.asString());
- }
-}
-
-void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
-{
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
- if ( im_floater )
- {
- im_floater->processAgentListUpdates(body);
- }
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
- if (speaker_mgr)
- {
- speaker_mgr->updateSpeakers(body);
- }
- else
- {
- //we don't have a speaker manager yet..something went wrong
- //we are probably receiving an update here before
- //a start or an acceptance of an invitation. Race condition.
- gIMMgr->addPendingAgentListUpdates(
- session_id,
- body);
- }
-}
-
-LLSD LLIMMgr::getPendingAgentListUpdates(const LLUUID& session_id)
-{
- if ( mPendingAgentListUpdates.has(session_id.asString()) )
- {
- return mPendingAgentListUpdates[session_id.asString()];
- }
- else
- {
- return LLSD();
- }
-}
-
-void LLIMMgr::addPendingAgentListUpdates(
- const LLUUID& session_id,
- const LLSD& updates)
-{
- LLSD::map_const_iterator iter;
-
- if ( !mPendingAgentListUpdates.has(session_id.asString()) )
- {
- //this is a new agent list update for this session
- mPendingAgentListUpdates[session_id.asString()] = LLSD::emptyMap();
- }
-
- if (
- updates.has("agent_updates") &&
- updates["agent_updates"].isMap() &&
- updates.has("updates") &&
- updates["updates"].isMap() )
- {
- //new school update
- LLSD update_types = LLSD::emptyArray();
- LLSD::array_iterator array_iter;
-
- update_types.append("agent_updates");
- update_types.append("updates");
-
- for (
- array_iter = update_types.beginArray();
- array_iter != update_types.endArray();
- ++array_iter)
- {
- //we only want to include the last update for a given agent
- for (
- iter = updates[array_iter->asString()].beginMap();
- iter != updates[array_iter->asString()].endMap();
- ++iter)
- {
- mPendingAgentListUpdates[session_id.asString()][array_iter->asString()][iter->first] =
- iter->second;
- }
- }
- }
- else if (
- updates.has("updates") &&
- updates["updates"].isMap() )
- {
- //old school update where the SD contained just mappings
- //of agent_id -> "LEAVE"/"ENTER"
-
- //only want to keep last update for each agent
- for (
- iter = updates["updates"].beginMap();
- iter != updates["updates"].endMap();
- ++iter)
- {
- mPendingAgentListUpdates[session_id.asString()]["updates"][iter->first] =
- iter->second;
- }
- }
-}
-
-void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
-{
- if ( mPendingAgentListUpdates.has(session_id.asString()) )
- {
- mPendingAgentListUpdates.erase(session_id.asString());
- }
-}
-
-void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
-{
- for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
- {
- (*it)->sessionAdded(session_id, name, other_participant_id);
- }
-}
-
-void LLIMMgr::notifyObserverSessionRemoved(const LLUUID& session_id)
-{
- for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
- {
- (*it)->sessionRemoved(session_id);
- }
-}
-
-void LLIMMgr::notifyObserverSessionIDUpdated( const LLUUID& old_session_id, const LLUUID& new_session_id )
-{
- for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
- {
- (*it)->sessionIDUpdated(old_session_id, new_session_id);
- }
-
-}
-
-void LLIMMgr::addSessionObserver(LLIMSessionObserver *observer)
-{
- mSessionObservers.push_back(observer);
-}
-
-void LLIMMgr::removeSessionObserver(LLIMSessionObserver *observer)
-{
- mSessionObservers.remove(observer);
-}
-
-bool LLIMMgr::startCall(const LLUUID& session_id)
-{
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
- if (!voice_channel) return false;
-
- voice_channel->activate();
- return true;
-}
-
-bool LLIMMgr::endCall(const LLUUID& session_id)
-{
- LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
- if (!voice_channel) return false;
-
- voice_channel->deactivate();
- return true;
-}
-
-// create a floater and update internal representation for
-// consistency. Returns the pointer, caller (the class instance since
-// it is a private method) is not responsible for deleting the
-// pointer. Add the floater to this but do not select it.
-LLFloaterIMPanel* LLIMMgr::createFloater(
- const LLUUID& session_id,
- const LLUUID& other_participant_id,
- const std::string& session_label,
- EInstantMessage dialog,
- BOOL user_initiated,
- const LLDynamicArray<LLUUID>& ids)
-{
- if (session_id.isNull())
- {
- llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
- }
-
- llinfos << "LLIMMgr::createFloater: from " << other_participant_id
- << " in session " << session_id << llendl;
- LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
- session_id,
- other_participant_id,
- ids,
- dialog);
- LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
- LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
- mFloaters.insert(floater->getHandle());
- return floater;
-}
-
-void LLIMMgr::noteOfflineUsers(
- const LLUUID& session_id,
- LLFloaterIMPanel* floater,
- const LLDynamicArray<LLUUID>& ids)
-{
- S32 count = ids.count();
- if(count == 0)
- {
- const std::string& only_user = LLTrans::getString("only_user_message");
- if (floater)
- {
- floater->addHistoryLine(only_user, LLUIColorTable::instance().getColor("SystemChatColor"));
- }
- LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, only_user);
- }
- else
- {
- const LLRelationship* info = NULL;
- LLAvatarTracker& at = LLAvatarTracker::instance();
- LLIMModel& im_model = LLIMModel::instance();
- for(S32 i = 0; i < count; ++i)
- {
- info = at.getBuddyInfo(ids.get(i));
- std::string first, last;
- if(info && !info->isOnline()
- && gCacheName->getName(ids.get(i), first, last))
- {
- LLUIString offline = LLTrans::getString("offline_message");
- offline.setArg("[FIRST]", first);
- offline.setArg("[LAST]", last);
- im_model.proccessOnlineOfflineNotification(session_id, offline);
- }
- }
- }
-}
-
-void LLIMMgr::noteMutedUsers(const LLUUID& session_id, LLFloaterIMPanel* floater,
- const LLDynamicArray<LLUUID>& ids)
-{
- // Don't do this if we don't have a mute list.
- LLMuteList *ml = LLMuteList::getInstance();
- if( !ml )
- {
- return;
- }
-
- S32 count = ids.count();
- if(count > 0)
- {
- LLIMModel* im_model = LLIMModel::getInstance();
-
- for(S32 i = 0; i < count; ++i)
- {
- if( ml->isMuted(ids.get(i)) )
- {
- LLUIString muted = LLTrans::getString("muted_message");
-
- //*TODO remove this "floater" thing when Communicate Floater's gone
- floater->addHistoryLine(muted);
-
- im_model->addMessage(session_id, SYSTEM_FROM, LLUUID::null, muted);
- break;
- }
- }
- }
-}
-
-void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
-{
- processIMTypingCore(im_info, TRUE);
-}
-
-void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
-{
- processIMTypingCore(im_info, FALSE);
-}
-
-void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
-{
- LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
- LLFloaterIMPanel* floater = findFloaterBySession(session_id);
- if (floater)
- {
- floater->processIMTyping(im_info, typing);
- }
-
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
- if ( im_floater )
- {
- im_floater->processIMTyping(im_info, typing);
- }
-}
-
-class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
-{
-public:
- virtual void describe(Description& desc) const
- {
- desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
- desc.postAPI();
- desc.input(
- "{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string");
- desc.source(__FILE__, __LINE__);
- }
-
- virtual void post(ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLSD body;
- LLUUID temp_session_id;
- LLUUID session_id;
- bool success;
-
- body = input["body"];
- success = body["success"].asBoolean();
- temp_session_id = body["temp_session_id"].asUUID();
-
- if ( success )
- {
- session_id = body["session_id"].asUUID();
-
- LLIMModel::getInstance()->processSessionInitializedReply(temp_session_id, session_id);
-
- LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
- if (speaker_mgr)
- {
- speaker_mgr->setSpeakers(body);
- speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
- }
-
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
- if (floaterp)
- {
- if ( body.has("session_info") )
- {
- floaterp->processSessionUpdate(body["session_info"]);
- }
- }
-
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
- if ( im_floater )
- {
- if ( body.has("session_info") )
- {
- im_floater->processSessionUpdate(body["session_info"]);
- }
- }
-
- gIMMgr->clearPendingAgentListUpdates(session_id);
- }
- else
- {
- //throw an error dialog and close the temp session's floater
- gIMMgr->showSessionStartError(body["error"].asString(), temp_session_id);
- }
-
- gIMMgr->clearPendingAgentListUpdates(session_id);
- }
-};
-
-class LLViewerChatterBoxSessionEventReply : public LLHTTPNode
-{
-public:
- virtual void describe(Description& desc) const
- {
- desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
- desc.postAPI();
- desc.input(
- "{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID");
- desc.source(__FILE__, __LINE__);
- }
-
- virtual void post(ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLUUID session_id;
- bool success;
-
- LLSD body = input["body"];
- success = body["success"].asBoolean();
- session_id = body["session_id"].asUUID();
-
- if ( !success )
- {
- //throw an error dialog
- gIMMgr->showSessionEventError(
- body["event"].asString(),
- body["error"].asString(),
- session_id);
- }
- }
-};
-
-class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
-{
-public:
- virtual void post(ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- LLUUID session_id;
- std::string reason;
-
- session_id = input["body"]["session_id"].asUUID();
- reason = input["body"]["reason"].asString();
-
- gIMMgr->showSessionForceClose(reason, session_id);
- }
-};
-
-class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
-{
-public:
- virtual void post(
- ResponsePtr responder,
- const LLSD& context,
- const LLSD& input) const
- {
- const LLUUID& session_id = input["body"]["session_id"].asUUID();
- gIMMgr->processAgentListUpdates(session_id, input["body"]);
- }
-};
-
-class LLViewerChatterBoxSessionUpdate : public LLHTTPNode
-{
-public:
- virtual void post(
- ResponsePtr responder,
- const LLSD& context,
- const LLSD& input) const
- {
- LLUUID session_id = input["body"]["session_id"].asUUID();
- LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
- if (floaterp)
- {
- floaterp->processSessionUpdate(input["body"]["info"]);
- }
- LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
- if ( im_floater )
- {
- im_floater->processSessionUpdate(input["body"]["info"]);
- }
- }
-};
-
-
-class LLViewerChatterBoxInvitation : public LLHTTPNode
-{
-public:
-
- virtual void post(
- ResponsePtr response,
- const LLSD& context,
- const LLSD& input) const
- {
- //for backwards compatiblity reasons...we need to still
- //check for 'text' or 'voice' invitations...bleh
- if ( input["body"].has("instantmessage") )
- {
- LLSD message_params =
- input["body"]["instantmessage"]["message_params"];
-
- //do something here to have the IM invite behave
- //just like a normal IM
- //this is just replicated code from process_improved_im
- //and should really go in it's own function -jwolk
- if (gNoRender)
- {
- return;
- }
- LLChat chat;
-
- std::string message = message_params["message"].asString();
- std::string name = message_params["from_name"].asString();
- LLUUID from_id = message_params["from_id"].asUUID();
- LLUUID session_id = message_params["id"].asUUID();
- std::vector<U8> bin_bucket = message_params["data"]["binary_bucket"].asBinary();
- U8 offline = (U8)message_params["offline"].asInteger();
-
- time_t timestamp =
- (time_t) message_params["timestamp"].asInteger();
-
- BOOL is_busy = gAgent.getBusy();
- BOOL is_muted = LLMuteList::getInstance()->isMuted(
- from_id,
- name,
- LLMute::flagTextChat);
-
- BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
- std::string separator_string(": ");
-
- chat.mMuted = is_muted && !is_linden;
- chat.mFromID = from_id;
- chat.mFromName = name;
-
- if (!is_linden && (is_busy || is_muted))
- {
- return;
- }
-
- // standard message, not from system
- std::string saved;
- if(offline == IM_OFFLINE)
- {
- saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
- }
- std::string buffer = saved + message;
-
- BOOL is_this_agent = FALSE;
- if(from_id == gAgentID)
- {
- is_this_agent = TRUE;
- }
- gIMMgr->addMessage(
- session_id,
- from_id,
- name,
- buffer,
- std::string((char*)&bin_bucket[0]),
- IM_SESSION_INVITE,
- message_params["parent_estate_id"].asInteger(),
- message_params["region_id"].asUUID(),
- ll_vector3_from_sd(message_params["position"]),
- true);
-
- chat.mText = std::string("IM: ") + name + separator_string + saved + message;
- LLFloaterChat::addChat(chat, TRUE, is_this_agent);
-
- //K now we want to accept the invitation
- std::string url = gAgent.getRegion()->getCapability(
- "ChatSessionRequest");
-
- if ( url != "" )
- {
- LLSD data;
- data["method"] = "accept invitation";
- data["session-id"] = session_id;
- LLHTTPClient::post(
- url,
- data,
- new LLViewerChatterBoxInvitationAcceptResponder(
- session_id,
- LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
- }
- } //end if invitation has instant message
- else if ( input["body"].has("voice") )
- {
- if (gNoRender)
- {
- return;
- }
-
- if(!LLVoiceClient::voiceEnabled())
- {
- // Don't display voice invites unless the user has voice enabled.
- return;
- }
-
- gIMMgr->inviteToSession(
- input["body"]["session_id"].asUUID(),
- input["body"]["session_name"].asString(),
- input["body"]["from_id"].asUUID(),
- input["body"]["from_name"].asString(),
- IM_SESSION_INVITE,
- LLIMMgr::INVITATION_TYPE_VOICE);
- }
- else if ( input["body"].has("immediate") )
- {
- gIMMgr->inviteToSession(
- input["body"]["session_id"].asUUID(),
- input["body"]["session_name"].asString(),
- input["body"]["from_id"].asUUID(),
- input["body"]["from_name"].asString(),
- IM_SESSION_INVITE,
- LLIMMgr::INVITATION_TYPE_IMMEDIATE);
- }
- }
-};
-
-LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>
- gHTTPRegistrationMessageChatterboxsessionstartreply(
- "/message/ChatterBoxSessionStartReply");
-
-LLHTTPRegistration<LLViewerChatterBoxSessionEventReply>
- gHTTPRegistrationMessageChatterboxsessioneventreply(
- "/message/ChatterBoxSessionEventReply");
-
-LLHTTPRegistration<LLViewerForceCloseChatterBoxSession>
- gHTTPRegistrationMessageForceclosechatterboxsession(
- "/message/ForceCloseChatterBoxSession");
-
-LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates>
- gHTTPRegistrationMessageChatterboxsessionagentlistupdates(
- "/message/ChatterBoxSessionAgentListUpdates");
-
-LLHTTPRegistration<LLViewerChatterBoxSessionUpdate>
- gHTTPRegistrationMessageChatterBoxSessionUpdate(
- "/message/ChatterBoxSessionUpdate");
-
-LLHTTPRegistration<LLViewerChatterBoxInvitation>
- gHTTPRegistrationMessageChatterBoxInvitation(
- "/message/ChatterBoxInvitation");
-
+#include "llresmgr.h"
+#include "llfloaterchat.h"
+#include "llfloaterchatterbox.h"
+#include "llavataractions.h"
+#include "llhttpnode.h"
+#include "llimfloater.h"
+#include "llimpanel.h"
+#include "llresizebar.h"
+#include "lltabcontainer.h"
+#include "llviewercontrol.h"
+#include "llfloater.h"
+#include "llmutelist.h"
+#include "llresizehandle.h"
+#include "llkeyboard.h"
+#include "llui.h"
+#include "llviewermenu.h"
+#include "llcallingcard.h"
+#include "lltoolbar.h"
+#include "llviewermessage.h"
+#include "llviewerwindow.h"
+#include "llnotify.h"
+#include "llviewerregion.h"
+#include "llvoicechannel.h"
+#include "lltrans.h"
+#include "llrecentpeople.h"
+#include "llsyswellwindow.h"
+
+#include "llfirstuse.h"
+#include "llagentui.h"
+
+//
+// Globals
+//
+LLIMMgr* gIMMgr = NULL;
+
+//
+// Statics
+//
+// *FIXME: make these all either UIStrings or Strings
+
+const static std::string IM_SEPARATOR(": ");
+
+
+void toast_callback(const LLSD& msg){
+ // do not show toast in busy mode or it goes from agent
+ if (gAgent.getBusy() || gAgent.getID() == msg["from_id"])
+ {
+ return;
+ }
+
+ // check whether incoming IM belongs to an active session or not
+ if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
+ {
+ return;
+ }
+
+ // Skip toasting for system messages
+ if (msg["from_id"].asUUID() == LLUUID::null)
+ {
+ return;
+ }
+
+ LLSD args;
+ args["MESSAGE"] = msg["message"];
+ args["TIME"] = msg["time"];
+ args["FROM"] = msg["from"];
+ args["FROM_ID"] = msg["from_id"];
+ args["SESSION_ID"] = msg["session_id"];
+
+ LLNotifications::instance().add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
+}
+
+void LLIMModel::setActiveSessionID(const LLUUID& session_id)
+{
+ // check if such an ID really exists
+ if (!findIMSession(session_id))
+ {
+ llwarns << "Trying to set as active a non-existent session!" << llendl;
+ return;
+ }
+
+ mActiveSessionID = session_id;
+}
+
+LLIMModel::LLIMModel()
+{
+ addNewMsgCallback(LLIMFloater::newIMCallback);
+ addNewMsgCallback(toast_callback);
+}
+
+LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids)
+: mSessionID(session_id),
+ mName(name),
+ mType(type),
+ mNumUnread(0),
+ mOtherParticipantID(other_participant_id),
+ mInitialTargetIDs(ids),
+ mVoiceChannel(NULL),
+ mSpeakers(NULL),
+ mSessionInitialized(false),
+ mCallBackEnabled(true),
+ mTextIMPossible(true),
+ mOtherParticipantIsAvatar(true)
+{
+ if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
+ {
+ mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id);
+ }
+ else
+ {
+ mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
+ }
+ mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+
+ // All participants will be added to the list of people we've recently interacted with.
+ mSpeakers->addListener(&LLRecentPeople::instance(), "add");
+
+ //we need to wait for session initialization for outgoing ad-hoc and group chat session
+ //correct session id for initiated ad-hoc chat will be received from the server
+ if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID,
+ mInitialTargetIDs, mType))
+ {
+ //we don't need to wait for any responses
+ //so we're already initialized
+ mSessionInitialized = true;
+ }
+
+ if (IM_NOTHING_SPECIAL == type)
+ {
+ mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionID);
+ mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID);
+ mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID);
+ }
+
+ if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+ LLLogChat::loadHistory(mName, &chatFromLogFile, (void *)this);
+}
+
+LLIMModel::LLIMSession::~LLIMSession()
+{
+ delete mSpeakers;
+ mSpeakers = NULL;
+
+ // End the text IM session if necessary
+ if(gVoiceClient && mOtherParticipantID.notNull())
+ {
+ switch(mType)
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_SESSION_P2P_INVITE:
+ gVoiceClient->endUserIMSession(mOtherParticipantID);
+ break;
+
+ default:
+ // Appease the linux compiler
+ break;
+ }
+ }
+
+ // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
+ mVoiceChannel->deactivate();
+
+ delete mVoiceChannel;
+ mVoiceChannel = NULL;
+}
+
+void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_id)
+{
+ mSessionInitialized = true;
+
+ if (new_session_id != mSessionID)
+ {
+ mSessionID = new_session_id;
+ mVoiceChannel->updateSessionID(new_session_id);
+ }
+}
+
+void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time)
+{
+ LLSD message;
+ message["from"] = from;
+ message["from_id"] = from_id;
+ message["message"] = utf8_text;
+ message["time"] = time;
+ message["index"] = (LLSD::Integer)mMsgs.size();
+
+ mMsgs.push_front(message);
+
+ if (mSpeakers && from_id.notNull())
+ {
+ mSpeakers->speakerChatted(from_id);
+ mSpeakers->setSpeakerTyping(from_id, FALSE);
+ }
+}
+
+void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata)
+{
+ if (!userdata) return;
+
+ LLIMSession* self = (LLIMSession*) userdata;
+
+ if (type == LLLogChat::LOG_LINE)
+ {
+ self->addMessage("", LLSD(), msg["message"].asString(), "");
+ }
+ else if (type == LLLogChat::LOG_LLSD)
+ {
+ self->addMessage(msg["from"].asString(), msg["from_id"].asUUID(), msg["message"].asString(), msg["time"].asString());
+ }
+}
+
+LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
+{
+ return get_if_there(mId2SessionMap, session_id,
+ (LLIMModel::LLIMSession*) NULL);
+}
+
+void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+ LLIMSession* session = findIMSession(old_session_id);
+ if (session)
+ {
+ session->sessionInitReplyReceived(new_session_id);
+
+ if (old_session_id != new_session_id)
+ {
+ mId2SessionMap.erase(old_session_id);
+ mId2SessionMap[new_session_id] = session;
+
+ gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
+ }
+
+ LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
+ if (im_floater)
+ {
+ im_floater->sessionInitReplyReceived(new_session_id);
+ }
+ }
+
+ //*TODO remove this "floater" stuff when Communicate Floater is gone
+ LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(old_session_id);
+ if (floater)
+ {
+ floater->sessionInitReplyReceived(new_session_id);
+ }
+}
+
+void LLIMModel::testMessages()
+{
+ LLUUID bot1_id("d0426ec6-6535-4c11-a5d9-526bb0c654d9");
+ LLUUID bot1_session_id;
+ std::string from = "IM Tester";
+
+ bot1_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot1_id);
+ newSession(bot1_session_id, from, IM_NOTHING_SPECIAL, bot1_id);
+ addMessage(bot1_session_id, from, bot1_id, "Test Message: Hi from testerbot land!");
+
+ LLUUID bot2_id;
+ std::string firstname[] = {"Roflcopter", "Joe"};
+ std::string lastname[] = {"Linden", "Tester", "Resident", "Schmoe"};
+
+ S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]);
+ S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]);
+
+ from = firstname[rand1] + " " + lastname[rand2];
+ bot2_id.generate(from);
+ LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id);
+ newSession(bot2_session_id, from, IM_NOTHING_SPECIAL, bot2_id);
+ addMessage(bot2_session_id, from, bot2_id, "Test Message: Hello there, I have a question. Can I bother you for a second? ");
+ addMessage(bot2_session_id, from, bot2_id, "Test Message: OMGWTFBBQ.");
+}
+
+
+bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
+ const LLUUID& other_participant_id, const std::vector<LLUUID>& ids)
+{
+ if (findIMSession(session_id))
+ {
+ llwarns << "IM Session " << session_id << " already exists" << llendl;
+ return false;
+ }
+
+ LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids);
+ mId2SessionMap[session_id] = session;
+
+ LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
+
+ return true;
+
+}
+
+bool LLIMModel::clearSession(const LLUUID& session_id)
+{
+ if (mId2SessionMap.find(session_id) == mId2SessionMap.end()) return false;
+ delete (mId2SessionMap[session_id]);
+ mId2SessionMap.erase(session_id);
+ return true;
+}
+
+void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return;
+ }
+
+ int i = session->mMsgs.size() - start_index;
+
+ for (std::list<LLSD>::iterator iter = session->mMsgs.begin();
+ iter != session->mMsgs.end() && i > 0;
+ iter++)
+ {
+ LLSD msg;
+ msg = *iter;
+ messages.push_back(*iter);
+ i--;
+ }
+
+ session->mNumUnread = 0;
+
+ LLSD arg;
+ arg["session_id"] = session_id;
+ arg["num_unread"] = 0;
+ mNoUnreadMsgsSignal(arg);
+}
+
+bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
+
+ LLIMSession* session = findIMSession(session_id);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return false;
+ }
+
+ session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false)); //might want to add date separately
+
+ return true;
+}
+
+bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
+{
+ S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions");
+ if (im_log_option != LOG_CHAT)
+ {
+ if(im_log_option == LOG_BOTH_TOGETHER)
+ {
+ LLLogChat::saveHistory(std::string("chat"), from, from_id, utf8_text);
+ return true;
+ }
+ else
+ {
+ LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), from, from_id, utf8_text);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool LLIMModel::proccessOnlineOfflineNotification(
+ const LLUUID& session_id,
+ const std::string& utf8_text)
+{
+ // Add message to old one floater
+ LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
+ if ( floater )
+ {
+ if ( !utf8_text.empty() )
+ {
+ floater->addHistoryLine(utf8_text, LLUIColorTable::instance().getColor("SystemChatColor"));
+ }
+ }
+ // Add system message to history
+ return addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text);
+}
+
+bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
+ const std::string& utf8_text, bool log2file /* = true */) {
+ LLIMSession* session = findIMSession(session_id);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return false;
+ }
+
+ addToHistory(session_id, from, from_id, utf8_text);
+ if (log2file) logToFile(session_id, from, from_id, utf8_text);
+
+ session->mNumUnread++;
+
+ // notify listeners
+ LLSD arg;
+ arg["session_id"] = session_id;
+ arg["num_unread"] = session->mNumUnread;
+ arg["message"] = utf8_text;
+ arg["from"] = from;
+ arg["from_id"] = from_id;
+ arg["time"] = LLLogChat::timestamp(false);
+ mNewMsgSignal(arg);
+
+ return true;
+}
+
+
+const std::string& LLIMModel::getName(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return LLStringUtil::null;
+ }
+
+ return session->mName;
+}
+
+const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return -1;
+ }
+
+ return session->mNumUnread;
+}
+
+const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return LLUUID::null;
+ }
+
+ return session->mOtherParticipantID;
+}
+
+EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return IM_COUNT;
+ }
+
+ return session->mType;
+}
+
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return NULL;
+ }
+
+ return session->mVoiceChannel;
+}
+
+LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
+{
+ LLIMSession* session = findIMSession(session_id);
+ if (!session)
+ {
+ llwarns << "session " << session_id << "does not exist " << llendl;
+ return NULL;
+ }
+
+ return session->mSpeakers;
+}
+
+
+// TODO get rid of other participant ID
+void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
+{
+ std::string name;
+ LLAgentUI::buildFullname(name);
+
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name,
+ std::string("typing"),
+ IM_ONLINE,
+ (typing ? IM_TYPING_START : IM_TYPING_STOP),
+ session_id);
+ gAgent.sendReliableMessage();
+}
+
+void LLIMModel::sendLeaveSession(const LLUUID& session_id, const LLUUID& other_participant_id)
+{
+ if(session_id.notNull())
+ {
+ std::string name;
+ LLAgentUI::buildFullname(name);
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name,
+ LLStringUtil::null,
+ IM_ONLINE,
+ IM_SESSION_LEAVE,
+ session_id);
+ gAgent.sendReliableMessage();
+ }
+}
+
+//*TODO this method is better be moved to the LLIMMgr
+void LLIMModel::sendMessage(const std::string& utf8_text,
+ const LLUUID& im_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage dialog)
+{
+ std::string name;
+ bool sent = false;
+ LLAgentUI::buildFullname(name);
+
+ const LLRelationship* info = NULL;
+ info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
+
+ U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
+
+ if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
+ {
+ // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice.
+ sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text);
+ }
+
+ if(!sent)
+ {
+ // Send message normally.
+
+ // default to IM_SESSION_SEND unless it's nothing special - in
+ // which case it's probably an IM to everyone.
+ U8 new_dialog = dialog;
+
+ if ( dialog != IM_NOTHING_SPECIAL )
+ {
+ new_dialog = IM_SESSION_SEND;
+ }
+ pack_instant_message(
+ gMessageSystem,
+ gAgent.getID(),
+ FALSE,
+ gAgent.getSessionID(),
+ other_participant_id,
+ name.c_str(),
+ utf8_text.c_str(),
+ offline,
+ (EInstantMessage)new_dialog,
+ im_session_id);
+ gAgent.sendReliableMessage();
+ }
+
+ // If there is a mute list and this is not a group chat...
+ if ( LLMuteList::getInstance() )
+ {
+ // ... the target should not be in our mute list for some message types.
+ // Auto-remove them if present.
+ switch( dialog )
+ {
+ case IM_NOTHING_SPECIAL:
+ case IM_GROUP_INVITATION:
+ case IM_INVENTORY_OFFERED:
+ case IM_SESSION_INVITE:
+ case IM_SESSION_P2P_INVITE:
+ case IM_SESSION_CONFERENCE_START:
+ case IM_SESSION_SEND: // This one is marginal - erring on the side of hearing.
+ case IM_LURE_USER:
+ case IM_GODLIKE_LURE_USER:
+ case IM_FRIENDSHIP_OFFERED:
+ LLMuteList::getInstance()->autoRemove(other_participant_id, LLMuteList::AR_IM);
+ break;
+ default: ; // do nothing
+ }
+ }
+
+ if((dialog == IM_NOTHING_SPECIAL) &&
+ (other_participant_id.notNull()))
+ {
+ // Do we have to replace the /me's here?
+ std::string from;
+ LLAgentUI::buildFullname(from);
+ LLIMModel::getInstance()->addMessage(im_session_id, from, gAgentID, utf8_text);
+
+ //local echo for the legacy communicate panel
+ std::string history_echo;
+ LLAgentUI::buildFullname(history_echo);
+
+ history_echo += ": " + utf8_text;
+
+ LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
+ if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
+
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->speakerChatted(gAgentID);
+ speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+ }
+ }
+
+ // Add the recipient to the recent people list.
+ LLRecentPeople::instance().add(other_participant_id);
+}
+
+void session_starter_helper(
+ const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage im_type)
+{
+ LLMessageSystem *msg = gMessageSystem;
+
+ msg->newMessageFast(_PREHASH_ImprovedInstantMessage);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+
+ msg->nextBlockFast(_PREHASH_MessageBlock);
+ msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
+ msg->addUUIDFast(_PREHASH_ToAgentID, other_participant_id);
+ msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
+ msg->addU8Fast(_PREHASH_Dialog, im_type);
+ msg->addUUIDFast(_PREHASH_ID, temp_session_id);
+ msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
+
+ std::string name;
+ LLAgentUI::buildFullname(name);
+
+ msg->addStringFast(_PREHASH_FromAgentName, name);
+ msg->addStringFast(_PREHASH_Message, LLStringUtil::null);
+ msg->addU32Fast(_PREHASH_ParentEstateID, 0);
+ msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null);
+ msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
+}
+
+void start_deprecated_conference_chat(
+ const LLUUID& temp_session_id,
+ const LLUUID& creator_id,
+ const LLUUID& other_participant_id,
+ const LLSD& agents_to_invite)
+{
+ U8* bucket;
+ U8* pos;
+ S32 count;
+ S32 bucket_size;
+
+ // *FIX: this could suffer from endian issues
+ count = agents_to_invite.size();
+ bucket_size = UUID_BYTES * count;
+ bucket = new U8[bucket_size];
+ pos = bucket;
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ LLUUID agent_id = agents_to_invite[i].asUUID();
+
+ memcpy(pos, &agent_id, UUID_BYTES);
+ pos += UUID_BYTES;
+ }
+
+ session_starter_helper(
+ temp_session_id,
+ other_participant_id,
+ IM_SESSION_CONFERENCE_START);
+
+ gMessageSystem->addBinaryDataFast(
+ _PREHASH_BinaryBucket,
+ bucket,
+ bucket_size);
+
+ gAgent.sendReliableMessage();
+
+ delete[] bucket;
+}
+
+class LLStartConferenceChatResponder : public LLHTTPClient::Responder
+{
+public:
+ LLStartConferenceChatResponder(
+ const LLUUID& temp_session_id,
+ const LLUUID& creator_id,
+ const LLUUID& other_participant_id,
+ const LLSD& agents_to_invite)
+ {
+ mTempSessionID = temp_session_id;
+ mCreatorID = creator_id;
+ mOtherParticipantID = other_participant_id;
+ mAgents = agents_to_invite;
+ }
+
+ virtual void error(U32 statusNum, const std::string& reason)
+ {
+ //try an "old school" way.
+ if ( statusNum == 400 )
+ {
+ start_deprecated_conference_chat(
+ mTempSessionID,
+ mCreatorID,
+ mOtherParticipantID,
+ mAgents);
+ }
+
+ //else throw an error back to the client?
+ //in theory we should have just have these error strings
+ //etc. set up in this file as opposed to the IMMgr,
+ //but the error string were unneeded here previously
+ //and it is not worth the effort switching over all
+ //the possible different language translations
+ }
+
+private:
+ LLUUID mTempSessionID;
+ LLUUID mCreatorID;
+ LLUUID mOtherParticipantID;
+
+ LLSD mAgents;
+};
+
+// Returns true if any messages were sent, false otherwise.
+// Is sort of equivalent to "does the server need to do anything?"
+bool LLIMModel::sendStartSession(
+ const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ const std::vector<LLUUID>& ids,
+ EInstantMessage dialog)
+{
+ if ( dialog == IM_SESSION_GROUP_START )
+ {
+ session_starter_helper(
+ temp_session_id,
+ other_participant_id,
+ dialog);
+ gMessageSystem->addBinaryDataFast(
+ _PREHASH_BinaryBucket,
+ EMPTY_BINARY_BUCKET,
+ EMPTY_BINARY_BUCKET_SIZE);
+ gAgent.sendReliableMessage();
+
+ return true;
+ }
+ else if ( dialog == IM_SESSION_CONFERENCE_START )
+ {
+ LLSD agents;
+ for (int i = 0; i < (S32) ids.size(); i++)
+ {
+ agents.append(ids[i]);
+ }
+
+ //we have a new way of starting conference calls now
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string url = region->getCapability(
+ "ChatSessionRequest");
+ LLSD data;
+ data["method"] = "start conference";
+ data["session-id"] = temp_session_id;
+
+ data["params"] = agents;
+
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLStartConferenceChatResponder(
+ temp_session_id,
+ gAgent.getID(),
+ other_participant_id,
+ data["params"]));
+ }
+ else
+ {
+ start_deprecated_conference_chat(
+ temp_session_id,
+ gAgent.getID(),
+ other_participant_id,
+ agents);
+ }
+
+ //we also need to wait for reply from the server in case of ad-hoc chat (we'll get new session id)
+ return true;
+ }
+
+ return false;
+}
+
+// static
+void LLIMModel::sendSessionInitialized(const LLUUID &session_id)
+{
+ LLIMSession* session = getInstance()->findIMSession(session_id);
+ if (session)
+ {
+ LLSD arg;
+ arg["session_id"] = session_id;
+ getInstance()->mSessionInitializedSignal(arg);
+ }
+}
+
+//
+// Helper Functions
+//
+
+class LLViewerChatterBoxInvitationAcceptResponder :
+ public LLHTTPClient::Responder
+{
+public:
+ LLViewerChatterBoxInvitationAcceptResponder(
+ const LLUUID& session_id,
+ LLIMMgr::EInvitationType invitation_type)
+ {
+ mSessionID = session_id;
+ mInvitiationType = invitation_type;
+ }
+
+ void result(const LLSD& content)
+ {
+ if ( gIMMgr)
+ {
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+ if (speaker_mgr)
+ {
+ //we've accepted our invitation
+ //and received a list of agents that were
+ //currently in the session when the reply was sent
+ //to us. Now, it is possible that there were some agents
+ //to slip in/out between when that message was sent to us
+ //and now.
+
+ //the agent list updates we've received have been
+ //accurate from the time we were added to the session
+ //but unfortunately, our base that we are receiving here
+ //may not be the most up to date. It was accurate at
+ //some point in time though.
+ speaker_mgr->setSpeakers(content);
+
+ //we now have our base of users in the session
+ //that was accurate at some point, but maybe not now
+ //so now we apply all of the udpates we've received
+ //in case of race conditions
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
+ }
+
+ if (LLIMMgr::INVITATION_TYPE_VOICE == mInvitiationType)
+ {
+ gIMMgr->startCall(mSessionID);
+ }
+
+ if ((mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE
+ || mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE)
+ && LLIMModel::getInstance()->findIMSession(mSessionID))
+ {
+ // always open IM window when connecting to voice
+ LLIMFloater::show(mSessionID);
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(mSessionID);
+ gIMMgr->clearPendingInvitation(mSessionID);
+ }
+ }
+
+ void error(U32 statusNum, const std::string& reason)
+ {
+ //throw something back to the viewer here?
+ if ( gIMMgr )
+ {
+ gIMMgr->clearPendingAgentListUpdates(mSessionID);
+ gIMMgr->clearPendingInvitation(mSessionID);
+ if ( 404 == statusNum )
+ {
+ std::string error_string;
+ error_string = "does not exist";
+ gIMMgr->showSessionStartError(error_string, mSessionID);
+ }
+ }
+ }
+
+private:
+ LLUUID mSessionID;
+ LLIMMgr::EInvitationType mInvitiationType;
+};
+
+
+// the other_participant_id is either an agent_id, a group_id, or an inventory
+// folder item_id (collection of calling cards)
+
+// static
+LLUUID LLIMMgr::computeSessionID(
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id)
+{
+ LLUUID session_id;
+ if (IM_SESSION_GROUP_START == dialog)
+ {
+ // slam group session_id to the group_id (other_participant_id)
+ session_id = other_participant_id;
+ }
+ else if (IM_SESSION_CONFERENCE_START == dialog)
+ {
+ session_id.generate();
+ }
+ else if (IM_SESSION_INVITE == dialog)
+ {
+ // use provided session id for invites
+ session_id = other_participant_id;
+ }
+ else
+ {
+ LLUUID agent_id = gAgent.getID();
+ if (other_participant_id == agent_id)
+ {
+ // if we try to send an IM to ourselves then the XOR would be null
+ // so we just make the session_id the same as the agent_id
+ session_id = agent_id;
+ }
+ else
+ {
+ // peer-to-peer or peer-to-asset session_id is the XOR
+ session_id = other_participant_id ^ agent_id;
+ }
+ }
+ return session_id;
+}
+
+inline LLFloater* getFloaterBySessionID(const LLUUID session_id)
+{
+ LLFloater* floater = NULL;
+ if ( gIMMgr )
+ {
+ floater = dynamic_cast < LLFloater* >
+ ( gIMMgr->findFloaterBySession(session_id) );
+ }
+ if ( !floater )
+ {
+ floater = dynamic_cast < LLFloater* >
+ ( LLIMFloater::findInstance(session_id) );
+ }
+ return floater;
+}
+
+void
+LLIMMgr::showSessionStartError(
+ const std::string& error_string,
+ const LLUUID session_id)
+{
+ const LLFloater* floater = getFloaterBySessionID (session_id);
+ if (!floater) return;
+
+ LLSD args;
+ args["REASON"] = LLTrans::getString(error_string);
+ args["RECIPIENT"] = floater->getTitle();
+
+ LLSD payload;
+ payload["session_id"] = session_id;
+
+ LLNotifications::instance().add(
+ "ChatterBoxSessionStartError",
+ args,
+ payload,
+ LLIMMgr::onConfirmForceCloseError);
+}
+
+void
+LLIMMgr::showSessionEventError(
+ const std::string& event_string,
+ const std::string& error_string,
+ const LLUUID session_id)
+{
+ const LLFloater* floater = getFloaterBySessionID (session_id);
+ if (!floater) return;
+
+ LLSD args;
+ args["REASON"] =
+ LLTrans::getString(error_string);
+ args["EVENT"] =
+ LLTrans::getString(event_string);
+ args["RECIPIENT"] = floater->getTitle();
+
+ LLNotifications::instance().add(
+ "ChatterBoxSessionEventError",
+ args);
+}
+
+void
+LLIMMgr::showSessionForceClose(
+ const std::string& reason_string,
+ const LLUUID session_id)
+{
+ const LLFloater* floater = getFloaterBySessionID (session_id);
+ if (!floater) return;
+
+ LLSD args;
+
+ args["NAME"] = floater->getTitle();
+ args["REASON"] = LLTrans::getString(reason_string);
+
+ LLSD payload;
+ payload["session_id"] = session_id;
+
+ LLNotifications::instance().add(
+ "ForceCloseChatterBoxSession",
+ args,
+ payload,
+ LLIMMgr::onConfirmForceCloseError);
+}
+
+//static
+bool
+LLIMMgr::onConfirmForceCloseError(
+ const LLSD& notification,
+ const LLSD& response)
+{
+ //only 1 option really
+ LLUUID session_id = notification["payload"]["session_id"];
+
+ LLFloater* floater = getFloaterBySessionID (session_id);
+ if ( floater )
+ {
+ floater->closeFloater(FALSE);
+ }
+ return false;
+}
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLOutgoingCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLOutgoingCallDialog::LLOutgoingCallDialog(const LLSD& payload) :
+ LLDockableFloater(NULL, false, payload),
+ mPayload(payload)
+{
+}
+
+void LLOutgoingCallDialog::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRectScaled();
+}
+
+void LLOutgoingCallDialog::onOpen(const LLSD& key)
+{
+ // tell the user which voice channel they are leaving
+ if (!mPayload["old_channel_name"].asString().empty())
+ {
+ childSetTextArg("leaving", "[CURRENT_CHAT]", mPayload["old_channel_name"].asString());
+ }
+ else
+ {
+ childSetTextArg("leaving", "[CURRENT_CHAT]", getString("localchat"));
+ }
+
+ std::string callee_name = mPayload["session_name"].asString();
+ if (callee_name == "anonymous")
+ {
+ callee_name = getString("anonymous");
+ }
+
+ setTitle(callee_name);
+
+ LLSD callee_id = mPayload["other_user_id"];
+ childSetTextArg("calling", "[CALLEE_NAME]", callee_name);
+ childSetTextArg("connecting", "[CALLEE_NAME]", callee_name);
+ LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ icon->setValue(callee_id);
+}
+
+
+//static
+void LLOutgoingCallDialog::onCancel(void* user_data)
+{
+ LLOutgoingCallDialog* self = (LLOutgoingCallDialog*)user_data;
+
+ if (!gIMMgr)
+ return;
+
+ LLUUID session_id = self->mPayload["session_id"].asUUID();
+ gIMMgr->endCall(session_id);
+
+ self->closeFloater();
+}
+
+
+BOOL LLOutgoingCallDialog::postBuild()
+{
+ BOOL success = LLDockableFloater::postBuild();
+
+ childSetAction("Cancel", onCancel, this);
+
+ // dock the dialog to the sys well, where other sys messages appear
+ setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
+ this, getDockTongue(), LLDockControl::TOP,
+ boost::bind(&LLOutgoingCallDialog::getAllowedRect, this, _1)));
+
+ return success;
+}
+
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLIncomingCallDialog
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
+ LLDockableFloater(NULL, false, payload),
+ mPayload(payload)
+{
+}
+
+BOOL LLIncomingCallDialog::postBuild()
+{
+ LLDockableFloater::postBuild();
+
+ LLSD caller_id = mPayload["caller_id"];
+ EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
+
+ std::string call_type = getString("VoiceInviteP2P");
+ std::string caller_name = mPayload["caller_name"].asString();
+ if (caller_name == "anonymous")
+ {
+ caller_name = getString("anonymous");
+ }
+
+ setTitle(caller_name + " " + call_type);
+
+ // If it is not a P2P invite, then it's an AdHoc invite
+ if ( type != IM_SESSION_P2P_INVITE )
+ {
+ call_type = getString("VoiceInviteAdHoc");
+ }
+
+ // check to see if this is an Avaline call
+ LLUUID session_id = mPayload["session_id"].asUUID();
+ bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
+ childSetVisible("Start IM", is_avatar); // no IM for avaline
+
+ LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
+ caller_name_widget->setValue(caller_name + " " + call_type);
+ LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+ icon->setValue(caller_id);
+
+ childSetAction("Accept", onAccept, this);
+ childSetAction("Reject", onReject, this);
+ childSetAction("Start IM", onStartIM, this);
+ childSetFocus("Accept");
+
+ return TRUE;
+}
+
+void LLIncomingCallDialog::getAllowedRect(LLRect& rect)
+{
+ rect = gViewerWindow->getWorldViewRectScaled();
+}
+
+void LLIncomingCallDialog::onOpen(const LLSD& key)
+{
+ // tell the user which voice channel they would be leaving
+ LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
+ if (voice && !voice->getSessionName().empty())
+ {
+ childSetTextArg("question", "[CURRENT_CHAT]", voice->getSessionName());
+ }
+ else
+ {
+ childSetTextArg("question", "[CURRENT_CHAT]", getString("localchat"));
+ }
+
+ // dock the dialog to the sys well, where other sys messages appear
+ setDockControl(new LLDockControl(LLBottomTray::getInstance()->getSysWell(),
+ this, getDockTongue(), LLDockControl::TOP,
+ boost::bind(&LLIncomingCallDialog::getAllowedRect, this, _1)));
+}
+
+//static
+void LLIncomingCallDialog::onAccept(void* user_data)
+{
+ LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
+ self->processCallResponse(0);
+ self->closeFloater();
+}
+
+//static
+void LLIncomingCallDialog::onReject(void* user_data)
+{
+ LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
+ self->processCallResponse(1);
+ self->closeFloater();
+}
+
+//static
+void LLIncomingCallDialog::onStartIM(void* user_data)
+{
+ LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
+ self->processCallResponse(2);
+ self->closeFloater();
+}
+
+void LLIncomingCallDialog::processCallResponse(S32 response)
+{
+ if (!gIMMgr)
+ return;
+
+ LLUUID session_id = mPayload["session_id"].asUUID();
+ EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
+ LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)mPayload["inv_type"].asInteger();
+ bool voice = true;
+ switch(response)
+ {
+ case 2: // start IM: just don't start the voice chat
+ {
+ voice = false;
+ /* FALLTHROUGH */
+ }
+ case 0: // accept
+ {
+ if (type == IM_SESSION_P2P_INVITE)
+ {
+ // create a normal IM session
+ session_id = gIMMgr->addP2PSession(
+ mPayload["session_name"].asString(),
+ mPayload["caller_id"].asUUID(),
+ mPayload["session_handle"].asString());
+
+ if (voice)
+ {
+ if (gIMMgr->startCall(session_id))
+ {
+ // always open IM window when connecting to voice
+ LLIMFloater::show(session_id);
+ }
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ gIMMgr->clearPendingInvitation(session_id);
+ }
+ else
+ {
+ LLUUID session_id = gIMMgr->addSession(
+ mPayload["session_name"].asString(),
+ type,
+ session_id);
+ if (session_id != LLUUID::null)
+ {
+ LLIMFloater::show(session_id);
+ }
+
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ if (voice)
+ {
+ LLSD data;
+ data["method"] = "accept invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLViewerChatterBoxInvitationAcceptResponder(
+ session_id,
+ inv_type));
+ }
+ }
+ if (voice)
+ {
+ break;
+ }
+ }
+ case 1: // decline
+ {
+ if (type == IM_SESSION_P2P_INVITE)
+ {
+ if(gVoiceClient)
+ {
+ std::string s = mPayload["session_handle"].asString();
+ gVoiceClient->declineInvite(s);
+ }
+ }
+ else
+ {
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ LLSD data;
+ data["method"] = "decline invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ NULL);
+ }
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ gIMMgr->clearPendingInvitation(session_id);
+ }
+}
+
+bool inviteUserResponse(const LLSD& notification, const LLSD& response)
+{
+ if (!gIMMgr)
+ return false;
+
+ const LLSD& payload = notification["payload"];
+ LLUUID session_id = payload["session_id"].asUUID();
+ EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
+ LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ switch(option)
+ {
+ case 0: // accept
+ {
+ if (type == IM_SESSION_P2P_INVITE)
+ {
+ // create a normal IM session
+ session_id = gIMMgr->addP2PSession(
+ payload["session_name"].asString(),
+ payload["caller_id"].asUUID(),
+ payload["session_handle"].asString(),
+ payload["session_uri"].asString());
+
+ if (gIMMgr->startCall(session_id))
+ {
+ // always open IM window when connecting to voice
+ LLIMFloater::show(session_id);
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ gIMMgr->clearPendingInvitation(session_id);
+ }
+ else
+ {
+ LLUUID session_id = gIMMgr->addSession(
+ payload["session_name"].asString(),
+ type,
+ session_id);
+ if (session_id != LLUUID::null)
+ {
+ LLIMFloater::show(session_id);
+ }
+
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ LLSD data;
+ data["method"] = "accept invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLViewerChatterBoxInvitationAcceptResponder(
+ session_id,
+ inv_type));
+ }
+ }
+ break;
+ case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
+ {
+ // mute the sender of this invite
+ if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID()))
+ {
+ LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT);
+ LLMuteList::getInstance()->add(mute);
+ }
+ }
+ /* FALLTHROUGH */
+
+ case 1: // decline
+ {
+ if (type == IM_SESSION_P2P_INVITE)
+ {
+ if(gVoiceClient)
+ {
+ std::string s = payload["session_handle"].asString();
+ gVoiceClient->declineInvite(s);
+ }
+ }
+ else
+ {
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ LLSD data;
+ data["method"] = "decline invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ NULL);
+ }
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ gIMMgr->clearPendingInvitation(session_id);
+ break;
+ }
+
+ return false;
+}
+
+//
+// Member Functions
+//
+
+LLIMMgr::LLIMMgr() :
+ mIMReceived(FALSE)
+{
+ mPendingInvitations = LLSD::emptyMap();
+ mPendingAgentListUpdates = LLSD::emptyMap();
+}
+
+// Add a message to a session.
+void LLIMMgr::addMessage(
+ const LLUUID& session_id,
+ const LLUUID& target_id,
+ const std::string& from,
+ const std::string& msg,
+ const std::string& session_name,
+ EInstantMessage dialog,
+ U32 parent_estate_id,
+ const LLUUID& region_id,
+ const LLVector3& position,
+ bool link_name) // If this is true, then we insert the name and link it to a profile
+{
+ LLUUID other_participant_id = target_id;
+
+ // don't process muted IMs
+ if (LLMuteList::getInstance()->isMuted(
+ other_participant_id,
+ LLMute::flagTextChat) && !LLMuteList::getInstance()->isLinden(from))
+ {
+ return;
+ }
+
+ LLFloaterIMPanel* floater;
+ LLUUID new_session_id = session_id;
+ if (new_session_id.isNull())
+ {
+ //no session ID...compute new one
+ new_session_id = computeSessionID(dialog, other_participant_id);
+ }
+
+ //*NOTE session_name is empty in case of incoming P2P sessions
+ std::string fixed_session_name = from;
+ if(!session_name.empty() && session_name.size()>1)
+ {
+ fixed_session_name = session_name;
+ }
+
+ bool new_session = !hasSession(new_session_id);
+ if (new_session)
+ {
+ LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id);
+ }
+
+ floater = findFloaterBySession(new_session_id);
+ if (!floater)
+ {
+ floater = findFloaterBySession(other_participant_id);
+ if (floater)
+ {
+ llinfos << "found the IM session " << session_id
+ << " by participant " << other_participant_id << llendl;
+ }
+ }
+
+ // create IM window as necessary
+ if(!floater)
+ {
+ floater = createFloater(
+ new_session_id,
+ other_participant_id,
+ fixed_session_name,
+ dialog,
+ FALSE);
+ }
+
+ if (new_session)
+ {
+ // When we get a new IM, and if you are a god, display a bit
+ // of information about the source. This is to help liaisons
+ // when answering questions.
+ if(gAgent.isGodlike())
+ {
+ // *TODO:translate (low priority, god ability)
+ std::ostringstream bonus_info;
+ bonus_info << LLTrans::getString("***")+ " "+ LLTrans::getString("IMParentEstate") + ":" + " "
+ << parent_estate_id
+ << ((parent_estate_id == 1) ? "," + LLTrans::getString("IMMainland") : "")
+ << ((parent_estate_id == 5) ? "," + LLTrans::getString ("IMTeen") : "");
+
+ // once we have web-services (or something) which returns
+ // information about a region id, we can print this out
+ // and even have it link to map-teleport or something.
+ //<< "*** region_id: " << region_id << std::endl
+ //<< "*** position: " << position << std::endl;
+
+ floater->addHistoryLine(bonus_info.str(), LLUIColorTable::instance().getColor("SystemChatColor"));
+ LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str());
+ }
+
+ make_ui_sound("UISndNewIncomingIMSession");
+ }
+
+ // now add message to floater
+ bool is_from_system = target_id.isNull() || (from == SYSTEM_FROM);
+ const LLColor4& color = ( is_from_system ?
+ LLUIColorTable::instance().getColor("SystemChatColor") :
+ LLUIColorTable::instance().getColor("IMChatColor"));
+ if ( !link_name )
+ {
+ floater->addHistoryLine(msg,color); // No name to prepend, so just add the message normally
+ }
+ else
+ {
+ floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
+ }
+
+ LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
+
+ if( !LLFloaterReg::instanceVisible("communicate") && !floater->getVisible())
+ {
+ LLFloaterChatterBox* chat_floater = LLFloaterChatterBox::getInstance();
+
+ //if the IM window is not open and the floater is not visible (i.e. not torn off)
+ LLFloater* previouslyActiveFloater = chat_floater->getActiveFloater();
+
+ // select the newly added floater (or the floater with the new line added to it).
+ // it should be there.
+ chat_floater->selectFloater(floater);
+
+ //there was a previously unseen IM, make that old tab flashing
+ //it is assumed that the most recently unseen IM tab is the one current selected/active
+ if ( previouslyActiveFloater && getIMReceived() )
+ {
+ chat_floater->setFloaterFlashing(previouslyActiveFloater, TRUE);
+ }
+
+ //notify of a new IM
+ notifyNewIM();
+ }
+}
+
+void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
+{
+ LLUIString message;
+
+ // null session id means near me (chat history)
+ if (session_id.isNull())
+ {
+ message = LLTrans::getString(message_name);
+ message.setArgs(args);
+
+ LLChat chat(message);
+ chat.mSourceType = CHAT_SOURCE_SYSTEM;
+ LLFloaterChat::addChatHistory(chat);
+ }
+ else // going to IM session
+ {
+ if (hasSession(session_id))
+ {
+ message = LLTrans::getString(message_name + "-im");
+ message.setArgs(args);
+ gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
+ }
+ }
+}
+
+void LLIMMgr::notifyNewIM()
+{
+ if(!LLFloaterReg::instanceVisible("communicate"))
+ {
+ mIMReceived = TRUE;
+ }
+}
+
+S32 LLIMMgr::getNumberOfUnreadIM()
+{
+ std::map<LLUUID, LLIMModel::LLIMSession*>::iterator it;
+
+ S32 num = 0;
+ for(it = LLIMModel::getInstance()->mId2SessionMap.begin(); it != LLIMModel::getInstance()->mId2SessionMap.end(); ++it)
+ {
+ num += (*it).second->mNumUnread;
+ }
+
+ return num;
+}
+
+void LLIMMgr::clearNewIMNotification()
+{
+ mIMReceived = FALSE;
+}
+
+BOOL LLIMMgr::getIMReceived() const
+{
+ return mIMReceived;
+}
+
+LLUUID LLIMMgr::addP2PSession(const std::string& name,
+ const LLUUID& other_participant_id,
+ const std::string& voice_session_handle,
+ const std::string& caller_uri)
+{
+ LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
+ if (session_id != LLUUID::null)
+ {
+ LLIMFloater::show(session_id);
+ }
+
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
+ {
+ LLVoiceChannelP2P* voice_channel = dynamic_cast<LLVoiceChannelP2P*>(speaker_mgr->getVoiceChannel());
+ if (voice_channel)
+ {
+ voice_channel->setSessionHandle(voice_session_handle, caller_uri);
+ }
+ }
+ return session_id;
+}
+
+// This adds a session to the talk view. The name is the local name of
+// the session, dialog specifies the type of session. If the session
+// exists, it is brought forward. Specifying id = NULL results in an
+// im session to everyone. Returns the uuid of the session.
+LLUUID LLIMMgr::addSession(
+ const std::string& name,
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id)
+{
+ LLDynamicArray<LLUUID> ids;
+ ids.put(other_participant_id);
+ return addSession(name, dialog, other_participant_id, ids);
+}
+
+// Adds a session using the given session_id. If the session already exists
+// the dialog type is assumed correct. Returns the uuid of the session.
+LLUUID LLIMMgr::addSession(
+ const std::string& name,
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id,
+ const LLDynamicArray<LLUUID>& ids)
+{
+ if (0 == ids.getLength())
+ {
+ return LLUUID::null;
+ }
+
+ LLUUID session_id = computeSessionID(dialog,other_participant_id);
+
+ bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
+
+ if (new_session)
+ {
+ LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids);
+ }
+
+
+ //*TODO remove this "floater" thing when Communicate Floater's gone
+ LLFloaterIMPanel* floater = findFloaterBySession(session_id);
+ if(!floater)
+ {
+ // On creation, use the first element of ids as the
+ // "other_participant_id"
+ floater = createFloater(
+ session_id,
+ other_participant_id,
+ name,
+ dialog,
+ TRUE,
+ ids);
+ }
+
+ //we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
+ if (!new_session) return session_id;
+
+ noteOfflineUsers(session_id, floater, ids);
+
+ // Only warn for regular IMs - not group IMs
+ if( dialog == IM_NOTHING_SPECIAL )
+ {
+ noteMutedUsers(session_id, floater, ids);
+ }
+
+ return session_id;
+}
+
+bool LLIMMgr::leaveSession(const LLUUID& session_id)
+{
+ LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
+ if (!im_session) return false;
+
+ LLIMModel::getInstance()->sendLeaveSession(session_id, im_session->mOtherParticipantID);
+ gIMMgr->removeSession(session_id);
+ return true;
+}
+
+// Removes data associated with a particular session specified by session_id
+void LLIMMgr::removeSession(const LLUUID& session_id)
+{
+ llassert_always(hasSession(session_id));
+
+ //*TODO remove this floater thing when Communicate Floater is being deleted (IB)
+ LLFloaterIMPanel* floater = findFloaterBySession(session_id);
+ if(floater)
+ {
+ mFloaters.erase(floater->getHandle());
+ LLFloaterChatterBox::getInstance()->removeFloater(floater);
+ }
+
+ clearPendingInvitation(session_id);
+ clearPendingAgentListUpdates(session_id);
+
+ LLIMModel::getInstance()->clearSession(session_id);
+
+ notifyObserverSessionRemoved(session_id);
+}
+
+void LLIMMgr::inviteToSession(
+ const LLUUID& session_id,
+ const std::string& session_name,
+ const LLUUID& caller_id,
+ const std::string& caller_name,
+ EInstantMessage type,
+ EInvitationType inv_type,
+ const std::string& session_handle,
+ const std::string& session_uri)
+{
+ //ignore invites from muted residents
+ if (LLMuteList::getInstance()->isMuted(caller_id))
+ {
+ return;
+ }
+
+ std::string notify_box_type;
+
+ BOOL ad_hoc_invite = FALSE;
+ if(type == IM_SESSION_P2P_INVITE)
+ {
+ //P2P is different...they only have voice invitations
+ notify_box_type = "VoiceInviteP2P";
+ }
+ else if ( gAgent.isInGroup(session_id) )
+ {
+ //only really old school groups have voice invitations
+ notify_box_type = "VoiceInviteGroup";
+ }
+ else if ( inv_type == INVITATION_TYPE_VOICE )
+ {
+ //else it's an ad-hoc
+ //and a voice ad-hoc
+ notify_box_type = "VoiceInviteAdHoc";
+ ad_hoc_invite = TRUE;
+ }
+ else if ( inv_type == INVITATION_TYPE_IMMEDIATE )
+ {
+ notify_box_type = "InviteAdHoc";
+ ad_hoc_invite = TRUE;
+ }
+
+ LLSD payload;
+ payload["session_id"] = session_id;
+ payload["session_name"] = session_name;
+ payload["caller_id"] = caller_id;
+ payload["caller_name"] = caller_name;
+ payload["type"] = type;
+ payload["inv_type"] = inv_type;
+ payload["session_handle"] = session_handle;
+ payload["session_uri"] = session_uri;
+ payload["notify_box_type"] = notify_box_type;
+
+ LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
+ if (channelp && channelp->callStarted())
+ {
+ // you have already started a call to the other user, so just accept the invite
+ LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
+ return;
+ }
+
+ if (type == IM_SESSION_P2P_INVITE || ad_hoc_invite)
+ {
+ // is the inviter a friend?
+ if (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)
+ {
+ // if not, and we are ignoring voice invites from non-friends
+ // then silently decline
+ if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
+ {
+ // invite not from a friend, so decline
+ LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
+ return;
+ }
+ }
+ }
+
+ if ( !mPendingInvitations.has(session_id.asString()) )
+ {
+ if (caller_name.empty())
+ {
+ gCacheName->get(caller_id, FALSE, boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3, _4));
+ }
+ else
+ {
+ if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
+ {
+ LLFloaterReg::showInstance("incoming_call", payload, TRUE);
+ }
+ else
+ {
+ LLSD args;
+ args["NAME"] = caller_name;
+ args["GROUP"] = session_name;
+
+ LLNotifications::instance().add(notify_box_type, args, payload, &inviteUserResponse);
+ }
+ }
+ mPendingInvitations[session_id.asString()] = LLSD();
+ }
+}
+
+void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group)
+{
+ payload["caller_name"] = first + " " + last;
+ payload["session_name"] = payload["caller_name"].asString();
+
+ std::string notify_box_type = payload["notify_box_type"].asString();
+
+ if (notify_box_type == "VoiceInviteP2P" || notify_box_type == "VoiceInviteAdHoc")
+ {
+ LLFloaterReg::showInstance("incoming_call", payload, TRUE);
+ }
+ else
+ {
+ LLSD args;
+ args["NAME"] = payload["caller_name"].asString();
+
+ LLNotifications::instance().add(
+ payload["notify_box_type"].asString(),
+ args,
+ payload,
+ &inviteUserResponse);
+ }
+}
+
+void LLIMMgr::disconnectAllSessions()
+{
+ LLFloaterIMPanel* floater = NULL;
+ std::set<LLHandle<LLFloater> >::iterator handle_it;
+ for(handle_it = mFloaters.begin();
+ handle_it != mFloaters.end();
+ )
+ {
+ floater = (LLFloaterIMPanel*)handle_it->get();
+
+ // MUST do this BEFORE calling floater->onClose() because that may remove the item from the set, causing the subsequent increment to crash.
+ ++handle_it;
+
+ if (floater)
+ {
+ floater->setEnabled(FALSE);
+ floater->closeFloater(TRUE);
+ }
+ }
+}
+
+
+// This method returns the im panel corresponding to the uuid
+// provided. The uuid can either be a session id or an agent
+// id. Returns NULL if there is no matching panel.
+LLFloaterIMPanel* LLIMMgr::findFloaterBySession(const LLUUID& session_id)
+{
+ LLFloaterIMPanel* rv = NULL;
+ std::set<LLHandle<LLFloater> >::iterator handle_it;
+ for(handle_it = mFloaters.begin();
+ handle_it != mFloaters.end();
+ ++handle_it)
+ {
+ rv = (LLFloaterIMPanel*)handle_it->get();
+ if(rv && session_id == rv->getSessionID())
+ {
+ break;
+ }
+ rv = NULL;
+ }
+ return rv;
+}
+
+
+BOOL LLIMMgr::hasSession(const LLUUID& session_id)
+{
+ return LLIMModel::getInstance()->findIMSession(session_id) != NULL;
+}
+
+void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
+{
+ if ( mPendingInvitations.has(session_id.asString()) )
+ {
+ mPendingInvitations.erase(session_id.asString());
+ }
+}
+
+void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
+{
+ LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ if ( im_floater )
+ {
+ im_floater->processAgentListUpdates(body);
+ }
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->updateSpeakers(body);
+ }
+ else
+ {
+ //we don't have a speaker manager yet..something went wrong
+ //we are probably receiving an update here before
+ //a start or an acceptance of an invitation. Race condition.
+ gIMMgr->addPendingAgentListUpdates(
+ session_id,
+ body);
+ }
+}
+
+LLSD LLIMMgr::getPendingAgentListUpdates(const LLUUID& session_id)
+{
+ if ( mPendingAgentListUpdates.has(session_id.asString()) )
+ {
+ return mPendingAgentListUpdates[session_id.asString()];
+ }
+ else
+ {
+ return LLSD();
+ }
+}
+
+void LLIMMgr::addPendingAgentListUpdates(
+ const LLUUID& session_id,
+ const LLSD& updates)
+{
+ LLSD::map_const_iterator iter;
+
+ if ( !mPendingAgentListUpdates.has(session_id.asString()) )
+ {
+ //this is a new agent list update for this session
+ mPendingAgentListUpdates[session_id.asString()] = LLSD::emptyMap();
+ }
+
+ if (
+ updates.has("agent_updates") &&
+ updates["agent_updates"].isMap() &&
+ updates.has("updates") &&
+ updates["updates"].isMap() )
+ {
+ //new school update
+ LLSD update_types = LLSD::emptyArray();
+ LLSD::array_iterator array_iter;
+
+ update_types.append("agent_updates");
+ update_types.append("updates");
+
+ for (
+ array_iter = update_types.beginArray();
+ array_iter != update_types.endArray();
+ ++array_iter)
+ {
+ //we only want to include the last update for a given agent
+ for (
+ iter = updates[array_iter->asString()].beginMap();
+ iter != updates[array_iter->asString()].endMap();
+ ++iter)
+ {
+ mPendingAgentListUpdates[session_id.asString()][array_iter->asString()][iter->first] =
+ iter->second;
+ }
+ }
+ }
+ else if (
+ updates.has("updates") &&
+ updates["updates"].isMap() )
+ {
+ //old school update where the SD contained just mappings
+ //of agent_id -> "LEAVE"/"ENTER"
+
+ //only want to keep last update for each agent
+ for (
+ iter = updates["updates"].beginMap();
+ iter != updates["updates"].endMap();
+ ++iter)
+ {
+ mPendingAgentListUpdates[session_id.asString()]["updates"][iter->first] =
+ iter->second;
+ }
+ }
+}
+
+void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
+{
+ if ( mPendingAgentListUpdates.has(session_id.asString()) )
+ {
+ mPendingAgentListUpdates.erase(session_id.asString());
+ }
+}
+
+void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+ {
+ (*it)->sessionAdded(session_id, name, other_participant_id);
+ }
+}
+
+void LLIMMgr::notifyObserverSessionRemoved(const LLUUID& session_id)
+{
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+ {
+ (*it)->sessionRemoved(session_id);
+ }
+}
+
+void LLIMMgr::notifyObserverSessionIDUpdated( const LLUUID& old_session_id, const LLUUID& new_session_id )
+{
+ for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+ {
+ (*it)->sessionIDUpdated(old_session_id, new_session_id);
+ }
+
+}
+
+void LLIMMgr::addSessionObserver(LLIMSessionObserver *observer)
+{
+ mSessionObservers.push_back(observer);
+}
+
+void LLIMMgr::removeSessionObserver(LLIMSessionObserver *observer)
+{
+ mSessionObservers.remove(observer);
+}
+
+bool LLIMMgr::startCall(const LLUUID& session_id)
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
+ if (!voice_channel) return false;
+
+ voice_channel->activate();
+ return true;
+}
+
+bool LLIMMgr::endCall(const LLUUID& session_id)
+{
+ LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
+ if (!voice_channel) return false;
+
+ voice_channel->deactivate();
+ return true;
+}
+
+// create a floater and update internal representation for
+// consistency. Returns the pointer, caller (the class instance since
+// it is a private method) is not responsible for deleting the
+// pointer. Add the floater to this but do not select it.
+LLFloaterIMPanel* LLIMMgr::createFloater(
+ const LLUUID& session_id,
+ const LLUUID& other_participant_id,
+ const std::string& session_label,
+ EInstantMessage dialog,
+ BOOL user_initiated,
+ const LLDynamicArray<LLUUID>& ids)
+{
+ if (session_id.isNull())
+ {
+ llwarns << "Creating LLFloaterIMPanel with null session ID" << llendl;
+ }
+
+ llinfos << "LLIMMgr::createFloater: from " << other_participant_id
+ << " in session " << session_id << llendl;
+ LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
+ session_id,
+ other_participant_id,
+ ids,
+ dialog);
+ LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
+ LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
+ mFloaters.insert(floater->getHandle());
+ return floater;
+}
+
+void LLIMMgr::noteOfflineUsers(
+ const LLUUID& session_id,
+ LLFloaterIMPanel* floater,
+ const LLDynamicArray<LLUUID>& ids)
+{
+ S32 count = ids.count();
+ if(count == 0)
+ {
+ const std::string& only_user = LLTrans::getString("only_user_message");
+ if (floater)
+ {
+ floater->addHistoryLine(only_user, LLUIColorTable::instance().getColor("SystemChatColor"));
+ }
+ LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, only_user);
+ }
+ else
+ {
+ const LLRelationship* info = NULL;
+ LLAvatarTracker& at = LLAvatarTracker::instance();
+ LLIMModel& im_model = LLIMModel::instance();
+ for(S32 i = 0; i < count; ++i)
+ {
+ info = at.getBuddyInfo(ids.get(i));
+ std::string first, last;
+ if(info && !info->isOnline()
+ && gCacheName->getName(ids.get(i), first, last))
+ {
+ LLUIString offline = LLTrans::getString("offline_message");
+ offline.setArg("[FIRST]", first);
+ offline.setArg("[LAST]", last);
+ im_model.proccessOnlineOfflineNotification(session_id, offline);
+ }
+ }
+ }
+}
+
+void LLIMMgr::noteMutedUsers(const LLUUID& session_id, LLFloaterIMPanel* floater,
+ const LLDynamicArray<LLUUID>& ids)
+{
+ // Don't do this if we don't have a mute list.
+ LLMuteList *ml = LLMuteList::getInstance();
+ if( !ml )
+ {
+ return;
+ }
+
+ S32 count = ids.count();
+ if(count > 0)
+ {
+ LLIMModel* im_model = LLIMModel::getInstance();
+
+ for(S32 i = 0; i < count; ++i)
+ {
+ if( ml->isMuted(ids.get(i)) )
+ {
+ LLUIString muted = LLTrans::getString("muted_message");
+
+ //*TODO remove this "floater" thing when Communicate Floater's gone
+ floater->addHistoryLine(muted);
+
+ im_model->addMessage(session_id, SYSTEM_FROM, LLUUID::null, muted);
+ break;
+ }
+ }
+ }
+}
+
+void LLIMMgr::processIMTypingStart(const LLIMInfo* im_info)
+{
+ processIMTypingCore(im_info, TRUE);
+}
+
+void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
+{
+ processIMTypingCore(im_info, FALSE);
+}
+
+void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
+{
+ LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
+ LLFloaterIMPanel* floater = findFloaterBySession(session_id);
+ if (floater)
+ {
+ floater->processIMTyping(im_info, typing);
+ }
+
+ LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ if ( im_floater )
+ {
+ im_floater->processIMTyping(im_info, typing);
+ }
+}
+
+class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
+{
+public:
+ virtual void describe(Description& desc) const
+ {
+ desc.shortInfo("Used for receiving a reply to a request to initialize an ChatterBox session");
+ desc.postAPI();
+ desc.input(
+ "{\"client_session_id\": UUID, \"session_id\": UUID, \"success\" boolean, \"reason\": string");
+ desc.source(__FILE__, __LINE__);
+ }
+
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLSD body;
+ LLUUID temp_session_id;
+ LLUUID session_id;
+ bool success;
+
+ body = input["body"];
+ success = body["success"].asBoolean();
+ temp_session_id = body["temp_session_id"].asUUID();
+
+ if ( success )
+ {
+ session_id = body["session_id"].asUUID();
+
+ LLIMModel::getInstance()->processSessionInitializedReply(temp_session_id, session_id);
+
+ LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+ if (speaker_mgr)
+ {
+ speaker_mgr->setSpeakers(body);
+ speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
+ }
+
+ LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
+ if (floaterp)
+ {
+ if ( body.has("session_info") )
+ {
+ floaterp->processSessionUpdate(body["session_info"]);
+ }
+ }
+
+ LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ if ( im_floater )
+ {
+ if ( body.has("session_info") )
+ {
+ im_floater->processSessionUpdate(body["session_info"]);
+ }
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ }
+ else
+ {
+ //throw an error dialog and close the temp session's floater
+ gIMMgr->showSessionStartError(body["error"].asString(), temp_session_id);
+ }
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
+ }
+};
+
+class LLViewerChatterBoxSessionEventReply : public LLHTTPNode
+{
+public:
+ virtual void describe(Description& desc) const
+ {
+ desc.shortInfo("Used for receiving a reply to a ChatterBox session event");
+ desc.postAPI();
+ desc.input(
+ "{\"event\": string, \"reason\": string, \"success\": boolean, \"session_id\": UUID");
+ desc.source(__FILE__, __LINE__);
+ }
+
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLUUID session_id;
+ bool success;
+
+ LLSD body = input["body"];
+ success = body["success"].asBoolean();
+ session_id = body["session_id"].asUUID();
+
+ if ( !success )
+ {
+ //throw an error dialog
+ gIMMgr->showSessionEventError(
+ body["event"].asString(),
+ body["error"].asString(),
+ session_id);
+ }
+ }
+};
+
+class LLViewerForceCloseChatterBoxSession: public LLHTTPNode
+{
+public:
+ virtual void post(ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLUUID session_id;
+ std::string reason;
+
+ session_id = input["body"]["session_id"].asUUID();
+ reason = input["body"]["reason"].asString();
+
+ gIMMgr->showSessionForceClose(reason, session_id);
+ }
+};
+
+class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
+{
+public:
+ virtual void post(
+ ResponsePtr responder,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ const LLUUID& session_id = input["body"]["session_id"].asUUID();
+ gIMMgr->processAgentListUpdates(session_id, input["body"]);
+ }
+};
+
+class LLViewerChatterBoxSessionUpdate : public LLHTTPNode
+{
+public:
+ virtual void post(
+ ResponsePtr responder,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLUUID session_id = input["body"]["session_id"].asUUID();
+ LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
+ if (floaterp)
+ {
+ floaterp->processSessionUpdate(input["body"]["info"]);
+ }
+ LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+ if ( im_floater )
+ {
+ im_floater->processSessionUpdate(input["body"]["info"]);
+ }
+ }
+};
+
+
+class LLViewerChatterBoxInvitation : public LLHTTPNode
+{
+public:
+
+ virtual void post(
+ ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ //for backwards compatiblity reasons...we need to still
+ //check for 'text' or 'voice' invitations...bleh
+ if ( input["body"].has("instantmessage") )
+ {
+ LLSD message_params =
+ input["body"]["instantmessage"]["message_params"];
+
+ //do something here to have the IM invite behave
+ //just like a normal IM
+ //this is just replicated code from process_improved_im
+ //and should really go in it's own function -jwolk
+ if (gNoRender)
+ {
+ return;
+ }
+ LLChat chat;
+
+ std::string message = message_params["message"].asString();
+ std::string name = message_params["from_name"].asString();
+ LLUUID from_id = message_params["from_id"].asUUID();
+ LLUUID session_id = message_params["id"].asUUID();
+ std::vector<U8> bin_bucket = message_params["data"]["binary_bucket"].asBinary();
+ U8 offline = (U8)message_params["offline"].asInteger();
+
+ time_t timestamp =
+ (time_t) message_params["timestamp"].asInteger();
+
+ BOOL is_busy = gAgent.getBusy();
+ BOOL is_muted = LLMuteList::getInstance()->isMuted(
+ from_id,
+ name,
+ LLMute::flagTextChat);
+
+ BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
+ std::string separator_string(": ");
+
+ chat.mMuted = is_muted && !is_linden;
+ chat.mFromID = from_id;
+ chat.mFromName = name;
+
+ if (!is_linden && (is_busy || is_muted))
+ {
+ return;
+ }
+
+ // standard message, not from system
+ std::string saved;
+ if(offline == IM_OFFLINE)
+ {
+ saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+ }
+ std::string buffer = saved + message;
+
+ BOOL is_this_agent = FALSE;
+ if(from_id == gAgentID)
+ {
+ is_this_agent = TRUE;
+ }
+ gIMMgr->addMessage(
+ session_id,
+ from_id,
+ name,
+ buffer,
+ std::string((char*)&bin_bucket[0]),
+ IM_SESSION_INVITE,
+ message_params["parent_estate_id"].asInteger(),
+ message_params["region_id"].asUUID(),
+ ll_vector3_from_sd(message_params["position"]),
+ true);
+
+ chat.mText = std::string("IM: ") + name + separator_string + saved + message;
+ LLFloaterChat::addChat(chat, TRUE, is_this_agent);
+
+ //K now we want to accept the invitation
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ if ( url != "" )
+ {
+ LLSD data;
+ data["method"] = "accept invitation";
+ data["session-id"] = session_id;
+ LLHTTPClient::post(
+ url,
+ data,
+ new LLViewerChatterBoxInvitationAcceptResponder(
+ session_id,
+ LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
+ }
+ } //end if invitation has instant message
+ else if ( input["body"].has("voice") )
+ {
+ if (gNoRender)
+ {
+ return;
+ }
+
+ if(!LLVoiceClient::voiceEnabled())
+ {
+ // Don't display voice invites unless the user has voice enabled.
+ return;
+ }
+
+ gIMMgr->inviteToSession(
+ input["body"]["session_id"].asUUID(),
+ input["body"]["session_name"].asString(),
+ input["body"]["from_id"].asUUID(),
+ input["body"]["from_name"].asString(),
+ IM_SESSION_INVITE,
+ LLIMMgr::INVITATION_TYPE_VOICE);
+ }
+ else if ( input["body"].has("immediate") )
+ {
+ gIMMgr->inviteToSession(
+ input["body"]["session_id"].asUUID(),
+ input["body"]["session_name"].asString(),
+ input["body"]["from_id"].asUUID(),
+ input["body"]["from_name"].asString(),
+ IM_SESSION_INVITE,
+ LLIMMgr::INVITATION_TYPE_IMMEDIATE);
+ }
+ }
+};
+
+LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>
+ gHTTPRegistrationMessageChatterboxsessionstartreply(
+ "/message/ChatterBoxSessionStartReply");
+
+LLHTTPRegistration<LLViewerChatterBoxSessionEventReply>
+ gHTTPRegistrationMessageChatterboxsessioneventreply(
+ "/message/ChatterBoxSessionEventReply");
+
+LLHTTPRegistration<LLViewerForceCloseChatterBoxSession>
+ gHTTPRegistrationMessageForceclosechatterboxsession(
+ "/message/ForceCloseChatterBoxSession");
+
+LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates>
+ gHTTPRegistrationMessageChatterboxsessionagentlistupdates(
+ "/message/ChatterBoxSessionAgentListUpdates");
+
+LLHTTPRegistration<LLViewerChatterBoxSessionUpdate>
+ gHTTPRegistrationMessageChatterBoxSessionUpdate(
+ "/message/ChatterBoxSessionUpdate");
+
+LLHTTPRegistration<LLViewerChatterBoxInvitation>
+ gHTTPRegistrationMessageChatterBoxInvitation(
+ "/message/ChatterBoxInvitation");
+
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 9ca207a579..f30821cacf 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -265,8 +265,8 @@ BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVect
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
{
BOOL result = FALSE;
- F32 mouse_x = ((F32)x / gViewerWindow->getWindowWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom;
- F32 mouse_y = ((F32)y / gViewerWindow->getWindowHeightScaled() - 0.5f) / gAgent.mHUDCurZoom;
+ F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom;
+ F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgent.mHUDCurZoom;
LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin);
LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y);
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index bcaebb6bbb..8535d52015 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -1107,8 +1107,11 @@ BOOL LLManipRotate::updateVisiblity()
mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
- mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewWidthRaw()),
- (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeightRaw()));
+ // x axis range is (-aspect * 0.5f, +aspect * 0.5)
+ // y axis range is (-0.5, 0.5)
+ // so use getWorldViewHeightRaw as scale factor when converting to pixel coordinates
+ mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()),
+ (S32)((center.mV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()));
visible = TRUE;
}
else
@@ -1624,8 +1627,8 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_
{
if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
{
- F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewWidthRaw()) - 0.5f) / gAgent.mHUDCurZoom;
- F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewHeightRaw()) - 0.5f) / gAgent.mHUDCurZoom;
+ F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgent.mHUDCurZoom;
+ F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgent.mHUDCurZoom;
*ray_pt = LLVector3(-1.f, -mouse_x, mouse_y);
*ray_dir = LLVector3(1.f, 0.f, 0.f);
@@ -1699,7 +1702,7 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y )
F32 dist_y = mouse_dir_y.normVec();
F32 dist_z = mouse_dir_z.normVec();
- F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeightRaw();
+ F32 distance_threshold = (MAX_MANIP_SELECT_DISTANCE * mRadiusMeters) / gViewerWindow->getWorldViewHeightScaled();
if (llabs(dist_x - mRadiusMeters) * llmax(0.05f, proj_rot_x_axis) < distance_threshold)
{
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 90c009887d..5cd40273f6 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -102,17 +102,17 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
setCaretColor( (unsigned int)color.mV[0], (unsigned int)color.mV[1], (unsigned int)color.mV[2] );
}
- setIgnoreUIScale(p.ignore_ui_scale());
+ setIgnoreUIScale(p.ignore_ui_scale);
- setHomePageUrl(p.start_url());
+ setHomePageUrl(p.start_url);
- setBorderVisible(p.border_visible());
+ setBorderVisible(p.border_visible);
- mHideLoading = p.hide_loading();
+ mHideLoading = p.hide_loading;
- setDecoupleTextureSize(p.decouple_texture_size());
+ setDecoupleTextureSize(p.decouple_texture_size);
- setTextureSize(p.texture_width(), p.texture_height());
+ setTextureSize(p.texture_width, p.texture_height);
if(!getDecoupleTextureSize())
{
@@ -735,13 +735,13 @@ void LLMediaCtrl::draw()
{
// max width, adjusted height
width = r.getWidth();
- height = llmin(llmax(S32(width / media_aspect), 0), r.getHeight());
+ height = llmin(llmax(llround(width / media_aspect), 0), r.getHeight());
}
else
{
// max height, adjusted width
height = r.getHeight();
- width = llmin(llmax(S32(height * media_aspect), 0), r.getWidth());
+ width = llmin(llmax(llround(height * media_aspect), 0), r.getWidth());
}
}
else
@@ -759,6 +759,14 @@ void LLMediaCtrl::draw()
x_offset = (r.getWidth() - width) / 2;
y_offset = (r.getHeight() - height) / 2;
+ if(mIgnoreUIScale)
+ {
+ x_offset = llround((F32)x_offset * LLUI::sGLScaleFactor.mV[VX]);
+ y_offset = llround((F32)y_offset * LLUI::sGLScaleFactor.mV[VY]);
+ width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]);
+ height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]);
+ }
+
// draw the browser
gGL.setSceneBlendType(LLRender::BT_REPLACE);
gGL.begin( LLRender::QUADS );
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 1f984e3af8..09fd9b2949 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -222,5 +222,5 @@ void LLNearbyChat::setRect (const LLRect &rect)
void LLNearbyChat::getAllowedRect(LLRect& rect)
{
- rect = gViewerWindow->getWorldViewRectRaw();
+ rect = gViewerWindow->getWorldViewRectScaled();
}
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 6145588df2..234fe13217 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -92,7 +92,6 @@ LLNetMap::LLNetMap (const Params & p)
mObjectImagep(),
mClosestAgentToCursor(),
mClosestAgentAtLastRightClick(),
- mRotateMap(FALSE),
mToolTipMsg()
{
mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS);
@@ -175,7 +174,8 @@ void LLNetMap::draw()
gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f);
- if( mRotateMap )
+ static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
+ if( rotate_map )
{
// rotate subsequent draws to agent rotation
rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
@@ -408,7 +408,7 @@ void LLNetMap::draw()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if( mRotateMap )
+ if( rotate_map )
{
gGL.color4fv((map_frustum_color()).mV);
@@ -454,7 +454,8 @@ LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
pos_local.mV[VY] *= mPixelsPerMeter;
// leave Z component in meters
- if( mRotateMap )
+ static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
+ if( rotate_map )
{
F32 radians = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
@@ -502,7 +503,8 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
F32 radians = - atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] );
- if( mRotateMap )
+ static LLUICachedControl<bool> rotate_map("MiniMapRotate", true);
+ if( rotate_map )
{
LLQuaternion rot(radians, LLVector3(0.f, 0.f, 1.f));
pos_local.rotVec( rot );
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 7088ab3e70..3d7f3233ac 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -80,9 +80,7 @@ public:
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void setScale( F32 scale );
- void setRotateMap( BOOL b ) { mRotateMap = b; }
void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
- BOOL getRotateMap( ) { return mRotateMap; }
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
@@ -122,7 +120,6 @@ private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- BOOL mRotateMap;
std::string mToolTipMsg;
};
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 1f68c76bfc..5c11bc7310 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -66,7 +66,7 @@ LLAlertHandler::~LLAlertHandler()
//--------------------------------------------------------------------------
void LLAlertHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().getWidth() / 2;
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().getWidth() / 2;
mChannel->init(channel_right_bound, channel_right_bound);
}
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 26730e1f10..b7466ec6d4 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -61,7 +61,7 @@ LLGroupHandler::~LLGroupHandler()
//--------------------------------------------------------------------------
void LLGroupHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 94e733913d..598d021703 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -65,7 +65,7 @@ LLOfferHandler::~LLOfferHandler()
//--------------------------------------------------------------------------
void LLOfferHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 70b86e8b97..4be98201d1 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -64,7 +64,7 @@ LLScriptHandler::~LLScriptHandler()
//--------------------------------------------------------------------------
void LLScriptHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 60a27d5154..b962fa2184 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -60,7 +60,7 @@ LLTipHandler::~LLTipHandler()
//--------------------------------------------------------------------------
void LLTipHandler::initChannel()
{
- S32 channel_right_bound = gViewerWindow->getWorldViewRectRaw().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
+ S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mChannel->init(channel_right_bound - channel_width, channel_right_bound);
}
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 1c2875bf46..a1d54367c9 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -213,6 +213,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
}
mFounderName = panel_group->getChild<LLNameBox>("founder_name");
mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor");
+ mGroupNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII );
}
// static
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index b3e14eb2fb..78f3469f0e 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -210,8 +210,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
}
#if !USE_VIEWER_AUTH
- childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
- childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
+ childSetPrevalidate("first_name_edit", LLLineEditor::prevalidateASCIIPrintableNoSpace);
+ childSetPrevalidate("last_name_edit", LLLineEditor::prevalidateASCIIPrintableNoSpace);
childSetCommitCallback("password_edit", mungePassword, this);
getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 709525d4e2..4dc8872557 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -1017,7 +1017,7 @@ void LLPanelPeople::onChatButtonClicked()
{
LLUUID group_id = getCurrentItemID();
if (group_id.notNull())
- LLGroupActions::startChat(group_id);
+ LLGroupActions::startIM(group_id);
}
void LLPanelPeople::onImButtonClicked()
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 1051326e72..0dc010e2e7 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -80,9 +80,9 @@ LLPanelPermissions::LLPanelPermissions() :
BOOL LLPanelPermissions::postBuild()
{
childSetCommitCallback("Object Name",LLPanelPermissions::onCommitName,this);
- childSetPrevalidate("Object Name",LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("Object Name",LLLineEditor::prevalidateASCIIPrintableNoPipe);
childSetCommitCallback("Object Description",LLPanelPermissions::onCommitDesc,this);
- childSetPrevalidate("Object Description",LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("Object Description",LLLineEditor::prevalidateASCIIPrintableNoPipe);
getChild<LLUICtrl>("button set group")->setCommitCallback(boost::bind(&LLPanelPermissions::onClickGroup,this));
diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp
index 604faf8eb4..92bd4dc62b 100644
--- a/indra/newview/llpreviewanim.cpp
+++ b/indra/newview/llpreviewanim.cpp
@@ -79,7 +79,7 @@ BOOL LLPreviewAnim::postBuild()
childSetAction("Anim audition btn",auditionAnim, this);
childSetCommitCallback("desc", LLPreview::onText, this);
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
return LLPreview::postBuild();
}
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 7b3a20d102..49a2a3723d 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -493,7 +493,7 @@ BOOL LLPreviewGesture::postBuild()
{
childSetCommitCallback("desc", LLPreview::onText, this);
childSetText("desc", item->getDescription());
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
}
return LLPreview::postBuild();
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index ab9cfbf850..ce81077d80 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -96,7 +96,7 @@ BOOL LLPreviewNotecard::postBuild()
childSetCommitCallback("desc", LLPreview::onText, this);
if (item)
childSetText("desc", item->getDescription());
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
return LLPreview::postBuild();
}
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 2382befcfa..4e4711f8fb 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -956,7 +956,7 @@ BOOL LLPreviewLSL::postBuild()
childSetCommitCallback("desc", LLPreview::onText, this);
childSetText("desc", item->getDescription());
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
return LLPreview::postBuild();
}
diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp
index 7659c50ed3..d7fd252fb6 100644
--- a/indra/newview/llpreviewsound.cpp
+++ b/indra/newview/llpreviewsound.cpp
@@ -75,7 +75,7 @@ BOOL LLPreviewSound::postBuild()
button->setSoundFlags(LLView::SILENT);
childSetCommitCallback("desc", LLPreview::onText, this);
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
return LLPreview::postBuild();
}
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 13d02b7dec..41cf402d6f 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -152,7 +152,7 @@ BOOL LLPreviewTexture::postBuild()
{
childSetCommitCallback("desc", LLPreview::onText, this);
childSetText("desc", item->getDescription());
- childSetPrevalidate("desc", &LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("desc", &LLLineEditor::prevalidateASCIIPrintableNoPipe);
}
}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 81eb133b07..d1cf4a0810 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -103,8 +103,8 @@ void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect ne
void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
{
- S32 channel_top = gViewerWindow->getWorldViewRectRaw().getHeight();
- S32 channel_bottom = gViewerWindow->getWorldViewRectRaw().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+ S32 channel_top = gViewerWindow->getWorldViewRectScaled().getHeight();
+ S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
setVisible(TRUE);
}
@@ -710,7 +710,7 @@ void LLScreenChannel::updateShowToastsState()
// for Message Well floater showed in a docked state - adjust channel's height
if(dynamic_cast<LLSysWellWindow*>(floater))
{
- S32 channel_bottom = gViewerWindow->getWorldViewRectRaw().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");;
+ S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");;
LLRect this_rect = getRect();
if(floater->getVisible() && floater->isDocked())
{
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index a3efea7b7e..ff6e2d7363 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -111,9 +111,9 @@ BOOL LLSidepanelItemInfo::postBuild()
// build the UI
// item name & description
- childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("LabelItemName",&LLLineEditor::prevalidateASCIIPrintableNoPipe);
//getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitName,this));
- childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("LabelItemDesc",&LLLineEditor::prevalidateASCIIPrintableNoPipe);
//getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this));
// Creator information
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 01c832d7d5..4396cce545 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -100,8 +100,8 @@ BOOL LLSidepanelTaskInfo::postBuild()
mBuyBtn = getChild<LLButton>("buy_btn");
mBuyBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onBuyButtonClicked, this));
- childSetPrevalidate("Object Name",LLLineEditor::prevalidatePrintableNotPipe);
- childSetPrevalidate("Object Description",LLLineEditor::prevalidatePrintableNotPipe);
+ childSetPrevalidate("Object Name",LLLineEditor::prevalidateASCIIPrintableNoPipe);
+ childSetPrevalidate("Object Description",LLLineEditor::prevalidateASCIIPrintableNoPipe);
// getChild<LLUICtrl>("button set group")->setCommitCallback(boost::bind(&LLSidepanelTaskInfo::onClickGroup,this));
// childSetAction("button deed",LLSidepanelTaskInfo::onClickDeedToGroup,this);
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 04ecf769d5..539536b527 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -238,7 +238,7 @@ void LLSysWellWindow::initChannel()
//---------------------------------------------------------------------------------
void LLSysWellWindow::getAllowedRect(LLRect& rect)
{
- rect = gViewerWindow->getWorldViewRectRaw();
+ rect = gViewerWindow->getWorldViewRectScaled();
}
//---------------------------------------------------------------------------------
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index e2ccc05e30..2320ae57df 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -365,7 +365,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
// Orbit tool
if (hasMouseCapture())
{
- const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidthRaw();
+ const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidthScaled();
if (dx != 0)
{
@@ -393,7 +393,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
F32 dist = (F32) camera_to_focus.normVec();
// Fudge factor for pan
- F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWorldViewWidthRaw();
+ F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWorldViewWidthScaled();
if (dx != 0)
{
@@ -415,7 +415,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
if (hasMouseCapture())
{
- const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidthRaw();
+ const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWorldViewWidthScaled();
if (dx != 0)
{
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 44fb6e9271..26dbe6a489 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -510,8 +510,8 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
const F32 RADIANS_PER_PIXEL_X = 0.01f;
const F32 RADIANS_PER_PIXEL_Y = 0.01f;
- S32 dx = x - (gViewerWindow->getWorldViewWidthRaw() / 2);
- S32 dy = y - (gViewerWindow->getWorldViewHeightRaw() / 2);
+ S32 dx = x - (gViewerWindow->getWorldViewWidthScaled() / 2);
+ S32 dy = y - (gViewerWindow->getWorldViewHeightScaled() / 2);
if (dx != 0 || dy != 0)
{
@@ -631,10 +631,10 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
// Handle auto-rotation at screen edge.
LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global );
- LLCoordGL grab_center_gl( gViewerWindow->getWorldViewWidthRaw() / 2, gViewerWindow->getWorldViewHeightRaw() / 2);
+ LLCoordGL grab_center_gl( gViewerWindow->getWorldViewWidthScaled() / 2, gViewerWindow->getWorldViewHeightScaled() / 2);
LLViewerCamera::getInstance()->projectPosAgentToScreen(grab_pos_agent, grab_center_gl);
- const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidthRaw() / 20;
+ const S32 ROTATE_H_MARGIN = gViewerWindow->getWorldViewWidthScaled() / 20;
const F32 ROTATE_ANGLE_PER_SECOND = 30.f * DEG_TO_RAD;
const F32 rotate_angle = ROTATE_ANGLE_PER_SECOND / gFPSClamped;
// ...build mode moves camera about focus point
@@ -649,7 +649,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
gAgent.cameraOrbitAround(rotate_angle);
}
}
- else if (grab_center_gl.mX > gViewerWindow->getWorldViewWidthRaw() - ROTATE_H_MARGIN)
+ else if (grab_center_gl.mX > gViewerWindow->getWorldViewWidthScaled() - ROTATE_H_MARGIN)
{
if (gAgent.getFocusOnAvatar())
{
@@ -662,7 +662,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
}
// Don't move above top of screen or below bottom
- if ((grab_center_gl.mY < gViewerWindow->getWorldViewHeightRaw() - 6)
+ if ((grab_center_gl.mY < gViewerWindow->getWorldViewHeightScaled() - 6)
&& (grab_center_gl.mY > 24))
{
// Transmit update to simulator
@@ -893,7 +893,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
gAgent.yaw(rotate_angle);
//gAgent.setControlFlags(AGENT_CONTROL_YAW_POS);
}
- else if (x == (gViewerWindow->getWorldViewWidthRaw() - 1) )
+ else if (x == (gViewerWindow->getWorldViewWidthScaled() - 1) )
{
gAgent.yaw(-rotate_angle);
//gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG);
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 49506db173..e7f904023a 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -86,16 +86,6 @@ void init_audio()
gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectDelete")));
gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezIn")));
gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezOut")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuAppear")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuHide")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight0")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight1")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight2")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight3")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight4")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight5")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight6")));
- gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight7")));
gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndSnapshot")));
//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartAutopilot")));
//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartFollowpilot")));
@@ -231,9 +221,9 @@ void audio_update_wind(bool force_update)
}
}
// this line rotates the wind vector to be listener (agent) relative
- // unfortunately we have to pre-translate to undo the translation that
- // occurs in the transform call
- gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal(gWindVec - gAgent.getVelocity());
+ // Only use the agent's motion to compute wind noise, otherwise the world
+ // feels desolate on login when you are standing still.
+ gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal( -gAgent.getVelocity() );
// don't use the setter setMaxWindGain() because we don't
// want to screw up the fade-in on startup by setting actual source gain
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 5566fea89f..f3c64088c9 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -485,7 +485,7 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
y /= gViewerWindow->getDisplayScale().mV[VY];
// should now have the x,y coords of grab_point in screen space
- LLRect world_view_rect = gViewerWindow->getWorldViewRectScaled();
+ LLRect world_rect = gViewerWindow->getWorldViewRectScaled();
// convert to pixel coordinates
S32 int_x = lltrunc(x);
@@ -495,14 +495,14 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
if (clamp)
{
- if (int_x < world_view_rect.mLeft)
+ if (int_x < world_rect.mLeft)
{
- out_point.mX = world_view_rect.mLeft;
+ out_point.mX = world_rect.mLeft;
valid = FALSE;
}
- else if (int_x > world_view_rect.mRight)
+ else if (int_x > world_rect.mRight)
{
- out_point.mX = world_view_rect.mRight;
+ out_point.mX = world_rect.mRight;
valid = FALSE;
}
else
@@ -510,14 +510,14 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
out_point.mX = int_x;
}
- if (int_y < world_view_rect.mBottom)
+ if (int_y < world_rect.mBottom)
{
- out_point.mY = world_view_rect.mBottom;
+ out_point.mY = world_rect.mBottom;
valid = FALSE;
}
- else if (int_y > world_view_rect.mTop)
+ else if (int_y > world_rect.mTop)
{
- out_point.mY = world_view_rect.mTop;
+ out_point.mY = world_rect.mTop;
valid = FALSE;
}
else
@@ -531,19 +531,19 @@ BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
out_point.mX = int_x;
out_point.mY = int_y;
- if (int_x < world_view_rect.mLeft)
+ if (int_x < world_rect.mLeft)
{
valid = FALSE;
}
- else if (int_x > world_view_rect.mRight)
+ else if (int_x > world_rect.mRight)
{
valid = FALSE;
}
- if (int_y < world_view_rect.mBottom)
+ if (int_y < world_rect.mBottom)
{
valid = FALSE;
}
- else if (int_y > world_view_rect.mTop)
+ else if (int_y > world_rect.mTop)
{
valid = FALSE;
}
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 703a13976c..dbcf563010 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1467,14 +1467,14 @@ struct UIImageDeclaration : public LLInitParam::Block<UIImageDeclaration>
Mandatory<std::string> name;
Optional<std::string> file_name;
Optional<bool> preload;
- Optional<LLRect> scale_rect;
+ Optional<LLRect> scale;
Optional<bool> use_mips;
UIImageDeclaration()
: name("name"),
file_name("file_name"),
preload("preload", false),
- scale_rect("scale"),
+ scale("scale"),
use_mips("use_mips", false)
{}
};
@@ -1564,7 +1564,7 @@ bool LLUIImageList::initFromFile()
{
continue;
}
- preloadUIImage(image_it->name, file_name, image_it->use_mips, image_it->scale_rect);
+ preloadUIImage(image_it->name, file_name, image_it->use_mips, image_it->scale);
}
if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload"))
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c21c287fb6..db66faef81 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2278,7 +2278,7 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
// Zoom the camera in and out behavior
- if(top_ctrl == 0 && mWorldViewRectRaw.pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) )
+ if(top_ctrl == 0 && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) )
gAgent.handleScrollWheel(clicks);
return;
@@ -2286,8 +2286,8 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
void LLViewerWindow::moveCursorToCenter()
{
- S32 x = mWorldViewRectRaw.getWidth() / 2;
- S32 y = mWorldViewRectRaw.getHeight() / 2;
+ S32 x = getWorldViewWidthScaled() / 2;
+ S32 y = getWorldViewHeightScaled() / 2;
//on a forced move, all deltas get zeroed out to prevent jumping
mCurrentMousePoint.set(x,y);
@@ -2858,6 +2858,11 @@ void LLViewerWindow::updateWorldViewRect(bool use_full_window)
// clamp to at least a 1x1 rect so we don't try to allocate zero width gl buffers
new_world_rect.mTop = llmax(new_world_rect.mTop, new_world_rect.mBottom + 1);
new_world_rect.mRight = llmax(new_world_rect.mRight, new_world_rect.mLeft + 1);
+
+ new_world_rect.mLeft = llround((F32)new_world_rect.mLeft * mDisplayScale.mV[VX]);
+ new_world_rect.mRight = llround((F32)new_world_rect.mRight * mDisplayScale.mV[VX]);
+ new_world_rect.mBottom = llround((F32)new_world_rect.mBottom * mDisplayScale.mV[VY]);
+ new_world_rect.mTop = llround((F32)new_world_rect.mTop * mDisplayScale.mV[VY]);
}
if (mWorldViewRectRaw != new_world_rect)
@@ -2869,6 +2874,12 @@ void LLViewerWindow::updateWorldViewRect(bool use_full_window)
gResizeScreenTexture = TRUE;
LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
+
+ mWorldViewRectScaled = mWorldViewRectRaw;
+ mWorldViewRectScaled.mLeft = llround((F32)mWorldViewRectScaled.mLeft / mDisplayScale.mV[VX]);
+ mWorldViewRectScaled.mRight = llround((F32)mWorldViewRectScaled.mRight / mDisplayScale.mV[VX]);
+ mWorldViewRectScaled.mBottom = llround((F32)mWorldViewRectScaled.mBottom / mDisplayScale.mV[VY]);
+ mWorldViewRectScaled.mTop = llround((F32)mWorldViewRectScaled.mTop / mDisplayScale.mV[VY]);
}
}
@@ -3140,10 +3151,10 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback
{
mPickScreenRegion.setCenterAndSize(x, y_from_bot, PICK_DIAMETER, PICK_DIAMETER);
- if (mPickScreenRegion.mLeft < mWorldViewRectRaw.mLeft) mPickScreenRegion.translate(mWorldViewRectRaw.mLeft - mPickScreenRegion.mLeft, 0);
- if (mPickScreenRegion.mBottom < mWorldViewRectRaw.mBottom) mPickScreenRegion.translate(0, mWorldViewRectRaw.mBottom - mPickScreenRegion.mBottom);
- if (mPickScreenRegion.mRight > mWorldViewRectRaw.mRight ) mPickScreenRegion.translate(mWorldViewRectRaw.mRight - mPickScreenRegion.mRight, 0);
- if (mPickScreenRegion.mTop > mWorldViewRectRaw.mTop ) mPickScreenRegion.translate(0, mWorldViewRectRaw.mTop - mPickScreenRegion.mTop);
+ if (mPickScreenRegion.mLeft < mWorldViewRectScaled.mLeft) mPickScreenRegion.translate(mWorldViewRectScaled.mLeft - mPickScreenRegion.mLeft, 0);
+ if (mPickScreenRegion.mBottom < mWorldViewRectScaled.mBottom) mPickScreenRegion.translate(0, mWorldViewRectScaled.mBottom - mPickScreenRegion.mBottom);
+ if (mPickScreenRegion.mRight > mWorldViewRectScaled.mRight ) mPickScreenRegion.translate(mWorldViewRectScaled.mRight - mPickScreenRegion.mRight, 0);
+ if (mPickScreenRegion.mTop > mWorldViewRectScaled.mTop ) mPickScreenRegion.translate(0, mWorldViewRectScaled.mTop - mPickScreenRegion.mTop);
}
// set frame buffer region for picking results
@@ -3349,11 +3360,11 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
F32 fov = LLViewerCamera::getInstance()->getView();
// find world view center in scaled ui coordinates
- F32 center_x = (F32)getWorldViewRectRaw().getCenterX() / mDisplayScale.mV[VX];
- F32 center_y = (F32)getWorldViewRectRaw().getCenterY() / mDisplayScale.mV[VY];
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
// calculate pixel distance to screen
- F32 distance = ((F32)getWorldViewHeightRaw() / (mDisplayScale.mV[VY] * 2.f)) / (tan(fov / 2.f));
+ F32 distance = ((F32)getWorldViewHeightScaled() * 0.5f) / (tan(fov / 2.f));
// calculate click point relative to middle of screen
F32 click_x = x - center_x;
@@ -3372,11 +3383,11 @@ LLVector3 LLViewerWindow::mouseDirectionGlobal(const S32 x, const S32 y) const
LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const
{
// find screen resolution
- S32 height = llround((F32)getWorldViewHeightRaw() / mDisplayScale.mV[VY]);
+ S32 height = getWorldViewHeightScaled();
// find world view center
- F32 center_x = (F32)getWorldViewRectRaw().getCenterX() / mDisplayScale.mV[VX];
- F32 center_y = (F32)getWorldViewRectRaw().getCenterY() / mDisplayScale.mV[VY];
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
// remap with uniform scale (1/height) so that top is -0.5, bottom is +0.5
F32 hud_x = -((F32)x - center_x) / height;
@@ -3394,12 +3405,12 @@ LLVector3 LLViewerWindow::mouseDirectionCamera(const S32 x, const S32 y) const
F32 fov_width = fov_height * LLViewerCamera::getInstance()->getAspect();
// find screen resolution
- S32 height = llround((F32)getWorldViewHeightRaw() / mDisplayScale.mV[VY]);
- S32 width = llround((F32)getWorldViewWidthRaw() / mDisplayScale.mV[VX]);
+ S32 height = getWorldViewHeightScaled();
+ S32 width = getWorldViewWidthScaled();
// find world view center
- F32 center_x = (F32)getWorldViewRectRaw().getCenterX() / mDisplayScale.mV[VX];
- F32 center_y = (F32)getWorldViewRectRaw().getCenterY() / mDisplayScale.mV[VY];
+ F32 center_x = getWorldViewRectScaled().getCenterX();
+ F32 center_y = getWorldViewRectScaled().getCenterY();
// calculate click point relative to middle of screen
F32 click_x = (((F32)x - center_x) / (F32)width) * fov_width * -1.f;
@@ -4166,14 +4177,20 @@ LLRootView* LLViewerWindow::getRootView() const
LLRect LLViewerWindow::getWorldViewRectScaled() const
{
- LLRect world_view_rect = mWorldViewRectRaw;
- world_view_rect.mLeft = llround((F32)world_view_rect.mLeft / mDisplayScale.mV[VX]);
- world_view_rect.mRight = llround((F32)world_view_rect.mRight / mDisplayScale.mV[VX]);
- world_view_rect.mBottom = llround((F32)world_view_rect.mBottom / mDisplayScale.mV[VY]);
- world_view_rect.mTop = llround((F32)world_view_rect.mTop / mDisplayScale.mV[VY]);
- return world_view_rect;
+ return mWorldViewRectScaled;
+}
+
+S32 LLViewerWindow::getWorldViewHeightScaled() const
+{
+ return mWorldViewRectScaled.getHeight();
}
+S32 LLViewerWindow::getWorldViewWidthScaled() const
+{
+ return mWorldViewRectScaled.getWidth();
+}
+
+
S32 LLViewerWindow::getWorldViewHeightRaw() const
{
return mWorldViewRectRaw.getHeight();
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ce71ef6173..517993182b 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -212,6 +212,8 @@ public:
// 3D world area in scaled pixels (via UI scale), use for most UI computations
LLRect getWorldViewRectScaled() const;
+ S32 getWorldViewHeightScaled() const;
+ S32 getWorldViewWidthScaled() const;
// 3D world area, in raw unscaled pixels
LLRect getWorldViewRectRaw() const { return mWorldViewRectRaw; }
@@ -415,6 +417,7 @@ protected:
LLRect mWindowRectRaw; // whole window, including UI
LLRect mWindowRectScaled; // whole window, scaled by UI size
LLRect mWorldViewRectRaw; // area of screen for 3D world
+ LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size
LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views
LLVector2 mDisplayScale;
diff --git a/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png b/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png
new file mode 100644
index 0000000000..75bd73cef1
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/MinusItem_Disabled.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/MinusItem_Off.png b/indra/newview/skins/default/textures/icons/MinusItem_Off.png
new file mode 100644
index 0000000000..6f285f3546
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/MinusItem_Off.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/MinusItem_Press.png b/indra/newview/skins/default/textures/icons/MinusItem_Press.png
new file mode 100644
index 0000000000..50f65765d5
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/MinusItem_Press.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 8af65b25e9..f4a239be62 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -1,3 +1,33 @@
+<!--
+This file contains metadata about how to load, display, and scale textures for rendering in the UI.
+Images do *NOT* have to appear in this file in order to use them as textures in the UI...simply refer
+to them by filename (relative to textures directory).
+NOTE: if you want to reuse an image file with different metadata, simply create a new texture entry
+with the same filename but different name
+
+<texture
+ name="MyTexture" (mandatory)
+ - this is the name you reference the texture by in XUI. For example, <button image_unselected="MyTexture"/>
+ file_name="images/my_texture.png" (optional)
+ - this is the path to the actual file asset, relative to the current skins "textures" directory.
+ If not supplied, the filename will be taken from the texture name itself, "MyTexture" in this case.
+ NOTE: you need to provide an extension on the filename (".png", ".tga", ".jpg") for us to decode the image properly
+ preload="true" (optional, false by default)
+ - If true, we will attempt to load the image before displaying any UI.
+ If false, we will load in the background after initializing the UI.
+ use_mips="true" (currently unused)
+ scale.left="1"
+ scale.bottom="1"
+ scale.top="15"
+ scale.right="31"
+ - Specifies the segmentation for 9-slice image scaling. Specifically, the pixel offsets from the LOWER LEFT corner
+ that define the region of the image that is stretched to make the whole image fit in the required space.
+ In this example, if the source image is 32x16 pixels, we have defined a center region that starts one pixel up
+ and to the right from the bottom left corner and extends to 31 pixels right and 15 pixels up from the bottom left
+ corner. The end result is that the image will keep a 1 pixel border all around while stretching to fit the required
+ region.
+-->
+
<textures version="101">
<!-- Please add new files alphabetically to prevent merge conflicts. JC -->
<texture name="Accordion_ArrowClosed_Off" file_name="containers/Accordion_ArrowClosed_Off.png" preload="false" />
@@ -106,7 +136,6 @@
<texture name="DropDown_Press" file_name="widgets/DropDown_Press.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
<texture name="DropDown_Selected" file_name="widgets/DropDown_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
<texture name="DropDown_Off" file_name="widgets/DropDown_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
- <texture name="DropDown_On" file_name="widgets/DropDown_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
<texture name="DropTarget" file_name="widgets/DropTarget.png" preload="false" />
@@ -231,6 +260,10 @@
<texture name="Microphone_Mute" file_name="icons/Microphone_Mute.png" preload="false" />
<texture name="Microphone_On" file_name="icons/Microphone_On.png" preload="false" />
+ <texture name="MinusItem_Disabled" file_name="icons/MinusItem_Disabled.png" preload="false" />
+ <texture name="MinusItem_Off" file_name="icons/MinusItem_Off.png" preload="false" />
+ <texture name="MinusItem_Press" file_name="icons/MinusItem_Press.png" preload="false" />
+
<texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" />
<texture name="Move_Fly_Disabled" file_name="bottomtray/Move_Fly_Disabled.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml
index e4ab533bc5..4bbd561882 100644
--- a/indra/newview/skins/default/xui/en/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/en/floater_aaa.xml
@@ -5,6 +5,6 @@
name="floater_aaa"
can_resize="true"
width="1024">
- <string name="Nudge Parabuild">1</string>
+ <string name="Nudge Parabuild">2</string>
<panel filename="main_view.xml" follows="all" width="1024" height="768" top="0"/>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index f553184c19..69f9f6a2f8 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -87,9 +87,9 @@
<button
follows="top|left"
height="18"
- image_disabled="AddItem_Disabled"
- image_selected="AddItem_Press"
- image_unselected="AddItem_Off"
+ image_disabled="MinusItem_Disabled"
+ image_selected="MinusItem_Press"
+ image_unselected="MinusItem_Off"
layout="topleft"
name="zoom_minus_btn"
top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 4792a1a476..e972cf39bf 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -8,67 +8,71 @@
left="0"
name="panel_im"
top="0"
- can_close="false"
+ can_close="true"
can_dock="true"
- can_minimize="false"
+ can_minimize="true"
visible="true"
- width="320"
+ width="350"
can_resize="true"
min_width="300"
min_height="350">
- <layout_stack follows="all"
- height="350"
- width="300"
- layout="topleft"
- orientation="horizontal"
- name="im_panels"
- top="20"
- left="0">
+ <layout_stack
+ follows="all"
+ height="350"
+ width="300"
+ layout="topleft"
+ orientation="horizontal"
+ name="im_panels"
+ top="20"
+ left="0">
<layout_panel
name="panel_im_control_panel"
layout="topleft"
- top_delta="-3"
- height="350"
follows="left"
label="IM Control Panel"
auto_resize="false"
user_resize="false" />
- <layout_panel height="350"
- width=""
- left_delta="110"
- top="0"
- user_resize="false">
- <button height="20"
- follows="left|top"
- top="0"
- image_overlay="TabIcon_Open_Off"
- layout="topleft"
- width="25"
- name="slide_left_btn" />
- <button height="20"
- follows="left|top"
- top="0"
- image_overlay="TabIcon_Close_Off"
- width="25"
- name="slide_right_btn" />
- <chat_history
- length="1"
- follows="all"
- height="275"
- layout="topleft"
- name="chat_history"
- parse_highlights="true"
- allow_html="true"
- width="160">
- </chat_history>
- <line_editor
- follows="left|right"
- height="20"
- label="To"
- layout="topleft"
- name="chat_editor"
- width="160">
- </line_editor>
+ <layout_panel
+ left="0"
+ top="0"
+ user_resize="false">
+ <button
+ height="20"
+ follows="left|top"
+ top="0"
+ left="2"
+ image_overlay="TabIcon_Open_Off"
+ layout="topleft"
+ width="25"
+ name="slide_left_btn" />
+ <button
+ height="20"
+ follows="left|top"
+ top="0"
+ left="2"
+ image_overlay="TabIcon_Close_Off"
+ width="25"
+ name="slide_right_btn" />
+ <chat_history
+ length="1"
+ font="SansSerifSmall"
+ follows="left|right|top"
+ height="280"
+ name="chat_history"
+ parse_highlights="true"
+ allow_html="true"
+ left="1"
+ width="180">
+ </chat_history>
+ <line_editor
+ follows="left|right|top"
+ font="SansSerifSmall"
+ height="20"
+ label="To"
+ name="chat_editor"
+ top_pad="1"
+ width="180">
+ </line_editor>
</layout_panel>
</layout_stack>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_land_holdings.xml b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
index 2c04a94613..e3751f2bd9 100644
--- a/indra/newview/skins/default/xui/en/floater_land_holdings.xml
+++ b/indra/newview/skins/default/xui/en/floater_land_holdings.xml
@@ -42,7 +42,7 @@
</scroll_list>
<button
height="23"
- font="SansSerifBold"
+ font="SansSerif"
label="Teleport"
label_selected="Teleport"
layout="topleft"
@@ -53,7 +53,7 @@
width="80" />
<button
height="23"
- font="SansSerifBold"
+ font="SansSerif"
label="Map"
label_selected="Map"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
index 69b015a727..d8534bfe0b 100644
--- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -5,7 +5,7 @@
can_tear_off="false"
can_resize="true"
can_drag_on_left="false"
- can_close="false"
+ can_close="true"
can_dock="true"
bevel_style="in"
height="300"
diff --git a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
index 6faab84159..4909b8988f 100644
--- a/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
+++ b/indra/newview/skins/default/xui/en/floater_perm_prefs.xml
@@ -22,10 +22,10 @@
height="16"
label="Share with group"
layout="topleft"
- left_delta="-250"
+ left="10"
name="share_with_group"
- top_delta="2"
- width="106" />
+ top="5"
+ width="150" />
<check_box
control_name="EveryoneCopy"
height="16"
@@ -33,8 +33,8 @@
layout="topleft"
left_delta="0"
name="everyone_copy"
- top_pad="16"
- width="130" />
+ top_pad="5"
+ width="150" />
<text
type="string"
length="1"
@@ -43,8 +43,8 @@
layout="topleft"
left_delta="0"
name="NextOwnerLabel"
- top_pad="16"
- width="88">
+ top_pad="5"
+ width="150">
Next owner can:
</text>
<check_box
@@ -54,17 +54,17 @@
layout="topleft"
left_delta="0"
name="next_owner_modify"
- top_pad="14"
- width="78" />
+ top_pad="5"
+ width="150" />
<check_box
control_name="NextOwnerCopy"
height="16"
label="Copy"
layout="topleft"
- left_delta="78"
+ left_delta="0"
name="next_owner_copy"
- top_delta="0"
- width="88" >
+ top_pad="5"
+ width="150" >
<check_box.commit_callback
function="Perms.Copy" />
</check_box>
@@ -76,10 +76,10 @@
initial_value="true"
label="Resell/Give away"
layout="topleft"
- left_delta="88"
+ left_delta="0"
name="next_owner_transfer"
- top_delta="0"
- width="106" />
+ top_pad="5"
+ width="150" />
</panel>
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
index e017d404c6..0531b52e5a 100644
--- a/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_line_editor.xml
@@ -18,7 +18,18 @@
Enabled line editor
</line_editor>
<line_editor
- enabled="false"
+ height="20"
+ layout="topleft"
+ left_delta="0"
+ name="ascii_line_editor"
+ prevalidate_callback="ascii"
+ tool_tip="ascii line editor"
+ top_pad="10"
+ width="200">
+ ASCII only line editor
+ </line_editor>
+ <line_editor
+ enabled="false"
height="20"
layout="topleft"
left_delta="0"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index bfbfe7de7c..a626e1b353 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -811,11 +811,8 @@
Mixed Sale
</panel.string>
<text
- type="string"
- length="1"
follows="left|top"
height="10"
- layout="topleft"
left="10"
name="Name:"
top="0"
@@ -825,7 +822,6 @@
<line_editor
follows="left|top|right"
height="19"
- layout="topleft"
left_pad="0"
max_length="63"
name="Object Name"
@@ -833,11 +829,8 @@
top_delta="0"
width="170" />
<text
- type="string"
- length="1"
follows="left|top"
height="10"
- layout="topleft"
left="10"
name="Description:"
top_pad="3"
@@ -847,7 +840,6 @@
<line_editor
follows="left|top|right"
height="19"
- layout="topleft"
left_pad="0"
max_length="127"
name="Object Description"
diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml
index 83570e2528..16f6e49092 100644
--- a/indra/newview/skins/default/xui/en/inspect_object.xml
+++ b/indra/newview/skins/default/xui/en/inspect_object.xml
@@ -38,14 +38,14 @@ owner [OWNER]
width="220" />
<text
follows="all"
- height="30"
+ height="33"
left="8"
name="object_creator"
top_pad="0"
use_ellipses="true"
width="220">
-by Longavatarname Johnsonlongstonnammer
-owner James Linden
+ by secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+owner secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
</text>
<!-- *TODO: Replace this icon -->
<icon
@@ -54,7 +54,7 @@ owner James Linden
right="-5"
width="16"
height="16"
- top="50"
+ top="56"
follows="left|top"
/>
<text
@@ -66,7 +66,7 @@ owner James Linden
left="5"
name="price_text"
text_color="white"
- top="53"
+ top="58"
font_shadow="none"
width="196">
L$300,000
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
index 542e319792..8cbe62cfb0 100644
--- a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
@@ -9,7 +9,15 @@
visible="false"
width="128">
<menu_item_call
- label="Chat..."
+ label="Group Info"
+ layout="topleft"
+ name="Show Profile">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="info" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Session"
layout="topleft"
name="Chat">
<menu_item_call.on_click
@@ -17,11 +25,11 @@
parameter="group chat" />
</menu_item_call>
<menu_item_call
- label="Info..."
+ label="End Session"
layout="topleft"
- name="Show Profile">
+ name="End Session">
<menu_item_call.on_click
function="IMChicletMenu.Action"
- parameter="info" />
+ parameter="end" />
</menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
index c205868429..6891aaca32 100644
--- a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
@@ -9,7 +9,7 @@
visible="false"
width="128">
<menu_item_call
- label="Show Profile..."
+ label="Show Profile"
layout="topleft"
name="Show Profile">
<menu_item_call.on_click
@@ -17,7 +17,15 @@
parameter="profile" />
</menu_item_call>
<menu_item_call
- label="Send IM..."
+ label="Add Friend"
+ layout="topleft"
+ name="Add Friend">
+ <menu_item_call.on_click
+ function="IMChicletMenu.Action"
+ parameter="add" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Session"
layout="topleft"
name="Send IM">
<menu_item_call.on_click
@@ -25,11 +33,11 @@
parameter="im" />
</menu_item_call>
<menu_item_call
- label="Add Friend..."
+ label="End Session"
layout="topleft"
- name="Add Friend">
+ name="End Session">
<menu_item_call.on_click
function="IMChicletMenu.Action"
- parameter="add" />
+ parameter="end" />
</menu_item_call>
</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index 5cbbd71bfe..8d0edf018d 100644
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -10,7 +10,6 @@
width="128">
<menu_item_call
label="Zoom Close"
- layout="topleft"
name="Zoom Close">
<menu_item_call.on_click
function="Minimap.Zoom"
@@ -18,7 +17,6 @@
</menu_item_call>
<menu_item_call
label="Zoom Medium"
- layout="topleft"
name="Zoom Medium">
<menu_item_call.on_click
function="Minimap.Zoom"
@@ -26,29 +24,31 @@
</menu_item_call>
<menu_item_call
label="Zoom Far"
- layout="topleft"
name="Zoom Far">
<menu_item_call.on_click
function="Minimap.Zoom"
parameter="far" />
</menu_item_call>
- <menu_item_separator
- layout="topleft"
- name="Tracking Separator" />
+ <menu_item_check
+ label="Rotate Map"
+ name="Rotate Map">
+ <menu_item_check.on_check
+ control="MiniMapRotate" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapRotate" />
+ </menu_item_check>
+ <menu_item_separator />
<menu_item_call
label="Stop Tracking"
- layout="topleft"
name="Stop Tracking">
<menu_item_call.on_click
function="Minimap.Tracker"
parameter="task_properties" />
</menu_item_call>
- <menu_item_separator
- layout="topleft"
- name="Tracking Separator" />
+ <menu_item_separator />
<menu_item_call
label="World Map"
- layout="topleft"
name="World Map">
<menu_item_call.on_click
function="ShowFloater"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 181994a1bd..ccf6b08ed7 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1,3698 +1,3698 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu_bar
- bg_visible="false"
- follows="left|top|right"
- layout="topleft"
- name="Main Menu">
- <menu
- label="Me"
- layout="topleft"
- name="Me"
- tear_off="true">
- <menu_item_call
- label="Preferences"
- layout="topleft"
- name="Preferences"
- shortcut="control|P">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="preferences" />
- </menu_item_call>
- <menu_item_call
- label="My Dashboard"
- layout="topleft"
- name="Manage My Account">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="ManageMyAccount_url"
- parameter="WebLaunchJoinNow,http://secondlife.com/account/" />
- </menu_item_call>
- <menu_item_call
- label="Buy L$"
- layout="topleft"
- name="Buy and Sell L$">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="buy currency" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="My Profile"
- layout="topleft"
- name="Profile">
- <menu_item_call.on_click
- function="ShowAgentProfile"
- parameter="agent" />
- </menu_item_call>
- <menu_item_call
- label="My Appearance"
- layout="topleft"
- name="Appearance">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="appearance" />
- <menu_item_call.on_enable
- function="Edit.EnableCustomizeAvatar" />
- </menu_item_call>
- <menu_item_check
- label="My Inventory"
- layout="topleft"
- name="Inventory"
- shortcut="control|I">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="inventory" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="inventory" />
- </menu_item_check>
- <menu_item_call
- label="My Gestures"
- layout="topleft"
- name="Gestures"
- shortcut="control|G">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="gestures" />
- </menu_item_call>
- <menu
- label="My Status"
- layout="topleft"
- name="Status"
- tear_off="true">
- <menu_item_call
- label="Away"
- layout="topleft"
- name="Set Away">
- <menu_item_call.on_click
- function="World.SetAway" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft"/>
- <menu_item_call
- label="Busy"
- layout="topleft"
- name="Set Busy">
- <menu_item_call.on_click
- function="World.SetBusy"/>
- </menu_item_call>
- </menu>
- <menu_item_call
- label="Request Admin Status"
- layout="topleft"
- name="Request Admin Options"
- shortcut="control|alt|G"
- visible="false">
- <menu_item_call.on_click
- function="Advanced.RequestAdminStatus" />
- </menu_item_call>
- <menu_item_call
- label="Leave Admin Status"
- layout="topleft"
- name="Leave Admin Options"
- shortcut="control|alt|shift|G"
- visible="false">
- <menu_item_call.on_click
- function="Advanced.LeaveAdminStatus" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Quit [APP_NAME]"
- layout="topleft"
- name="Quit"
- shortcut="control|Q">
- <menu_item_call.on_click
- function="File.Quit" />
- </menu_item_call>
- </menu>
- <menu
- label="Communicate"
- layout="topleft"
- name="Communicate"
- tear_off="true">
- <menu_item_call
- label="My Friends"
- layout="topleft"
- name="My Friends"
- shortcut="control|shift|F">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="friends_panel" />
- </menu_item_call>
- <menu_item_call
- label="My Groups"
- layout="topleft"
- name="My Groups">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="groups_panel" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <!--menu_item_call
- label="Chat"
- layout="topleft"
- name="Chat">
- <menu_item_call.on_click
- function="World.Chat" />
- </menu_item_call-->
- <menu_item_check
- label="Nearby Chat"
- layout="topleft"
- name="Nearby Chat"
- shortcut="control|H">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="nearby_chat" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="nearby_chat" />
- </menu_item_check>
- <menu_item_call
- label="Nearby People"
- layout="topleft"
- name="Active Speakers"
- shortcut="control|shift|A">
- <menu_item_call.on_click
- function="SideTray.PanelPeopleTab"
- parameter="nearby_panel" />
- </menu_item_call>
- <menu_item_check
- label="Nearby Media"
- layout="topleft"
- name="Nearby Media"
- shortcut="control|alt|N">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="nearby_media" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="nearby_media" />
- </menu_item_check>
- <!--menu_item_check
- label="Block List"
- layout="topleft"
- name="Mute List">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="mute" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="mute" />
- </menu_item_check-->
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="(Legacy) Communicate"
- layout="topleft"
- name="Instant Message"
- shortcut="control|T">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="communicate" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="communicate" />
- </menu_item_check>
- <menu_item_call
- label="(Temp) Media Remote Ctrl"
- layout="topleft"
- name="Preferences"
- shortcut="control|alt|M">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="media_remote_ctrl" />
- </menu_item_call>
- </menu>
- <menu
- label="World"
- layout="topleft"
- name="World"
- tear_off="true">
- <menu_item_check
- label="Move"
- layout="topleft"
- name="Movement Controls">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="moveview" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="moveview" />
- </menu_item_check>
- <menu_item_check
- label="View"
- layout="topleft"
- name="Camera Controls">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="camera" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="camera" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="About Land"
- layout="topleft"
- name="About Land">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="about_land" />
- </menu_item_call>
- <menu_item_call
- label="Region/Estate"
- layout="topleft"
- name="Region/Estate">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="region_info" />
- </menu_item_call>
- <menu_item_call
- label="Buy Land"
- layout="topleft"
- name="Buy Land">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="buy land" />
- <menu_item_call.on_enable
- function="World.EnableBuyLand" />
- </menu_item_call>
- <menu_item_call
- label="My Land"
- layout="topleft"
- name="My Land">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="land_holdings" />
- </menu_item_call>
- <menu
- create_jump_keys="true"
- label="Show"
- layout="topleft"
- name="Land"
- tear_off="true">
- <menu_item_check
- label="Ban Lines"
- layout="topleft"
- name="Ban Lines">
- <menu_item_check.on_check
- control="ShowBanLines" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowBanLines" />
- </menu_item_check>
- <menu_item_check
- label="Beacons"
- layout="topleft"
- name="beacons"
- shortcut="control|alt|shift|N">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="beacons" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="beacons" />
- </menu_item_check>
- <menu_item_check
- label="Property Lines"
- layout="topleft"
- name="Property Lines"
- shortcut="control|alt|shift|P">
- <menu_item_check.on_check
- control="ShowPropertyLines" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowPropertyLines" />
- </menu_item_check>
- <menu_item_check
- label="Land Owners"
- layout="topleft"
- name="Land Owners">
- <menu_item_check.on_check
- control="ShowParcelOwners" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowParcelOwners" />
- </menu_item_check>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu
- label="Landmarks"
- layout="topleft"
- name="Landmarks"
- tear_off="true">
- <menu_item_call
- label="Create Landmark Here"
- layout="topleft"
- name="Create Landmark Here">
- <menu_item_call.on_click
- function="World.CreateLandmark" />
- <menu_item_call.on_enable
- function="World.EnableCreateLandmark" />
- </menu_item_call>
- <menu_item_call
- label="Set Home to Here"
- layout="topleft"
- name="Set Home to Here">
- <menu_item_call.on_click
- function="World.SetHomeLocation" />
- <menu_item_call.on_enable
- function="World.EnableSetHomeLocation" />
- </menu_item_call>
- <menu_item_call
- label="Teleport Home"
- layout="topleft"
- name="Teleport Home"
- shortcut="control|shift|H">
- <menu_item_call.on_click
- function="World.TeleportHome" />
- <menu_item_call.on_enable
- function="World.EnableTeleportHome" />
- </menu_item_call>
- </menu>
- <menu_item_check
- label="Mini-Map"
- layout="topleft"
- name="Mini-Map"
- shortcut="control|shift|M">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="mini_map" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="mini_map" />
- </menu_item_check>
- <menu_item_check
- label="World Map"
- layout="topleft"
- name="World Map"
- shortcut="control|M"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="world_map" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="world_map" />
- </menu_item_check>
- <!-- <menu_item_check
- label="Show Navigation Bar"
- layout="topleft"
- name="ShowNavbarNavigationPanel">
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowNavbarNavigationPanel" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowNavbarNavigationPanel" />
- </menu_item_check>
- <menu_item_check
- label="Show Favorites Bar"
- layout="topleft"
- name="ShowNavbarFavoritesPanel">
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowNavbarFavoritesPanel" />
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowNavbarFavoritesPanel" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />-->
- <menu_item_call
- label="Snapshot"
- layout="topleft"
- name="Take Snapshot"
- shortcut="control|shift|S">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="snapshot" />
- </menu_item_call>
- <menu
- create_jump_keys="true"
- label="Sun"
- layout="topleft"
- name="Environment Settings"
- tear_off="true">
- <menu_item_call
- label="Sunrise"
- layout="topleft"
- name="Sunrise">
- <menu_item_call.on_click
- function="World.EnvSettings"
- parameter="sunrise" />
- </menu_item_call>
- <menu_item_call
- label="Midday"
- layout="topleft"
- name="Noon"
- shortcut="control|shift|Y">
- <menu_item_call.on_click
- function="World.EnvSettings"
- parameter="noon" />
- </menu_item_call>
- <menu_item_call
- label="Sunset"
- layout="topleft"
- name="Sunset"
- shortcut="control|shift|N">
- <menu_item_call.on_click
- function="World.EnvSettings"
- parameter="sunset" />
- </menu_item_call>
- <menu_item_call
- label="Midnight"
- layout="topleft"
- name="Midnight">
- <menu_item_call.on_click
- function="World.EnvSettings"
- parameter="midnight" />
- </menu_item_call>
- <menu_item_call
- label="Use the Estate Time"
- layout="topleft"
- name="Revert to Region Default">
- <menu_item_call.on_click
- function="World.EnvSettings"
- parameter="default" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Environment Editor"
- layout="topleft"
- name="Environment Editor">
- <menu_item_call.on_click
- function="World.EnvSettings"
- parameter="editor" />
- </menu_item_call>
- </menu>
- </menu>
- <menu
- create_jump_keys="true"
- label="Build"
- layout="topleft"
- name="BuildTools"
- tear_off="true"
- visible="true">
- <menu_item_check
- label="Build"
- layout="topleft"
- name="Show Build Tools"
- shortcut="control|B">
- <menu_item_check.on_check
- function="Build.Active" />
- <menu_item_check.on_click
- function="Build.Toggle" />
- <menu_item_check.on_enable
- function="Build.Enabled" />
- </menu_item_check>
- <menu
- create_jump_keys="true"
- label="Select Build Tool"
- layout="topleft"
- name="Select Tool"
- tear_off="true">
- <menu_item_call
- label="Focus Tool"
- layout="topleft"
- name="Focus"
- shortcut="control|1">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="focus" />
- </menu_item_call>
- <menu_item_call
- label="Move Tool"
- layout="topleft"
- name="Move"
- shortcut="control|2">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="move" />
- </menu_item_call>
- <menu_item_call
- label="Edit Tool"
- layout="topleft"
- name="Edit"
- shortcut="control|3">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="edit" />
- </menu_item_call>
- <menu_item_call
- label="Create Tool"
- layout="topleft"
- name="Create"
- shortcut="control|4">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="create" />
- </menu_item_call>
- <menu_item_call
- label="Land Tool"
- layout="topleft"
- name="Land"
- shortcut="control|5">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="land" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Edit"
- layout="topleft"
- name="Edit"
- tear_off="true">
- <menu_item_call
- label="Undo"
- layout="topleft"
- name="Undo"
- shortcut="control|Z">
- <menu_item_call.on_click
- function="Edit.Undo" />
- <menu_item_call.on_enable
- function="Edit.EnableUndo" />
- </menu_item_call>
- <menu_item_call
- label="Redo"
- layout="topleft"
- name="Redo"
- shortcut="control|Y">
- <menu_item_call.on_click
- function="Edit.Redo" />
- <menu_item_call.on_enable
- function="Edit.EnableRedo" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Cut"
- layout="topleft"
- name="Cut"
- shortcut="control|X">
- <menu_item_call.on_click
- function="Edit.Cut" />
- <menu_item_call.on_enable
- function="Edit.EnableCut" />
- </menu_item_call>
- <menu_item_call
- label="Copy"
- layout="topleft"
- name="Copy"
- shortcut="control|C">
- <menu_item_call.on_click
- function="Edit.Copy" />
- <menu_item_call.on_enable
- function="Edit.EnableCopy" />
- </menu_item_call>
- <menu_item_call
- label="Paste"
- layout="topleft"
- name="Paste"
- shortcut="control|V">
- <menu_item_call.on_click
- function="Edit.Paste" />
- <menu_item_call.on_enable
- function="Edit.EnablePaste" />
- </menu_item_call>
- <menu_item_call
- label="Delete"
- layout="topleft"
- name="Delete"
- shortcut="Del">
- <menu_item_call.on_click
- function="Edit.Delete" />
- <menu_item_call.on_enable
- function="Edit.EnableDelete" />
- </menu_item_call>
- <menu_item_call
- label="Duplicate"
- layout="topleft"
- name="Duplicate"
- shortcut="control|D">
- <menu_item_call.on_click
- function="Edit.Duplicate" />
- <menu_item_call.on_enable
- function="Edit.EnableDuplicate" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Select All"
- layout="topleft"
- name="Select All"
- shortcut="control|A">
- <menu_item_call.on_click
- function="Edit.SelectAll" />
- <menu_item_call.on_enable
- function="Edit.EnableSelectAll" />
- </menu_item_call>
- <menu_item_call
- label="Deselect"
- layout="topleft"
- name="Deselect"
- shortcut="control|E">
- <menu_item_call.on_click
- function="Edit.Deselect" />
- <menu_item_call.on_enable
- function="Edit.EnableDeselect" />
- </menu_item_call>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Link"
- layout="topleft"
- name="Link"
- shortcut="control|L">
- <menu_item_call.on_click
- function="Tools.Link" />
- <menu_item_call.on_enable
- function="Tools.EnableLink" />
- </menu_item_call>
- <menu_item_call
- label="Unlink"
- layout="topleft"
- name="Unlink"
- shortcut="control|shift|L">
- <menu_item_call.on_click
- function="Tools.Unlink" />
- <menu_item_call.on_enable
- function="Tools.EnableUnlink" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Focus on Selection"
- layout="topleft"
- name="Focus on Selection"
- shortcut="H">
- <menu_item_call.on_click
- function="Tools.LookAtSelection"
- parameter="focus" />
- <menu_item_call.on_enable
- function="Tools.SomethingSelectedNoHUD" />
- </menu_item_call>
- <menu_item_call
- label="Zoom to Selection"
- layout="topleft"
- name="Zoom to Selection"
- shortcut="shift|H">
- <menu_item_call.on_click
- function="Tools.LookAtSelection"
- parameter="zoom" />
- <menu_item_call.on_enable
- function="Tools.SomethingSelectedNoHUD" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu
- create_jump_keys="true"
- label="Object"
- layout="topleft"
- name="Object"
- tear_off="true">
- <menu_item_call
- label="Buy"
- layout="topleft"
- name="Menu Object Take"
- visible="true">
- <menu_item_call.on_click
- function="Tools.BuyOrTake" />
- <menu_item_call.on_enable
- function="Tools.EnableBuyOrTake"
- name="EnableBuyOrTake"
- parameter="Buy,Take" />
- </menu_item_call>
- <menu_item_call
- label="Take Copy"
- layout="topleft"
- name="Take Copy">
- <menu_item_call.on_click
- function="Tools.TakeCopy" />
- <menu_item_call.on_enable
- function="Tools.EnableTakeCopy" />
- </menu_item_call>
- <menu_item_call
- label="Save Back to My Inventory"
- layout="topleft"
- name="Save Object Back to My Inventory">
- <menu_item_call.on_click
- function="Tools.SaveToInventory" />
- <menu_item_call.on_enable
- function="Tools.EnableSaveToInventory" />
- </menu_item_call>
- <menu_item_call
- label="Save Back to Object Contents"
- layout="topleft"
- name="Save Object Back to Object Contents">
- <menu_item_call.on_click
- function="Tools.SaveToObjectInventory" />
- <menu_item_call.on_enable
- function="Tools.EnableSaveToObjectInventory" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Scripts"
- layout="topleft"
- name="Scripts"
- tear_off="true">
- <menu_item_call
- label="Recompile Scripts (Mono)"
- layout="topleft"
- name="Mono">
- <menu_item_call.on_click
- function="Tools.SelectedScriptAction"
- parameter="compile mono" />
- <menu_item_call.on_enable
- function="EditableSelectedMono" />
- </menu_item_call>
- <menu_item_call
- label="Recompile Scripts (LSL)"
- layout="topleft"
- name="LSL">
- <menu_item_call.on_click
- function="Tools.SelectedScriptAction"
- parameter="compile lsl" />
- <menu_item_call.on_enable
- function="EditableSelected" />
- </menu_item_call>
- <menu_item_call
- label="Reset Scripts"
- layout="topleft"
- name="Reset Scripts">
- <menu_item_call.on_click
- function="Tools.SelectedScriptAction"
- parameter="reset" />
- <menu_item_call.on_enable
- function="EditableSelected" />
- </menu_item_call>
- <menu_item_call
- label="Set Scripts to Running"
- layout="topleft"
- name="Set Scripts to Running">
- <menu_item_call.on_click
- function="Tools.SelectedScriptAction"
- parameter="start" />
- <menu_item_call.on_enable
- function="EditableSelected" />
- </menu_item_call>
- <menu_item_call
- label="Set Scripts to Not Running"
- layout="topleft"
- name="Set Scripts to Not Running">
- <menu_item_call.on_click
- function="Tools.SelectedScriptAction"
- parameter="stop" />
- <menu_item_call.on_enable
- function="EditableSelected" />
- </menu_item_call>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu
- create_jump_keys="true"
- label="Options"
- layout="topleft"
- name="Options"
- tear_off="true">
- <menu_item_check
- label="Edit Linked Parts"
- layout="topleft"
- name="Edit Linked Parts">
- <menu_item_check.on_check
- control="EditLinkedParts" />
- <menu_item_check.on_click
- function="Tools.EditLinkedParts"
- parameter="EditLinkedParts" />
- <menu_item_check.on_enable
- function="Tools.EnableToolNotPie" />
- </menu_item_check>
- <menu_item_call
- label="Set Default Upload Permissions"
- layout="topleft"
- name="perm prefs">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="perm_prefs" />
- </menu_item_call>
- <menu_item_check
- label="Show Advanced Permissions"
- layout="topleft"
- name="DebugPermissions">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugPermissions" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugPermissions" />
- </menu_item_check>
- <!--menu_item_call
- label="Show Script Warning/Error Window"
- layout="topleft"
- name="Show Script Warning/Error Window">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="script errors" />
- </menu_item_call-->
- <menu_item_separator
- layout="topleft" />
- <menu
- create_jump_keys="true"
- label="Selection"
- layout="topleft"
- name="Selection"
- tear_off="true">
- <menu_item_check
- label="Select Only My Objects"
- layout="topleft"
- name="Select Only My Objects">
- <menu_item_check.on_check
- control="SelectOwnedOnly" />
- <menu_item_check.on_click
- function="Tools.SelectOnlyMyObjects"
- parameter="agents" />
- </menu_item_check>
- <menu_item_check
- label="Select Only Movable Objects"
- layout="topleft"
- name="Select Only Movable Objects">
- <menu_item_check.on_check
- control="SelectMovableOnly" />
- <menu_item_check.on_click
- function="Tools.SelectOnlyMovableObjects"
- parameter="movable" />
- </menu_item_check>
- <menu_item_check
- label="Select By Surrounding"
- layout="topleft"
- name="Select By Surrounding">
- <menu_item_check.on_check
- control="RectangleSelectInclusive" />
- <menu_item_check.on_click
- function="Tools.SelectBySurrounding" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Show"
- layout="topleft"
- name="Show"
- tear_off="true">
- <menu_item_check
- label="Show Hidden Selection"
- layout="topleft"
- name="Show Hidden Selection">
- <menu_item_check.on_check
- control="RenderHiddenSelections" />
- <menu_item_check.on_click
- function="Tools.ShowHiddenSelection" />
- </menu_item_check>
- <menu_item_check
- label="Show Light Radius for Selection"
- layout="topleft"
- name="Show Light Radius for Selection">
- <menu_item_check.on_check
- control="RenderLightRadius" />
- <menu_item_check.on_click
- function="Tools.ShowSelectionLightRadius" />
- </menu_item_check>
- <menu_item_check
- label="Show Selection Beam"
- layout="topleft"
- name="Show Selection Beam">
- <menu_item_check.on_check
- control="ShowSelectionBeam" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowSelectionBeam" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Grid"
- layout="topleft"
- name="Grid"
- tear_off="true">
- <menu_item_check
- label="Snap to Grid"
- layout="topleft"
- name="Snap to Grid"
- shortcut="G">
- <menu_item_check.on_check
- control="SnapEnabled" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="SnapEnabled" />
- <menu_item_check.on_enable
- function="Tools.EnableToolNotPie" />
- </menu_item_check>
- <menu_item_call
- label="Snap Object XY to Grid"
- layout="topleft"
- name="Snap Object XY to Grid"
- shortcut="shift|X">
- <menu_item_call.on_click
- function="Tools.SnapObjectXY" />
- <menu_item_call.on_enable
- function="Tools.EnableToolNotPie" />
- </menu_item_call>
- <menu_item_call
- label="Use Selection for Grid"
- layout="topleft"
- name="Use Selection for Grid"
- shortcut="shift|G">
- <menu_item_call.on_click
- function="Tools.UseSelectionForGrid" />
- <menu_item_call.on_enable
- function="SomethingSelected" />
- </menu_item_call>
- <menu_item_call
- label="Grid Options"
- layout="topleft"
- name="Grid Options"
- shortcut="control|shift|B">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="build_options" />
- <menu_item_call.on_enable
- function="Tools.EnableToolNotPie" />
- </menu_item_call>
- </menu>
- </menu>
- <menu
- create_jump_keys="true"
- label="Select Linked Parts"
- layout="topleft"
- name="Select Linked Parts"
- tear_off="true">
- <menu_item_call
- label="Select Next Part"
- layout="topleft"
- name="Select Next Part"
- shortcut="control|.">
- <menu_item_call.on_click
- function="Tools.SelectNextPart"
- parameter="next" />
- <menu_item_call.on_enable
- function="Tools.EnableSelectNextPart" />
- </menu_item_call>
- <menu_item_call
- label="Select Previous Part"
- layout="topleft"
- name="Select Previous Part"
- shortcut="control|,">
- <menu_item_call.on_click
- function="Tools.SelectNextPart"
- parameter="previous" />
- <menu_item_call.on_enable
- function="Tools.EnableSelectNextPart" />
- </menu_item_call>
- <menu_item_call
- label="Include Next Part"
- layout="topleft"
- name="Include Next Part"
- shortcut="control|shift|.">
- <menu_item_call.on_click
- function="Tools.SelectNextPart"
- parameter="includenext" />
- <menu_item_call.on_enable
- function="Tools.EnableSelectNextPart" />
- </menu_item_call>
- <menu_item_call
- label="Include Previous Part"
- layout="topleft"
- name="Include Previous Part"
- shortcut="control|shift|,">
- <menu_item_call.on_click
- function="Tools.SelectNextPart"
- parameter="includeprevious" />
- <menu_item_call.on_enable
- function="Tools.EnableSelectNextPart" />
- </menu_item_call>
- </menu>
- </menu>
- <menu
- label="Help"
- layout="topleft"
- name="Help"
- tear_off="true">
- <menu_item_call
- label="[SECOND_LIFE] Help"
- layout="topleft"
- name="Second Life Help"
- shortcut="F1">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="help f1" />
- </menu_item_call>
- <menu_item_call
- label="Tutorial"
- layout="topleft"
- name="Tutorial">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="hud" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Report Abuse"
- layout="topleft"
- name="Report Abuse">
- <menu_item_call.on_click
- function="ShowFloater"
- parameter="complaint reporter" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="About [APP_NAME]"
- layout="topleft"
- name="About Second Life">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="sl_about" />
- </menu_item_call>
- </menu>
- <menu
- label="Advanced"
- layout="topleft"
- name="Advanced"
- tear_off="true"
- visible="false">
- <menu_item_check
- label="Set Away After 30 Minutes"
- layout="topleft"
- name="Go Away/AFK When Idle">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="AllowIdleAFK" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="AllowIdleAFK" />
- </menu_item_check>
- <menu_item_call
- label="Stop Animating Me"
- layout="topleft"
- name="Stop Animating My Avatar">
- <menu_item_call.on_click
- function="Tools.StopAllAnimations" />
- </menu_item_call>
- <menu_item_call
- label="Rebake Textures"
- layout="topleft"
- name="Rebake Texture"
- shortcut="control|alt|R">
- <menu_item_call.on_click
- function="Advanced.RebakeTextures" />
- </menu_item_call>
- <menu_item_call
- label="Set UI Size to Default"
- layout="topleft"
- name="Set UI Size to Default">
- <menu_item_call.on_click
- function="View.DefaultUISize" />
- </menu_item_call>
- <menu_item_separator/>
- <menu_item_check
- label="Limit Select Distance"
- layout="topleft"
- name="Limit Select Distance">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="LimitSelectDistance" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="LimitSelectDistance" />
- </menu_item_check>
- <menu_item_check
- label="Disable Camera Constraints"
- layout="topleft"
- name="Disable Camera Distance">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DisableCameraConstraints" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DisableCameraConstraints" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="High-res Snapshot"
- layout="topleft"
- name="HighResSnapshot">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="HighResSnapshot" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="HighResSnapshot" />
- </menu_item_check>
- <menu_item_check
- label="Quiet Snapshots to Disk"
- layout="topleft"
- name="QuietSnapshotsToDisk">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="QuietSnapshotsToDisk" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="QuietSnapshotsToDisk" />
- </menu_item_check>
- <menu_item_check
- label="Compress Snapshots to Disk"
- layout="topleft"
- name="CompressSnapshotsToDisk">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="CompressSnapshotsToDisk" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="CompressSnapshotsToDisk" />
- </menu_item_check>
- <menu_item_call
- label="Save Texture As"
- layout="topleft"
- name="Save Texture As">
- <menu_item_call.on_click
- function="File.SaveTexture" />
- <menu_item_call.on_enable
- function="File.EnableSaveAs" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu
- create_jump_keys="true"
- label="Performance Tools"
- layout="topleft"
- name="Performance Tools"
- tear_off="true">
- <menu_item_call
- label="Lag Meter"
- layout="topleft"
- name="Lag Meter">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="lagmeter" />
- </menu_item_call>
- <menu_item_check
- label="Statistics Bar"
- layout="topleft"
- name="Statistics Bar"
- shortcut="control|shift|1">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="stats" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="stats" />
- </menu_item_check>
- <menu_item_check
- label="Show Avatar Rendering Cost"
- layout="topleft"
- name="Avatar Rendering Cost">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="shame" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="shame" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Highlighting and Visibility"
- layout="topleft"
- name="Highlighting and Visibility"
- tear_off="true">
- <menu_item_check
- label="Cheesy Beacon"
- layout="topleft"
- name="Cheesy Beacon">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="CheesyBeacon" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="CheesyBeacon" />
- </menu_item_check>
- <menu_item_check
- label="Hide Particles"
- layout="topleft"
- name="Hide Particles"
- shortcut="control|alt|shift|=">
- <menu_item_check.on_check
- function="View.CheckRenderType"
- parameter="hideparticles" />
- <menu_item_check.on_click
- function="View.ToggleRenderType"
- parameter="hideparticles" />
- </menu_item_check>
- <menu_item_check
- label="Hide Selected"
- layout="topleft"
- name="Hide Selected">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="HideSelectedObjects" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="HideSelectedObjects" />
- </menu_item_check>
- <menu_item_check
- label="Highlight Transparent"
- layout="topleft"
- name="Highlight Transparent"
- shortcut="control|alt|T">
- <menu_item_check.on_check
- function="View.CheckHighlightTransparent" />
- <menu_item_check.on_click
- function="View.HighlightTransparent" />
- </menu_item_check>
- <menu_item_check
- label="Show HUD Attachments"
- layout="topleft"
- name="Show HUD Attachments"
- shortcut="alt|shift|H">
- <menu_item_check.on_check
- function="View.CheckHUDAttachments" />
- <menu_item_check.on_click
- function="View.ShowHUDAttachments" />
- </menu_item_check>
- <menu_item_check
- label="Show Mouselook Crosshairs"
- layout="topleft"
- name="ShowCrosshairs">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowCrosshairs" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowCrosshairs" />
- </menu_item_check>
- <!-- <menu
- create_jump_keys="true"
- label="Hover Tips"
- layout="topleft"
- name="Hover Tips"
- tear_off="true">
- <menu_item_check
- label="Show Tips"
- layout="topleft"
- name="Show Tips"
- shortcut="control|shift|T">
- <menu_item_check.on_check
- function="View.CheckShowHoverTips" />
- <menu_item_check.on_click
- function="View.ShowHoverTips" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />-->
- <menu_item_check
- label="Show Land Tooltips"
- layout="topleft"
- name="Land Tips">
- <menu_item_check.on_check
- control="ShowLandHoverTip" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowLandHoverTip" />
- <menu_item_check.on_enable
- function="View.CheckShowHoverTips" />
- </menu_item_check>
- <!-- <menu_item_check
- label="Show Tips On All Objects"
- layout="topleft"
- name="Tips On All Objects">
- <menu_item_check.on_check
- control="ShowAllObjectHoverTip" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowAllObjectHoverTip" />
- <menu_item_check.on_enable
- function="View.CheckShowHoverTips" />
- </menu_item_check>
- </menu>-->
-
- </menu>
-
- <menu
- create_jump_keys="true"
- label="Rendering Types"
- layout="topleft"
- name="Rendering Types"
- tear_off="true">
- <menu_item_check
- label="Simple"
- layout="topleft"
- name="Simple"
- shortcut="control|alt|shift|1">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="simple" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="simple" />
- </menu_item_check>
- <menu_item_check
- label="Alpha"
- layout="topleft"
- name="Alpha"
- shortcut="control|alt|shift|2">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="alpha" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="alpha" />
- </menu_item_check>
- <menu_item_check
- label="Tree"
- layout="topleft"
- name="Tree"
- shortcut="control|alt|shift|3">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="tree" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="tree" />
- </menu_item_check>
- <menu_item_check
- label="Avatars"
- layout="topleft"
- name="Character"
- shortcut="control|alt|shift|4">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="character" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="character" />
- </menu_item_check>
- <menu_item_check
- label="SurfacePath"
- layout="topleft"
- name="SurfacePath"
- shortcut="control|alt|shift|5">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="surfacePath" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="surfacePath" />
- </menu_item_check>
- <menu_item_check
- label="Sky"
- layout="topleft"
- name="Sky"
- shortcut="control|alt|shift|6">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="sky" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="sky" />
- </menu_item_check>
- <menu_item_check
- label="Water"
- layout="topleft"
- name="Water"
- shortcut="control|alt|shift|7">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="water" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="water" />
- </menu_item_check>
- <menu_item_check
- label="Ground"
- layout="topleft"
- name="Ground"
- shortcut="control|alt|shift|8">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="ground" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="ground" />
- </menu_item_check>
- <menu_item_check
- label="Volume"
- layout="topleft"
- name="Volume"
- shortcut="control|alt|shift|9">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="volume" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="volume" />
- </menu_item_check>
- <menu_item_check
- label="Grass"
- layout="topleft"
- name="Grass"
- shortcut="control|alt|shift|0">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="grass" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="grass" />
- </menu_item_check>
- <menu_item_check
- label="Clouds"
- layout="topleft"
- name="Clouds"
- shortcut="control|alt|shift|-">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="clouds" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="clouds" />
- </menu_item_check>
- <menu_item_check
- label="Particles"
- layout="topleft"
- name="Particles"
- shortcut="control|alt|shift|=">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="particles" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="particles" />
- </menu_item_check>
- <menu_item_check
- label="Bump"
- layout="topleft"
- name="Bump"
- shortcut="control|alt|shift|\">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="bump" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="bump" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Rendering Features"
- layout="topleft"
- name="Rendering Features"
- tear_off="true">
- <menu_item_check
- label="UI"
- layout="topleft"
- name="UI"
- shortcut="control|alt|F1">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="ui" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="ui" />
- </menu_item_check>
- <menu_item_check
- label="Selected"
- layout="topleft"
- name="Selected"
- shortcut="control|alt|F2">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="selected" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="selected" />
- </menu_item_check>
- <menu_item_check
- label="Highlighted"
- layout="topleft"
- name="Highlighted"
- shortcut="control|alt|F3">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="highlighted" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="highlighted" />
- </menu_item_check>
- <menu_item_check
- label="Dynamic Textures"
- layout="topleft"
- name="Dynamic Textures"
- shortcut="control|alt|F4">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="dynamic textures" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="dynamic textures" />
- </menu_item_check>
- <menu_item_check
- label="Foot Shadows"
- layout="topleft"
- name="Foot Shadows"
- shortcut="control|alt|F5">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="foot shadows" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="foot shadows" />
- </menu_item_check>
- <menu_item_check
- label="Fog"
- layout="topleft"
- name="Fog"
- shortcut="control|alt|F6">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="fog" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="fog" />
- </menu_item_check>
- <menu_item_check
- label="Test FRInfo"
- layout="topleft"
- name="Test FRInfo"
- shortcut="control|alt|F8">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="fr info" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="fr info" />
- </menu_item_check>
- <menu_item_check
- label="Flexible Objects"
- layout="topleft"
- name="Flexible Objects"
- shortcut="control|alt|F9">
- <menu_item_check.on_check
- function="Advanced.CheckFeature"
- parameter="flexible" />
- <menu_item_check.on_click
- function="Advanced.ToggleFeature"
- parameter="flexible" />
- </menu_item_check>
- </menu>
- <menu_item_check
- label="Run Multiple Threads"
- layout="topleft"
- name="Run Multiple Threads">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RunMultipleThreads" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RunMultipleThreads" />
- </menu_item_check>
- <menu_item_call
- label="Clear Group Cache"
- layout="topleft"
- name="ClearGroupCache">
- <menu_item_call.on_click
- function="Advanced.ClearGroupCache"
- parameter="ClearGroupCache" />
- </menu_item_call>
- <menu_item_check
- label="Mouse Smoothing"
- layout="topleft"
- name="Mouse Smoothing">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="MouseSmooth" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="MouseSmooth" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu
- label="Shortcuts"
- layout="topleft"
- name="Shortcuts"
- tear_off="true"
- visible="false">
- <menu_item_check
- label="Search"
- layout="topleft"
- name="Search"
- shortcut="control|F">
- <menu_item_check.on_check
- function="Floater.Visible"
- parameter="search" />
- <menu_item_check.on_click
- function="Floater.Toggle"
- parameter="search" />
- </menu_item_check>
- <menu_item_call
- enabled="false"
- label="Release Keys"
- layout="topleft"
- name="Release Keys">
- <menu_item_call.on_click
- function="Tools.ReleaseKeys"
- parameter="" />
- <menu_item_call.on_enable
- function="Tools.EnableReleaseKeys"
- parameter="" />
- </menu_item_call>
- <menu_item_call
- label="Set UI Size to Default"
- layout="topleft"
- name="Set UI Size to Default">
- <menu_item_call.on_click
- function="View.DefaultUISize" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="Always Run"
- layout="topleft"
- name="Always Run"
- shortcut="control|R">
- <menu_item_check.on_check
- function="World.CheckAlwaysRun" />
- <menu_item_check.on_click
- function="World.AlwaysRun" />
- </menu_item_check>
- <menu_item_check
- label="Fly"
- layout="topleft"
- name="Fly"
- shortcut="Home">
- <menu_item_check.on_click
- function="Agent.toggleFlying" />
- <menu_item_check.on_enable
- function="Agent.enableFlying" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Close Window"
- layout="topleft"
- name="Close Window"
- shortcut="control|W">
- <menu_item_call.on_click
- function="File.CloseWindow" />
- <menu_item_call.on_enable
- function="File.EnableCloseWindow" />
- </menu_item_call>
- <menu_item_call
- label="Close All Windows"
- layout="topleft"
- name="Close All Windows"
- shortcut="control|shift|W">
- <menu_item_call.on_click
- function="File.CloseAllWindows" />
- <menu_item_call.on_enable
- function="File.EnableCloseAllWindows" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Snapshot to Disk"
- layout="topleft"
- name="Snapshot to Disk"
- shortcut="control|`"
- use_mac_ctrl="true">
- <menu_item_call.on_click
- function="File.TakeSnapshotToDisk" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Mouselook"
- layout="topleft"
- name="Mouselook"
- shortcut="M">
- <menu_item_call.on_click
- function="View.Mouselook" />
- <menu_item_call.on_enable
- function="View.EnableMouselook" />
- </menu_item_call>
- <menu_item_check
- label="Joystick Flycam"
- layout="topleft"
- name="Joystick Flycam"
- shortcut="alt|shift|F">
- <menu_item_check.on_check
- function="View.CheckJoystickFlycam" />
- <menu_item_check.on_click
- function="View.JoystickFlycam" />
- <menu_item_check.on_enable
- function="View.EnableJoystickFlycam" />
- </menu_item_check>
- <menu_item_call
- label="Reset View"
- layout="topleft"
- name="Reset View"
- shortcut="Esc">
- <menu_item_call.on_click
- function="View.ResetView" />
- </menu_item_call>
- <menu_item_call
- label="Look at Last Chatter"
- layout="topleft"
- name="Look at Last Chatter"
- shortcut="control|\">
- <menu_item_call.on_click
- function="View.LookAtLastChatter" />
- <menu_item_call.on_enable
- function="View.EnableLastChatter" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu
- create_jump_keys="true"
- label="Select Build Tool"
- layout="topleft"
- name="Select Tool"
- tear_off="true">
- <menu_item_call
- label="Focus Tool"
- layout="topleft"
- name="Focus"
- shortcut="control|1">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="focus" />
- </menu_item_call>
- <menu_item_call
- label="Move Tool"
- layout="topleft"
- name="Move"
- shortcut="control|2">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="move" />
- </menu_item_call>
- <menu_item_call
- label="Edit Tool"
- layout="topleft"
- name="Edit"
- shortcut="control|3">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="edit" />
- </menu_item_call>
- <menu_item_call
- label="Create Tool"
- layout="topleft"
- name="Create"
- shortcut="control|4">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="create" />
- </menu_item_call>
- <menu_item_call
- label="Land Tool"
- layout="topleft"
- name="Land"
- shortcut="control|5">
- <menu_item_call.on_click
- function="Tools.SelectTool"
- parameter="land" />
- </menu_item_call>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Zoom In"
- layout="topleft"
- name="Zoom In"
- shortcut="control|0">
- <menu_item_call.on_click
- function="View.ZoomIn" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- layout="topleft"
- name="Zoom Default"
- shortcut="control|9">
- <menu_item_call.on_click
- function="View.ZoomDefault" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Out"
- layout="topleft"
- name="Zoom Out"
- shortcut="control|8">
- <menu_item_call.on_click
- function="View.ZoomOut" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Toggle Fullscreen"
- layout="topleft"
- name="Toggle Fullscreen"
- >
- <!-- Note: shortcut="alt|Enter" was deleted from the preceding node-->
- <menu_item_call.on_click
- function="View.Fullscreen" />
- </menu_item_call>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Show Debug Settings"
- layout="topleft"
- name="Debug Settings">
- <menu_item_call.on_click
- function="Advanced.ShowDebugSettings"
- parameter="all" />
- </menu_item_call>
- <menu_item_check
- label="Show Develop Menu"
- layout="topleft"
- name="Debug Mode"
- shortcut="control|alt|Q">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="QAMode" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="QAMode" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Develop"
- layout="topleft"
- name="Develop"
- tear_off="true"
- visible="false">
- <menu
- create_jump_keys="true"
- label="Consoles"
- layout="topleft"
- name="Consoles"
- tear_off="true">
- <menu_item_check
- label="Texture Console"
- layout="topleft"
- name="Texture Console"
- shortcut="control|shift|3"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="texture" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="texture" />
- </menu_item_check>
- <menu_item_check
- label="Debug Console"
- layout="topleft"
- name="Debug Console"
- shortcut="control|shift|4"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="debug" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="debug" />
- </menu_item_check>
- <menu_item_call
- label="Notifications Console"
- layout="topleft"
- name="Notifications"
- shortcut="control|shift|5">
- <menu_item_call.on_click
- function="Floater.Toggle"
- parameter="notifications_console" />
- </menu_item_call>
- <menu_item_check
- label="Texture Size Console"
- layout="topleft"
- name="Texture Size"
- shortcut="control|shift|6">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="texture size" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="texture size" />
- </menu_item_check>
- <menu_item_check
- label="Texture Category Console"
- layout="topleft"
- name="Texture Category"
- shortcut="control|shift|7">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="texture category" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="texture category" />
- </menu_item_check>
- <menu_item_check
- label="Fast Timers"
- layout="topleft"
- name="Fast Timers"
- shortcut="control|shift|9"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="fast timers" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="fast timers" />
- </menu_item_check>
- <menu_item_check
- label="Memory"
- layout="topleft"
- name="Memory"
- shortcut="control|shift|0"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="Advanced.CheckConsole"
- parameter="memory view" />
- <menu_item_check.on_click
- function="Advanced.ToggleConsole"
- parameter="memory view" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Region Info to Debug Console"
- layout="topleft"
- name="Region Info to Debug Console">
- <menu_item_call.on_click
- function="Advanced.DumpInfoToConsole"
- parameter="region" />
- </menu_item_call>
- <menu_item_call
- label="Group Info to Debug Console"
- layout="topleft"
- name="Group Info to Debug Console">
- <menu_item_call.on_click
- function="Advanced.DumpInfoToConsole"
- parameter="group" />
- </menu_item_call>
- <menu_item_call
- label="Capabilities Info to Debug Console"
- layout="topleft"
- name="Capabilities Info to Debug Console">
- <menu_item_call.on_click
- function="Advanced.DumpInfoToConsole"
- parameter="capabilities" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="Camera"
- layout="topleft"
- name="Camera">
- <menu_item_check.on_check
- function="Advanced.CheckHUDInfo"
- parameter="camera" />
- <menu_item_check.on_click
- function="Advanced.ToggleHUDInfo"
- parameter="camera" />
- </menu_item_check>
- <menu_item_check
- label="Wind"
- layout="topleft"
- name="Wind">
- <menu_item_check.on_check
- function="Advanced.CheckHUDInfo"
- parameter="wind" />
- <menu_item_check.on_click
- function="Advanced.ToggleHUDInfo"
- parameter="wind" />
- </menu_item_check>
- <menu_item_check
- label="FOV"
- layout="topleft"
- name="FOV">
- <menu_item_check.on_check
- function="Advanced.CheckHUDInfo"
- parameter="fov" />
- <menu_item_check.on_click
- function="Advanced.ToggleHUDInfo"
- parameter="fov" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Show Info"
- layout="topleft"
- name="Display Info"
- tear_off="true">
- <menu_item_check
- label="Show Time"
- layout="topleft"
- name="Show Time">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugShowTime" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugShowTime" />
- </menu_item_check>
- <menu_item_check
- label="Show Render Info"
- layout="topleft"
- name="Show Render Info">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugShowRenderInfo" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugShowRenderInfo" />
- </menu_item_check>
- <menu_item_check
- label="Show Matrices"
- layout="topleft"
- name="Show Matrices">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugShowRenderMatrices" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugShowRenderMatrices" />
- </menu_item_check>
- <menu_item_check
- label="Show Color Under Cursor"
- layout="topleft"
- name="Show Color Under Cursor">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugShowColor" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugShowColor" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="Show Updates to Objects"
- layout="topleft"
- name="Show Updates"
- shortcut="control|alt|shift|U">
- <menu_item_check.on_check
- function="Advanced.CheckShowObjectUpdates"
- parameter="ObjectUpdates" />
- <menu_item_check.on_click
- function="Advanced.ToggleShowObjectUpdates" />
- </menu_item_check>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu
- create_jump_keys="true"
- label="Force an Error"
- layout="topleft"
- name="Force Errors"
- tear_off="true">
- <menu_item_call
- label="Force Breakpoint"
- layout="topleft"
- name="Force Breakpoint"
- shortcut="control|alt|shift|B">
- <menu_item_call.on_click
- function="Advanced.ForceErrorBreakpoint" />
- </menu_item_call>
- <menu_item_call
- label="Force LLError And Crash"
- layout="topleft"
- name="Force LLError And Crash">
- <menu_item_call.on_click
- function="Advanced.ForceErrorLlerror" />
- </menu_item_call>
- <menu_item_call
- label="Force Bad Memory Access"
- layout="topleft"
- name="Force Bad Memory Access">
- <menu_item_call.on_click
- function="Advanced.ForceErrorBadMemoryAccess" />
- </menu_item_call>
- <menu_item_call
- label="Force Infinite Loop"
- layout="topleft"
- name="Force Infinite Loop">
- <menu_item_call.on_click
- function="Advanced.ForceErrorInfiniteLoop" />
- </menu_item_call>
- <menu_item_call
- label="Force Driver Crash"
- layout="topleft"
- name="Force Driver Carsh">
- <menu_item_call.on_click
- function="Advanced.ForceErrorDriverCrash" />
- </menu_item_call>
- <menu_item_call
- label="Force Software Exception"
- layout="topleft"
- name="Force Software Exception">
- <menu_item_call.on_click
- function="Advanced.ForceErrorSoftwareException" />
- </menu_item_call>
- <menu_item_call
- label="Force Disconnect Viewer"
- layout="topleft"
- name="Force Disconnect Viewer">
- <menu_item_call.on_click
- function="Advanced.ForceErrorDisconnectViewer" />
- </menu_item_call>
- <menu_item_call
- label="Simulate a Memory Leak..."
- layout="topleft"
- name="Memory Leaking Simulation">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="mem_leaking" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Render Tests"
- layout="topleft"
- name="Render Tests"
- tear_off="true">
- <menu_item_check
- label="Camera Offset"
- layout="topleft"
- name="Camera Offset">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="CameraOffset" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="CameraOffset" />
- </menu_item_check>
- <menu_item_check
- label="Randomize Framerate"
- layout="topleft"
- name="Randomize Framerate">
- <menu_item_check.on_check
- function="Advanced.CheckRandomizeFramerate"
- parameter="Randomize Framerate" />
- <menu_item_check.on_click
- function="Advanced.ToggleRandomizeFramerate" />
- </menu_item_check>
- <menu_item_check
- label="Periodic Slow Frame"
- layout="topleft"
- name="Periodic Slow Frame">
- <menu_item_check.on_check
- function="Advanced.CheckPeriodicSlowFrame"
- parameter="points" />
- <menu_item_check.on_click
- function="Advanced.TogglePeriodicSlowFrame"
- parameter="points" />
- </menu_item_check>
- <menu_item_check
- label="Frame Test"
- layout="topleft"
- name="Frame Test">
- <menu_item_check.on_check
- function="Advanced.CheckFrameTest"
- parameter="Frame Test" />
- <menu_item_check.on_click
- function="Advanced.ToggleFrameTest" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Render Metadata"
- layout="topleft"
- name="Render Metadata"
- tear_off="true">
- <menu_item_check
- label="Bounding Boxes"
- layout="topleft"
- name="Bounding Boxes">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="bboxes" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="bboxes" />
- </menu_item_check>
- <menu_item_check
- label="Octree"
- layout="topleft"
- name="Octree">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="octree" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="octree" />
- </menu_item_check>
- <menu_item_check
- label="Shadow Frusta"
- layout="topleft"
- name="Shadow Frusta">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="shadow frusta" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="shadow frusta" />
- </menu_item_check>
- <menu_item_check
- label="Occlusion"
- layout="topleft"
- name="Occlusion">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="occlusion" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="occlusion" />
- </menu_item_check>
- <menu_item_check
- label="Render Batches"
- layout="topleft"
- name="Render Batches">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="render batches" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="render batches" />
- </menu_item_check>
- <menu_item_check
- label="Texture Anim"
- layout="topleft"
- name="Texture Anim">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="texture anim" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="texture anim" />
- </menu_item_check>
- <menu_item_check
- label="Texture Priority"
- layout="topleft"
- name="Texture Priority">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="texture priority" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="texture priority" />
- </menu_item_check>
- <menu_item_check
- label="Texture Area"
- layout="topleft"
- name="Texture Area">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="texture area" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="texture area" />
- </menu_item_check>
- <menu_item_check
- label="Face Area"
- layout="topleft"
- name="Face Area">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="face area" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="face area" />
- </menu_item_check>
- <menu_item_check
- label="Lights"
- layout="topleft"
- name="Lights">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="lights" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="lights" />
- </menu_item_check>
- <menu_item_check
- label="Collision Skeleton"
- layout="topleft"
- name="Collision Skeleton">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="collision skeleton" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="collision skeleton" />
- </menu_item_check>
- <menu_item_check
- label="Raycast"
- layout="topleft"
- name="Raycast">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="raycast" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="raycast" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="Rendering"
- layout="topleft"
- name="Rendering"
- tear_off="true">
- <menu_item_check
- label="Axes"
- name="Axes">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowAxes" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowAxes" />
- </menu_item_check>
- <menu_item_check
- label="Tangent Basis"
- name="Tangent Basis">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowTangentBasis" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowTangentBasis" />
- </menu_item_check>
- <menu_item_call
- label="Selected Texture Info Basis"
- name="Selected Texture Info Basis"
- shortcut="control|alt|shift|T">
- <menu_item_call.on_click
- function="Advanced.SelectedTextureInfo" />
- </menu_item_call>
- <menu_item_check
- label="Wireframe"
- name="Wireframe"
- shortcut="control|shift|R">
- <menu_item_check.on_check
- function="Advanced.CheckWireframe"
- parameter="Wireframe" />
- <menu_item_check.on_click
- function="Advanced.ToggleWireframe" />
- </menu_item_check>
- <menu_item_check
- label="Object-Object Occlusion"
- name="Object-Object Occlusion"
- shortcut="control|shift|O">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="UseOcclusion" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="UseOcclusion" />
- <menu_item_check.on_enable
- function="Advanced.EnableObjectObjectOcclusion" />
- </menu_item_check>
- <menu_item_check
- label="Framebuffer Objects"
- name="Framebuffer Objects">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderUseFBO" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderUseFBO" />
- <menu_item_check.on_enable
- function="Advanced.EnableRenderFBO" />
- </menu_item_check>
- <menu_item_check
- label="Deferred Rendering"
- name="Deferred Rendering">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_enable
- function="Advanced.EnableRenderDeferred" />
- </menu_item_check>
- <menu_item_check
- label="Global Illumintation"
- name="Global Illumination">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDeferredGI" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDeferredGI" />
- <menu_item_check.on_enable
- function="Advanced.EnableRenderDeferredGI" />
- </menu_item_check>
- <menu_item_separator />
- <menu_item_check
- label="Debug GL"
- name="Debug GL">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDebugGL" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDebugGL" />
- </menu_item_check>
- <menu_item_check
- label="Debug Pipeline"
- name="Debug Pipeline">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDebugGL" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDebugGL" />
- </menu_item_check>
- <menu_item_check
- label="Fast Alpha"
- name="Fast Alpha">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDebugGL" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDebugGL" />
- </menu_item_check>
- <menu_item_check
- label="Animation Textures"
- name="Animation Textures">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDebugGL" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDebugGL" />
- </menu_item_check>
- <menu_item_check
- label="Disable Textures"
- name="Disable Textures">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="TextureDisable" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="TextureDisable" />
- </menu_item_check>
- <menu_item_check
- label="Full Res Textures"
- layout="topleft"
- name="Rull Res Textures">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="TextureLoadFullRes" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="TextureLoadFullRes" />
- </menu_item_check>
- <menu_item_check
- label="Audit Textures"
- layout="topleft"
- name="Audit Textures">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="AuditTexture" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="AuditTexture" />
- </menu_item_check>
- <menu_item_check
- label="Texture Atlas"
- name="Texture Atlas">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="EnableTextureAtlas" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="EnableTextureAtlas" />
- </menu_item_check>
- <menu_item_check
- label="Render Attached Lights"
- name="Render Attached Lights">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderAttachedLights" />
- <menu_item_check.on_click
- function="Advanced.HandleAttchedLightParticles"
- parameter="RenderAttachedLights" />
- </menu_item_check>
- <menu_item_check
- label="Render Attached Particles"
- name="Render Attached Particles">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderAttachedParticles" />
- <menu_item_check.on_click
- function="Advanced.HandleAttchedLightParticles"
- parameter="RenderAttachedParticles" />
- </menu_item_check>
- <menu_item_check
- label="Hover Glow Objects"
- name="Hover Glow Objects">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderHoverGlowEnable" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderHoverGlowEnable" />
- </menu_item_check>
- </menu>
-
- <menu
- create_jump_keys="true"
- label="Network"
- layout="topleft"
- name="Network"
- tear_off="true">
- <menu_item_check
- label="Pause Agent"
- layout="topleft"
- name="AgentPause">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="AgentPause" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="AgentPause" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Enable Message Log"
- layout="topleft"
- name="Enable Message Log">
- <menu_item_call.on_click
- function="Advanced.EnableMessageLog" />
- </menu_item_call>
- <menu_item_call
- label="Disable Message Log"
- layout="topleft"
- name="Disable Message Log">
- <menu_item_call.on_click
- function="Advanced.DisableMessageLog" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="Velocity Interpolate Objects"
- layout="topleft"
- name="Velocity Interpolate Objects">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="VelocityInterpolate" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="VelocityInterpolate" />
- </menu_item_check>
- <menu_item_check
- label="Ping Interpolate Object Positions"
- layout="topleft"
- name="Ping Interpolate Object Positions">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="PingInterpolate" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="PingInterpolate" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Drop a Packet"
- layout="topleft"
- name="Drop a Packet"
- shortcut="control|alt|L">
- <menu_item_call.on_click
- function="Advanced.DropPacket" />
- </menu_item_call>
- </menu>
- <menu_item_call
- label="Dump Scripted Camera"
- layout="topleft"
- name="Dump Scripted Camera">
- <menu_item_call.on_click
- function="Advanced.DumpScriptedCamera" />
- </menu_item_call>
- <menu_item_call
- label="Bumps, Pushes &amp; Hits"
- layout="topleft"
- name="Bumps, Pushes &amp;amp; Hits">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="bumps" />
- </menu_item_call>
-
- <menu
- create_jump_keys="true"
- label="Recorder"
- layout="topleft"
- name="Recorder"
- tear_off="true">
- <menu_item_call
- label="Start Playback"
- layout="topleft"
- name="Start Playback">
- <menu_item_call.on_click
- function="Advanced.AgentPilot"
- parameter="start playback" />
- </menu_item_call>
- <menu_item_call
- label="Stop Playback"
- layout="topleft"
- name="Stop Playback">
- <menu_item_call.on_click
- function="Advanced.AgentPilot"
- parameter="stop playback" />
- </menu_item_call>
- <menu_item_check
- label="Loop Playback"
- layout="topleft"
- name="Loop Playback">
- <menu_item_check.on_check
- function="Advanced.CheckAgentPilotLoop"
- parameter="loopPlayback" />
- <menu_item_check.on_click
- function="Advanced.ToggleAgentPilotLoop" />
- </menu_item_check>
- <menu_item_call
- label="Start Record"
- layout="topleft"
- name="Start Record">
- <menu_item_call.on_click
- function="Advanced.AgentPilot"
- parameter="start record" />
- </menu_item_call>
- <menu_item_call
- label="Stop Record"
- layout="topleft"
- name="Stop Record">
- <menu_item_call.on_click
- function="Advanced.AgentPilot"
- parameter="stop record" />
- </menu_item_call>
- </menu>
-
- <menu
- create_jump_keys="true"
- label="World"
- layout="topleft"
- name="World"
- tear_off="true">
- <menu_item_check
- label="Sim Sun Override"
- layout="topleft"
- name="Sim Sun Override">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="SkyOverrideSimSunPosition" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="SkyOverrideSimSunPosition" />
- </menu_item_check>
- <menu_item_check
- label="Cheesy Beacon"
- layout="topleft"
- name="Cheesy Beacon">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="CheesyBeacon" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="CheesyBeacon" />
- </menu_item_check>
- <menu_item_check
- label="Fixed Weather"
- layout="topleft"
- name="Fixed Weather">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="FixedWeather" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="FixedWeather" />
- </menu_item_check>
- <menu_item_call
- label="Dump Region Object Cache"
- layout="topleft"
- name="Dump Region Object Cache">
- <menu_item_call.on_click
- function="Advanced.DumpRegionObjectCache" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="UI"
- layout="topleft"
- name="UI"
- tear_off="true">
- <!-- <menu_item_check
- label="New Bottom Bar"
- layout="topleft"
- name="New Bottom Bar">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="BottomPanelNew" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="BottomPanelNew" />
- </menu_item_check>-->
- <menu_item_call
- label="Web Browser Test"
- layout="topleft"
- name="Web Browser Test">
- <menu_item_call.on_click
- function="Advanced.WebBrowserTest"
- parameter="http://secondlife.com/app/search/slurls.html"/>
- </menu_item_call>
- <menu_item_call
- label="Dump SelectMgr"
- layout="topleft"
- name="Dump SelectMgr">
- <menu_item_call.on_click
- function="Advanced.DumpSelectMgr" />
- </menu_item_call>
- <menu_item_call
- label="Dump Inventory"
- layout="topleft"
- name="Dump Inventory">
- <menu_item_call.on_click
- function="Advanced.DumpInventory" />
- </menu_item_call>
- <menu_item_call
- label="Dump Timers"
- name="Dump Timers">
- <menu_item_call.on_click
- function="Advanced.DumpTimers" />
- </menu_item_call>
- <menu_item_call
- label="Dump Focus Holder"
- layout="topleft"
- name="Dump Focus Holder"
- shortcut="control|alt|F">
- <menu_item_call.on_click
- function="Advanced.DumpFocusHolder" />
- </menu_item_call>
- <menu_item_call
- label="Print Selected Object Info"
- layout="topleft"
- name="Print Selected Object Info"
- shortcut="control|shift|P">
- <menu_item_call.on_click
- function="Advanced.PrintSelectedObjectInfo" />
- </menu_item_call>
- <menu_item_call
- label="Print Agent Info"
- layout="topleft"
- name="Print Agent Info"
- shortcut="shift|P">
- <menu_item_call.on_click
- function="Advanced.PrintAgentInfo" />
- </menu_item_call>
- <menu_item_call
- label="Memory Stats"
- layout="topleft"
- name="Memory Stats"
- shortcut="control|alt|shift|M">
- <menu_item_call.on_click
- function="Advanced.PrintTextureMemoryStats" />
- </menu_item_call>
- <menu_item_check
- label="Double-ClickAuto-Pilot"
- layout="topleft"
- name="Double-ClickAuto-Pilot">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DoubleClickAutoPilot" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DoubleClickAutoPilot" />
- </menu_item_check>
-
- <menu_item_separator />
- <menu_item_check
- label="Debug SelectMgr"
- layout="topleft"
- name="Debug SelectMgr">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugSelectMgr" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugSelectMgr" />
- </menu_item_check>
- <menu_item_check
- label="Debug Clicks"
- layout="topleft"
- name="Debug Clicks">
- <menu_item_check.on_check
- function="Advanced.CheckDebugClicks"
- parameter="DebugClicks" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugClicks"
- parameter="DebugClicks" />
- </menu_item_check>
- <menu_item_check
- label="Debug Views"
- layout="topleft"
- name="Debug Views">
- <menu_item_check.on_check
- function="Advanced.CheckDebugViews" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugViews" />
- </menu_item_check>
- <menu_item_check
- label="Debug Name Tooltips"
- layout="topleft"
- name="Debug Name Tooltips">
- <menu_item_check.on_check
- function="Advanced.CheckXUINameTooltips"
- parameter="XUINameTooltips" />
- <menu_item_check.on_click
- function="Advanced.ToggleXUINameTooltips" />
- </menu_item_check>
- <menu_item_check
- label="Debug Mouse Events"
- layout="topleft"
- name="Debug Mouse Events">
- <menu_item_check.on_check
- function="Advanced.CheckDebugMouseEvents"
- parameter="MouseEvents" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugMouseEvents" />
- </menu_item_check>
- <menu_item_check
- label="Debug Keys"
- layout="topleft"
- name="Debug Keys">
- <menu_item_check.on_check
- function="Advanced.CheckDebugKeys"
- parameter="DebugKeys" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugKeys" />
- </menu_item_check>
- <menu_item_check
- label="Debug WindowProc"
- layout="topleft"
- name="Debug WindowProc">
- <menu_item_check.on_check
- function="Advanced.CheckDebugWindowProc"
- parameter="DebugWindowProc" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugWindowProc"
- parameter="DebugWindowProc" />
- </menu_item_check>
- </menu>
- <menu
- create_jump_keys="true"
- label="XUI"
- name="XUI"
- tear_off="true">
- <menu_item_call
- label="Reload Color Settings"
- layout="topleft"
- name="Reload Color Settings">
- <menu_item_call.on_click
- function="Advanced.ReloadColorSettings" />
- </menu_item_call>
- <menu_item_call
- label="Show Font Test"
- layout="topleft"
- name="Show Font Test">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="font_test" />
- </menu_item_call>
- <menu_item_call
- label="Load from XML..."
- layout="topleft"
- name="Load from XML">
- <menu_item_call.on_click
- function="Advanced.LoadUIFromXML" />
- </menu_item_call>
- <menu_item_call
- label="Save to XML..."
- layout="topleft"
- name="Save to XML">
- <menu_item_call.on_click
- function="Advanced.SaveUIToXML" />
- </menu_item_call>
- <menu_item_check
- label="Show XUI Names"
- layout="topleft"
- name="Show XUI Names">
- <menu_item_check.on_check
- function="Advanced.CheckXUINames"
- parameter="showUIname" />
- <menu_item_check.on_click
- function="Advanced.ToggleXUINames" />
- </menu_item_check>
- <menu_item_call
- label="Send Test IMs"
- layout="topleft"
- name="Send Test IMs">
- <menu_item_call.on_click
- function="Advanced.SendTestIMs" />
- </menu_item_call>
- <menu_item_call
- label="Test Inspectors"
- name="Test Inspectors"
- shortcut="control|shift|I">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="test_inspectors" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Avatar"
- layout="topleft"
- name="Character"
- tear_off="true">
- <menu
- create_jump_keys="true"
- label="Grab Baked Texture"
- layout="topleft"
- name="Grab Baked Texture"
- tear_off="true">
- <menu_item_call
- label="Iris"
- layout="topleft"
- name="Iris">
- <menu_item_call.on_click
- function="Advanced.GrabBakedTexture"
- parameter="iris" />
- <menu_item_call.on_enable
- function="Advanced.EnableGrabBakedTexture"
- parameter="iris" />
- </menu_item_call>
- <menu_item_call
- label="Head"
- layout="topleft"
- name="Head">
- <menu_item_call.on_click
- function="Advanced.GrabBakedTexture"
- parameter="head" />
- <menu_item_call.on_enable
- function="Advanced.EnableGrabBakedTexture"
- parameter="head" />
- </menu_item_call>
- <menu_item_call
- label="Upper Body"
- layout="topleft"
- name="Upper Body">
- <menu_item_call.on_click
- function="Advanced.GrabBakedTexture"
- parameter="upper" />
- <menu_item_call.on_enable
- function="Advanced.EnableGrabBakedTexture"
- parameter="upper" />
- </menu_item_call>
- <menu_item_call
- label="Lower Body"
- layout="topleft"
- name="Lower Body">
- <menu_item_call.on_click
- function="Advanced.GrabBakedTexture"
- parameter="lower" />
- <menu_item_call.on_enable
- function="Advanced.EnableGrabBakedTexture"
- parameter="lower" />
- </menu_item_call>
- <menu_item_call
- label="Skirt"
- layout="topleft"
- name="Skirt">
- <menu_item_call.on_click
- function="Advanced.GrabBakedTexture"
- parameter="skirt" />
- <menu_item_call.on_enable
- function="Advanced.EnableGrabBakedTexture"
- parameter="skirt" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Character Tests"
- layout="topleft"
- name="Character Tests"
- tear_off="true">
- <menu_item_call
- label="Appearance To XML"
- layout="topleft"
- name="Appearance To XML">
- <menu_item_call.on_click
- function="Advanced.AppearanceToXML" />
- </menu_item_call>
- <menu_item_call
- label="Toggle Character Geometry"
- layout="topleft"
- name="Toggle Character Geometry">
- <menu_item_call.on_click
- function="Advanced.ToggleCharacterGeometry" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Test Male"
- layout="topleft"
- name="Test Male">
- <menu_item_call.on_click
- function="Advanced.TestMale" />
- </menu_item_call>
- <menu_item_call
- label="Test Female"
- layout="topleft"
- name="Test Female">
- <menu_item_call.on_click
- function="Advanced.TestFemale" />
- </menu_item_call>
- <menu_item_call
- label="Toggle PG"
- layout="topleft"
- name="Toggle PG">
- <menu_item_call.on_click
- function="Advanced.TogglePG" />
- </menu_item_call>
- <menu_item_check
- label="Allow Select Avatar"
- layout="topleft"
- name="Allow Select Avatar">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="AllowSelectAvatar" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="AllowSelectAvatar" />
- </menu_item_check>
- </menu>
- <menu_item_call
- label="Force Params to Default"
- layout="topleft"
- name="Force Params to Default">
- <menu_item_call.on_click
- function="Advanced.ForceParamsToDefault" />
- </menu_item_call>
- <menu_item_check
- label="Animation Info"
- layout="topleft"
- name="Animation Info">
- <menu_item_check.on_check
- function="Advanced.CheckAnimationInfo"
- parameter="AnimationInfo" />
- <menu_item_check.on_click
- function="Advanced.ToggleAnimationInfo"
- parameter="" />
- </menu_item_check>
- <menu_item_check
- label="Slow Motion Animations"
- layout="topleft"
- name="Slow Motion Animations">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="SlowMotionAnimation" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="SlowMotionAnimation" />
- </menu_item_check>
- <menu_item_check
- label="Show Look At"
- layout="topleft"
- name="Show Look At">
- <menu_item_check.on_check
- function="Advanced.CheckShowLookAt"
- parameter="ShowLookAt" />
- <menu_item_check.on_click
- function="Advanced.ToggleShowLookAt" />
- </menu_item_check>
- <menu_item_check
- label="Show Point At"
- layout="topleft"
- name="Show Point At">
- <menu_item_check.on_check
- function="Advanced.CheckShowPointAt"
- parameter="ShowPointAt" />
- <menu_item_check.on_click
- function="Advanced.ToggleShowPointAt" />
- </menu_item_check>
- <menu_item_check
- label="Debug Joint Updates"
- layout="topleft"
- name="Debug Joint Updates">
- <menu_item_check.on_check
- function="Advanced.CheckDebugJointUpdates"
- parameter="DebugJointUpdates" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugJointUpdates" />
- </menu_item_check>
- <menu_item_check
- label="Disable LOD"
- layout="topleft"
- name="Disable LOD">
- <menu_item_check.on_check
- function="Advanced.CheckDisableLOD"
- parameter="DisableLOD" />
- <menu_item_check.on_click
- function="Advanced.ToggleDisableLOD" />
- </menu_item_check>
- <menu_item_check
- label="Debug Character Vis"
- layout="topleft"
- name="Debug Character Vis">
- <menu_item_check.on_check
- function="Advanced.CheckDebugCharacterVis"
- parameter="DebugCharacterVis" />
- <menu_item_check.on_click
- function="Advanced.ToggleDebugCharacterVis" />
- </menu_item_check>
- <menu_item_check
- label="Show Collision Skeleton"
- layout="topleft"
- name="Show Collision Skeleton">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="collision skeleton" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="collision skeleton" />
- </menu_item_check>
- <menu_item_check
- label="Display Agent Target"
- layout="topleft"
- name="Display Agent Target">
- <menu_item_check.on_check
- function="Advanced.CheckInfoDisplay"
- parameter="agent target" />
- <menu_item_check.on_click
- function="Advanced.ToggleInfoDisplay"
- parameter="agent target" />
- </menu_item_check>
-<!-- Appears not to exist anymore
- <menu_item_check
- label="Debug Rotation"
- layout="topleft"
- name="Debug Rotation">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="DebugAvatarRotation" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="DebugAvatarRotation" />
- </menu_item_check> -->
--->
- <menu_item_call
- label="Dump Attachments"
- layout="topleft"
- name="Dump Attachments">
- <menu_item_call.on_click
- function="Advanced.DumpAttachments" />
- </menu_item_call>
- <menu_item_call
- label="Debug Avatar Textures"
- layout="topleft"
- name="Debug Avatar Textures"
- shortcut="control|alt|shift|A">
- <menu_item_call.on_click
- function="Advanced.DebugAvatarTextures" />
- </menu_item_call>
- <menu_item_call
- label="Dump Local Textures"
- layout="topleft"
- name="Dump Local Textures"
- shortcut="alt|shift|M">
- <menu_item_call.on_click
- function="Advanced.DumpAvatarLocalTextures" />
- </menu_item_call>
- </menu>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Compress Images"
- layout="topleft"
- name="Compress Images">
- <menu_item_call.on_click
- function="Advanced.CompressImage" />
- </menu_item_call>
- <menu_item_check
- label="Output Debug Minidump"
- layout="topleft"
- name="Output Debug Minidump">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="SaveMinidump" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="SaveMinidump" />
- </menu_item_check>
- <menu_item_check
- label="Console Window on next Run"
- layout="topleft"
- name="Console Window">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ShowConsoleWindow" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ShowConsoleWindow" />
- </menu_item_check>
- <menu_item_separator
- layout="topleft" />
- <menu_item_check
- label="Show Admin Menu"
- layout="topleft"
- name="View Admin Options">
- <menu_item_check.on_check
- function="Advanced.CheckViewAdminOptions"
- parameter="ViewAdminOptions" />
- <menu_item_check.on_click
- function="Advanced.ToggleViewAdminOptions" />
- </menu_item_check>
- <menu_item_call
- label="Request Admin Status"
- layout="topleft"
- name="Request Admin Options"
- shortcut="control|alt|G">
- <menu_item_call.on_click
- function="Advanced.RequestAdminStatus" />
- </menu_item_call>
- <menu_item_call
- label="Leave Admin Status"
- layout="topleft"
- name="Leave Admin Options"
- shortcut="control|alt|shift|G">
- <menu_item_call.on_click
- function="Advanced.LeaveAdminStatus" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Admin"
- layout="topleft"
- name="Admin"
- tear_off="true"
- visible="false">
- <menu
- create_jump_keys="true"
- label="Object"
- layout="topleft"
- tear_off="true">
- <menu_item_call
- label="Take Copy"
- layout="topleft"
- name="Take Copy"
- shortcut="control|alt|shift|O">
- <menu_item_call.on_click
- function="Admin.ForceTakeCopy" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Force Owner To Me"
- layout="topleft"
- name="Force Owner To Me">
- <menu_item_call.on_click
- function="Admin.HandleObjectOwnerSelf" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Force Owner Permissive"
- layout="topleft"
- name="Force Owner Permissive">
- <menu_item_call.on_click
- function="Admin.HandleObjectOwnerPermissive" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Delete"
- layout="topleft"
- name="Delete"
- shortcut="control|alt|shift|Del">
- <menu_item_call.on_click
- function="Admin.HandleForceDelete" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Lock"
- layout="topleft"
- name="Lock"
- shortcut="control|alt|shift|L">
- <menu_item_call.on_click
- function="Admin.HandleObjectLock" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Get Assets IDs"
- layout="topleft"
- name="Get Assets IDs"
- shortcut="control|alt|shift|I">
- <menu_item_call.on_click
- function="Admin.HandleObjectAssetIDs" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Parcel"
- layout="topleft"
- name="Parcel"
- tear_off="true">
- <menu_item_call
- label="Owner To Me"
- layout="topleft"
- name="Owner To Me">
- <menu_item_call.on_click
- function="Admin.HandleForceParcelOwnerToMe" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Set to Linden Content"
- layout="topleft"
- name="Set to Linden Content"
- shortcut="control|alt|shift|C">
- <menu_item_call.on_click
- function="Admin.HandleForceParcelToContent" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Claim Public Land"
- layout="topleft"
- name="Claim Public Land">
- <menu_item_call.on_click
- function="Admin.HandleClaimPublicLand" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Region"
- layout="topleft"
- name="Region"
- tear_off="true">
- <menu_item_call
- label="Dump Temp Asset Data"
- layout="topleft"
- name="Dump Temp Asset Data">
- <menu_item_call.on_click
- function="Admin.HandleRegionDumpTempAssetData" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- <menu_item_call
- label="Save Region State"
- layout="topleft"
- name="Save Region State">
- <menu_item_call.on_click
- function="Admin.OnSaveState" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- </menu>
- <menu_item_call
- label="God Tools"
- layout="topleft"
- name="God Tools">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="god_tools" />
- <menu_item_call.on_enable
- function="IsGodCustomerService" />
- </menu_item_call>
- </menu>
- <menu
- create_jump_keys="true"
- label="Admin"
- layout="topleft"
- name="Deprecated"
- tear_off="true"
- visible="false">
- <menu
- create_jump_keys="true"
- label="Attach Object"
- layout="topleft"
- mouse_opaque="false"
- name="Attach Object"
- tear_off="true" />
- <menu
- create_jump_keys="true"
- label="Detach Object"
- layout="topleft"
- mouse_opaque="false"
- name="Detach Object"
- tear_off="true" />
- <menu
- create_jump_keys="true"
- label="Take Off Clothing"
- layout="topleft"
- mouse_opaque="false"
- name="Take Off Clothing"
- tear_off="true">
- <menu_item_call
- label="Shirt"
- layout="topleft"
- name="Shirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shirt" />
- </menu_item_call>
- <menu_item_call
- label="Pants"
- layout="topleft"
- name="Pants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="pants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="pants" />
- </menu_item_call>
- <menu_item_call
- label="Shoes"
- layout="topleft"
- name="Shoes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="shoes" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="shoes" />
- </menu_item_call>
- <menu_item_call
- label="Socks"
- layout="topleft"
- name="Socks">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="socks" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="socks" />
- </menu_item_call>
- <menu_item_call
- label="Jacket"
- layout="topleft"
- name="Jacket">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="jacket" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="jacket" />
- </menu_item_call>
- <menu_item_call
- label="Gloves"
- layout="topleft"
- name="Gloves">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="gloves" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="gloves" />
- </menu_item_call>
- <menu_item_call
- label="Undershirt"
- layout="topleft"
- name="Menu Undershirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="undershirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="undershirt" />
- </menu_item_call>
- <menu_item_call
- label="Underpants"
- layout="topleft"
- name="Menu Underpants">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="underpants" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="underpants" />
- </menu_item_call>
- <menu_item_call
- label="Skirt"
- layout="topleft"
- name="Skirt">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="skirt" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="skirt" />
- </menu_item_call>
- <menu_item_call
- label="Alpha"
- layout="topleft"
- name="Alpha">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="alpha" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="alpha" />
- </menu_item_call>
- <menu_item_call
- label="Tattoo"
- layout="topleft"
- name="Tattoo">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="tattoo" />
- <menu_item_call.on_enable
- function="Edit.EnableTakeOff"
- parameter="tattoo" />
- </menu_item_call>
- <menu_item_call
- label="All Clothes"
- layout="topleft"
- name="All Clothes">
- <menu_item_call.on_click
- function="Edit.TakeOff"
- parameter="all" />
- </menu_item_call>
- </menu>
- <menu_item_check
- label="Show Toolbar"
- layout="topleft"
- name="Show Toolbar">
- <menu_item_check.on_check
- function="FloaterVisible"
- parameter="toolbar" />
- <menu_item_check.on_click
- function="ShowFloater"
- parameter="toolbar" />
- </menu_item_check>
- <menu
- create_jump_keys="true"
- label="Help"
- layout="topleft"
- name="Help"
- tear_off="true">
- <menu_item_call
- label="Official Linden Blog"
- layout="topleft"
- name="Official Linden Blog">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="OfficialLindenBlog_url"
- parameter="WebLaunchSupportWiki,http://blog.secondlife.com/" />
- </menu_item_call>
- <menu_item_call
- label="Scripting Portal"
- layout="topleft"
- name="Scripting Portal">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="ScriptingPortal_url"
- parameter="WebLaunchLSLWiki,http://wiki.secondlife.com/wiki/LSL_Portal" />
- </menu_item_call>
- <menu
- create_jump_keys="true"
- label="Bug Reporting"
- layout="topleft"
- name="Bug Reporting"
- tear_off="true">
- <menu_item_call
- label="Public Issue Tracker"
- layout="topleft"
- name="Public Issue Tracker">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="PublicIssueTracker_url"
- parameter="WebLaunchPublicIssue,http://jira.secondlife.com" />
- </menu_item_call>
- <menu_item_call
- label="Public Issue Tracker Help"
- layout="topleft"
- name="Publc Issue Tracker Help">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="PublicIssueTrackerHelp_url"
- parameter="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker" />
- </menu_item_call>
- <menu_item_separator
- layout="topleft" />
- <menu_item_call
- label="Bug Reporting 101"
- layout="topleft"
- name="Bug Reporing 101">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="BugReporting101_url"
- parameter="WebLaunchBugReport101,http://wiki.secondlife.com/wiki/Bug_Reporting_101" />
- </menu_item_call>
- <menu_item_call
- label="Security Issues"
- layout="topleft"
- name="Security Issues">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="SecurityIssues_url"
- parameter="WebLaunchSecurityIssues,http://wiki.secondlife.com/wiki/Security_issues" />
- </menu_item_call>
- <menu_item_call
- label="QA Wiki"
- layout="topleft"
- name="QA Wiki">
- <menu_item_call.on_click
- function="PromptShowURL"
- name="QAWiki_url"
- parameter="WebLaunchQAWiki,http://wiki.secondlife.com/wiki/QA_Portal" />
- </menu_item_call>
- </menu>
- </menu>
- </menu>
-</menu_bar>
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu_bar
+ bg_visible="false"
+ follows="left|top|right"
+ layout="topleft"
+ name="Main Menu">
+ <menu
+ label="Me"
+ layout="topleft"
+ name="Me"
+ tear_off="true">
+ <menu_item_call
+ label="Preferences"
+ layout="topleft"
+ name="Preferences"
+ shortcut="control|P">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="preferences" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Dashboard"
+ layout="topleft"
+ name="Manage My Account">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="ManageMyAccount_url"
+ parameter="WebLaunchJoinNow,http://secondlife.com/account/" />
+ </menu_item_call>
+ <menu_item_call
+ label="Buy L$"
+ layout="topleft"
+ name="Buy and Sell L$">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="buy currency" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="My Profile"
+ layout="topleft"
+ name="Profile">
+ <menu_item_call.on_click
+ function="ShowAgentProfile"
+ parameter="agent" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Appearance"
+ layout="topleft"
+ name="Appearance">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="appearance" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
+ </menu_item_call>
+ <menu_item_check
+ label="My Inventory"
+ layout="topleft"
+ name="Inventory"
+ shortcut="control|I">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="inventory" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="inventory" />
+ </menu_item_check>
+ <menu_item_call
+ label="My Gestures"
+ layout="topleft"
+ name="Gestures"
+ shortcut="control|G">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="gestures" />
+ </menu_item_call>
+ <menu
+ label="My Status"
+ layout="topleft"
+ name="Status"
+ tear_off="true">
+ <menu_item_call
+ label="Away"
+ layout="topleft"
+ name="Set Away">
+ <menu_item_call.on_click
+ function="World.SetAway" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft"/>
+ <menu_item_call
+ label="Busy"
+ layout="topleft"
+ name="Set Busy">
+ <menu_item_call.on_click
+ function="World.SetBusy"/>
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="Request Admin Status"
+ layout="topleft"
+ name="Request Admin Options"
+ shortcut="control|alt|G"
+ visible="false">
+ <menu_item_call.on_click
+ function="Advanced.RequestAdminStatus" />
+ </menu_item_call>
+ <menu_item_call
+ label="Leave Admin Status"
+ layout="topleft"
+ name="Leave Admin Options"
+ shortcut="control|alt|shift|G"
+ visible="false">
+ <menu_item_call.on_click
+ function="Advanced.LeaveAdminStatus" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Quit [APP_NAME]"
+ layout="topleft"
+ name="Quit"
+ shortcut="control|Q">
+ <menu_item_call.on_click
+ function="File.Quit" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="Communicate"
+ layout="topleft"
+ name="Communicate"
+ tear_off="true">
+ <menu_item_call
+ label="My Friends"
+ layout="topleft"
+ name="My Friends"
+ shortcut="control|shift|F">
+ <menu_item_call.on_click
+ function="SideTray.PanelPeopleTab"
+ parameter="friends_panel" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Groups"
+ layout="topleft"
+ name="My Groups">
+ <menu_item_call.on_click
+ function="SideTray.PanelPeopleTab"
+ parameter="groups_panel" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <!--menu_item_call
+ label="Chat"
+ layout="topleft"
+ name="Chat">
+ <menu_item_call.on_click
+ function="World.Chat" />
+ </menu_item_call-->
+ <menu_item_check
+ label="Nearby Chat"
+ layout="topleft"
+ name="Nearby Chat"
+ shortcut="control|H">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="nearby_chat" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="nearby_chat" />
+ </menu_item_check>
+ <menu_item_call
+ label="Nearby People"
+ layout="topleft"
+ name="Active Speakers"
+ shortcut="control|shift|A">
+ <menu_item_call.on_click
+ function="SideTray.PanelPeopleTab"
+ parameter="nearby_panel" />
+ </menu_item_call>
+ <menu_item_check
+ label="Nearby Media"
+ layout="topleft"
+ name="Nearby Media"
+ shortcut="control|alt|N">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="nearby_media" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="nearby_media" />
+ </menu_item_check>
+ <!--menu_item_check
+ label="Block List"
+ layout="topleft"
+ name="Mute List">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="mute" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="mute" />
+ </menu_item_check-->
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="(Legacy) Communicate"
+ layout="topleft"
+ name="Instant Message"
+ shortcut="control|T">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="communicate" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="communicate" />
+ </menu_item_check>
+ <menu_item_call
+ label="(Temp) Media Remote Ctrl"
+ layout="topleft"
+ name="Preferences"
+ shortcut="control|alt|M">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="media_remote_ctrl" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="World"
+ layout="topleft"
+ name="World"
+ tear_off="true">
+ <menu_item_check
+ label="Move"
+ layout="topleft"
+ name="Movement Controls">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="moveview" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="moveview" />
+ </menu_item_check>
+ <menu_item_check
+ label="View"
+ layout="topleft"
+ name="Camera Controls">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="camera" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="camera" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="About Land"
+ layout="topleft"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="about_land" />
+ </menu_item_call>
+ <menu_item_call
+ label="Region/Estate"
+ layout="topleft"
+ name="Region/Estate">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="region_info" />
+ </menu_item_call>
+ <menu_item_call
+ label="Buy Land"
+ layout="topleft"
+ name="Buy Land">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="buy land" />
+ <menu_item_call.on_enable
+ function="World.EnableBuyLand" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Land"
+ layout="topleft"
+ name="My Land">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="land_holdings" />
+ </menu_item_call>
+ <menu
+ create_jump_keys="true"
+ label="Show"
+ layout="topleft"
+ name="Land"
+ tear_off="true">
+ <menu_item_check
+ label="Ban Lines"
+ layout="topleft"
+ name="Ban Lines">
+ <menu_item_check.on_check
+ control="ShowBanLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowBanLines" />
+ </menu_item_check>
+ <menu_item_check
+ label="Beacons"
+ layout="topleft"
+ name="beacons"
+ shortcut="control|alt|shift|N">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="beacons" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="beacons" />
+ </menu_item_check>
+ <menu_item_check
+ label="Property Lines"
+ layout="topleft"
+ name="Property Lines"
+ shortcut="control|alt|shift|P">
+ <menu_item_check.on_check
+ control="ShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowPropertyLines" />
+ </menu_item_check>
+ <menu_item_check
+ label="Land Owners"
+ layout="topleft"
+ name="Land Owners">
+ <menu_item_check.on_check
+ control="ShowParcelOwners" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowParcelOwners" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ label="Landmarks"
+ layout="topleft"
+ name="Landmarks"
+ tear_off="true">
+ <menu_item_call
+ label="Create Landmark Here"
+ layout="topleft"
+ name="Create Landmark Here">
+ <menu_item_call.on_click
+ function="World.CreateLandmark" />
+ <menu_item_call.on_enable
+ function="World.EnableCreateLandmark" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Home to Here"
+ layout="topleft"
+ name="Set Home to Here">
+ <menu_item_call.on_click
+ function="World.SetHomeLocation" />
+ <menu_item_call.on_enable
+ function="World.EnableSetHomeLocation" />
+ </menu_item_call>
+ <menu_item_call
+ label="Teleport Home"
+ layout="topleft"
+ name="Teleport Home"
+ shortcut="control|shift|H">
+ <menu_item_call.on_click
+ function="World.TeleportHome" />
+ <menu_item_call.on_enable
+ function="World.EnableTeleportHome" />
+ </menu_item_call>
+ </menu>
+ <menu_item_check
+ label="Mini-Map"
+ layout="topleft"
+ name="Mini-Map"
+ shortcut="control|shift|M">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="mini_map" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="mini_map" />
+ </menu_item_check>
+ <menu_item_check
+ label="World Map"
+ layout="topleft"
+ name="World Map"
+ shortcut="control|M"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="world_map" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="world_map" />
+ </menu_item_check>
+ <!-- <menu_item_check
+ label="Show Navigation Bar"
+ layout="topleft"
+ name="ShowNavbarNavigationPanel">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowNavbarNavigationPanel" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowNavbarNavigationPanel" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Favorites Bar"
+ layout="topleft"
+ name="ShowNavbarFavoritesPanel">
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowNavbarFavoritesPanel" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowNavbarFavoritesPanel" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />-->
+ <menu_item_call
+ label="Snapshot"
+ layout="topleft"
+ name="Take Snapshot"
+ shortcut="control|shift|S">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="snapshot" />
+ </menu_item_call>
+ <menu
+ create_jump_keys="true"
+ label="Sun"
+ layout="topleft"
+ name="Environment Settings"
+ tear_off="true">
+ <menu_item_call
+ label="Sunrise"
+ layout="topleft"
+ name="Sunrise">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="sunrise" />
+ </menu_item_call>
+ <menu_item_call
+ label="Midday"
+ layout="topleft"
+ name="Noon"
+ shortcut="control|shift|Y">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="noon" />
+ </menu_item_call>
+ <menu_item_call
+ label="Sunset"
+ layout="topleft"
+ name="Sunset"
+ shortcut="control|shift|N">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="sunset" />
+ </menu_item_call>
+ <menu_item_call
+ label="Midnight"
+ layout="topleft"
+ name="Midnight">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="midnight" />
+ </menu_item_call>
+ <menu_item_call
+ label="Use the Estate Time"
+ layout="topleft"
+ name="Revert to Region Default">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="default" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Environment Editor"
+ layout="topleft"
+ name="Environment Editor">
+ <menu_item_call.on_click
+ function="World.EnvSettings"
+ parameter="editor" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Build"
+ layout="topleft"
+ name="BuildTools"
+ tear_off="true"
+ visible="true">
+ <menu_item_check
+ label="Build"
+ layout="topleft"
+ name="Show Build Tools"
+ shortcut="control|B">
+ <menu_item_check.on_check
+ function="Build.Active" />
+ <menu_item_check.on_click
+ function="Build.Toggle" />
+ <menu_item_check.on_enable
+ function="Build.Enabled" />
+ </menu_item_check>
+ <menu
+ create_jump_keys="true"
+ label="Select Build Tool"
+ layout="topleft"
+ name="Select Tool"
+ tear_off="true">
+ <menu_item_call
+ label="Focus Tool"
+ layout="topleft"
+ name="Focus"
+ shortcut="control|1">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="focus" />
+ </menu_item_call>
+ <menu_item_call
+ label="Move Tool"
+ layout="topleft"
+ name="Move"
+ shortcut="control|2">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="move" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Tool"
+ layout="topleft"
+ name="Edit"
+ shortcut="control|3">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="edit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Create Tool"
+ layout="topleft"
+ name="Create"
+ shortcut="control|4">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="create" />
+ </menu_item_call>
+ <menu_item_call
+ label="Land Tool"
+ layout="topleft"
+ name="Land"
+ shortcut="control|5">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="land" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Edit"
+ layout="topleft"
+ name="Edit"
+ tear_off="true">
+ <menu_item_call
+ label="Undo"
+ layout="topleft"
+ name="Undo"
+ shortcut="control|Z">
+ <menu_item_call.on_click
+ function="Edit.Undo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableUndo" />
+ </menu_item_call>
+ <menu_item_call
+ label="Redo"
+ layout="topleft"
+ name="Redo"
+ shortcut="control|Y">
+ <menu_item_call.on_click
+ function="Edit.Redo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableRedo" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Cut"
+ layout="topleft"
+ name="Cut"
+ shortcut="control|X">
+ <menu_item_call.on_click
+ function="Edit.Cut" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCut" />
+ </menu_item_call>
+ <menu_item_call
+ label="Copy"
+ layout="topleft"
+ name="Copy"
+ shortcut="control|C">
+ <menu_item_call.on_click
+ function="Edit.Copy" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCopy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Paste"
+ layout="topleft"
+ name="Paste"
+ shortcut="control|V">
+ <menu_item_call.on_click
+ function="Edit.Paste" />
+ <menu_item_call.on_enable
+ function="Edit.EnablePaste" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete"
+ shortcut="Del">
+ <menu_item_call.on_click
+ function="Edit.Delete" />
+ <menu_item_call.on_enable
+ function="Edit.EnableDelete" />
+ </menu_item_call>
+ <menu_item_call
+ label="Duplicate"
+ layout="topleft"
+ name="Duplicate"
+ shortcut="control|D">
+ <menu_item_call.on_click
+ function="Edit.Duplicate" />
+ <menu_item_call.on_enable
+ function="Edit.EnableDuplicate" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Select All"
+ layout="topleft"
+ name="Select All"
+ shortcut="control|A">
+ <menu_item_call.on_click
+ function="Edit.SelectAll" />
+ <menu_item_call.on_enable
+ function="Edit.EnableSelectAll" />
+ </menu_item_call>
+ <menu_item_call
+ label="Deselect"
+ layout="topleft"
+ name="Deselect"
+ shortcut="control|E">
+ <menu_item_call.on_click
+ function="Edit.Deselect" />
+ <menu_item_call.on_enable
+ function="Edit.EnableDeselect" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Link"
+ layout="topleft"
+ name="Link"
+ shortcut="control|L">
+ <menu_item_call.on_click
+ function="Tools.Link" />
+ <menu_item_call.on_enable
+ function="Tools.EnableLink" />
+ </menu_item_call>
+ <menu_item_call
+ label="Unlink"
+ layout="topleft"
+ name="Unlink"
+ shortcut="control|shift|L">
+ <menu_item_call.on_click
+ function="Tools.Unlink" />
+ <menu_item_call.on_enable
+ function="Tools.EnableUnlink" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Focus on Selection"
+ layout="topleft"
+ name="Focus on Selection"
+ shortcut="H">
+ <menu_item_call.on_click
+ function="Tools.LookAtSelection"
+ parameter="focus" />
+ <menu_item_call.on_enable
+ function="Tools.SomethingSelectedNoHUD" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom to Selection"
+ layout="topleft"
+ name="Zoom to Selection"
+ shortcut="shift|H">
+ <menu_item_call.on_click
+ function="Tools.LookAtSelection"
+ parameter="zoom" />
+ <menu_item_call.on_enable
+ function="Tools.SomethingSelectedNoHUD" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Object"
+ layout="topleft"
+ name="Object"
+ tear_off="true">
+ <menu_item_call
+ label="Buy"
+ layout="topleft"
+ name="Menu Object Take"
+ visible="true">
+ <menu_item_call.on_click
+ function="Tools.BuyOrTake" />
+ <menu_item_call.on_enable
+ function="Tools.EnableBuyOrTake"
+ name="EnableBuyOrTake"
+ parameter="Buy,Take" />
+ </menu_item_call>
+ <menu_item_call
+ label="Take Copy"
+ layout="topleft"
+ name="Take Copy">
+ <menu_item_call.on_click
+ function="Tools.TakeCopy" />
+ <menu_item_call.on_enable
+ function="Tools.EnableTakeCopy" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save Back to My Inventory"
+ layout="topleft"
+ name="Save Object Back to My Inventory">
+ <menu_item_call.on_click
+ function="Tools.SaveToInventory" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSaveToInventory" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save Back to Object Contents"
+ layout="topleft"
+ name="Save Object Back to Object Contents">
+ <menu_item_call.on_click
+ function="Tools.SaveToObjectInventory" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSaveToObjectInventory" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Scripts"
+ layout="topleft"
+ name="Scripts"
+ tear_off="true">
+ <menu_item_call
+ label="Recompile Scripts (Mono)"
+ layout="topleft"
+ name="Mono">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="compile mono" />
+ <menu_item_call.on_enable
+ function="EditableSelectedMono" />
+ </menu_item_call>
+ <menu_item_call
+ label="Recompile Scripts (LSL)"
+ layout="topleft"
+ name="LSL">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="compile lsl" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Reset Scripts"
+ layout="topleft"
+ name="Reset Scripts">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="reset" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Scripts to Running"
+ layout="topleft"
+ name="Set Scripts to Running">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="start" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set Scripts to Not Running"
+ layout="topleft"
+ name="Set Scripts to Not Running">
+ <menu_item_call.on_click
+ function="Tools.SelectedScriptAction"
+ parameter="stop" />
+ <menu_item_call.on_enable
+ function="EditableSelected" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Options"
+ layout="topleft"
+ name="Options"
+ tear_off="true">
+ <menu_item_check
+ label="Edit Linked Parts"
+ layout="topleft"
+ name="Edit Linked Parts">
+ <menu_item_check.on_check
+ control="EditLinkedParts" />
+ <menu_item_check.on_click
+ function="Tools.EditLinkedParts"
+ parameter="EditLinkedParts" />
+ <menu_item_check.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_check>
+ <menu_item_call
+ label="Set Default Upload Permissions"
+ layout="topleft"
+ name="perm prefs">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="perm_prefs" />
+ </menu_item_call>
+ <menu_item_check
+ label="Show Advanced Permissions"
+ layout="topleft"
+ name="DebugPermissions">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugPermissions" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugPermissions" />
+ </menu_item_check>
+ <!--menu_item_call
+ label="Show Script Warning/Error Window"
+ layout="topleft"
+ name="Show Script Warning/Error Window">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="script errors" />
+ </menu_item_call-->
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Selection"
+ layout="topleft"
+ name="Selection"
+ tear_off="true">
+ <menu_item_check
+ label="Select Only My Objects"
+ layout="topleft"
+ name="Select Only My Objects">
+ <menu_item_check.on_check
+ control="SelectOwnedOnly" />
+ <menu_item_check.on_click
+ function="Tools.SelectOnlyMyObjects"
+ parameter="agents" />
+ </menu_item_check>
+ <menu_item_check
+ label="Select Only Movable Objects"
+ layout="topleft"
+ name="Select Only Movable Objects">
+ <menu_item_check.on_check
+ control="SelectMovableOnly" />
+ <menu_item_check.on_click
+ function="Tools.SelectOnlyMovableObjects"
+ parameter="movable" />
+ </menu_item_check>
+ <menu_item_check
+ label="Select By Surrounding"
+ layout="topleft"
+ name="Select By Surrounding">
+ <menu_item_check.on_check
+ control="RectangleSelectInclusive" />
+ <menu_item_check.on_click
+ function="Tools.SelectBySurrounding" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Show"
+ layout="topleft"
+ name="Show"
+ tear_off="true">
+ <menu_item_check
+ label="Show Hidden Selection"
+ layout="topleft"
+ name="Show Hidden Selection">
+ <menu_item_check.on_check
+ control="RenderHiddenSelections" />
+ <menu_item_check.on_click
+ function="Tools.ShowHiddenSelection" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Light Radius for Selection"
+ layout="topleft"
+ name="Show Light Radius for Selection">
+ <menu_item_check.on_check
+ control="RenderLightRadius" />
+ <menu_item_check.on_click
+ function="Tools.ShowSelectionLightRadius" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Selection Beam"
+ layout="topleft"
+ name="Show Selection Beam">
+ <menu_item_check.on_check
+ control="ShowSelectionBeam" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowSelectionBeam" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Grid"
+ layout="topleft"
+ name="Grid"
+ tear_off="true">
+ <menu_item_check
+ label="Snap to Grid"
+ layout="topleft"
+ name="Snap to Grid"
+ shortcut="G">
+ <menu_item_check.on_check
+ control="SnapEnabled" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SnapEnabled" />
+ <menu_item_check.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_check>
+ <menu_item_call
+ label="Snap Object XY to Grid"
+ layout="topleft"
+ name="Snap Object XY to Grid"
+ shortcut="shift|X">
+ <menu_item_call.on_click
+ function="Tools.SnapObjectXY" />
+ <menu_item_call.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_call>
+ <menu_item_call
+ label="Use Selection for Grid"
+ layout="topleft"
+ name="Use Selection for Grid"
+ shortcut="shift|G">
+ <menu_item_call.on_click
+ function="Tools.UseSelectionForGrid" />
+ <menu_item_call.on_enable
+ function="SomethingSelected" />
+ </menu_item_call>
+ <menu_item_call
+ label="Grid Options"
+ layout="topleft"
+ name="Grid Options"
+ shortcut="control|shift|B">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="build_options" />
+ <menu_item_call.on_enable
+ function="Tools.EnableToolNotPie" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Select Linked Parts"
+ layout="topleft"
+ name="Select Linked Parts"
+ tear_off="true">
+ <menu_item_call
+ label="Select Next Part"
+ layout="topleft"
+ name="Select Next Part"
+ shortcut="control|.">
+ <menu_item_call.on_click
+ function="Tools.SelectNextPart"
+ parameter="next" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSelectNextPart" />
+ </menu_item_call>
+ <menu_item_call
+ label="Select Previous Part"
+ layout="topleft"
+ name="Select Previous Part"
+ shortcut="control|,">
+ <menu_item_call.on_click
+ function="Tools.SelectNextPart"
+ parameter="previous" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSelectNextPart" />
+ </menu_item_call>
+ <menu_item_call
+ label="Include Next Part"
+ layout="topleft"
+ name="Include Next Part"
+ shortcut="control|shift|.">
+ <menu_item_call.on_click
+ function="Tools.SelectNextPart"
+ parameter="includenext" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSelectNextPart" />
+ </menu_item_call>
+ <menu_item_call
+ label="Include Previous Part"
+ layout="topleft"
+ name="Include Previous Part"
+ shortcut="control|shift|,">
+ <menu_item_call.on_click
+ function="Tools.SelectNextPart"
+ parameter="includeprevious" />
+ <menu_item_call.on_enable
+ function="Tools.EnableSelectNextPart" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ <menu
+ label="Help"
+ layout="topleft"
+ name="Help"
+ tear_off="true">
+ <menu_item_call
+ label="[SECOND_LIFE] Help"
+ layout="topleft"
+ name="Second Life Help"
+ shortcut="F1">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="help f1" />
+ </menu_item_call>
+ <menu_item_call
+ label="Tutorial"
+ layout="topleft"
+ name="Tutorial">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="hud" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Report Abuse"
+ layout="topleft"
+ name="Report Abuse">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="complaint reporter" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="About [APP_NAME]"
+ layout="topleft"
+ name="About Second Life">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="sl_about" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="Advanced"
+ layout="topleft"
+ name="Advanced"
+ tear_off="true"
+ visible="false">
+ <menu_item_check
+ label="Set Away After 30 Minutes"
+ layout="topleft"
+ name="Go Away/AFK When Idle">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AllowIdleAFK" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="AllowIdleAFK" />
+ </menu_item_check>
+ <menu_item_call
+ label="Stop Animating Me"
+ layout="topleft"
+ name="Stop Animating My Avatar">
+ <menu_item_call.on_click
+ function="Tools.StopAllAnimations" />
+ </menu_item_call>
+ <menu_item_call
+ label="Rebake Textures"
+ layout="topleft"
+ name="Rebake Texture"
+ shortcut="control|alt|R">
+ <menu_item_call.on_click
+ function="Advanced.RebakeTextures" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set UI Size to Default"
+ layout="topleft"
+ name="Set UI Size to Default">
+ <menu_item_call.on_click
+ function="View.DefaultUISize" />
+ </menu_item_call>
+ <menu_item_separator/>
+ <menu_item_check
+ label="Limit Select Distance"
+ layout="topleft"
+ name="Limit Select Distance">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="LimitSelectDistance" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="LimitSelectDistance" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable Camera Constraints"
+ layout="topleft"
+ name="Disable Camera Distance">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DisableCameraConstraints" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DisableCameraConstraints" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="High-res Snapshot"
+ layout="topleft"
+ name="HighResSnapshot">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="HighResSnapshot" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="HighResSnapshot" />
+ </menu_item_check>
+ <menu_item_check
+ label="Quiet Snapshots to Disk"
+ layout="topleft"
+ name="QuietSnapshotsToDisk">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="QuietSnapshotsToDisk" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="QuietSnapshotsToDisk" />
+ </menu_item_check>
+ <menu_item_check
+ label="Compress Snapshots to Disk"
+ layout="topleft"
+ name="CompressSnapshotsToDisk">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CompressSnapshotsToDisk" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CompressSnapshotsToDisk" />
+ </menu_item_check>
+ <menu_item_call
+ label="Save Texture As"
+ layout="topleft"
+ name="Save Texture As">
+ <menu_item_call.on_click
+ function="File.SaveTexture" />
+ <menu_item_call.on_enable
+ function="File.EnableSaveAs" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Performance Tools"
+ layout="topleft"
+ name="Performance Tools"
+ tear_off="true">
+ <menu_item_call
+ label="Lag Meter"
+ layout="topleft"
+ name="Lag Meter">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="lagmeter" />
+ </menu_item_call>
+ <menu_item_check
+ label="Statistics Bar"
+ layout="topleft"
+ name="Statistics Bar"
+ shortcut="control|shift|1">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="stats" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="stats" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Avatar Rendering Cost"
+ layout="topleft"
+ name="Avatar Rendering Cost">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="shame" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="shame" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Highlighting and Visibility"
+ layout="topleft"
+ name="Highlighting and Visibility"
+ tear_off="true">
+ <menu_item_check
+ label="Cheesy Beacon"
+ layout="topleft"
+ name="Cheesy Beacon">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CheesyBeacon" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CheesyBeacon" />
+ </menu_item_check>
+ <menu_item_check
+ label="Hide Particles"
+ layout="topleft"
+ name="Hide Particles"
+ shortcut="control|alt|shift|=">
+ <menu_item_check.on_check
+ function="View.CheckRenderType"
+ parameter="hideparticles" />
+ <menu_item_check.on_click
+ function="View.ToggleRenderType"
+ parameter="hideparticles" />
+ </menu_item_check>
+ <menu_item_check
+ label="Hide Selected"
+ layout="topleft"
+ name="Hide Selected">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="HideSelectedObjects" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="HideSelectedObjects" />
+ </menu_item_check>
+ <menu_item_check
+ label="Highlight Transparent"
+ layout="topleft"
+ name="Highlight Transparent"
+ shortcut="control|alt|T">
+ <menu_item_check.on_check
+ function="View.CheckHighlightTransparent" />
+ <menu_item_check.on_click
+ function="View.HighlightTransparent" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show HUD Attachments"
+ layout="topleft"
+ name="Show HUD Attachments"
+ shortcut="alt|shift|H">
+ <menu_item_check.on_check
+ function="View.CheckHUDAttachments" />
+ <menu_item_check.on_click
+ function="View.ShowHUDAttachments" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Mouselook Crosshairs"
+ layout="topleft"
+ name="ShowCrosshairs">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowCrosshairs" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowCrosshairs" />
+ </menu_item_check>
+ <!-- <menu
+ create_jump_keys="true"
+ label="Hover Tips"
+ layout="topleft"
+ name="Hover Tips"
+ tear_off="true">
+ <menu_item_check
+ label="Show Tips"
+ layout="topleft"
+ name="Show Tips"
+ shortcut="control|shift|T">
+ <menu_item_check.on_check
+ function="View.CheckShowHoverTips" />
+ <menu_item_check.on_click
+ function="View.ShowHoverTips" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />-->
+ <menu_item_check
+ label="Show Land Tooltips"
+ layout="topleft"
+ name="Land Tips">
+ <menu_item_check.on_check
+ control="ShowLandHoverTip" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowLandHoverTip" />
+ <menu_item_check.on_enable
+ function="View.CheckShowHoverTips" />
+ </menu_item_check>
+ <!-- <menu_item_check
+ label="Show Tips On All Objects"
+ layout="topleft"
+ name="Tips On All Objects">
+ <menu_item_check.on_check
+ control="ShowAllObjectHoverTip" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowAllObjectHoverTip" />
+ <menu_item_check.on_enable
+ function="View.CheckShowHoverTips" />
+ </menu_item_check>
+ </menu>-->
+
+ </menu>
+
+ <menu
+ create_jump_keys="true"
+ label="Rendering Types"
+ layout="topleft"
+ name="Rendering Types"
+ tear_off="true">
+ <menu_item_check
+ label="Simple"
+ layout="topleft"
+ name="Simple"
+ shortcut="control|alt|shift|1">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="simple" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="simple" />
+ </menu_item_check>
+ <menu_item_check
+ label="Alpha"
+ layout="topleft"
+ name="Alpha"
+ shortcut="control|alt|shift|2">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="alpha" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="alpha" />
+ </menu_item_check>
+ <menu_item_check
+ label="Tree"
+ layout="topleft"
+ name="Tree"
+ shortcut="control|alt|shift|3">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="tree" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="tree" />
+ </menu_item_check>
+ <menu_item_check
+ label="Avatars"
+ layout="topleft"
+ name="Character"
+ shortcut="control|alt|shift|4">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="character" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="character" />
+ </menu_item_check>
+ <menu_item_check
+ label="SurfacePath"
+ layout="topleft"
+ name="SurfacePath"
+ shortcut="control|alt|shift|5">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="surfacePath" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="surfacePath" />
+ </menu_item_check>
+ <menu_item_check
+ label="Sky"
+ layout="topleft"
+ name="Sky"
+ shortcut="control|alt|shift|6">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="sky" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="sky" />
+ </menu_item_check>
+ <menu_item_check
+ label="Water"
+ layout="topleft"
+ name="Water"
+ shortcut="control|alt|shift|7">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="water" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="water" />
+ </menu_item_check>
+ <menu_item_check
+ label="Ground"
+ layout="topleft"
+ name="Ground"
+ shortcut="control|alt|shift|8">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="ground" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="ground" />
+ </menu_item_check>
+ <menu_item_check
+ label="Volume"
+ layout="topleft"
+ name="Volume"
+ shortcut="control|alt|shift|9">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="volume" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="volume" />
+ </menu_item_check>
+ <menu_item_check
+ label="Grass"
+ layout="topleft"
+ name="Grass"
+ shortcut="control|alt|shift|0">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="grass" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="grass" />
+ </menu_item_check>
+ <menu_item_check
+ label="Clouds"
+ layout="topleft"
+ name="Clouds"
+ shortcut="control|alt|shift|-">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="clouds" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="clouds" />
+ </menu_item_check>
+ <menu_item_check
+ label="Particles"
+ layout="topleft"
+ name="Particles"
+ shortcut="control|alt|shift|=">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="particles" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="particles" />
+ </menu_item_check>
+ <menu_item_check
+ label="Bump"
+ layout="topleft"
+ name="Bump"
+ shortcut="control|alt|shift|\">
+ <menu_item_check.on_check
+ function="Advanced.CheckRenderType"
+ parameter="bump" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRenderType"
+ parameter="bump" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Rendering Features"
+ layout="topleft"
+ name="Rendering Features"
+ tear_off="true">
+ <menu_item_check
+ label="UI"
+ layout="topleft"
+ name="UI"
+ shortcut="control|alt|F1">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="ui" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="ui" />
+ </menu_item_check>
+ <menu_item_check
+ label="Selected"
+ layout="topleft"
+ name="Selected"
+ shortcut="control|alt|F2">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="selected" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="selected" />
+ </menu_item_check>
+ <menu_item_check
+ label="Highlighted"
+ layout="topleft"
+ name="Highlighted"
+ shortcut="control|alt|F3">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="highlighted" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="highlighted" />
+ </menu_item_check>
+ <menu_item_check
+ label="Dynamic Textures"
+ layout="topleft"
+ name="Dynamic Textures"
+ shortcut="control|alt|F4">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="dynamic textures" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="dynamic textures" />
+ </menu_item_check>
+ <menu_item_check
+ label="Foot Shadows"
+ layout="topleft"
+ name="Foot Shadows"
+ shortcut="control|alt|F5">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="foot shadows" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="foot shadows" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fog"
+ layout="topleft"
+ name="Fog"
+ shortcut="control|alt|F6">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="fog" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="fog" />
+ </menu_item_check>
+ <menu_item_check
+ label="Test FRInfo"
+ layout="topleft"
+ name="Test FRInfo"
+ shortcut="control|alt|F8">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="fr info" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="fr info" />
+ </menu_item_check>
+ <menu_item_check
+ label="Flexible Objects"
+ layout="topleft"
+ name="Flexible Objects"
+ shortcut="control|alt|F9">
+ <menu_item_check.on_check
+ function="Advanced.CheckFeature"
+ parameter="flexible" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFeature"
+ parameter="flexible" />
+ </menu_item_check>
+ </menu>
+ <menu_item_check
+ label="Run Multiple Threads"
+ layout="topleft"
+ name="Run Multiple Threads">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RunMultipleThreads" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RunMultipleThreads" />
+ </menu_item_check>
+ <menu_item_call
+ label="Clear Group Cache"
+ layout="topleft"
+ name="ClearGroupCache">
+ <menu_item_call.on_click
+ function="Advanced.ClearGroupCache"
+ parameter="ClearGroupCache" />
+ </menu_item_call>
+ <menu_item_check
+ label="Mouse Smoothing"
+ layout="topleft"
+ name="Mouse Smoothing">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="MouseSmooth" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MouseSmooth" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ label="Shortcuts"
+ layout="topleft"
+ name="Shortcuts"
+ tear_off="true"
+ visible="false">
+ <menu_item_check
+ label="Search"
+ layout="topleft"
+ name="Search"
+ shortcut="control|F">
+ <menu_item_check.on_check
+ function="Floater.Visible"
+ parameter="search" />
+ <menu_item_check.on_click
+ function="Floater.Toggle"
+ parameter="search" />
+ </menu_item_check>
+ <menu_item_call
+ enabled="false"
+ label="Release Keys"
+ layout="topleft"
+ name="Release Keys">
+ <menu_item_call.on_click
+ function="Tools.ReleaseKeys"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="Tools.EnableReleaseKeys"
+ parameter="" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set UI Size to Default"
+ layout="topleft"
+ name="Set UI Size to Default">
+ <menu_item_call.on_click
+ function="View.DefaultUISize" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Always Run"
+ layout="topleft"
+ name="Always Run"
+ shortcut="control|R">
+ <menu_item_check.on_check
+ function="World.CheckAlwaysRun" />
+ <menu_item_check.on_click
+ function="World.AlwaysRun" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fly"
+ layout="topleft"
+ name="Fly"
+ shortcut="Home">
+ <menu_item_check.on_click
+ function="Agent.toggleFlying" />
+ <menu_item_check.on_enable
+ function="Agent.enableFlying" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Close Window"
+ layout="topleft"
+ name="Close Window"
+ shortcut="control|W">
+ <menu_item_call.on_click
+ function="File.CloseWindow" />
+ <menu_item_call.on_enable
+ function="File.EnableCloseWindow" />
+ </menu_item_call>
+ <menu_item_call
+ label="Close All Windows"
+ layout="topleft"
+ name="Close All Windows"
+ shortcut="control|shift|W">
+ <menu_item_call.on_click
+ function="File.CloseAllWindows" />
+ <menu_item_call.on_enable
+ function="File.EnableCloseAllWindows" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Snapshot to Disk"
+ layout="topleft"
+ name="Snapshot to Disk"
+ shortcut="control|`"
+ use_mac_ctrl="true">
+ <menu_item_call.on_click
+ function="File.TakeSnapshotToDisk" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Mouselook"
+ layout="topleft"
+ name="Mouselook"
+ shortcut="M">
+ <menu_item_call.on_click
+ function="View.Mouselook" />
+ <menu_item_call.on_enable
+ function="View.EnableMouselook" />
+ </menu_item_call>
+ <menu_item_check
+ label="Joystick Flycam"
+ layout="topleft"
+ name="Joystick Flycam"
+ shortcut="alt|shift|F">
+ <menu_item_check.on_check
+ function="View.CheckJoystickFlycam" />
+ <menu_item_check.on_click
+ function="View.JoystickFlycam" />
+ <menu_item_check.on_enable
+ function="View.EnableJoystickFlycam" />
+ </menu_item_check>
+ <menu_item_call
+ label="Reset View"
+ layout="topleft"
+ name="Reset View"
+ shortcut="Esc">
+ <menu_item_call.on_click
+ function="View.ResetView" />
+ </menu_item_call>
+ <menu_item_call
+ label="Look at Last Chatter"
+ layout="topleft"
+ name="Look at Last Chatter"
+ shortcut="control|\">
+ <menu_item_call.on_click
+ function="View.LookAtLastChatter" />
+ <menu_item_call.on_enable
+ function="View.EnableLastChatter" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Select Build Tool"
+ layout="topleft"
+ name="Select Tool"
+ tear_off="true">
+ <menu_item_call
+ label="Focus Tool"
+ layout="topleft"
+ name="Focus"
+ shortcut="control|1">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="focus" />
+ </menu_item_call>
+ <menu_item_call
+ label="Move Tool"
+ layout="topleft"
+ name="Move"
+ shortcut="control|2">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="move" />
+ </menu_item_call>
+ <menu_item_call
+ label="Edit Tool"
+ layout="topleft"
+ name="Edit"
+ shortcut="control|3">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="edit" />
+ </menu_item_call>
+ <menu_item_call
+ label="Create Tool"
+ layout="topleft"
+ name="Create"
+ shortcut="control|4">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="create" />
+ </menu_item_call>
+ <menu_item_call
+ label="Land Tool"
+ layout="topleft"
+ name="Land"
+ shortcut="control|5">
+ <menu_item_call.on_click
+ function="Tools.SelectTool"
+ parameter="land" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Zoom In"
+ layout="topleft"
+ name="Zoom In"
+ shortcut="control|0">
+ <menu_item_call.on_click
+ function="View.ZoomIn" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom Default"
+ layout="topleft"
+ name="Zoom Default"
+ shortcut="control|9">
+ <menu_item_call.on_click
+ function="View.ZoomDefault" />
+ </menu_item_call>
+ <menu_item_call
+ label="Zoom Out"
+ layout="topleft"
+ name="Zoom Out"
+ shortcut="control|8">
+ <menu_item_call.on_click
+ function="View.ZoomOut" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Toggle Fullscreen"
+ layout="topleft"
+ name="Toggle Fullscreen"
+ >
+ <!-- Note: shortcut="alt|Enter" was deleted from the preceding node-->
+ <menu_item_call.on_click
+ function="View.Fullscreen" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Show Debug Settings"
+ layout="topleft"
+ name="Debug Settings">
+ <menu_item_call.on_click
+ function="Advanced.ShowDebugSettings"
+ parameter="all" />
+ </menu_item_call>
+ <menu_item_check
+ label="Show Develop Menu"
+ layout="topleft"
+ name="Debug Mode"
+ shortcut="control|alt|Q">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="QAMode" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="QAMode" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Develop"
+ layout="topleft"
+ name="Develop"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Consoles"
+ layout="topleft"
+ name="Consoles"
+ tear_off="true">
+ <menu_item_check
+ label="Texture Console"
+ layout="topleft"
+ name="Texture Console"
+ shortcut="control|shift|3"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="texture" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="texture" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Console"
+ layout="topleft"
+ name="Debug Console"
+ shortcut="control|shift|4"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="debug" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="debug" />
+ </menu_item_check>
+ <menu_item_call
+ label="Notifications Console"
+ layout="topleft"
+ name="Notifications"
+ shortcut="control|shift|5">
+ <menu_item_call.on_click
+ function="Floater.Toggle"
+ parameter="notifications_console" />
+ </menu_item_call>
+ <menu_item_check
+ label="Texture Size Console"
+ layout="topleft"
+ name="Texture Size"
+ shortcut="control|shift|6">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="texture size" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="texture size" />
+ </menu_item_check>
+ <menu_item_check
+ label="Texture Category Console"
+ layout="topleft"
+ name="Texture Category"
+ shortcut="control|shift|7">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="texture category" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="texture category" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fast Timers"
+ layout="topleft"
+ name="Fast Timers"
+ shortcut="control|shift|9"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="fast timers" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="fast timers" />
+ </menu_item_check>
+ <menu_item_check
+ label="Memory"
+ layout="topleft"
+ name="Memory"
+ shortcut="control|shift|0"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="Advanced.CheckConsole"
+ parameter="memory view" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleConsole"
+ parameter="memory view" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Region Info to Debug Console"
+ layout="topleft"
+ name="Region Info to Debug Console">
+ <menu_item_call.on_click
+ function="Advanced.DumpInfoToConsole"
+ parameter="region" />
+ </menu_item_call>
+ <menu_item_call
+ label="Group Info to Debug Console"
+ layout="topleft"
+ name="Group Info to Debug Console">
+ <menu_item_call.on_click
+ function="Advanced.DumpInfoToConsole"
+ parameter="group" />
+ </menu_item_call>
+ <menu_item_call
+ label="Capabilities Info to Debug Console"
+ layout="topleft"
+ name="Capabilities Info to Debug Console">
+ <menu_item_call.on_click
+ function="Advanced.DumpInfoToConsole"
+ parameter="capabilities" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Camera"
+ layout="topleft"
+ name="Camera">
+ <menu_item_check.on_check
+ function="Advanced.CheckHUDInfo"
+ parameter="camera" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleHUDInfo"
+ parameter="camera" />
+ </menu_item_check>
+ <menu_item_check
+ label="Wind"
+ layout="topleft"
+ name="Wind">
+ <menu_item_check.on_check
+ function="Advanced.CheckHUDInfo"
+ parameter="wind" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleHUDInfo"
+ parameter="wind" />
+ </menu_item_check>
+ <menu_item_check
+ label="FOV"
+ layout="topleft"
+ name="FOV">
+ <menu_item_check.on_check
+ function="Advanced.CheckHUDInfo"
+ parameter="fov" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleHUDInfo"
+ parameter="fov" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Show Info"
+ layout="topleft"
+ name="Display Info"
+ tear_off="true">
+ <menu_item_check
+ label="Show Time"
+ layout="topleft"
+ name="Show Time">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowTime" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowTime" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Render Info"
+ layout="topleft"
+ name="Show Render Info">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowRenderInfo" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowRenderInfo" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Matrices"
+ layout="topleft"
+ name="Show Matrices">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowRenderMatrices" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowRenderMatrices" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Color Under Cursor"
+ layout="topleft"
+ name="Show Color Under Cursor">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugShowColor" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugShowColor" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Show Updates to Objects"
+ layout="topleft"
+ name="Show Updates"
+ shortcut="control|alt|shift|U">
+ <menu_item_check.on_check
+ function="Advanced.CheckShowObjectUpdates"
+ parameter="ObjectUpdates" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleShowObjectUpdates" />
+ </menu_item_check>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu
+ create_jump_keys="true"
+ label="Force an Error"
+ layout="topleft"
+ name="Force Errors"
+ tear_off="true">
+ <menu_item_call
+ label="Force Breakpoint"
+ layout="topleft"
+ name="Force Breakpoint"
+ shortcut="control|alt|shift|B">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBreakpoint" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force LLError And Crash"
+ layout="topleft"
+ name="Force LLError And Crash">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorLlerror" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Bad Memory Access"
+ layout="topleft"
+ name="Force Bad Memory Access">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorBadMemoryAccess" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Infinite Loop"
+ layout="topleft"
+ name="Force Infinite Loop">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorInfiniteLoop" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Driver Crash"
+ layout="topleft"
+ name="Force Driver Carsh">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorDriverCrash" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Software Exception"
+ layout="topleft"
+ name="Force Software Exception">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorSoftwareException" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Disconnect Viewer"
+ layout="topleft"
+ name="Force Disconnect Viewer">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorDisconnectViewer" />
+ </menu_item_call>
+ <menu_item_call
+ label="Simulate a Memory Leak"
+ layout="topleft"
+ name="Memory Leaking Simulation">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="mem_leaking" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Render Tests"
+ layout="topleft"
+ name="Render Tests"
+ tear_off="true">
+ <menu_item_check
+ label="Camera Offset"
+ layout="topleft"
+ name="Camera Offset">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CameraOffset" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CameraOffset" />
+ </menu_item_check>
+ <menu_item_check
+ label="Randomize Framerate"
+ layout="topleft"
+ name="Randomize Framerate">
+ <menu_item_check.on_check
+ function="Advanced.CheckRandomizeFramerate"
+ parameter="Randomize Framerate" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleRandomizeFramerate" />
+ </menu_item_check>
+ <menu_item_check
+ label="Periodic Slow Frame"
+ layout="topleft"
+ name="Periodic Slow Frame">
+ <menu_item_check.on_check
+ function="Advanced.CheckPeriodicSlowFrame"
+ parameter="points" />
+ <menu_item_check.on_click
+ function="Advanced.TogglePeriodicSlowFrame"
+ parameter="points" />
+ </menu_item_check>
+ <menu_item_check
+ label="Frame Test"
+ layout="topleft"
+ name="Frame Test">
+ <menu_item_check.on_check
+ function="Advanced.CheckFrameTest"
+ parameter="Frame Test" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleFrameTest" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Render Metadata"
+ layout="topleft"
+ name="Render Metadata"
+ tear_off="true">
+ <menu_item_check
+ label="Bounding Boxes"
+ layout="topleft"
+ name="Bounding Boxes">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="bboxes" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="bboxes" />
+ </menu_item_check>
+ <menu_item_check
+ label="Octree"
+ layout="topleft"
+ name="Octree">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="octree" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="octree" />
+ </menu_item_check>
+ <menu_item_check
+ label="Shadow Frusta"
+ layout="topleft"
+ name="Shadow Frusta">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="shadow frusta" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="shadow frusta" />
+ </menu_item_check>
+ <menu_item_check
+ label="Occlusion"
+ layout="topleft"
+ name="Occlusion">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="occlusion" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="occlusion" />
+ </menu_item_check>
+ <menu_item_check
+ label="Render Batches"
+ layout="topleft"
+ name="Render Batches">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="render batches" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="render batches" />
+ </menu_item_check>
+ <menu_item_check
+ label="Texture Anim"
+ layout="topleft"
+ name="Texture Anim">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="texture anim" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="texture anim" />
+ </menu_item_check>
+ <menu_item_check
+ label="Texture Priority"
+ layout="topleft"
+ name="Texture Priority">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="texture priority" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="texture priority" />
+ </menu_item_check>
+ <menu_item_check
+ label="Texture Area"
+ layout="topleft"
+ name="Texture Area">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="texture area" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="texture area" />
+ </menu_item_check>
+ <menu_item_check
+ label="Face Area"
+ layout="topleft"
+ name="Face Area">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="face area" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="face area" />
+ </menu_item_check>
+ <menu_item_check
+ label="Lights"
+ layout="topleft"
+ name="Lights">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="lights" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="lights" />
+ </menu_item_check>
+ <menu_item_check
+ label="Collision Skeleton"
+ layout="topleft"
+ name="Collision Skeleton">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="collision skeleton" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="collision skeleton" />
+ </menu_item_check>
+ <menu_item_check
+ label="Raycast"
+ layout="topleft"
+ name="Raycast">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="raycast" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="raycast" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Rendering"
+ layout="topleft"
+ name="Rendering"
+ tear_off="true">
+ <menu_item_check
+ label="Axes"
+ name="Axes">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowAxes" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowAxes" />
+ </menu_item_check>
+ <menu_item_check
+ label="Tangent Basis"
+ name="Tangent Basis">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowTangentBasis" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowTangentBasis" />
+ </menu_item_check>
+ <menu_item_call
+ label="Selected Texture Info Basis"
+ name="Selected Texture Info Basis"
+ shortcut="control|alt|shift|T">
+ <menu_item_call.on_click
+ function="Advanced.SelectedTextureInfo" />
+ </menu_item_call>
+ <menu_item_check
+ label="Wireframe"
+ name="Wireframe"
+ shortcut="control|shift|R">
+ <menu_item_check.on_check
+ function="Advanced.CheckWireframe"
+ parameter="Wireframe" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleWireframe" />
+ </menu_item_check>
+ <menu_item_check
+ label="Object-Object Occlusion"
+ name="Object-Object Occlusion"
+ shortcut="control|shift|O">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="UseOcclusion" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="UseOcclusion" />
+ <menu_item_check.on_enable
+ function="Advanced.EnableObjectObjectOcclusion" />
+ </menu_item_check>
+ <menu_item_check
+ label="Framebuffer Objects"
+ name="Framebuffer Objects">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderUseFBO" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderUseFBO" />
+ <menu_item_check.on_enable
+ function="Advanced.EnableRenderFBO" />
+ </menu_item_check>
+ <menu_item_check
+ label="Deferred Rendering"
+ name="Deferred Rendering">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDeferred" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDeferred" />
+ <menu_item_check.on_enable
+ function="Advanced.EnableRenderDeferred" />
+ </menu_item_check>
+ <menu_item_check
+ label="Global Illumintation"
+ name="Global Illumination">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDeferredGI" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDeferredGI" />
+ <menu_item_check.on_enable
+ function="Advanced.EnableRenderDeferredGI" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Debug GL"
+ name="Debug GL">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Pipeline"
+ name="Debug Pipeline">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fast Alpha"
+ name="Fast Alpha">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Animation Textures"
+ name="Animation Textures">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderDebugGL" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDebugGL" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable Textures"
+ name="Disable Textures">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="TextureDisable" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="TextureDisable" />
+ </menu_item_check>
+ <menu_item_check
+ label="Full Res Textures"
+ layout="topleft"
+ name="Rull Res Textures">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="TextureLoadFullRes" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="TextureLoadFullRes" />
+ </menu_item_check>
+ <menu_item_check
+ label="Audit Textures"
+ layout="topleft"
+ name="Audit Textures">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AuditTexture" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="AuditTexture" />
+ </menu_item_check>
+ <menu_item_check
+ label="Texture Atlas"
+ name="Texture Atlas">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="EnableTextureAtlas" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="EnableTextureAtlas" />
+ </menu_item_check>
+ <menu_item_check
+ label="Render Attached Lights"
+ name="Render Attached Lights">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderAttachedLights" />
+ <menu_item_check.on_click
+ function="Advanced.HandleAttchedLightParticles"
+ parameter="RenderAttachedLights" />
+ </menu_item_check>
+ <menu_item_check
+ label="Render Attached Particles"
+ name="Render Attached Particles">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderAttachedParticles" />
+ <menu_item_check.on_click
+ function="Advanced.HandleAttchedLightParticles"
+ parameter="RenderAttachedParticles" />
+ </menu_item_check>
+ <menu_item_check
+ label="Hover Glow Objects"
+ name="Hover Glow Objects">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderHoverGlowEnable" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderHoverGlowEnable" />
+ </menu_item_check>
+ </menu>
+
+ <menu
+ create_jump_keys="true"
+ label="Network"
+ layout="topleft"
+ name="Network"
+ tear_off="true">
+ <menu_item_check
+ label="Pause Agent"
+ layout="topleft"
+ name="AgentPause">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AgentPause" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="AgentPause" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Enable Message Log"
+ layout="topleft"
+ name="Enable Message Log">
+ <menu_item_call.on_click
+ function="Advanced.EnableMessageLog" />
+ </menu_item_call>
+ <menu_item_call
+ label="Disable Message Log"
+ layout="topleft"
+ name="Disable Message Log">
+ <menu_item_call.on_click
+ function="Advanced.DisableMessageLog" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Velocity Interpolate Objects"
+ layout="topleft"
+ name="Velocity Interpolate Objects">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="VelocityInterpolate" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="VelocityInterpolate" />
+ </menu_item_check>
+ <menu_item_check
+ label="Ping Interpolate Object Positions"
+ layout="topleft"
+ name="Ping Interpolate Object Positions">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="PingInterpolate" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="PingInterpolate" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Drop a Packet"
+ layout="topleft"
+ name="Drop a Packet"
+ shortcut="control|alt|L">
+ <menu_item_call.on_click
+ function="Advanced.DropPacket" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="Dump Scripted Camera"
+ layout="topleft"
+ name="Dump Scripted Camera">
+ <menu_item_call.on_click
+ function="Advanced.DumpScriptedCamera" />
+ </menu_item_call>
+ <menu_item_call
+ label="Bumps, Pushes &amp; Hits"
+ layout="topleft"
+ name="Bumps, Pushes &amp;amp; Hits">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="bumps" />
+ </menu_item_call>
+
+ <menu
+ create_jump_keys="true"
+ label="Recorder"
+ layout="topleft"
+ name="Recorder"
+ tear_off="true">
+ <menu_item_call
+ label="Start Playback"
+ layout="topleft"
+ name="Start Playback">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="start playback" />
+ </menu_item_call>
+ <menu_item_call
+ label="Stop Playback"
+ layout="topleft"
+ name="Stop Playback">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="stop playback" />
+ </menu_item_call>
+ <menu_item_check
+ label="Loop Playback"
+ layout="topleft"
+ name="Loop Playback">
+ <menu_item_check.on_check
+ function="Advanced.CheckAgentPilotLoop"
+ parameter="loopPlayback" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleAgentPilotLoop" />
+ </menu_item_check>
+ <menu_item_call
+ label="Start Record"
+ layout="topleft"
+ name="Start Record">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="start record" />
+ </menu_item_call>
+ <menu_item_call
+ label="Stop Record"
+ layout="topleft"
+ name="Stop Record">
+ <menu_item_call.on_click
+ function="Advanced.AgentPilot"
+ parameter="stop record" />
+ </menu_item_call>
+ </menu>
+
+ <menu
+ create_jump_keys="true"
+ label="World"
+ layout="topleft"
+ name="World"
+ tear_off="true">
+ <menu_item_check
+ label="Sim Sun Override"
+ layout="topleft"
+ name="Sim Sun Override">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SkyOverrideSimSunPosition" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SkyOverrideSimSunPosition" />
+ </menu_item_check>
+ <menu_item_check
+ label="Cheesy Beacon"
+ layout="topleft"
+ name="Cheesy Beacon">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="CheesyBeacon" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="CheesyBeacon" />
+ </menu_item_check>
+ <menu_item_check
+ label="Fixed Weather"
+ layout="topleft"
+ name="Fixed Weather">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="FixedWeather" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="FixedWeather" />
+ </menu_item_check>
+ <menu_item_call
+ label="Dump Region Object Cache"
+ layout="topleft"
+ name="Dump Region Object Cache">
+ <menu_item_call.on_click
+ function="Advanced.DumpRegionObjectCache" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="UI"
+ layout="topleft"
+ name="UI"
+ tear_off="true">
+ <!-- <menu_item_check
+ label="New Bottom Bar"
+ layout="topleft"
+ name="New Bottom Bar">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="BottomPanelNew" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="BottomPanelNew" />
+ </menu_item_check>-->
+ <menu_item_call
+ label="Web Browser Test"
+ layout="topleft"
+ name="Web Browser Test">
+ <menu_item_call.on_click
+ function="Advanced.WebBrowserTest"
+ parameter="http://secondlife.com/app/search/slurls.html"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Dump SelectMgr"
+ layout="topleft"
+ name="Dump SelectMgr">
+ <menu_item_call.on_click
+ function="Advanced.DumpSelectMgr" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Inventory"
+ layout="topleft"
+ name="Dump Inventory">
+ <menu_item_call.on_click
+ function="Advanced.DumpInventory" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Timers"
+ name="Dump Timers">
+ <menu_item_call.on_click
+ function="Advanced.DumpTimers" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Focus Holder"
+ layout="topleft"
+ name="Dump Focus Holder"
+ shortcut="control|alt|F">
+ <menu_item_call.on_click
+ function="Advanced.DumpFocusHolder" />
+ </menu_item_call>
+ <menu_item_call
+ label="Print Selected Object Info"
+ layout="topleft"
+ name="Print Selected Object Info"
+ shortcut="control|shift|P">
+ <menu_item_call.on_click
+ function="Advanced.PrintSelectedObjectInfo" />
+ </menu_item_call>
+ <menu_item_call
+ label="Print Agent Info"
+ layout="topleft"
+ name="Print Agent Info"
+ shortcut="shift|P">
+ <menu_item_call.on_click
+ function="Advanced.PrintAgentInfo" />
+ </menu_item_call>
+ <menu_item_call
+ label="Memory Stats"
+ layout="topleft"
+ name="Memory Stats"
+ shortcut="control|alt|shift|M">
+ <menu_item_call.on_click
+ function="Advanced.PrintTextureMemoryStats" />
+ </menu_item_call>
+ <menu_item_check
+ label="Double-ClickAuto-Pilot"
+ layout="topleft"
+ name="Double-ClickAuto-Pilot">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DoubleClickAutoPilot" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DoubleClickAutoPilot" />
+ </menu_item_check>
+
+ <menu_item_separator />
+ <menu_item_check
+ label="Debug SelectMgr"
+ layout="topleft"
+ name="Debug SelectMgr">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugSelectMgr" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugSelectMgr" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Clicks"
+ layout="topleft"
+ name="Debug Clicks">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugClicks"
+ parameter="DebugClicks" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugClicks"
+ parameter="DebugClicks" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Views"
+ layout="topleft"
+ name="Debug Views">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugViews" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugViews" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Name Tooltips"
+ layout="topleft"
+ name="Debug Name Tooltips">
+ <menu_item_check.on_check
+ function="Advanced.CheckXUINameTooltips"
+ parameter="XUINameTooltips" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleXUINameTooltips" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Mouse Events"
+ layout="topleft"
+ name="Debug Mouse Events">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugMouseEvents"
+ parameter="MouseEvents" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugMouseEvents" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Keys"
+ layout="topleft"
+ name="Debug Keys">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugKeys"
+ parameter="DebugKeys" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugKeys" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug WindowProc"
+ layout="topleft"
+ name="Debug WindowProc">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugWindowProc"
+ parameter="DebugWindowProc" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugWindowProc"
+ parameter="DebugWindowProc" />
+ </menu_item_check>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="XUI"
+ name="XUI"
+ tear_off="true">
+ <menu_item_call
+ label="Reload Color Settings"
+ layout="topleft"
+ name="Reload Color Settings">
+ <menu_item_call.on_click
+ function="Advanced.ReloadColorSettings" />
+ </menu_item_call>
+ <menu_item_call
+ label="Show Font Test"
+ layout="topleft"
+ name="Show Font Test">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="font_test" />
+ </menu_item_call>
+ <menu_item_call
+ label="Load from XML"
+ layout="topleft"
+ name="Load from XML">
+ <menu_item_call.on_click
+ function="Advanced.LoadUIFromXML" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save to XML"
+ layout="topleft"
+ name="Save to XML">
+ <menu_item_call.on_click
+ function="Advanced.SaveUIToXML" />
+ </menu_item_call>
+ <menu_item_check
+ label="Show XUI Names"
+ layout="topleft"
+ name="Show XUI Names">
+ <menu_item_check.on_check
+ function="Advanced.CheckXUINames"
+ parameter="showUIname" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleXUINames" />
+ </menu_item_check>
+ <menu_item_call
+ label="Send Test IMs"
+ layout="topleft"
+ name="Send Test IMs">
+ <menu_item_call.on_click
+ function="Advanced.SendTestIMs" />
+ </menu_item_call>
+ <menu_item_call
+ label="Test Inspectors"
+ name="Test Inspectors"
+ shortcut="control|shift|I">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="test_inspectors" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Avatar"
+ layout="topleft"
+ name="Character"
+ tear_off="true">
+ <menu
+ create_jump_keys="true"
+ label="Grab Baked Texture"
+ layout="topleft"
+ name="Grab Baked Texture"
+ tear_off="true">
+ <menu_item_call
+ label="Iris"
+ layout="topleft"
+ name="Iris">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="iris" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture"
+ parameter="iris" />
+ </menu_item_call>
+ <menu_item_call
+ label="Head"
+ layout="topleft"
+ name="Head">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="head" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture"
+ parameter="head" />
+ </menu_item_call>
+ <menu_item_call
+ label="Upper Body"
+ layout="topleft"
+ name="Upper Body">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="upper" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture"
+ parameter="upper" />
+ </menu_item_call>
+ <menu_item_call
+ label="Lower Body"
+ layout="topleft"
+ name="Lower Body">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="lower" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture"
+ parameter="lower" />
+ </menu_item_call>
+ <menu_item_call
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Advanced.GrabBakedTexture"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Advanced.EnableGrabBakedTexture"
+ parameter="skirt" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Character Tests"
+ layout="topleft"
+ name="Character Tests"
+ tear_off="true">
+ <menu_item_call
+ label="Appearance To XML"
+ layout="topleft"
+ name="Appearance To XML">
+ <menu_item_call.on_click
+ function="Advanced.AppearanceToXML" />
+ </menu_item_call>
+ <menu_item_call
+ label="Toggle Character Geometry"
+ layout="topleft"
+ name="Toggle Character Geometry">
+ <menu_item_call.on_click
+ function="Advanced.ToggleCharacterGeometry" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Test Male"
+ layout="topleft"
+ name="Test Male">
+ <menu_item_call.on_click
+ function="Advanced.TestMale" />
+ </menu_item_call>
+ <menu_item_call
+ label="Test Female"
+ layout="topleft"
+ name="Test Female">
+ <menu_item_call.on_click
+ function="Advanced.TestFemale" />
+ </menu_item_call>
+ <menu_item_call
+ label="Toggle PG"
+ layout="topleft"
+ name="Toggle PG">
+ <menu_item_call.on_click
+ function="Advanced.TogglePG" />
+ </menu_item_call>
+ <menu_item_check
+ label="Allow Select Avatar"
+ layout="topleft"
+ name="Allow Select Avatar">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="AllowSelectAvatar" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="AllowSelectAvatar" />
+ </menu_item_check>
+ </menu>
+ <menu_item_call
+ label="Force Params to Default"
+ layout="topleft"
+ name="Force Params to Default">
+ <menu_item_call.on_click
+ function="Advanced.ForceParamsToDefault" />
+ </menu_item_call>
+ <menu_item_check
+ label="Animation Info"
+ layout="topleft"
+ name="Animation Info">
+ <menu_item_check.on_check
+ function="Advanced.CheckAnimationInfo"
+ parameter="AnimationInfo" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleAnimationInfo"
+ parameter="" />
+ </menu_item_check>
+ <menu_item_check
+ label="Slow Motion Animations"
+ layout="topleft"
+ name="Slow Motion Animations">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SlowMotionAnimation" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SlowMotionAnimation" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Look At"
+ layout="topleft"
+ name="Show Look At">
+ <menu_item_check.on_check
+ function="Advanced.CheckShowLookAt"
+ parameter="ShowLookAt" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleShowLookAt" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Point At"
+ layout="topleft"
+ name="Show Point At">
+ <menu_item_check.on_check
+ function="Advanced.CheckShowPointAt"
+ parameter="ShowPointAt" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleShowPointAt" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Joint Updates"
+ layout="topleft"
+ name="Debug Joint Updates">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugJointUpdates"
+ parameter="DebugJointUpdates" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugJointUpdates" />
+ </menu_item_check>
+ <menu_item_check
+ label="Disable LOD"
+ layout="topleft"
+ name="Disable LOD">
+ <menu_item_check.on_check
+ function="Advanced.CheckDisableLOD"
+ parameter="DisableLOD" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDisableLOD" />
+ </menu_item_check>
+ <menu_item_check
+ label="Debug Character Vis"
+ layout="topleft"
+ name="Debug Character Vis">
+ <menu_item_check.on_check
+ function="Advanced.CheckDebugCharacterVis"
+ parameter="DebugCharacterVis" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleDebugCharacterVis" />
+ </menu_item_check>
+ <menu_item_check
+ label="Show Collision Skeleton"
+ layout="topleft"
+ name="Show Collision Skeleton">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="collision skeleton" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="collision skeleton" />
+ </menu_item_check>
+ <menu_item_check
+ label="Display Agent Target"
+ layout="topleft"
+ name="Display Agent Target">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="agent target" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="agent target" />
+ </menu_item_check>
+<!-- Appears not to exist anymore
+ <menu_item_check
+ label="Debug Rotation"
+ layout="topleft"
+ name="Debug Rotation">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="DebugAvatarRotation" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="DebugAvatarRotation" />
+ </menu_item_check> -->
+-->
+ <menu_item_call
+ label="Dump Attachments"
+ layout="topleft"
+ name="Dump Attachments">
+ <menu_item_call.on_click
+ function="Advanced.DumpAttachments" />
+ </menu_item_call>
+ <menu_item_call
+ label="Debug Avatar Textures"
+ layout="topleft"
+ name="Debug Avatar Textures"
+ shortcut="control|alt|shift|A">
+ <menu_item_call.on_click
+ function="Advanced.DebugAvatarTextures" />
+ </menu_item_call>
+ <menu_item_call
+ label="Dump Local Textures"
+ layout="topleft"
+ name="Dump Local Textures"
+ shortcut="alt|shift|M">
+ <menu_item_call.on_click
+ function="Advanced.DumpAvatarLocalTextures" />
+ </menu_item_call>
+ </menu>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Compress Images"
+ layout="topleft"
+ name="Compress Images">
+ <menu_item_call.on_click
+ function="Advanced.CompressImage" />
+ </menu_item_call>
+ <menu_item_check
+ label="Output Debug Minidump"
+ layout="topleft"
+ name="Output Debug Minidump">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="SaveMinidump" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="SaveMinidump" />
+ </menu_item_check>
+ <menu_item_check
+ label="Console Window on next Run"
+ layout="topleft"
+ name="Console Window">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="ShowConsoleWindow" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="ShowConsoleWindow" />
+ </menu_item_check>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_check
+ label="Show Admin Menu"
+ layout="topleft"
+ name="View Admin Options">
+ <menu_item_check.on_check
+ function="Advanced.CheckViewAdminOptions"
+ parameter="ViewAdminOptions" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleViewAdminOptions" />
+ </menu_item_check>
+ <menu_item_call
+ label="Request Admin Status"
+ layout="topleft"
+ name="Request Admin Options"
+ shortcut="control|alt|G">
+ <menu_item_call.on_click
+ function="Advanced.RequestAdminStatus" />
+ </menu_item_call>
+ <menu_item_call
+ label="Leave Admin Status"
+ layout="topleft"
+ name="Leave Admin Options"
+ shortcut="control|alt|shift|G">
+ <menu_item_call.on_click
+ function="Advanced.LeaveAdminStatus" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Admin"
+ layout="topleft"
+ name="Admin"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Object"
+ layout="topleft"
+ tear_off="true">
+ <menu_item_call
+ label="Take Copy"
+ layout="topleft"
+ name="Take Copy"
+ shortcut="control|alt|shift|O">
+ <menu_item_call.on_click
+ function="Admin.ForceTakeCopy" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Owner To Me"
+ layout="topleft"
+ name="Force Owner To Me">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectOwnerSelf" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force Owner Permissive"
+ layout="topleft"
+ name="Force Owner Permissive">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectOwnerPermissive" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Delete"
+ layout="topleft"
+ name="Delete"
+ shortcut="control|alt|shift|Del">
+ <menu_item_call.on_click
+ function="Admin.HandleForceDelete" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Lock"
+ layout="topleft"
+ name="Lock"
+ shortcut="control|alt|shift|L">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectLock" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Get Assets IDs"
+ layout="topleft"
+ name="Get Assets IDs"
+ shortcut="control|alt|shift|I">
+ <menu_item_call.on_click
+ function="Admin.HandleObjectAssetIDs" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Parcel"
+ layout="topleft"
+ name="Parcel"
+ tear_off="true">
+ <menu_item_call
+ label="Owner To Me"
+ layout="topleft"
+ name="Owner To Me">
+ <menu_item_call.on_click
+ function="Admin.HandleForceParcelOwnerToMe" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Set to Linden Content"
+ layout="topleft"
+ name="Set to Linden Content"
+ shortcut="control|alt|shift|C">
+ <menu_item_call.on_click
+ function="Admin.HandleForceParcelToContent" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Claim Public Land"
+ layout="topleft"
+ name="Claim Public Land">
+ <menu_item_call.on_click
+ function="Admin.HandleClaimPublicLand" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Region"
+ layout="topleft"
+ name="Region"
+ tear_off="true">
+ <menu_item_call
+ label="Dump Temp Asset Data"
+ layout="topleft"
+ name="Dump Temp Asset Data">
+ <menu_item_call.on_click
+ function="Admin.HandleRegionDumpTempAssetData" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ <menu_item_call
+ label="Save Region State"
+ layout="topleft"
+ name="Save Region State">
+ <menu_item_call.on_click
+ function="Admin.OnSaveState" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu_item_call
+ label="God Tools"
+ layout="topleft"
+ name="God Tools">
+ <menu_item_call.on_click
+ function="Floater.Show"
+ parameter="god_tools" />
+ <menu_item_call.on_enable
+ function="IsGodCustomerService" />
+ </menu_item_call>
+ </menu>
+ <menu
+ create_jump_keys="true"
+ label="Admin"
+ layout="topleft"
+ name="Deprecated"
+ tear_off="true"
+ visible="false">
+ <menu
+ create_jump_keys="true"
+ label="Attach Object"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Attach Object"
+ tear_off="true" />
+ <menu
+ create_jump_keys="true"
+ label="Detach Object"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Detach Object"
+ tear_off="true" />
+ <menu
+ create_jump_keys="true"
+ label="Take Off Clothing"
+ layout="topleft"
+ mouse_opaque="false"
+ name="Take Off Clothing"
+ tear_off="true">
+ <menu_item_call
+ label="Shirt"
+ layout="topleft"
+ name="Shirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Pants"
+ layout="topleft"
+ name="Pants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="pants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="Shoes"
+ layout="topleft"
+ name="Shoes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="shoes" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="Socks"
+ layout="topleft"
+ name="Socks">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="socks" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="Jacket"
+ layout="topleft"
+ name="Jacket">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="jacket" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="Gloves"
+ layout="topleft"
+ name="Gloves">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="gloves" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="Undershirt"
+ layout="topleft"
+ name="Menu Undershirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="undershirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Underpants"
+ layout="topleft"
+ name="Menu Underpants">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="underpants" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="Skirt"
+ layout="topleft"
+ name="Skirt">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="skirt" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="Alpha"
+ layout="topleft"
+ name="Alpha">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="alpha" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="Tattoo"
+ layout="topleft"
+ name="Tattoo">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="tattoo" />
+ <menu_item_call.on_enable
+ function="Edit.EnableTakeOff"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ label="All Clothes"
+ layout="topleft"
+ name="All Clothes">
+ <menu_item_call.on_click
+ function="Edit.TakeOff"
+ parameter="all" />
+ </menu_item_call>
+ </menu>
+ <menu_item_check
+ label="Show Toolbar"
+ layout="topleft"
+ name="Show Toolbar">
+ <menu_item_check.on_check
+ function="FloaterVisible"
+ parameter="toolbar" />
+ <menu_item_check.on_click
+ function="ShowFloater"
+ parameter="toolbar" />
+ </menu_item_check>
+ <menu
+ create_jump_keys="true"
+ label="Help"
+ layout="topleft"
+ name="Help"
+ tear_off="true">
+ <menu_item_call
+ label="Official Linden Blog"
+ layout="topleft"
+ name="Official Linden Blog">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="OfficialLindenBlog_url"
+ parameter="WebLaunchSupportWiki,http://blog.secondlife.com/" />
+ </menu_item_call>
+ <menu_item_call
+ label="Scripting Portal"
+ layout="topleft"
+ name="Scripting Portal">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="ScriptingPortal_url"
+ parameter="WebLaunchLSLWiki,http://wiki.secondlife.com/wiki/LSL_Portal" />
+ </menu_item_call>
+ <menu
+ create_jump_keys="true"
+ label="Bug Reporting"
+ layout="topleft"
+ name="Bug Reporting"
+ tear_off="true">
+ <menu_item_call
+ label="Public Issue Tracker"
+ layout="topleft"
+ name="Public Issue Tracker">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="PublicIssueTracker_url"
+ parameter="WebLaunchPublicIssue,http://jira.secondlife.com" />
+ </menu_item_call>
+ <menu_item_call
+ label="Public Issue Tracker Help"
+ layout="topleft"
+ name="Publc Issue Tracker Help">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="PublicIssueTrackerHelp_url"
+ parameter="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker" />
+ </menu_item_call>
+ <menu_item_separator
+ layout="topleft" />
+ <menu_item_call
+ label="Bug Reporting 101"
+ layout="topleft"
+ name="Bug Reporing 101">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="BugReporting101_url"
+ parameter="WebLaunchBugReport101,http://wiki.secondlife.com/wiki/Bug_Reporting_101" />
+ </menu_item_call>
+ <menu_item_call
+ label="Security Issues"
+ layout="topleft"
+ name="Security Issues">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="SecurityIssues_url"
+ parameter="WebLaunchSecurityIssues,http://wiki.secondlife.com/wiki/Security_issues" />
+ </menu_item_call>
+ <menu_item_call
+ label="QA Wiki"
+ layout="topleft"
+ name="QA Wiki">
+ <menu_item_call.on_click
+ function="PromptShowURL"
+ name="QAWiki_url"
+ parameter="WebLaunchQAWiki,http://wiki.secondlife.com/wiki/QA_Portal" />
+ </menu_item_call>
+ </menu>
+ </menu>
+ </menu>
+</menu_bar>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 56cb54c975..0d1ed6fc64 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5747,7 +5747,7 @@ Are you sure you want to delete your teleport history?
name="BottomTrayButtonCanNotBeShown"
type="alert">
Selected button can not be shown right now.
-The button will be shown when there is enough space for it.
+The button will be shown when there is enough space for it.
</notification>
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
index 38294c907a..3ed91cb48f 100644
--- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml
+++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
@@ -7,8 +7,8 @@
left="0"
height="35"
width="318"
- background_opaque="false"
- background_visible="true"
+ background_opaque="false"
+ background_visible="true"
bg_alpha_color="0.0 0.0 0.0 0.0" >
<chiclet_im_p2p
name="p2p_chiclet"
diff --git a/indra/newview/skins/default/xui/en/panel_chat_header.xml b/indra/newview/skins/default/xui/en/panel_chat_header.xml
index 323ee957e7..7a3eae35a9 100644
--- a/indra/newview/skins/default/xui/en/panel_chat_header.xml
+++ b/indra/newview/skins/default/xui/en/panel_chat_header.xml
@@ -3,13 +3,13 @@
background_visible="true"
bevel_style="in"
bg_alpha_color="black"
- follows="top"
+ follows="top|left|right"
height="24"
- label="im_header"
- layout="topleft"
- name="im_header"
- width="300">
- <avatar_icon
+ label="im_header"
+ layout="topleft"
+ name="im_header"
+ width="300">
+ <avatar_icon
follows="left"
height="18"
image_name="Generic_Person"
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
index 9573904c93..73d843e6dd 100644
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
@@ -38,28 +38,29 @@
label="Teleport"
name="teleport_btn"
width="100" />
- <button
+ <!-- <button
follows="left|top"
height="20"
label="Share"
name="share_btn"
- width="100" />
- <button
+ width="100" />-->
+ <!--Removing pay button to save space - will update spec - verified by Erica/Steve -->
+ <!-- <button
follows="left|top"
height="20"
label="Pay"
name="pay_btn"
- width="100" />
+ width="100" />-->
<panel
background_visible="true"
bg_alpha_color="DkGray2"
border="false"
- follows="left|top"
+ top_pad="10"
+ follows="left|bottom"
height="70"
- left="0"
- left_pad="0"
+ left="1"
name="panel_call_buttons"
- width="110">
+ width="109">
<button
bottom="10"
height="20"
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index 962dad3363..5cefe3e4ab 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -131,7 +131,7 @@
<button
enabled="false"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Info"
layout="topleft"
@@ -143,7 +143,7 @@
<button
enabled="false"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Teleport"
layout="topleft"
@@ -155,7 +155,7 @@
<button
enabled="false"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Map"
layout="topleft"
@@ -167,7 +167,7 @@
<button
enabled="false"
follows="bottom|right"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="▼"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 8fc78c6701..b1afe76500 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -48,38 +48,40 @@
image_unselected="BuyArrow_Off"
image_pressed="BuyArrow_Press"
height="16"
- left="-245"
+ left="-200"
name="buycurrency"
- pad_right="22px"
+ pad_right="20px"
tool_tip="My Balance: Click to buy more L$"
top="1"
- width="117" />
- <button
- follows="right|bottom"
- height="16"
- image_selected="parcel_drk_VoiceNo"
- image_unselected="parcel_drk_Voice"
- is_toggle="true"
- left_pad="15"
- top="1"
- name="volume_btn"
- width="16" />
+ width="90" />
<text
type="string"
length="1"
+ font="SansSerifSmall"
text_readonly_color="TimeTextColor"
follows="right|bottom"
halign="right"
height="16"
top="5"
layout="topleft"
- left_pad="7"
+ left_pad="-5"
name="TimeText"
text_color="TimeTextColor"
tool_tip="Current time (Pacific)"
width="80">
12:00 AM
</text>
+ <button
+ follows="right|bottom"
+ height="16"
+ image_selected="parcel_drk_VoiceNo"
+ image_unselected="parcel_drk_Voice"
+ is_toggle="true"
+ left_pad="5"
+ top="1"
+ name="volume_btn"
+ tool_tip="Global Volume Control"
+ width="16" />
<text
enabled="true"
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
index 63e60aab78..ccb57b6552 100644
--- a/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_sys_well_item.xml
@@ -10,8 +10,8 @@
height="35"
layout="topleft"
follows="left|right"
- background_opaque="false"
- background_visible="true"
+ background_opaque="false"
+ background_visible="true"
bg_alpha_color="0.0 0.0 0.0 0.0" >
<text
top="2"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
index 2ce156cfda..041297a542 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml
@@ -62,7 +62,7 @@
width="313" />
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Wear"
layout="topleft"
@@ -72,7 +72,7 @@
width="80" />
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="New Outfit"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index cbcc3f10ad..377d34cdcc 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
@@ -41,7 +41,7 @@
<button
enabled="true"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Info"
layout="topleft"
@@ -52,7 +52,7 @@
<button
enabled="true"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Share"
layout="topleft"
@@ -63,7 +63,7 @@
<button
enabled="false"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Wear"
layout="topleft"
@@ -74,7 +74,7 @@
<button
enabled="false"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Play"
layout="topleft"
@@ -85,7 +85,7 @@
<button
enabled="false"
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Teleport"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 39cd75074e..0c605650fc 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -479,7 +479,7 @@
width="313">
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Edit"
layout="topleft"
@@ -489,7 +489,7 @@
width="50" />
<button
follows="bottom|right"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Cancel"
layout="topleft"
@@ -499,7 +499,7 @@
width="70" />
<button
follows="bottom|right"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Save"
layout="topleft"
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 8eb2254112..7647be7830 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -485,7 +485,7 @@
width="313">
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Edit"
layout="topleft"
@@ -495,7 +495,7 @@
width="50" />
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Open"
layout="topleft"
@@ -505,7 +505,7 @@
width="60" />
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Pay"
layout="topleft"
@@ -515,7 +515,7 @@
width="50" />
<button
follows="bottom|left"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Buy"
layout="topleft"
@@ -525,7 +525,7 @@
width="60" />
<button
follows="bottom|right"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Cancel"
layout="topleft"
@@ -535,7 +535,7 @@
width="70" />
<button
follows="bottom|right"
- font="SansSerifSmallBold"
+ font="SansSerifSmall"
height="25"
label="Save"
layout="topleft"