summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llagent.cpp102
-rw-r--r--indra/newview/llappviewer.cpp2
-rw-r--r--indra/newview/llassetuploadresponders.cpp3
-rw-r--r--indra/newview/llchatbar.cpp166
-rw-r--r--indra/newview/llchatbar.h16
-rw-r--r--indra/newview/llfloateranimpreview.cpp2
-rw-r--r--indra/newview/llfloateravatarpicker.cpp13
-rw-r--r--indra/newview/llfloaterchat.cpp30
-rw-r--r--indra/newview/llfloaterchat.h1
-rw-r--r--indra/newview/llfloaterchatterbox.cpp103
-rw-r--r--indra/newview/llfloaterchatterbox.h4
-rw-r--r--indra/newview/llfloaterfriends.cpp443
-rw-r--r--indra/newview/llfloaterfriends.h24
-rw-r--r--indra/newview/llfloaterinspect.cpp1
-rw-r--r--indra/newview/llfloaterland.cpp88
-rw-r--r--indra/newview/llfloaterland.h2
-rw-r--r--indra/newview/llfloaterpostcard.cpp5
-rw-r--r--indra/newview/llfloaterpostcard.h2
-rw-r--r--indra/newview/llfloaterregioninfo.cpp84
-rw-r--r--indra/newview/llfloaterregioninfo.h18
-rw-r--r--indra/newview/llfloaterscriptdebug.cpp4
-rw-r--r--indra/newview/llfloatertools.cpp3
-rw-r--r--indra/newview/llfloatertopobjects.cpp8
-rw-r--r--indra/newview/llfloaterworldmap.cpp8
-rw-r--r--indra/newview/llfloaterworldmap.h1
-rw-r--r--indra/newview/llfolderview.cpp18
-rw-r--r--indra/newview/llfolderview.h2
-rw-r--r--indra/newview/llhudview.cpp4
-rw-r--r--indra/newview/llhudview.h6
-rw-r--r--indra/newview/llimpanel.cpp564
-rw-r--r--indra/newview/llimpanel.h54
-rw-r--r--indra/newview/llimview.cpp466
-rw-r--r--indra/newview/llimview.h32
-rw-r--r--indra/newview/llinventorybridge.cpp2
-rw-r--r--indra/newview/llinventorymodel.cpp2
-rw-r--r--indra/newview/lljoystickbutton.cpp12
-rw-r--r--indra/newview/llmutelist.cpp54
-rw-r--r--indra/newview/llmutelist.h6
-rw-r--r--indra/newview/llnameeditor.cpp2
-rw-r--r--indra/newview/llnameeditor.h2
-rw-r--r--indra/newview/llnamelistctrl.cpp4
-rw-r--r--indra/newview/lloverlaybar.cpp493
-rw-r--r--indra/newview/lloverlaybar.h20
-rw-r--r--indra/newview/llpanelavatar.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp8
-rw-r--r--indra/newview/llpanelclassified.h2
-rw-r--r--indra/newview/llpanelface.cpp2
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp12
-rw-r--r--indra/newview/llpanelgroupgeneral.h1
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp2
-rw-r--r--indra/newview/llpanelgrouproles.cpp15
-rw-r--r--indra/newview/llpanelgrouproles.h1
-rw-r--r--indra/newview/llpanellogin.cpp2
-rw-r--r--indra/newview/llpanelobject.cpp2
-rw-r--r--indra/newview/llpanelvolume.cpp2
-rw-r--r--indra/newview/llpreviewgesture.cpp2
-rw-r--r--indra/newview/llpreviewscript.cpp2
-rw-r--r--indra/newview/llpreviewsound.cpp2
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/llstatusbar.cpp88
-rw-r--r--indra/newview/lltextureview.cpp1
-rw-r--r--indra/newview/lltoolbar.cpp182
-rw-r--r--indra/newview/lltoolbar.h9
-rw-r--r--indra/newview/lltoolplacer.cpp2
-rw-r--r--indra/newview/llvieweraudio.cpp14
-rw-r--r--indra/newview/llviewermenu.cpp11
-rw-r--r--indra/newview/llviewermessage.cpp20
-rw-r--r--indra/newview/llviewerobject.cpp6
-rw-r--r--indra/newview/llviewerparcelmgr.cpp17
-rw-r--r--indra/newview/llviewerparcelmgr.h2
-rw-r--r--indra/newview/llviewerregion.cpp5
-rw-r--r--indra/newview/llviewerregion.h2
-rw-r--r--indra/newview/llviewertexteditor.cpp86
-rw-r--r--indra/newview/llviewerwindow.cpp209
-rw-r--r--indra/newview/llviewerwindow.h9
-rw-r--r--indra/newview/llvoavatar.cpp4
-rw-r--r--indra/newview/llvoiceclient.cpp184
-rw-r--r--indra/newview/llvoiceclient.h10
-rw-r--r--indra/newview/llvoicevisualizer.cpp2
-rw-r--r--indra/newview/llworldmapview.cpp5
-rwxr-xr-xindra/newview/viewer_manifest.py2
81 files changed, 2211 insertions, 1594 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 5aaf9d0097..a692ef6a3e 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2880,7 +2880,7 @@ void LLAgent::endAnimationUpdateUI()
mCameraLag.clearVec();
// JC - Added for always chat in third person option
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
gToolMgr->setCurrentToolset(gMouselookToolset);
@@ -4004,7 +4004,7 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
if( mCameraMode != CAMERA_MODE_MOUSELOOK )
{
- gViewerWindow->setKeyboardFocus( NULL, NULL );
+ gViewerWindow->setKeyboardFocus( NULL );
mLastCameraMode = mCameraMode;
mCameraMode = CAMERA_MODE_MOUSELOOK;
@@ -4225,7 +4225,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL animate)
mbFlagsDirty = TRUE;
}
- gViewerWindow->setKeyboardFocus( NULL, NULL );
+ gViewerWindow->setKeyboardFocus( NULL );
gViewerWindow->setMouseCapture( NULL );
LLVOAvatar::onCustomizeStart();
@@ -5225,6 +5225,102 @@ void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **)
}
}
+class LLAgentDropGroupViewerNode : public LLHTTPNode
+{
+ virtual void post(
+ LLHTTPNode::ResponsePtr response,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+
+ if (
+ !input.isMap() ||
+ !input.has("body") )
+ {
+ //what to do with badly formed message?
+ response->status(400);
+ response->result(LLSD("Invalid message parameters"));
+ }
+
+ LLSD body = input["body"];
+ if ( body.has("body") )
+ {
+ //stupid message system doubles up the "body"s
+ body = body["body"];
+ }
+
+ if (
+ body.has("AgentData") &&
+ body["AgentData"].isArray() &&
+ body["AgentData"][0].isMap() )
+ {
+ llinfos << "VALID DROP GROUP" << llendl;
+
+ //there is only one set of data in the AgentData block
+ LLSD agent_data = body["AgentData"][0];
+ LLUUID agent_id;
+ LLUUID group_id;
+
+ agent_id = agent_data["AgentID"].asUUID();
+ group_id = agent_data["GroupID"].asUUID();
+
+ if (agent_id != gAgentID)
+ {
+ llwarns
+ << "AgentDropGroup for agent other than me" << llendl;
+
+ response->notFound();
+ return;
+ }
+
+ // Remove the group if it already exists remove it
+ // and add the new data to pick up changes.
+ LLGroupData gd;
+ gd.mID = group_id;
+ S32 index = gAgent.mGroups.find(gd);
+ if (index != -1)
+ {
+ gAgent.mGroups.remove(index);
+ if (gAgent.getGroupID() == group_id)
+ {
+ gAgent.mGroupID.setNull();
+ gAgent.mGroupPowers = 0;
+ gAgent.mGroupName[0] = '\0';
+ gAgent.mGroupTitle[0] = '\0';
+ }
+
+ // refresh all group information
+ gAgent.sendAgentDataUpdateRequest();
+
+ gGroupMgr->clearGroupData(group_id);
+ // close the floater for this group, if any.
+ LLFloaterGroupInfo::closeGroup(group_id);
+ // refresh the group panel of the search window,
+ //if necessary.
+ LLFloaterDirectory::refreshGroup(group_id);
+ }
+ else
+ {
+ llwarns
+ << "AgentDropGroup, agent is not part of group "
+ << group_id << llendl;
+ }
+
+ response->result(LLSD());
+ }
+ else
+ {
+ //what to do with badly formed message?
+ response->status(400);
+ response->result(LLSD("Invalid message parameters"));
+ }
+ }
+};
+
+LLHTTPRegistration<LLAgentDropGroupViewerNode>
+ gHTTPRegistrationAgentDropGroupViewerNode(
+ "/message/AgentDropGroup");
+
// static
void LLAgent::processAgentGroupDataUpdate(LLMessageSystem *msg, void **)
{
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ad934abfa7..8b126b7597 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -425,7 +425,7 @@ static void ui_audio_callback(const LLUUID& uuid)
{
if (gAudiop)
{
- F32 volume = gSavedSettings.getF32("AudioLevelUI");
+ F32 volume = gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI");
gAudiop->triggerSound(uuid, gAgent.getID(), volume);
}
}
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index c3c892a572..76cfe92c4c 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -252,7 +252,6 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
if(view)
{
LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
if((LLAssetType::AT_TEXTURE == asset_type)
@@ -262,7 +261,7 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
}
//LLInventoryView::dumpSelectionInformation((void*)view);
// restore keyboard focus
- gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
+ gFocusMgr.setKeyboardFocus(focus_ctrl);
}
}
else
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 3517c1e18a..78365e66f1 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -93,51 +93,20 @@ private:
// Functions
//
-//inline constructor
-// for chat bars embedded in floaters, etc
-LLChatBar::LLChatBar(const std::string& name)
-: LLPanel(name, LLRect(), BORDER_NO),
+LLChatBar::LLChatBar()
+: LLPanel("", LLRect(), BORDER_NO),
mInputEditor(NULL),
mGestureLabelTimer(),
mLastSpecialChatChannel(0),
mIsBuilt(FALSE),
- mDynamicLayout(FALSE),
- mGestureCombo(NULL),
- mObserver(NULL)
-{
-}
-
-LLChatBar::LLChatBar(const std::string& name, const LLRect& rect)
-: LLPanel(name, rect, BORDER_NO),
- mInputEditor(NULL),
- mGestureLabelTimer(),
- mLastSpecialChatChannel(0),
- mIsBuilt(FALSE),
- mDynamicLayout(TRUE),
mGestureCombo(NULL),
mObserver(NULL)
{
setIsChrome(TRUE);
- gUICtrlFactory->buildPanel(this,"panel_chat_bar.xml");
-
- mIsFocusRoot = TRUE;
-
- setRect(rect); // override xml rect
-
- setBackgroundOpaque(TRUE);
- setBackgroundVisible(TRUE);
-
- // Start visible if we left the app while chatting.
- setVisible( gSavedSettings.getBOOL("ChatVisible") );
-
- // Apply custom layout.
- layout();
-
-#if !LL_RELEASE_FOR_DOWNLOAD
+ #if !LL_RELEASE_FOR_DOWNLOAD
childDisplayNotFound();
#endif
-
}
@@ -151,25 +120,18 @@ LLChatBar::~LLChatBar()
BOOL LLChatBar::postBuild()
{
childSetAction("History", toggleChatHistory, this);
- childSetAction("Say", onClickSay, this);
- childSetAction("Shout", onClickShout, this);
+ childSetCommitCallback("Say", onClickSay, this);
// attempt to bind to an existing combo box named gesture
setGestureCombo(LLUICtrlFactory::getComboBoxByName(this, "Gesture"));
- LLButton * sayp = static_cast<LLButton*>(getChildByName("Say", TRUE));
- if(sayp)
- {
- setDefaultBtn(sayp);
- }
-
mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "Chat Editor");
if (mInputEditor)
{
mInputEditor->setCallbackUserData(this);
mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke);
- mInputEditor->setFocusLostCallback(&onInputEditorFocusLost);
- mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus );
+ mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
+ mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
mInputEditor->setCommitOnFocusLost( FALSE );
mInputEditor->setRevertOnEsc( FALSE );
mInputEditor->setIgnoreTab(TRUE);
@@ -189,16 +151,6 @@ BOOL LLChatBar::postBuild()
//-----------------------------------------------------------------------
// virtual
-void LLChatBar::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
- if (mIsBuilt)
- {
- layout();
- }
-}
-
-// virtual
BOOL LLChatBar::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
{
BOOL handled = FALSE;
@@ -208,13 +160,6 @@ BOOL LLChatBar::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
// ALT-RETURN is reserved for windowed/fullscreen toggle
if( KEY_RETURN == key )
{
- //if (childGetValue("Chat Editor").asString().empty())
- //{
- // // no text, just close chat bar
- // stopChat();
- // return TRUE;
- //}
-
if (mask == MASK_CONTROL)
{
// shout
@@ -239,78 +184,8 @@ BOOL LLChatBar::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
return handled;
}
-
-void LLChatBar::layout()
-{
- if (!mDynamicLayout) return;
-
- S32 rect_width = mRect.getWidth();
- S32 count = 9; // number of elements in LLToolBar
- S32 pad = 4;
-
- LLRect gesture_rect;
- S32 gesture_width = 0;
- if (childGetRect("Gesture", gesture_rect))
- {
- gesture_width = gesture_rect.getWidth();
- }
- F32 segment_width = (F32)(rect_width - (pad + gesture_width)) / (F32)count;
-
- S32 btn_width = lltrunc(segment_width-pad);
-
- S32 x = 0;
- S32 y = 1;
- LLRect r;
-
- x = llround(0 * segment_width);
- r.setOriginAndSize(x, y, btn_width, BTN_HEIGHT);
- childSetRect("History", r);
-
- x = llround(1 * segment_width);
- // Hack this one up so it looks nice.
- if (mInputEditor)
- {
- r.setOriginAndSize(x, y+2, llfloor(6*segment_width-pad), 18);
- mInputEditor->reshape(r.getWidth(), r.getHeight(), TRUE);
- mInputEditor->setRect(r);
- }
-
- x = llround(7 * segment_width);
- r.setOriginAndSize(x, y, btn_width, BTN_HEIGHT);
- childSetRect("Say", r);
-
- x = llround(8 * segment_width);
- r.setOriginAndSize(x, y, btn_width, BTN_HEIGHT);
- childSetRect("Shout", r);
-
- x = rect_width - (pad + gesture_width);
- r.setOriginAndSize(x, y, gesture_width, BTN_HEIGHT);
- childSetRect("Gesture", r);
-}
-
-
void LLChatBar::refresh()
{
- //BOOL chat_mode = gSavedSettings.getBOOL("ChatVisible");
-
- //// Grab focus when no one else has it, and we're in chat mode.
- //if (!gFocusMgr.getKeyboardFocus()
- // && chat_mode)
- //{
- // childSetFocus("Chat Editor", TRUE);
- //}
-
- // Only show this view when user wants to be chatting
- //setVisible(chat_mode);
-
- // hide in mouselook, but keep previous visibility state
- //BOOL mouselook = gAgent.cameraMouselook();
- // call superclass setVisible so that we don't overwrite the saved setting
- if (mDynamicLayout)
- {
- LLPanel::setVisible(gSavedSettings.getBOOL("ChatVisible"));
- }
-
// HACK: Leave the name of the gesture in place for a few seconds.
const F32 SHOW_GESTURE_NAME_TIME = 2.f;
if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
@@ -584,12 +459,7 @@ void LLChatBar::stopChat()
// hide chat bar so it doesn't grab focus back
gChatBar->setVisible(FALSE);
-}
-
-void LLChatBar::setVisible(BOOL visible)
-{
- gSavedSettings.setBOOL("ChatVisible", visible);
- LLPanel::setVisible(visible);
+ gSavedSettings.setBOOL("ChatVisible", FALSE);
}
// static
@@ -663,30 +533,30 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
}
// static
-void LLChatBar::onInputEditorFocusLost( LLUICtrl* caller, void* userdata)
+void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
{
// stop typing animation
gAgent.stopTyping();
}
// static
-void LLChatBar::onInputEditorGainFocus( LLUICtrl* caller, void* userdata )
+void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
{
LLFloaterChat::setHistoryCursorAndScrollToEnd();
}
// static
-void LLChatBar::onClickSay( void* userdata )
+void LLChatBar::onClickSay( LLUICtrl* ctrl, void* userdata )
{
LLChatBar* self = (LLChatBar*) userdata;
- self->sendChat( CHAT_TYPE_NORMAL );
-}
-
-// static
-void LLChatBar::onClickShout( void* userdata )
-{
- LLChatBar *self = (LLChatBar *)userdata;
- self->sendChat( CHAT_TYPE_SHOUT );
+ if (ctrl->getValue().asString() == "shout")
+ {
+ self->sendChat( CHAT_TYPE_SHOUT );
+ }
+ else
+ {
+ self->sendChat( CHAT_TYPE_NORMAL );
+ }
}
void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
index 76a80125ae..f198574dcd 100644
--- a/indra/newview/llchatbar.h
+++ b/indra/newview/llchatbar.h
@@ -49,17 +49,12 @@ class LLChatBar
{
public:
// constructor for inline chat-bars (e.g. hosted in chat history window)
- LLChatBar(const std::string& name);
- LLChatBar(const std::string& name, const LLRect& rect);
+ LLChatBar();
~LLChatBar();
virtual BOOL postBuild();
- virtual void reshape(S32 width, S32 height, BOOL called_from_parent);
virtual BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
- // Adjust buttons and input field for width
- void layout();
-
void refresh();
void refreshGestures();
@@ -86,20 +81,18 @@ public:
LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
// callbacks
- static void onClickSay( void* userdata );
- static void onClickShout( void* userdata );
+ static void onClickSay( LLUICtrl*, void* userdata );
static void onTabClick( void* userdata );
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
- static void onInputEditorFocusLost(LLUICtrl* caller,void* userdata);
- static void onInputEditorGainFocus(LLUICtrl* caller,void* userdata);
+ static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
+ static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
static void onCommitGesture(LLUICtrl* ctrl, void* data);
static void startChat(void*);
static void stopChat();
- /*virtual*/ void setVisible(BOOL visible);
protected:
void sendChat(EChatType type);
void updateChat();
@@ -113,7 +106,6 @@ protected:
S32 mLastSpecialChatChannel;
BOOL mIsBuilt;
- BOOL mDynamicLayout;
LLComboBox* mGestureCombo;
LLChatBarGestureObserver* mObserver;
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 693ffe091b..18c3983b9a 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -155,7 +155,6 @@ BOOL LLFloaterAnimPreview::postBuild()
mPlayButton->setDisabledImages("","");
mPlayButton->setScaleImage(TRUE);
- mPlayButton->setFixedBorder(0, 0);
mStopButton = LLViewerUICtrlFactory::getButtonByName(this, "stop_btn");
if (!mStopButton)
@@ -170,7 +169,6 @@ BOOL LLFloaterAnimPreview::postBuild()
mStopButton->setDisabledImages("","");
mStopButton->setScaleImage(TRUE);
- mStopButton->setFixedBorder(0, 0);
r.set(r.mRight + PREVIEW_HPAD, y, getRect().getWidth() - PREVIEW_HPAD, y - BTN_HEIGHT);
childSetCommitCallback("playback_slider", onSliderMove, this);
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index a2ea8c2794..8dcd38c0bb 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -189,12 +189,15 @@ void LLFloaterAvatarPicker::onList(LLUICtrl* ctrl, void* userdata)
return;
}
- std::vector<LLScrollListItem*> items = self->mListNames->getAllSelected();
- for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
- iter != items.end(); ++iter)
+ std::vector<LLScrollListItem*> items =
+ self->mListNames->getAllSelected();
+ for (
+ std::vector<LLScrollListItem*>::iterator iter = items.begin();
+ iter != items.end();
+ ++iter)
{
LLScrollListItem* item = *iter;
- self->mAvatarNames.push_back(item->getColumn(0)->getText());
+ self->mAvatarNames.push_back(item->getColumn(0)->getValue().asString());
self->mAvatarIDs.push_back(item->getUUID());
self->childSetEnabled("Select", TRUE);
}
@@ -225,8 +228,8 @@ void LLFloaterAvatarPicker::doSelectionChange(const std::deque<LLFolderViewItem*
mAvatarNames.clear();
childSetEnabled("Select", FALSE);
}
+ BOOL first_calling_card = TRUE;
- BOOL first_calling_card = TRUE;
std::deque<LLFolderViewItem*>::const_iterator item_it;
for (item_it = items.begin(); item_it != items.end(); ++item_it)
{
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 5fdbf7d408..82fe16172b 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -164,10 +164,16 @@ void LLFloaterChat::onVisibilityChange(BOOL new_visibility)
{
// Hide the chat overlay when our history is visible.
gConsole->setVisible( !new_visibility );
+
+ // stop chat history tab from flashing when it appears
+ if (new_visibility)
+ {
+ LLFloaterChatterBox::getInstance()->setFloaterFlashing(this, FALSE);
+ }
+
LLFloater::onVisibilityChange(new_visibility);
}
-
void add_timestamped_line(LLViewerTextEditor* edit, const LLString& line, const LLColor4& color)
{
bool prepend_newline = true;
@@ -238,6 +244,12 @@ void LLFloaterChat::addChatHistory(const LLChat& chat, bool log_to_file)
{
chat_floater->mPanel->setSpeaker(chat.mFromID, chat.mFromName, LLSpeaker::STATUS_NOT_IN_CHANNEL, LLSpeaker::SPEAKER_OBJECT);
}
+
+ // start tab flashing on incoming text from other users (ignoring system text, etc)
+ if (!chat_floater->isInVisibleChain() && chat.mSourceType == CHAT_SOURCE_AGENT)
+ {
+ LLFloaterChatterBox::getInstance()->setFloaterFlashing(chat_floater, TRUE);
+ }
}
// static
@@ -246,8 +258,14 @@ void LLFloaterChat::setHistoryCursorAndScrollToEnd()
LLViewerTextEditor* history_editor = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor", TRUE);
LLViewerTextEditor* history_editor_with_mute = (LLViewerTextEditor*)LLFloaterChat::getInstance(LLSD())->getChildByName("Chat History Editor with mute", TRUE);
- history_editor->setCursorAndScrollToEnd();
- history_editor_with_mute->setCursorAndScrollToEnd();
+ if (history_editor)
+ {
+ history_editor->setCursorAndScrollToEnd();
+ }
+ if (history_editor_with_mute)
+ {
+ history_editor_with_mute->setCursorAndScrollToEnd();
+ }
}
@@ -269,7 +287,7 @@ void LLFloaterChat::onClickMute(void *data)
if (gFloaterMute)
{
- gFloaterMute->show();
+ LLFloaterMute::showInstance();
}
}
@@ -433,7 +451,7 @@ void* LLFloaterChat::createSpeakersPanel(void* data)
//static
void* LLFloaterChat::createChatPanel(void* data)
{
- LLChatBar* chatp = new LLChatBar("floating_chat_bar");
+ LLChatBar* chatp = new LLChatBar();
return chatp;
}
@@ -441,7 +459,7 @@ void* LLFloaterChat::createChatPanel(void* data)
void LLFloaterChat::hideInstance(const LLSD& id)
{
LLFloaterChat* floaterp = LLFloaterChat::getInstance(LLSD());
- // don't do anything when hosted in the chatterbox
+
if(floaterp->getHost())
{
LLFloaterChatterBox::hideInstance(LLSD());
diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h
index 808393b267..58fa607b38 100644
--- a/indra/newview/llfloaterchat.h
+++ b/indra/newview/llfloaterchat.h
@@ -82,6 +82,7 @@ public:
protected:
LLPanelActiveSpeakers* mPanel;
+ BOOL mScrolledToEnd;
};
#endif
diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp
index bdd30906d2..85bc8182a5 100644
--- a/indra/newview/llfloaterchatterbox.cpp
+++ b/indra/newview/llfloaterchatterbox.cpp
@@ -86,9 +86,15 @@ LLFloaterMyFriends* LLFloaterMyFriends::showInstance(const LLSD& id)
//static
void LLFloaterMyFriends::hideInstance(const LLSD& id)
{
- if(instanceVisible(id))
+ LLFloaterMyFriends* floaterp = LLFloaterMyFriends::getInstance();
+
+ if(floaterp->getHost())
{
- LLFloaterChatterBox::hideInstance(LLSD());
+ LLFloaterChatterBox::hideInstance();
+ }
+ else
+ {
+ LLUISingleton<LLFloaterMyFriends>::hideInstance(id);
}
}
@@ -124,10 +130,23 @@ LLFloaterChatterBox::LLFloaterChatterBox(const LLSD& seed) :
mAutoResize = FALSE;
gUICtrlFactory->buildFloater(this, "floater_chatterbox.xml", NULL, FALSE);
- addFloater(LLFloaterMyFriends::getInstance(0), TRUE);
+ if (gSavedSettings.getBOOL("ContactsTornOff"))
+ {
+ LLFloaterMyFriends* floater_contacts = LLFloaterMyFriends::getInstance(0);
+ // add then remove to set up relationship for re-attach
+ addFloater(floater_contacts, FALSE);
+ removeFloater(floater_contacts);
+ // reparent to floater view
+ gFloaterView->addChild(floater_contacts);
+ }
+ else
+ {
+ addFloater(LLFloaterMyFriends::getInstance(0), TRUE);
+ }
+
if (gSavedSettings.getBOOL("ChatHistoryTornOff"))
{
- LLFloaterChat* floater_chat = LLFloaterChat::getInstance(LLSD());
+ LLFloaterChat* floater_chat = LLFloaterChat::getInstance();
// add then remove to set up relationship for re-attach
addFloater(floater_chat, FALSE);
removeFloater(floater_chat);
@@ -217,7 +236,7 @@ void LLFloaterChatterBox::draw()
mActiveVoiceFloater = current_active_floater;
- LLFloater::draw();
+ LLMultiFloater::draw();
}
void LLFloaterChatterBox::onOpen()
@@ -236,10 +255,17 @@ void LLFloaterChatterBox::removeFloater(LLFloater* floaterp)
if (floaterp->getName() == "chat floater")
{
// only my friends floater now locked
- mTabContainer->lockTabs(1);
+ mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1);
gSavedSettings.setBOOL("ChatHistoryTornOff", TRUE);
floaterp->setCanClose(TRUE);
}
+ else if (floaterp->getName() == "floater_my_friends")
+ {
+ // only chat floater now locked
+ mTabContainer->lockTabs(mTabContainer->getNumLockedTabs() - 1);
+ gSavedSettings.setBOOL("ContactsTornOff", TRUE);
+ floaterp->setCanClose(TRUE);
+ }
LLMultiFloater::removeFloater(floaterp);
}
@@ -247,19 +273,43 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
BOOL select_added_floater,
LLTabContainerCommon::eInsertionPoint insertion_point)
{
+ S32 num_locked_tabs = mTabContainer->getNumLockedTabs();
+
+ // already here
+ if (floaterp->getHost() == this) return;
+
// make sure my friends and chat history both locked when re-attaching chat history
if (floaterp->getName() == "chat floater")
{
- // select my friends tab
- mTabContainer->selectFirstTab();
- // add chat history to the right of the my friends tab
- //*TODO: respect select_added_floater so that we don't leave first tab selected
- LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT);
+ mTabContainer->unlockTabs();
+ // add chat history as second tab if contact window is present, first tab otherwise
+ if (getChildByName("floater_my_friends", TRUE))
+ {
+ // assuming contacts window is first tab, select it
+ mTabContainer->selectFirstTab();
+ // and add ourselves after
+ LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::RIGHT_OF_CURRENT);
+ }
+ else
+ {
+ LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START);
+ }
+
// make sure first two tabs are now locked
- mTabContainer->lockTabs(2);
+ mTabContainer->lockTabs(num_locked_tabs + 1);
gSavedSettings.setBOOL("ChatHistoryTornOff", FALSE);
floaterp->setCanClose(FALSE);
}
+ else if (floaterp->getName() == "floater_my_friends")
+ {
+ mTabContainer->unlockTabs();
+ // add contacts window as first tab
+ LLMultiFloater::addFloater(floaterp, select_added_floater, LLTabContainer::START);
+ // make sure first two tabs are now locked
+ mTabContainer->lockTabs(num_locked_tabs + 1);
+ gSavedSettings.setBOOL("ContactsTornOff", FALSE);
+ floaterp->setCanClose(FALSE);
+ }
else
{
LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
@@ -276,24 +326,27 @@ void LLFloaterChatterBox::addFloater(LLFloater* floaterp,
//static
LLFloaterChatterBox* LLFloaterChatterBox::showInstance(const LLSD& seed)
{
- LLFloaterChatterBox* floater = LLUISingleton<LLFloaterChatterBox>::showInstance(seed);
+ LLFloaterChatterBox* chatterbox_floater = LLUISingleton<LLFloaterChatterBox>::showInstance(seed);
// if TRUE, show tab for active voice channel, otherwise, just show last tab
- if (seed.asBoolean())
+ LLFloater* floater_to_show = NULL;
+ LLUUID session_id = seed.asUUID();
+ if (session_id.notNull())
{
- LLFloater* floater_to_show = getCurrentVoiceFloater();
- if (floater_to_show)
- {
- floater_to_show->open();
- }
- else
- {
- // just open chatterbox if there is no active voice window
- LLUISingleton<LLFloaterChatterBox>::getInstance(seed)->open();
- }
+ floater_to_show = gIMMgr->findFloaterBySession(session_id);
+ }
+
+ if (floater_to_show)
+ {
+ floater_to_show->open();
+ }
+ else
+ {
+ // just open chatterbox to the last selected tab
+ chatterbox_floater->open();
}
- return floater;
+ return chatterbox_floater;
}
//static
diff --git a/indra/newview/llfloaterchatterbox.h b/indra/newview/llfloaterchatterbox.h
index 34410935f2..bf06ee9d38 100644
--- a/indra/newview/llfloaterchatterbox.h
+++ b/indra/newview/llfloaterchatterbox.h
@@ -50,7 +50,7 @@ public:
void onClose(bool app_quitting);
// override LLUISingleton behavior
- static LLFloaterMyFriends* showInstance(const LLSD& id);
+ static LLFloaterMyFriends* showInstance(const LLSD& id = LLSD());
static void hideInstance(const LLSD& id);
static BOOL instanceVisible(const LLSD& id);
@@ -77,7 +77,7 @@ public:
BOOL select_added_floater,
LLTabContainerCommon::eInsertionPoint insertion_point = LLTabContainerCommon::END);
- static LLFloaterChatterBox* showInstance(const LLSD& seed);
+ static LLFloaterChatterBox* showInstance(const LLSD& seed = LLSD());
static BOOL instanceVisible(const LLSD& seed);
static LLFloater* getCurrentVoiceFloater();
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 6f4945e54b..9d52107a20 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -104,7 +104,6 @@ LLPanelFriends::LLPanelFriends() :
LLPanel(),
LLEventTimer(1000000),
mObserver(NULL),
- mMenuState(0),
mShowMaxSelectWarning(TRUE),
mAllowRightsChange(TRUE),
mNumRightsChanged(0)
@@ -182,16 +181,13 @@ BOOL LLPanelFriends::postBuild()
{
mFriendsList = LLUICtrlFactory::getScrollListByName(this, "friend_list");
mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
- mFriendsList->setMaxiumumSelectCallback(onMaximumSelect);
+ mFriendsList->setMaximumSelectCallback(onMaximumSelect);
mFriendsList->setCommitOnSelectionChange(TRUE);
childSetCommitCallback("friend_list", onSelectName, this);
childSetDoubleClickCallback("friend_list", onClickIM);
refreshNames();
- childSetCommitCallback("online_status_cb", onClickOnlineStatus, this);
- childSetCommitCallback("map_status_cb", onClickMapStatus, this);
- childSetCommitCallback("modify_status_cb", onClickModifyStatus, this);
childSetAction("im_btn", onClickIM, this);
childSetAction("profile_btn", onClickProfile, this);
childSetAction("offer_teleport_btn", onClickOfferTeleport, this);
@@ -204,6 +200,10 @@ BOOL LLPanelFriends::postBuild()
updateFriends(LLFriendObserver::ADD);
refreshUI();
+ // primary sort = online status, secondary sort = name
+ mFriendsList->sortByColumn("friend_name", TRUE);
+ mFriendsList->sortByColumn("icon_online_status", TRUE);
+
return TRUE;
}
@@ -222,64 +222,63 @@ void LLPanelFriends::addFriend(const std::string& name, const LLUUID& agent_id)
element["columns"][LIST_FRIEND_NAME]["font"] = "SANSSERIF";
element["columns"][LIST_FRIEND_NAME]["font-style"] = "NORMAL";
element["columns"][LIST_ONLINE_STATUS]["column"] = "icon_online_status";
- element["columns"][LIST_ONLINE_STATUS]["type"] = "text";
+ element["columns"][LIST_ONLINE_STATUS]["type"] = "icon";
if (online)
{
element["columns"][LIST_FRIEND_NAME]["font-style"] = "BOLD";
- element["columns"][LIST_ONLINE_STATUS]["type"] = "icon";
element["columns"][LIST_ONLINE_STATUS]["value"] = gViewerArt.getString("icon_avatar_online.tga");
}
-
element["columns"][LIST_VISIBLE_ONLINE]["column"] = "icon_visible_online";
- element["columns"][LIST_VISIBLE_ONLINE]["type"] = "text";
- if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
- {
- element["columns"][LIST_VISIBLE_ONLINE]["type"] = "icon";
- element["columns"][LIST_VISIBLE_ONLINE]["value"] = gViewerArt.getString("ff_visible_online.tga");
- }
+ element["columns"][LIST_VISIBLE_ONLINE]["type"] = "checkbox";
+ element["columns"][LIST_VISIBLE_ONLINE]["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS);
+
element["columns"][LIST_VISIBLE_MAP]["column"] = "icon_visible_map";
- element["columns"][LIST_VISIBLE_MAP]["type"] = "text";
- if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION))
- {
- element["columns"][LIST_VISIBLE_MAP]["type"] = "icon";
- element["columns"][LIST_VISIBLE_MAP]["value"] = gViewerArt.getString("ff_visible_map.tga");
- }
+ element["columns"][LIST_VISIBLE_MAP]["type"] = "checkbox";
+ element["columns"][LIST_VISIBLE_MAP]["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION);
+
element["columns"][LIST_EDIT_MINE]["column"] = "icon_edit_mine";
- element["columns"][LIST_EDIT_MINE]["type"] = "text";
- if(relationInfo->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
- {
- element["columns"][LIST_EDIT_MINE]["type"] = "icon";
- element["columns"][LIST_EDIT_MINE]["value"] = gViewerArt.getString("ff_edit_mine.tga");
- }
+ element["columns"][LIST_EDIT_MINE]["type"] = "checkbox";
+ element["columns"][LIST_EDIT_MINE]["value"] = relationInfo->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
+
element["columns"][LIST_EDIT_THEIRS]["column"] = "icon_edit_theirs";
- element["columns"][LIST_EDIT_THEIRS]["type"] = "text";
- if(relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS))
- {
- element["columns"][LIST_EDIT_THEIRS]["type"] = "icon";
- element["columns"][LIST_EDIT_THEIRS]["value"] = gViewerArt.getString("ff_edit_theirs.tga");
- }
+ element["columns"][LIST_EDIT_THEIRS]["type"] = "checkbox";
+ element["columns"][LIST_EDIT_THEIRS]["enabled"] = "";
+ element["columns"][LIST_EDIT_THEIRS]["value"] = relationInfo->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS);
+
+ element["columns"][LIST_FRIEND_UPDATE_GEN]["column"] = "friend_last_update_generation";
+ element["columns"][LIST_FRIEND_UPDATE_GEN]["value"] = relationInfo->getChangeSerialNum();
+
mFriendsList->addElement(element, ADD_BOTTOM);
}
+// propagate actual relationship to UI
+void LLPanelFriends::updateFriendItem(LLScrollListItem* itemp, const LLRelationship* info)
+{
+ if (!itemp) return;
+ if (!info) return;
+
+ itemp->getColumn(LIST_ONLINE_STATUS)->setValue(info->isOnline() ? gViewerArt.getString("icon_avatar_online.tga") : LLString());
+ // render name of online friends in bold text
+ ((LLScrollListText*)itemp->getColumn(LIST_FRIEND_NAME))->setFontStyle(info->isOnline() ? LLFontGL::BOLD : LLFontGL::NORMAL);
+ itemp->getColumn(LIST_VISIBLE_ONLINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
+ itemp->getColumn(LIST_VISIBLE_MAP)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION));
+ itemp->getColumn(LIST_EDIT_MINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS));
+ itemp->getColumn(LIST_FRIEND_UPDATE_GEN)->setValue(info->getChangeSerialNum());
+
+ // enable this item, in case it was disabled after user input
+ itemp->setEnabled(TRUE);
+
+ // changed item in place, need to request sort
+ mFriendsList->sortItems();
+}
+
void LLPanelFriends::refreshRightsChangeList()
{
LLDynamicArray<LLUUID> friends = getSelectedIDs();
S32 num_selected = friends.size();
- LLSD row;
bool can_offer_teleport = num_selected >= 1;
-
- // aggregate permissions over all selected friends
- bool friends_see_online = true;
- bool friends_see_on_map = true;
- bool friends_modify_objects = true;
-
- // do at least some of the friends selected have these rights?
- bool some_friends_see_online = false;
- bool some_friends_see_on_map = false;
- bool some_friends_modify_objects = false;
-
bool selected_friends_online = true;
LLTextBox* processing_label = LLUICtrlFactory::getTextBoxByName(this, "process_rights_label");
@@ -294,12 +293,9 @@ void LLPanelFriends::refreshRightsChangeList()
num_selected = 0;
}
}
- else
+ else if(processing_label)
{
- if(processing_label)
- {
- processing_label->setVisible(false);
- }
+ processing_label->setVisible(false);
}
const LLRelationship* friend_status = NULL;
@@ -308,20 +304,6 @@ void LLPanelFriends::refreshRightsChangeList()
friend_status = LLAvatarTracker::instance().getBuddyInfo(*itr);
if (friend_status)
{
- bool can_see_online = friend_status->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS);
- bool can_see_on_map = friend_status->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION);
- bool can_modify_objects = friend_status->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS);
-
- // aggregate rights of this friend into total selection
- friends_see_online &= can_see_online;
- friends_see_on_map &= can_see_on_map;
- friends_modify_objects &= can_modify_objects;
-
- // can at least one of your selected friends do any of these?
- some_friends_see_online |= can_see_online;
- some_friends_see_on_map |= can_see_on_map;
- some_friends_modify_objects |= can_modify_objects;
-
if(!friend_status->isOnline())
{
can_offer_teleport = false;
@@ -331,44 +313,13 @@ void LLPanelFriends::refreshRightsChangeList()
else // missing buddy info, don't allow any operations
{
can_offer_teleport = false;
-
- friends_see_online = false;
- friends_see_on_map = false;
- friends_modify_objects = false;
-
- some_friends_see_online = false;
- some_friends_see_on_map = false;
- some_friends_modify_objects = false;
}
}
-
- // seeing a friend on the map requires seeing online status as a prerequisite
- friends_see_on_map &= friends_see_online;
-
- mMenuState = 0;
-
- // make checkboxes visible after we have finished processing rights
- childSetVisible("online_status_cb", mAllowRightsChange);
- childSetVisible("map_status_cb", mAllowRightsChange);
- childSetVisible("modify_status_cb", mAllowRightsChange);
-
if (num_selected == 0) // nothing selected
{
childSetEnabled("im_btn", FALSE);
childSetEnabled("offer_teleport_btn", FALSE);
-
- childSetEnabled("online_status_cb", FALSE);
- childSetValue("online_status_cb", FALSE);
- childSetTentative("online_status_cb", FALSE);
-
- childSetEnabled("map_status_cb", FALSE);
- childSetValue("map_status_cb", FALSE);
- childSetTentative("map_status_cb", FALSE);
-
- childSetEnabled("modify_status_cb", FALSE);
- childSetValue("modify_status_cb", FALSE);
- childSetTentative("modify_status_cb", FALSE);
}
else // we have at least one friend selected...
{
@@ -376,61 +327,76 @@ void LLPanelFriends::refreshRightsChangeList()
// to be consistent with context menus in inventory and because otherwise
// offline friends would be silently dropped from the session
childSetEnabled("im_btn", selected_friends_online || num_selected == 1);
-
childSetEnabled("offer_teleport_btn", can_offer_teleport);
-
- childSetEnabled("online_status_cb", TRUE);
- childSetValue("online_status_cb", some_friends_see_online);
- childSetTentative("online_status_cb", some_friends_see_online != friends_see_online);
- if (friends_see_online)
- {
- mMenuState |= LLRelationship::GRANT_ONLINE_STATUS;
- }
-
- childSetEnabled("map_status_cb", TRUE);
- childSetValue("map_status_cb", some_friends_see_on_map);
- childSetTentative("map_status_cb", some_friends_see_on_map != friends_see_on_map);
- if(friends_see_on_map)
- {
- mMenuState |= LLRelationship::GRANT_MAP_LOCATION;
- }
-
- // for now, don't allow modify rights change for multiple select
- childSetEnabled("modify_status_cb", num_selected == 1);
- childSetValue("modify_status_cb", some_friends_modify_objects);
- childSetTentative("modify_status_cb", some_friends_modify_objects != friends_modify_objects);
- if(friends_modify_objects)
- {
- mMenuState |= LLRelationship::GRANT_MODIFY_OBJECTS;
- }
}
}
+struct SortFriendsByID
+{
+ bool SortFriendsByID::operator() (const LLScrollListItem* const a, const LLScrollListItem* const b) const
+ {
+ return a->getValue().asUUID() < b->getValue().asUUID();
+ }
+};
+
void LLPanelFriends::refreshNames()
{
LLDynamicArray<LLUUID> selected_ids = getSelectedIDs();
S32 pos = mFriendsList->getScrollPos();
- mFriendsList->operateOnAll(LLCtrlListInterface::OP_DELETE);
- LLCollectAllBuddies collect;
- LLAvatarTracker::instance().applyFunctor(collect);
- LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin();
- LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end();
+ // get all buddies we know about
+ LLAvatarTracker::buddy_map_t all_buddies;
+ LLAvatarTracker::instance().copyBuddyList(all_buddies);
- for ( ; it != end; ++it)
- {
- const std::string& name = it->first;
- const LLUUID& agent_id = it->second;
- addFriend(name, agent_id);
- }
- it = collect.mOffline.begin();
- end = collect.mOffline.end();
- for ( ; it != end; ++it)
+ // get all friends in list and sort by UUID
+ std::vector<LLScrollListItem*> items = mFriendsList->getAllData();
+ std::sort(items.begin(), items.end(), SortFriendsByID());
+
+ std::vector<LLScrollListItem*>::iterator item_it = items.begin();
+ std::vector<LLScrollListItem*>::iterator item_end = items.end();
+
+ LLAvatarTracker::buddy_map_t::iterator buddy_it;
+ for (buddy_it = all_buddies.begin() ; buddy_it != all_buddies.end(); ++buddy_it)
{
- const std::string& name = it->first;
- const LLUUID& agent_id = it->second;
- addFriend(name, agent_id);
+ // erase any items that reflect residents who are no longer buddies
+ while(item_it != item_end && buddy_it->first > (*item_it)->getValue().asUUID())
+ {
+ mFriendsList->deleteItems((*item_it)->getValue());
+ ++item_it;
+ }
+
+ // update existing friends with new info
+ if (item_it != item_end && buddy_it->first == (*item_it)->getValue().asUUID())
+ {
+ const LLRelationship* info = buddy_it->second;
+ if (!info)
+ {
+ ++item_it;
+ continue;
+ }
+
+ S32 last_change_generation = (*item_it)->getColumn(LIST_FRIEND_UPDATE_GEN)->getValue().asInteger();
+ if (last_change_generation < info->getChangeSerialNum())
+ {
+ // update existing item in UI
+ updateFriendItem(mFriendsList->getItem(buddy_it->first), info);
+ }
+ ++item_it;
+ }
+ // add new friend to list
+ else
+ {
+ const LLUUID& buddy_id = buddy_it->first;
+ char first_name[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
+ char last_name[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
+
+ gCacheName->getName(buddy_id, first_name, last_name);
+ std::ostringstream fullname;
+ fullname << first_name << " " << last_name;
+ addFriend(fullname.str(), buddy_id);
+ }
}
+
mFriendsList->selectMultiple(selected_ids);
mFriendsList->setScrollPos(pos);
}
@@ -451,7 +417,7 @@ void LLPanelFriends::refreshUI()
}
else
{
- childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getText() + "...");
+ childSetText("friend_name_label", mFriendsList->getFirstSelected()->getColumn(LIST_FRIEND_NAME)->getValue().asString() + "...");
}
}
else
@@ -493,6 +459,8 @@ void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
if(panelp)
{
panelp->refreshUI();
+ // check to see if rights have changed
+ panelp->applyRightsToFriends();
}
}
@@ -687,35 +655,22 @@ void LLPanelFriends::onClickPay(void* user_data)
}
}
-void LLPanelFriends::onClickOnlineStatus(LLUICtrl* ctrl, void* user_data)
-{
- LLPanelFriends* panelp = (LLPanelFriends*)user_data;
-
- bool checked = ctrl->getValue();
- panelp->updateMenuState(LLRelationship::GRANT_ONLINE_STATUS, checked);
- panelp->applyRightsToFriends(LLRelationship::GRANT_ONLINE_STATUS, checked);
-}
-
-void LLPanelFriends::onClickMapStatus(LLUICtrl* ctrl, void* user_data)
-{
- LLPanelFriends* panelp = (LLPanelFriends*)user_data;
- bool checked = ctrl->getValue();
- panelp->updateMenuState(LLRelationship::GRANT_MAP_LOCATION, checked);
- panelp->applyRightsToFriends(LLRelationship::GRANT_MAP_LOCATION, checked);
-}
-
-void LLPanelFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data)
+void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command)
{
- LLPanelFriends* panelp = (LLPanelFriends*)user_data;
-
- bool checked = ctrl->getValue();
- LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
+ if (ids.empty()) return;
+
LLStringBase<char>::format_map_t args;
if(ids.size() > 0)
{
+ // copy map of ids onto heap
+ rights_map_t* rights = new rights_map_t(ids);
+ // package with panel pointer
+ std::pair<LLPanelFriends*, rights_map_t*>* user_data = new std::pair<LLPanelFriends*, rights_map_t*>(this, rights);
+
+ // for single friend, show their name
if(ids.size() == 1)
{
- LLUUID agent_id = ids[0];
+ LLUUID agent_id = ids.begin()->first;
char first[DB_FIRST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
char last[DB_LAST_NAME_BUF_SIZE]; /*Flawfinder: ignore*/
if(gCacheName->getName(agent_id, first, last))
@@ -723,56 +678,174 @@ void LLPanelFriends::onClickModifyStatus(LLUICtrl* ctrl, void* user_data)
args["[FIRST_NAME]"] = first;
args["[LAST_NAME]"] = last;
}
- if(checked) gViewerWindow->alertXml("GrantModifyRights", args, handleModifyRights, user_data);
- else gViewerWindow->alertXml("RevokeModifyRights", args, handleModifyRights, user_data);
+ if (command == GRANT)
+ {
+ gViewerWindow->alertXml("GrantModifyRights", args, modifyRightsConfirmation, user_data);
+ }
+ else
+ {
+ gViewerWindow->alertXml("RevokeModifyRights", args, modifyRightsConfirmation, user_data);
+ }
+ }
+ else
+ {
+ if (command == GRANT)
+ {
+ gViewerWindow->alertXml("GrantModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
+ }
+ else
+ {
+ gViewerWindow->alertXml("RevokeModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
+ }
}
- else return;
}
}
-void LLPanelFriends::handleModifyRights(S32 option, void* user_data)
+// static
+void LLPanelFriends::modifyRightsConfirmation(S32 option, void* user_data)
{
- LLPanelFriends* panelp = (LLPanelFriends*)user_data;
+ std::pair<LLPanelFriends*, rights_map_t*>* data = (std::pair<LLPanelFriends*, rights_map_t*>*)user_data;
+ LLPanelFriends* panelp = data->first;
if(panelp)
{
- if(!option)
+ if(0 == option)
{
- panelp->updateMenuState(LLRelationship::GRANT_MODIFY_OBJECTS, !((panelp->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
- panelp->applyRightsToFriends(LLRelationship::GRANT_MODIFY_OBJECTS, ((panelp->getMenuState() & LLRelationship::GRANT_MODIFY_OBJECTS) != 0));
+ panelp->sendRightsGrant(*(data->second));
+ }
+ else
+ {
+ // need to resync view with model, since user cancelled operation
+ rights_map_t* rights = data->second;
+ rights_map_t::iterator rights_it;
+ for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it)
+ {
+ LLScrollListItem* itemp = panelp->mFriendsList->getItem(rights_it->first);
+ const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
+ panelp->updateFriendItem(itemp, info);
+ }
}
panelp->refreshUI();
}
+
+ delete data->second;
+ delete data;
}
-void LLPanelFriends::updateMenuState(S32 flag, BOOL value)
+void LLPanelFriends::applyRightsToFriends()
{
- if(value) mMenuState |= flag;
- else mMenuState &= ~flag;
+ BOOL rights_changed = FALSE;
+
+ // store modify rights separately for confirmation
+ rights_map_t rights_updates;
+
+ BOOL need_confirmation = FALSE;
+ EGrantRevoke confirmation_type = GRANT;
+
+ // this assumes that changes only happened to selected items
+ std::vector<LLScrollListItem*> selected = mFriendsList->getAllSelected();
+ for(std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
+ {
+ LLUUID id = (*itr)->getValue();
+ const LLRelationship* buddy_relationship = LLAvatarTracker::instance().getBuddyInfo(id);
+ if (buddy_relationship == NULL) continue;
+
+ bool show_online_staus = (*itr)->getColumn(LIST_VISIBLE_ONLINE)->getValue().asBoolean();
+ bool show_map_location = (*itr)->getColumn(LIST_VISIBLE_MAP)->getValue().asBoolean();
+ bool allow_modify_objects = (*itr)->getColumn(LIST_EDIT_MINE)->getValue().asBoolean();
+
+ S32 rights = buddy_relationship->getRightsGrantedTo();
+ if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS) != show_online_staus)
+ {
+ rights_changed = TRUE;
+ if(show_online_staus)
+ {
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ }
+ else
+ {
+ // ONLINE_STATUS necessary for MAP_LOCATION
+ rights &= ~LLRelationship::GRANT_ONLINE_STATUS;
+ rights &= ~LLRelationship::GRANT_MAP_LOCATION;
+ // propagate rights constraint to UI
+ (*itr)->getColumn(LIST_VISIBLE_MAP)->setValue(FALSE);
+ }
+ }
+ if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) != show_map_location)
+ {
+ rights_changed = TRUE;
+ if(show_map_location)
+ {
+ // ONLINE_STATUS necessary for MAP_LOCATION
+ rights |= LLRelationship::GRANT_MAP_LOCATION;
+ rights |= LLRelationship::GRANT_ONLINE_STATUS;
+ (*itr)->getColumn(LIST_VISIBLE_ONLINE)->setValue(TRUE);
+ }
+ else
+ {
+ rights &= ~LLRelationship::GRANT_MAP_LOCATION;
+ }
+ }
+
+ // now check for change in modify object rights, which requires confirmation
+ if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS) != allow_modify_objects)
+ {
+ rights_changed = TRUE;
+ need_confirmation = TRUE;
+
+ if(allow_modify_objects)
+ {
+ rights |= LLRelationship::GRANT_MODIFY_OBJECTS;
+ confirmation_type = GRANT;
+ }
+ else
+ {
+ rights &= ~LLRelationship::GRANT_MODIFY_OBJECTS;
+ confirmation_type = REVOKE;
+ }
+ }
+
+ if (rights_changed)
+ {
+ rights_updates.insert(std::make_pair(id, rights));
+ // disable these ui elements until response from server
+ // to avoid race conditions
+ (*itr)->setEnabled(FALSE);
+ }
+ }
+
+ // separately confirm grant and revoke of modify rights
+ if (need_confirmation)
+ {
+ confirmModifyRights(rights_updates, confirmation_type);
+ }
+ else
+ {
+ sendRightsGrant(rights_updates);
+ }
}
-void LLPanelFriends::applyRightsToFriends(S32 flag, BOOL value)
+void LLPanelFriends::sendRightsGrant(rights_map_t& ids)
{
+ if (ids.empty()) return;
+
LLMessageSystem* msg = gMessageSystem;
+
+ // setup message header
msg->newMessageFast(_PREHASH_GrantUserRights);
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUID(_PREHASH_AgentID, gAgent.getID());
msg->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
- LLDynamicArray<LLUUID> ids = getSelectedIDs();
- S32 rights;
- for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
+ rights_map_t::iterator id_it;
+ rights_map_t::iterator end_it = ids.end();
+ for(id_it = ids.begin(); id_it != end_it; ++id_it)
{
- rights = LLAvatarTracker::instance().getBuddyInfo(*itr)->getRightsGrantedTo();
- if(LLAvatarTracker::instance().getBuddyInfo(*itr)->isRightGrantedTo(flag) != (bool)value)
- {
- if(value) rights |= flag;
- else rights &= ~flag;
- msg->nextBlockFast(_PREHASH_Rights);
- msg->addUUID(_PREHASH_AgentRelated, *itr);
- msg->addS32(_PREHASH_RelatedRights, rights);
- }
+ msg->nextBlockFast(_PREHASH_Rights);
+ msg->addUUID(_PREHASH_AgentRelated, id_it->first);
+ msg->addS32(_PREHASH_RelatedRights, id_it->second);
}
+
mNumRightsChanged = ids.size();
gAgent.sendReliableMessage();
}
diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h
index 3d0b7a9bba..46e4eaaf79 100644
--- a/indra/newview/llfloaterfriends.h
+++ b/indra/newview/llfloaterfriends.h
@@ -40,6 +40,7 @@
#include "lltimer.h"
class LLFriendObserver;
+class LLRelationship;
/**
@@ -88,19 +89,27 @@ private:
LIST_VISIBLE_ONLINE,
LIST_VISIBLE_MAP,
LIST_EDIT_MINE,
- LIST_EDIT_THEIRS
+ LIST_EDIT_THEIRS,
+ LIST_FRIEND_UPDATE_GEN
};
// protected members
-
+ typedef std::map<LLUUID, S32> rights_map_t;
void reloadNames();
void refreshNames();
void refreshUI();
void refreshRightsChangeList();
- void applyRightsToFriends(S32 flag, BOOL value);
- void updateMenuState(S32 flag, BOOL value);
- S32 getMenuState() { return mMenuState; }
+ void applyRightsToFriends();
void addFriend(const std::string& name, const LLUUID& agent_id);
+ void updateFriendItem(LLScrollListItem* itemp, const LLRelationship* relationship);
+
+ typedef enum
+ {
+ GRANT,
+ REVOKE
+ } EGrantRevoke;
+ void confirmModifyRights(rights_map_t& ids, EGrantRevoke command);
+ void sendRightsGrant(rights_map_t& ids);
// return LLUUID::null if nothing is selected
LLDynamicArray<LLUUID> getSelectedIDs();
@@ -119,12 +128,10 @@ private:
static void onClickOfferTeleport(void* user_data);
static void onClickPay(void* user_data);
- static void onClickOnlineStatus(LLUICtrl* ctrl, void* user_data);
- static void onClickMapStatus(LLUICtrl* ctrl, void* user_data);
static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data);
static void handleRemove(S32 option, void* user_data);
- static void handleModifyRights(S32 option, void* user_data);
+ static void modifyRightsConfirmation(S32 option, void* user_data);
private:
// member data
@@ -132,7 +139,6 @@ private:
LLUUID mAddFriendID;
LLString mAddFriendName;
LLScrollListCtrl* mFriendsList;
- S32 mMenuState;
BOOL mShowMaxSelectWarning;
BOOL mAllowRightsChange;
S32 mNumRightsChanged;
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 0ce91ef740..9f1624d20c 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -262,6 +262,7 @@ void LLFloaterInspect::refresh()
void LLFloaterInspect::onFocusReceived()
{
gToolMgr->setTransientTool(gToolInspect);
+ LLFloater::onFocusReceived();
}
void LLFloaterInspect::dirty()
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 3b96a4ce5e..2a352dfc3d 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1045,8 +1045,10 @@ BOOL LLPanelLandObjects::postBuild()
mSelectedObjects = LLUICtrlFactory::getTextBoxByName(this, "selected_objects_text");
mCleanOtherObjectsTime = LLUICtrlFactory::getLineEditorByName(this, "clean other time");
- mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus);
+
+ mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
mCleanOtherObjectsTime->setCommitCallback(onCommitClean);
+
childSetPrevalidate("clean other time", LLLineEditor::prevalidateNonNegativeS32);
childSetUserData("clean other time", this);
@@ -1135,7 +1137,7 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata)
return;
}
// Is this a group?
- BOOL is_group = cell->getText() == OWNER_GROUP;
+ BOOL is_group = cell->getValue().asString() == OWNER_GROUP;
if (is_group)
{
LLFloaterGroupInfo::showFromUUID(owner_id);
@@ -1180,19 +1182,16 @@ void LLPanelLandObjects::refresh()
}
else
{
- S32 sw_max = 0;
- S32 sw_total = 0;
- S32 max = 0;
- S32 total = 0;
- S32 owned = 0;
- S32 group = 0;
- S32 other = 0;
- S32 selected = 0;
- F32 parcel_object_bonus = 0.f;
-
- gParcelMgr->getPrimInfo(sw_max, sw_total,
- max, total, owned, group, other, selected,
- parcel_object_bonus, mOtherTime);
+ S32 sw_max = parcel->getSimWideMaxPrimCapacity();
+ S32 sw_total = parcel->getSimWidePrimCount();
+ S32 max = llround(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus());
+ S32 total = parcel->getPrimCount();
+ S32 owned = parcel->getOwnerPrimCount();
+ S32 group = parcel->getGroupPrimCount();
+ S32 other = parcel->getOtherPrimCount();
+ S32 selected = parcel->getSelectedPrimCount();
+ F32 parcel_object_bonus = parcel->getParcelPrimBonus();
+ mOtherTime = parcel->getCleanOtherTime();
// Can't have more than region max tasks, regardless of parcel
// object bonus factor.
@@ -1442,14 +1441,6 @@ void LLPanelLandObjects::onClickReturnOwnerList(void* userdata)
{
LLPanelLandObjects *self = (LLPanelLandObjects *)userdata;
- S32 sw_max, sw_total;
- S32 max, total;
- S32 owned, group, other, selected;
- F32 parcel_object_bonus;
- S32 other_time;
-
- gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time);
-
LLParcel* parcelp = self->mParcel->getParcel();
if (!parcelp) return;
@@ -1632,11 +1623,11 @@ void LLPanelLandObjects::onCommitList(LLUICtrl* ctrl, void* data)
return;
}
// Is this a group?
- self->mSelectedIsGroup = cell->getText() == OWNER_GROUP;
+ self->mSelectedIsGroup = cell->getValue().asString() == OWNER_GROUP;
cell = item->getColumn(2);
- self->mSelectedName = cell->getText();
+ self->mSelectedName = cell->getValue().asString();
cell = item->getColumn(3);
- self->mSelectedCount = atoi(cell->getText().c_str());
+ self->mSelectedCount = atoi(cell->getValue().asString().c_str());
// Set the selection, and enable the return button.
self->mSelectedOwners.clear();
@@ -1700,18 +1691,14 @@ void LLPanelLandObjects::onClickShowOtherObjects(void* userdata)
// static
void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
{
- S32 sw_max=0, sw_total=0;
- S32 max=0, total=0;
- S32 owned=0, group=0, other=0, selected=0;
- F32 parcel_object_bonus=0;
- S32 other_time=0;
-
- gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time);
+ S32 owned = 0;
LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
LLParcel* parcel = panelp->mParcel->getParcel();
if (!parcel) return;
+ owned = parcel->getOwnerPrimCount();
+
send_parcel_select_objects(parcel->getLocalID(), RT_OWNER);
LLUUID owner_id = parcel->getOwnerID();
@@ -1739,14 +1726,6 @@ void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
// static
void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
{
- S32 sw_max=0, sw_total=0;
- S32 max=0, total=0;
- S32 owned=0, group=0, other=0, selected=0;
- F32 parcel_object_bonus=0;
- S32 other_time=0;
-
- gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time);
-
LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
LLParcel* parcel = panelp->mParcel->getParcel();
if (!parcel) return;
@@ -1758,7 +1737,7 @@ void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
LLStringBase<char>::format_map_t args;
args["[NAME]"] = group_name;
- args["[N]"] = llformat("%d",group);
+ args["[N]"] = llformat("%d", parcel->getGroupPrimCount());
// create and show confirmation textbox
gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnGroupObjects, userdata);
@@ -1767,17 +1746,13 @@ void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
// static
void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
{
- S32 sw_max=0, sw_total=0;
- S32 max=0, total=0;
- S32 owned=0, group=0, other=0, selected=0;
- F32 parcel_object_bonus=0;
- S32 other_time=0;
-
- gParcelMgr->getPrimInfo(sw_max, sw_total, max, total, owned, group, other, selected, parcel_object_bonus, other_time);
+ S32 other = 0;
LLPanelLandObjects* panelp = (LLPanelLandObjects*)userdata;
LLParcel* parcel = panelp->mParcel->getParcel();
if (!parcel) return;
+
+ other = parcel->getOtherPrimCount();
send_parcel_select_objects(parcel->getLocalID(), RT_OTHER);
@@ -1817,9 +1792,9 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
}
// static
-void LLPanelLandObjects::onLostFocus(LLUICtrl *caller, void* user_data)
+void LLPanelLandObjects::onLostFocus(LLFocusableElement* caller, void* user_data)
{
- onCommitClean(caller, user_data);
+ onCommitClean((LLUICtrl*)caller, user_data);
}
// static
@@ -2408,6 +2383,13 @@ void LLPanelLandMedia::refresh()
mCheckSoundLocal->set( parcel->getSoundLocal() );
mCheckSoundLocal->setEnabled( can_change_media );
+ LLViewerRegion* selection_region = gParcelMgr->getSelectionRegion();
+ BOOL region_allows_voice = FALSE;
+ if (selection_region)
+ {
+ region_allows_voice = selection_region->isVoiceEnabled();
+ }
+
if(parcel->getVoiceEnabled())
{
if(parcel->getVoiceUseEstateChannel())
@@ -2420,7 +2402,7 @@ void LLPanelLandMedia::refresh()
mRadioVoiceChat->setSelectedIndex(kRadioVoiceChatDisable);
}
- mRadioVoiceChat->setEnabled( can_change_media );
+ mRadioVoiceChat->setEnabled( can_change_media && region_allows_voice );
// don't display urls if you're not able to change it
// much requested change in forums so people can't 'steal' urls
@@ -2535,7 +2517,7 @@ void LLPanelLandMedia::onClickStopMedia ( void* data )
void LLPanelLandMedia::onClickStartMedia ( void* data )
{
// force a commit
- gFocusMgr.setKeyboardFocus ( NULL, NULL );
+ gFocusMgr.setKeyboardFocus ( NULL );
// force a reload
LLMediaEngine::getInstance ()->convertImageAndLoadUrl ( true, false, std::string());
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index fa941caf78..4bb88aa127 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -257,7 +257,7 @@ public:
static void onDoubleClickOwner(void*);
static void onCommitList(LLUICtrl* ctrl, void* data);
- static void onLostFocus(LLUICtrl* caller, void* user_data);
+ static void onLostFocus(LLFocusableElement* caller, void* user_data);
static void onCommitClean(LLUICtrl* caller, void* user_data);
static void processParcelObjectOwnersReply(LLMessageSystem *msg, void **);
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index a00f512515..5306ce11b1 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -137,8 +137,7 @@ BOOL LLFloaterPostcard::postBuild()
MsgField->setWordWrap(TRUE);
// For the first time a user focusess to .the msg box, all text will be selected.
- MsgField->setFocusChangedCallback(onMsgFormFocusRecieved);
- MsgField->setCallbackUserData(this);
+ MsgField->setFocusChangedCallback(onMsgFormFocusRecieved, this);
}
childSetFocus("to_form", TRUE);
@@ -347,7 +346,7 @@ void LLFloaterPostcard::updateUserInfo(const char *email)
}
}
-void LLFloaterPostcard::onMsgFormFocusRecieved(LLUICtrl* receiver, void* data)
+void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data)
{
LLFloaterPostcard* self = (LLFloaterPostcard *)data;
if(self)
diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h
index 78da8b55d8..287d34c706 100644
--- a/indra/newview/llfloaterpostcard.h
+++ b/indra/newview/llfloaterpostcard.h
@@ -65,7 +65,7 @@ public:
static void updateUserInfo(const char *email);
- static void onMsgFormFocusRecieved(LLUICtrl* receiver, void* data);
+ static void onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data);
static void missingSubjMsgAlertCallback(S32 option, void* data);
void sendPostcard();
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 3306142856..eaf7832eab 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -161,50 +161,55 @@ bool estate_dispatch_initialized = false;
/// LLFloaterRegionInfo
///----------------------------------------------------------------------------
-LLFloaterRegionInfo* LLFloaterRegionInfo::sInstance = NULL;
//S32 LLFloaterRegionInfo::sRequestSerial = 0;
LLUUID LLFloaterRegionInfo::sRequestInvoice;
-LLFloaterRegionInfo::LLFloaterRegionInfo(const LLRect& rect) :
- LLFloater("regioninfo", rect, "Region/Estate")
+LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed)
{
- LLRect tr(0, rect.getHeight() - LLFLOATER_HEADER_SIZE, rect.getWidth(), 0);
- mTab = new LLTabContainer("tab", tr, LLTabContainer::TOP, NULL,NULL,"");
- mTab->setBorderVisible(FALSE);
- addChild(mTab);
+ gUICtrlFactory->buildFloater(this, "floater_region_info.xml", NULL, FALSE);
+}
+
+BOOL LLFloaterRegionInfo::postBuild()
+{
+ mTab = gUICtrlFactory->getTabContainerByName(this, "region_panels");
// contruct the panels
- LLPanel* panel;
+ LLPanelRegionInfo* panel;
panel = new LLPanelRegionGeneralInfo;
- mInfoPanels.push_back((LLPanelRegionInfo*)panel);
+ mInfoPanels.push_back(panel);
gUICtrlFactory->buildPanel(panel, "panel_region_general.xml");
mTab->addTabPanel(panel, panel->getLabel(), TRUE);
panel = new LLPanelRegionDebugInfo;
- mInfoPanels.push_back((LLPanelRegionInfo*)panel);
+ mInfoPanels.push_back(panel);
gUICtrlFactory->buildPanel(panel, "panel_region_debug.xml");
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
panel = new LLPanelRegionTextureInfo;
- mInfoPanels.push_back((LLPanelRegionInfo*)panel);
+ mInfoPanels.push_back(panel);
gUICtrlFactory->buildPanel(panel, "panel_region_texture.xml");
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
panel = new LLPanelRegionTerrainInfo;
- mInfoPanels.push_back((LLPanelRegionInfo*)panel);
+ mInfoPanels.push_back(panel);
gUICtrlFactory->buildPanel(panel, "panel_region_terrain.xml");
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
panel = new LLPanelEstateInfo;
- mInfoPanels.push_back((LLPanelRegionInfo*)panel);
+ mInfoPanels.push_back(panel);
gUICtrlFactory->buildPanel(panel, "panel_region_estate.xml");
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
panel = new LLPanelEstateCovenant;
- mInfoPanels.push_back((LLPanelRegionInfo*)panel);
+ mInfoPanels.push_back(panel);
gUICtrlFactory->buildPanel(panel, "panel_region_covenant.xml");
mTab->addTabPanel(panel, panel->getLabel(), FALSE);
+ gMessageSystem->setHandlerFunc(
+ "EstateOwnerMessage",
+ &processEstateOwnerRequest);
+
+ return TRUE;
}
LLFloaterRegionInfo::~LLFloaterRegionInfo()
@@ -212,23 +217,20 @@ LLFloaterRegionInfo::~LLFloaterRegionInfo()
sInstance = NULL;
}
-// static
-void LLFloaterRegionInfo::show(LLViewerRegion* region)
+void LLFloaterRegionInfo::onOpen()
{
- if (!sInstance)
- {
- LLRect rect = gSavedSettings.getRect("FloaterRegionInfo");
- S32 left, top;
- gFloaterView->getNewFloaterPosition(&left, &top);
- rect.translate(left,top);
- sInstance = new LLFloaterRegionInfo(rect);
- gMessageSystem->setHandlerFunc(
- "EstateOwnerMessage",
- &processEstateOwnerRequest);
- }
- sInstance->open(); /* Flawfinder: ignore*/
- sInstance->refreshFromRegion(region);
+ LLRect rect = gSavedSettings.getRect("FloaterRegionInfo");
+ S32 left, top;
+ gFloaterView->getNewFloaterPosition(&left, &top);
+ rect.translate(left,top);
+
+ requestRegionInfo();
+ refreshFromRegion(gAgent.getRegion());
+ LLFloater::onOpen();
+}
+void LLFloaterRegionInfo::requestRegionInfo()
+{
// Must allow anyone to request the RegionInfo data
// so non-owners/non-gods can see the values.
// Therefore can't use an EstateOwnerMessage JC
@@ -242,18 +244,6 @@ void LLFloaterRegionInfo::show(LLViewerRegion* region)
}
// static
-void LLFloaterRegionInfo::show(void*)
-{
- show(gAgent.getRegion());
-}
-
-// static
-LLFloaterRegionInfo* LLFloaterRegionInfo::getInstance()
-{
- return sInstance;
-}
-
-// static
void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
{
static LLDispatcher dispatch;
@@ -264,7 +254,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
LLPanelEstateInfo::initDispatch(dispatch);
}
- LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(sInstance, "tab");
+ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(sInstance, "region_panels");
if (!tab) return;
LLPanelEstateInfo* panel = (LLPanelEstateInfo*)LLUICtrlFactory::getPanelByName(tab, "Estate");
@@ -293,7 +283,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
llinfos << "LLFloaterRegionInfo::processRegionInfo" << llendl;
if(!sInstance) return;
- LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(sInstance, "tab");
+ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(sInstance, "region_panels");
if(!tab) return;
// extract message
@@ -376,7 +366,7 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate()
{
LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
if (!floater) return NULL;
- LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "tab");
+ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels");
if (!tab) return NULL;
LLPanelEstateInfo* panel = (LLPanelEstateInfo*)LLUICtrlFactory::getPanelByName(tab,"Estate");
return panel;
@@ -387,7 +377,7 @@ LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant()
{
LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
if (!floater) return NULL;
- LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "tab");
+ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels");
if (!tab) return NULL;
LLPanelEstateCovenant* panel = (LLPanelEstateCovenant*)LLUICtrlFactory::getPanelByName(tab, "Covenant");
return panel;
@@ -1241,7 +1231,7 @@ BOOL LLPanelRegionTerrainInfo::sendUpdate()
LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
if (!floater) return true;
- LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "tab");
+ LLTabContainerCommon* tab = LLUICtrlFactory::getTabContainerByName(floater, "region_panels");
if (!tab) return true;
LLPanelEstateInfo* panel = (LLPanelEstateInfo*)LLUICtrlFactory::getPanelByName(tab, "Estate");
@@ -2803,7 +2793,7 @@ bool LLDispatchSetEstateOwner::operator()(
LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance();
if (!floater) return true;
- LLTabContainer* tab = (LLTabContainer*)(floater->getChildByName("tab"));
+ LLTabContainer* tab = (LLTabContainer*)(floater->getChildByName("region_panels"));
if (!tab) return true;
LLPanelEstateInfo* panel = (LLPanelEstateInfo*)(tab->getChildByName("Estate"));
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index abf4789b6d..6f9ed1fc34 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -58,14 +58,15 @@ class LLPanelRegionTerrainInfo;
class LLPanelEstateInfo;
class LLPanelEstateCovenant;
-class LLFloaterRegionInfo : public LLFloater
+class LLFloaterRegionInfo : public LLFloater, public LLUISingleton<LLFloaterRegionInfo>
{
+ friend class LLUISingleton<LLFloaterRegionInfo>;
public:
~LLFloaterRegionInfo();
- static void show(LLViewerRegion* region);
- static void show(void*);
- static LLFloaterRegionInfo* getInstance();
+ /*virtual*/ void onOpen();
+ /*virtual*/ BOOL postBuild();
+
static void processEstateOwnerRequest(LLMessageSystem* msg, void**);
// get and process region info if necessary.
@@ -82,15 +83,14 @@ public:
// from LLPanel
virtual void refresh();
+ void requestRegionInfo();
+
protected:
- LLFloaterRegionInfo(const LLRect& rect);
+ LLFloaterRegionInfo(const LLSD& seed);
void refreshFromRegion(LLViewerRegion* region);
- // static data
- static LLFloaterRegionInfo* sInstance;
-
// member data
- LLTabContainer* mTab;
+ LLTabContainerCommon* mTab;
typedef std::vector<LLPanelRegionInfo*> info_panels_t;
info_panels_t mInfoPanels;
//static S32 sRequestSerial; // serial # of last EstateOwnerRequest
diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp
index 9d600befdb..80a686d162 100644
--- a/indra/newview/llfloaterscriptdebug.cpp
+++ b/indra/newview/llfloaterscriptdebug.cpp
@@ -177,7 +177,7 @@ LLFloaterScriptDebugOutput::LLFloaterScriptDebugOutput(const LLUUID& object_id)
mHistoryEditor->setWordWrap( TRUE );
mHistoryEditor->setFollowsAll();
mHistoryEditor->setEnabled( FALSE );
- mHistoryEditor->setTakesFocus( TRUE ); // We want to be able to cut or copy from the history.
+ mHistoryEditor->setTabStop( TRUE ); // We want to be able to cut or copy from the history.
addChild(mHistoryEditor);
}
@@ -200,7 +200,7 @@ void LLFloaterScriptDebugOutput::init(const LLString& title, BOOL resizable,
mHistoryEditor->setWordWrap( TRUE );
mHistoryEditor->setFollowsAll();
mHistoryEditor->setEnabled( FALSE );
- mHistoryEditor->setTakesFocus( TRUE ); // We want to be able to cut or copy from the history.
+ mHistoryEditor->setTabStop( TRUE ); // We want to be able to cut or copy from the history.
addChild(mHistoryEditor);
}
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 22581c6576..d03ce373cc 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -942,7 +942,7 @@ void commit_select_component(LLUICtrl *ctrl, void *data)
//forfeit focus
if (gFocusMgr.childHasKeyboardFocus(floaterp))
{
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
}
BOOL select_individuals = floaterp->mCheckSelectIndividual->get();
@@ -992,4 +992,5 @@ void LLFloaterTools::setEditTool(void* tool_pointer)
void LLFloaterTools::onFocusReceived()
{
gToolMgr->setCurrentToolset(gBasicToolset);
+ LLFloater::onFocusReceived();
}
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index e3f236becc..6bbb748a10 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -257,8 +257,8 @@ void LLFloaterTopObjects::updateSelectionInfo()
std::string object_id_string = object_id.asString();
childSetValue("id_editor", LLSD(object_id_string));
- childSetValue("object_name_editor", list->getFirstSelected()->getColumn(1)->getText());
- childSetValue("owner_name_editor", list->getFirstSelected()->getColumn(2)->getText());
+ childSetValue("object_name_editor", list->getFirstSelected()->getColumn(1)->getValue().asString());
+ childSetValue("owner_name_editor", list->getFirstSelected()->getColumn(2)->getValue().asString());
}
// static
@@ -451,8 +451,8 @@ void LLFloaterTopObjects::showBeacon()
LLScrollListItem* first_selected = list->getFirstSelected();
if (!first_selected) return;
- LLString name = first_selected->getColumn(1)->getText();
- LLString pos_string = first_selected->getColumn(3)->getText();
+ LLString name = first_selected->getColumn(1)->getValue().asString();
+ LLString pos_string = first_selected->getColumn(3)->getValue().asString();
F32 x, y, z;
S32 matched = sscanf(pos_string.c_str(), "<%g,%g,%g>", &x, &y, &z);
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 4c03a15619..b1bbb341fd 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -234,7 +234,7 @@ BOOL LLFloaterWorldMap::postBuild()
childSetAction("DoSearch", onLocationCommit, this);
- childSetFocusChangedCallback("location", updateSearchEnabled);
+ childSetFocusChangedCallback("location", onLocationFocusChanged, this);
LLLineEditor *location_editor = LLUICtrlFactory::getLineEditorByName(this, "location");
if (location_editor)
@@ -1221,6 +1221,12 @@ void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata )
}
}
+//static
+void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus, void* userdata )
+{
+ updateSearchEnabled((LLUICtrl*)focus, userdata);
+}
+
// static
void LLFloaterWorldMap::updateSearchEnabled( LLUICtrl* ctrl, void* userdata )
{
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index c069b40929..6f3c583557 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -153,6 +153,7 @@ protected:
void teleportToAvatar();
static void updateSearchEnabled( LLUICtrl* ctrl, void* userdata );
+ static void onLocationFocusChanged( LLFocusableElement* ctrl, void* userdata );
static void onLocationCommit( void* userdata );
static void onCommitLocation( LLUICtrl* ctrl, void* userdata );
static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata );
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 2577474e24..deffca3b79 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -94,7 +94,7 @@ void copy_selected_item(void* user_data);
void open_selected_items(void* user_data);
void properties_selected_items(void* user_data);
void paste_items(void* user_data);
-void renamer_focus_lost( LLUICtrl* handler, void* user_data );
+void renamer_focus_lost( LLFocusableElement* handler, void* user_data );
///----------------------------------------------------------------------------
/// Class LLFolderViewItem
@@ -693,7 +693,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
// Release keyboard focus, so that if stuff is dropped into the
// world, pressing the delete key won't blow away the inventory
// item.
- gViewerWindow->setKeyboardFocus(NULL, NULL);
+ gViewerWindow->setKeyboardFocus(NULL);
return gToolDragAndDrop->handleHover( x, y, mask );
}
@@ -3164,7 +3164,7 @@ void LLFolderView::draw()
}
if(gViewerWindow->hasKeyboardFocus(this) && !getVisible())
{
- gViewerWindow->setKeyboardFocus( NULL, NULL );
+ gViewerWindow->setKeyboardFocus( NULL );
}
// while dragging, update selection rendering to reflect single/multi drag status
@@ -3656,7 +3656,7 @@ void LLFolderView::startRenamingSelectedItem( void )
mRenamer->setVisible( TRUE );
// set focus will fail unless item is visible
mRenamer->setFocus( TRUE );
- mRenamer->setFocusLostCallback(renamer_focus_lost);
+ mRenamer->setLostTopCallback(onRenamerLost);
gViewerWindow->setTopCtrl( mRenamer );
}
}
@@ -3730,7 +3730,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask, BOOL called_from_parent )
{
if( gViewerWindow->childHasKeyboardFocus( this ) )
{
- gViewerWindow->setKeyboardFocus( NULL, NULL );
+ gViewerWindow->setKeyboardFocus( NULL );
}
}
mSearchString.clear();
@@ -4438,12 +4438,10 @@ bool LLInventorySort::operator()(LLFolderViewItem* a, LLFolderViewItem* b)
}
}
-void renamer_focus_lost( LLUICtrl* ctrl, void* userdata)
+//static
+void LLFolderView::onRenamerLost( LLUICtrl* renamer, void* user_data)
{
- if( ctrl )
- {
- ctrl->setVisible( FALSE );
- }
+ renamer->setVisible(FALSE);
}
void delete_selected_item(void* user_data)
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index dd0dd21705..9fcf94d802 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -876,6 +876,8 @@ protected:
LLScrollableContainerView* mScrollContainer; // NULL if this is not a child of a scroll container.
static void commitRename( LLUICtrl* renamer, void* user_data );
+ static void onRenamerLost( LLUICtrl* renamer, void* user_data);
+
void finishRenamingItem( void );
void revertRenamingItem( void );
diff --git a/indra/newview/llhudview.cpp b/indra/newview/llhudview.cpp
index e40e84b9da..7f549bb2eb 100644
--- a/indra/newview/llhudview.cpp
+++ b/indra/newview/llhudview.cpp
@@ -52,8 +52,8 @@ LLHUDView *gHUDView = NULL;
const S32 HUD_ARROW_SIZE = 32;
-LLHUDView::LLHUDView(const std::string& name, const LLRect& rect)
-: LLView(name, rect, FALSE)
+LLHUDView::LLHUDView()
+: LLPanel()
{ }
LLHUDView::~LLHUDView()
diff --git a/indra/newview/llhudview.h b/indra/newview/llhudview.h
index b2353ad5df..cbefdc121e 100644
--- a/indra/newview/llhudview.h
+++ b/indra/newview/llhudview.h
@@ -32,16 +32,16 @@
#ifndef LL_LLHUDVIEW_H
#define LL_LLHUDVIEW_H
-#include "llview.h"
+#include "llpanel.h"
#include "v4color.h"
class LLVector3d;
class LLHUDView
-: public LLView
+: public LLPanel
{
public:
- LLHUDView(const std::string& name, const LLRect& rect);
+ LLHUDView();
virtual ~LLHUDView();
virtual EWidgetType getWidgetType() const;
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 810d3a26a1..b1fefc4f5d 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -63,6 +63,7 @@
#include "llviewerstats.h"
#include "llviewercontrol.h"
#include "llvieweruictrlfactory.h"
+#include "llviewerwindow.h"
#include "lllogchat.h"
#include "llfloaterhtml.h"
#include "llweb.h"
@@ -92,10 +93,14 @@ static LLString sSessionStartString = "Starting session with [NAME] please wait.
LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
LLVoiceChannel::voice_channel_map_uri_t LLVoiceChannel::sVoiceChannelURIMap;
LLVoiceChannel* LLVoiceChannel::sCurrentVoiceChannel = NULL;
+LLVoiceChannel* LLVoiceChannel::sSuspendedVoiceChannel = NULL;
-void session_starter_helper(const LLUUID& temp_session_id,
- const LLUUID& other_participant_id,
- EInstantMessage im_type)
+BOOL LLVoiceChannel::sSuspended = FALSE;
+
+void session_starter_helper(
+ const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ EInstantMessage im_type)
{
LLMessageSystem *msg = gMessageSystem;
@@ -122,47 +127,111 @@ void session_starter_helper(const LLUUID& temp_session_id,
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 send_start_session_messages(const LLUUID& temp_session_id,
- const LLUUID& other_participant_id,
- const LLDynamicArray<LLUUID>& ids,
- EInstantMessage dialog)
+bool send_start_session_messages(
+ const LLUUID& temp_session_id,
+ const LLUUID& other_participant_id,
+ const LLDynamicArray<LLUUID>& ids,
+ EInstantMessage dialog)
{
- if ( (dialog == IM_SESSION_GROUP_START) ||
- (dialog == IM_SESSION_CONFERENCE_START) )
+ if ( dialog == IM_SESSION_GROUP_START )
{
- S32 count = ids.size();
- S32 bucket_size = UUID_BYTES * count;
- U8* bucket;
- U8* pos;
-
- session_starter_helper(temp_session_id,
- other_participant_id,
- dialog);
+ session_starter_helper(
+ temp_session_id,
+ other_participant_id,
+ dialog);
switch(dialog)
{
case IM_SESSION_GROUP_START:
- gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket,
- EMPTY_BINARY_BUCKET,
- EMPTY_BINARY_BUCKET_SIZE);
- break;
- case IM_SESSION_CONFERENCE_START:
- bucket = new U8[bucket_size];
- pos = bucket;
-
- // *FIX: this could suffer from endian issues
- for(S32 i = 0; i < count; ++i)
- {
- memcpy(pos, &(ids.get(i)), UUID_BYTES);
- pos += UUID_BYTES;
- }
- gMessageSystem->addBinaryDataFast(_PREHASH_BinaryBucket,
- bucket,
- bucket_size);
- delete[] bucket;
-
+ gMessageSystem->addBinaryDataFast(
+ _PREHASH_BinaryBucket,
+ EMPTY_BINARY_BUCKET,
+ EMPTY_BINARY_BUCKET_SIZE);
break;
default:
break;
@@ -171,6 +240,44 @@ bool send_start_session_messages(const LLUUID& temp_session_id,
return true;
}
+ else if ( dialog == IM_SESSION_CONFERENCE_START )
+ {
+ LLSD agents;
+ for (int i = 0; i < (S32) ids.size(); i++)
+ {
+ agents.append(ids.get(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);
+ }
+ }
return false;
}
@@ -194,8 +301,20 @@ void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
<< status << ": " << reason << ")"
<< llendl;
LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
- if (channelp)
+ if ( channelp )
{
+ if ( 403 == status )
+ {
+ LLNotifyBox::showXml(
+ "VoiceNotAllowed",
+ channelp->getNotifyArgs());
+ }
+ else
+ {
+ LLNotifyBox::showXml(
+ "VoiceCallGenericError",
+ channelp->getNotifyArgs());
+ }
channelp->deactivate();
}
}
@@ -242,10 +361,6 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const LLString& session
LLVoiceChannel::~LLVoiceChannel()
{
- // CANNOT do this here, since it will crash on quit in the LLVoiceChannelProximal singleton destructor.
- // Do it in all other subclass destructors instead.
- // deactivate();
-
// Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed.
if(gVoiceClient)
{
@@ -266,7 +381,19 @@ void LLVoiceChannel::setChannelInfo(
if (mState == STATE_NO_CHANNEL_INFO)
{
- if(!mURI.empty() && !mCredentials.empty())
+ if (mURI.empty())
+ {
+ LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs);
+ llwarns << "Received empty URI for channel " << mSessionName << llendl;
+ deactivate();
+ }
+ else if (mCredentials.empty())
+ {
+ LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs);
+ llwarns << "Received empty credentials for channel " << mSessionName << llendl;
+ deactivate();
+ }
+ else
{
setState(STATE_READY);
@@ -279,12 +406,6 @@ void LLVoiceChannel::setChannelInfo(
activate();
}
}
- else
- {
- //*TODO: notify user
- llwarns << "Received invalid credentials for channel " << mSessionName << llendl;
- deactivate();
- }
}
}
@@ -325,7 +446,7 @@ void LLVoiceChannel::handleStatusChange(EStatusType type)
}
break;
case STATUS_LEFT_CHANNEL:
- if (callStarted() && !mIgnoreNextSessionLeave)
+ if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended)
{
// if forceably removed from channel
// update the UI and revert to default channel
@@ -496,6 +617,38 @@ void LLVoiceChannel::initClass()
sCurrentVoiceChannel = LLVoiceChannelProximal::getInstance();
}
+
+//static
+void LLVoiceChannel::suspend()
+{
+ if (!sSuspended)
+ {
+ sSuspendedVoiceChannel = sCurrentVoiceChannel;
+ sSuspended = TRUE;
+ }
+}
+
+//static
+void LLVoiceChannel::resume()
+{
+ if (sSuspended)
+ {
+ if (gVoiceClient->voiceEnabled())
+ {
+ if (sSuspendedVoiceChannel)
+ {
+ sSuspendedVoiceChannel->activate();
+ }
+ else
+ {
+ LLVoiceChannelProximal::getInstance()->activate();
+ }
+ }
+ sSuspended = FALSE;
+ }
+}
+
+
//
// LLVoiceChannelGroup
//
@@ -507,11 +660,6 @@ LLVoiceChannelGroup::LLVoiceChannelGroup(const LLUUID& session_id, const LLStrin
mIsRetrying = FALSE;
}
-LLVoiceChannelGroup::~LLVoiceChannelGroup()
-{
- deactivate();
-}
-
void LLVoiceChannelGroup::deactivate()
{
if (callStarted())
@@ -635,6 +783,7 @@ void LLVoiceChannelGroup::handleError(EStatusType status)
}
break;
+
case ERROR_UNKNOWN:
default:
break;
@@ -677,11 +826,6 @@ LLVoiceChannelProximal::LLVoiceChannelProximal() :
activate();
}
-LLVoiceChannelProximal::~LLVoiceChannelProximal()
-{
- // DO NOT call deactivate() here, since this will only happen at atexit() time.
-}
-
BOOL LLVoiceChannelProximal::isActive()
{
return callStarted() && LLVoiceClient::getInstance()->inProximalChannel();
@@ -725,6 +869,9 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
case STATUS_LEFT_CHANNEL:
// do not notify user when leaving proximal channel
return;
+ case STATUS_VOICE_DISABLED:
+ gIMMgr->addSystemMessage(LLUUID::null, "unavailable", mNotifyArgs);
+ return;
default:
break;
}
@@ -762,29 +909,26 @@ void LLVoiceChannelProximal::deactivate()
}
}
+
//
// LLVoiceChannelP2P
//
LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const LLString& session_name, const LLUUID& other_user_id) :
LLVoiceChannelGroup(session_id, session_name),
- mOtherUserID(other_user_id)
+ mOtherUserID(other_user_id),
+ mReceivedCall(FALSE)
{
// make sure URI reflects encoded version of other user's agent id
setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id));
}
-LLVoiceChannelP2P::~LLVoiceChannelP2P()
-{
- deactivate();
-}
-
void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
{
// status updates
switch(type)
{
case STATUS_LEFT_CHANNEL:
- if (callStarted() && !mIgnoreNextSessionLeave)
+ if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended)
{
if (mState == STATE_RINGING)
{
@@ -832,6 +976,7 @@ void LLVoiceChannelP2P::activate()
// no session handle yet, we're starting the call
if (mSessionHandle.empty())
{
+ mReceivedCall = FALSE;
LLVoiceClient::getInstance()->callUser(mOtherUserID);
}
// otherwise answering the call
@@ -879,24 +1024,37 @@ void LLVoiceChannelP2P::setSessionHandle(const LLString& handle)
mSessionHandle = handle;
// The URI of a p2p session should always be the other end's SIP URI.
setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID));
-
+ mReceivedCall = TRUE;
+
if (needs_activate)
{
activate();
}
}
+void LLVoiceChannelP2P::setState(EState state)
+{
+ // you only "answer" voice invites in p2p mode
+ // so provide a special purpose message here
+ if (mReceivedCall && state == STATE_RINGING)
+ {
+ gIMMgr->addSystemMessage(mSessionID, "answering", mNotifyArgs);
+ mState = state;
+ return;
+ }
+ LLVoiceChannel::setState(state);
+}
+
+
//
// LLFloaterIMPanel
//
LLFloaterIMPanel::LLFloaterIMPanel(
- const std::string& name,
- const LLRect& rect,
const std::string& session_label,
const LLUUID& session_id,
const LLUUID& other_participant_id,
EInstantMessage dialog) :
- LLFloater(name, rect, session_label),
+ LLFloater(session_label, LLRect(), session_label),
mInputEditor(NULL),
mHistoryEditor(NULL),
mSessionUUID(session_id),
@@ -909,6 +1067,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(
mOtherTyping(FALSE),
mTypingLineStartIndex(0),
mSentTypingState(TRUE),
+ mNumUnreadMessages(0),
mShowSpeakersOnConnect(TRUE),
mAutoConnect(FALSE),
mSpeakerPanel(NULL),
@@ -919,14 +1078,12 @@ LLFloaterIMPanel::LLFloaterIMPanel(
}
LLFloaterIMPanel::LLFloaterIMPanel(
- const std::string& name,
- const LLRect& rect,
const std::string& session_label,
const LLUUID& session_id,
const LLUUID& other_participant_id,
const LLDynamicArray<LLUUID>& ids,
EInstantMessage dialog) :
- LLFloater(name, rect, session_label),
+ LLFloater(session_label, LLRect(), session_label),
mInputEditor(NULL),
mHistoryEditor(NULL),
mSessionUUID(session_id),
@@ -952,13 +1109,15 @@ LLFloaterIMPanel::LLFloaterIMPanel(
void LLFloaterIMPanel::init(const LLString& session_label)
{
+ mSessionLabel = session_label;
+
LLString xml_filename;
switch(mDialog)
{
case IM_SESSION_GROUP_START:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
xml_filename = "floater_instant_message_group.xml";
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label);
+ mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
case IM_SESSION_INVITE:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
@@ -970,21 +1129,21 @@ void LLFloaterIMPanel::init(const LLString& session_label)
{
xml_filename = "floater_instant_message_ad_hoc.xml";
}
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label);
+ mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
case IM_SESSION_P2P_INVITE:
xml_filename = "floater_instant_message.xml";
- mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, session_label, mOtherParticipantUUID);
+ mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
break;
case IM_SESSION_CONFERENCE_START:
mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
xml_filename = "floater_instant_message_ad_hoc.xml";
- mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, session_label);
+ mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
break;
// just received text from another user
case IM_NOTHING_SPECIAL:
xml_filename = "floater_instant_message.xml";
- mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, session_label, mOtherParticipantUUID);
+ mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
break;
default:
llwarns << "Unknown session type" << llendl;
@@ -999,15 +1158,14 @@ void LLFloaterIMPanel::init(const LLString& session_label)
&getFactoryMap(),
FALSE);
- setLabel(session_label);
- setTitle(session_label);
+ setTitle(mSessionLabel);
mInputEditor->setMaxTextLength(1023);
// enable line history support for instant message bar
mInputEditor->setEnableLineHistory(TRUE);
if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
{
- LLLogChat::loadHistory(session_label,
+ LLLogChat::loadHistory(mSessionLabel,
&chatFromLogFile,
(void *)this);
}
@@ -1060,16 +1218,12 @@ BOOL LLFloaterIMPanel::postBuild()
{
requires("chat_editor", WIDGET_TYPE_LINE_EDITOR);
requires("im_history", WIDGET_TYPE_TEXT_EDITOR);
- requires("live_help_dialog", WIDGET_TYPE_TEXT_BOX);
- requires("title_string", WIDGET_TYPE_TEXT_BOX);
- requires("typing_start_string", WIDGET_TYPE_TEXT_BOX);
- requires("session_start_string", WIDGET_TYPE_TEXT_BOX);
if (checkRequirements())
{
mInputEditor = LLUICtrlFactory::getLineEditorByName(this, "chat_editor");
- mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived );
- mInputEditor->setFocusLostCallback( onInputEditorFocusLost );
+ mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
+ mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
mInputEditor->setKeystrokeCallback( onInputEditorKeystroke );
mInputEditor->setCommitCallback( onCommitChat );
mInputEditor->setCallbackUserData(this);
@@ -1084,6 +1238,7 @@ BOOL LLFloaterIMPanel::postBuild()
childSetAction("send_btn", onClickSend, this);
childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
+ childSetAction("moderator_kick_speaker", onKickSpeaker, this);
//LLButton* close_btn = LLUICtrlFactory::getButtonByName(this, "close_btn");
//close_btn->setClickedCallback(&LLFloaterIMPanel::onClickClose, this);
@@ -1094,17 +1249,11 @@ BOOL LLFloaterIMPanel::postBuild()
{
childSetEnabled("profile_btn", FALSE);
}
- LLTextBox* title = LLUICtrlFactory::getTextBoxByName(this, "title_string");
- sTitleString = title->getText();
-
- LLTextBox* typing_start = LLUICtrlFactory::getTextBoxByName(this, "typing_start_string");
-
- sTypingStartString = typing_start->getText();
-
- LLTextBox* session_start = LLUICtrlFactory::getTextBoxByName(
- this,
- "session_start_string");
- sSessionStartString = session_start->getText();
+
+ sTitleString = getFormattedUIString("title_string");
+ sTypingStartString = getFormattedUIString("typing_start_string");
+ sSessionStartString = getFormattedUIString("session_start_string");
+
if (mSpeakerPanel)
{
mSpeakerPanel->refreshSpeakers();
@@ -1112,7 +1261,7 @@ BOOL LLFloaterIMPanel::postBuild()
if (mDialog == IM_NOTHING_SPECIAL)
{
- childSetCommitCallback("mute_btn", onClickMuteVoice, this);
+ childSetAction("mute_btn", onClickMuteVoice, this);
childSetCommitCallback("speaker_volume", onVolumeChange, this);
}
@@ -1131,7 +1280,7 @@ void* LLFloaterIMPanel::createSpeakersPanel(void* data)
}
//static
-void LLFloaterIMPanel::onClickMuteVoice(LLUICtrl* source, void* user_data)
+void LLFloaterIMPanel::onClickMuteVoice(void* user_data)
{
LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)user_data;
if (floaterp)
@@ -1171,10 +1320,22 @@ void LLFloaterIMPanel::draw()
&& LLVoiceClient::voiceEnabled();
// hide/show start call and end call buttons
- childSetVisible("end_call_btn", mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
- childSetVisible("start_call_btn", mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
+ childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
+ childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
childSetEnabled("start_call_btn", enable_connect);
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
+
+ LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
+ if (self_speaker.notNull() && self_speaker->mModeratorMutedText)
+ {
+ mInputEditor->setEnabled(FALSE);
+ mInputEditor->setLabel(getFormattedUIString("muted_text_label"));
+ }
+ else
+ {
+ mInputEditor->setEnabled(TRUE);
+ mInputEditor->setLabel(getFormattedUIString("default_text_label"));
+ }
if (mAutoConnect && enable_connect)
{
@@ -1215,11 +1376,11 @@ void LLFloaterIMPanel::draw()
else
{
// refresh volume and mute checkbox
- childSetEnabled("speaker_volume", mVoiceChannel->isActive());
+ childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
childSetValue("mute_btn", gMuteListp->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
- childSetEnabled("mute_btn", mVoiceChannel->isActive());
+ childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
}
LLFloater::draw();
}
@@ -1235,7 +1396,6 @@ public:
void error(U32 statusNum, const std::string& reason)
{
llinfos << "Error inviting all agents to session" << llendl;
-
//throw something back to the viewer here?
}
@@ -1243,6 +1403,48 @@ private:
LLUUID mSessionID;
};
+class LLSessionImmediateInviteResponder : public LLHTTPClient::Responder
+{
+public:
+ LLSessionImmediateInviteResponder(
+ const LLUUID& session_id,
+ const std::string& chat_req_url,
+ const LLSD& post_data)
+ {
+ mSessionID = session_id;
+ mURL = chat_req_url;
+ mPostData = post_data;
+ }
+
+ void error(U32 statusNum, const std::string& reason)
+ {
+ if ( statusNum == 400 )
+ {
+ //hrm 400 indicates invalid parameters...more
+ //than likely the method doesn't exist
+ //so try a soon to be deprecated old school way of doing this
+ mPostData["method"] = "invite";
+
+ LLHTTPClient::post(
+ mURL,
+ mPostData,
+ new LLSessionInviteResponder(mSessionID));
+ }
+ else
+ {
+ //throw something back to the viewer here?
+ llinfos << "Error inviting all agents to session" << llendl;
+ }
+ }
+
+private:
+ LLUUID mSessionID;
+ LLSD mPostData;
+
+ std::string mURL;
+};
+
+
BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
{
LLViewerRegion* region = gAgent.getRegion();
@@ -1267,12 +1469,15 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
data["params"].append(ids.get(i));
}
- data["method"] = "invite";
+ data["method"] = "immediate invite";
data["session-id"] = mSessionUUID;
LLHTTPClient::post(
url,
data,
- new LLSessionInviteResponder(mSessionUUID));
+ new LLSessionImmediateInviteResponder(
+ mSessionUUID,
+ url,
+ data));
}
else
@@ -1289,6 +1494,15 @@ BOOL LLFloaterIMPanel::inviteToSession(const LLDynamicArray<LLUUID>& ids)
void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &utf8msg, const LLColor4& color, bool log_to_file)
{
+ // start tab flashing when receiving im for background session from user
+ LLMultiFloater* hostp = getHost();
+ if( !isInVisibleChain()
+ && hostp
+ && source != gAgent.getID())
+ {
+ hostp->setFloaterFlashing(this, TRUE);
+ }
+
addHistoryLine(utf8msg, color, log_to_file);
mSpeakers->speakerChatted(source);
mSpeakers->setSpeakerTyping(source, FALSE);
@@ -1296,14 +1510,6 @@ void LLFloaterIMPanel::addHistoryLine(const LLUUID& source, const std::string &u
void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4& color, bool log_to_file)
{
- LLMultiFloater* hostp = getHost();
- if( !getVisible() && hostp && log_to_file)
- {
- // Only flash for logged ("real") messages
- LLTabContainer* parent = (LLTabContainer*) getParent();
- parent->setTabPanelFlashing( this, TRUE );
- }
-
// Now we're adding the actual line of text, so erase the
// "Foo is typing..." text segment, and the optional timestamp
// if it was present. JC
@@ -1330,6 +1536,11 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
LLLogChat::saveHistory(getTitle(),histstr);
}
+
+ if (!isInVisibleChain())
+ {
+ mNumUnreadMessages++;
+ }
}
@@ -1340,10 +1551,7 @@ void LLFloaterIMPanel::setVisible(BOOL b)
LLMultiFloater* hostp = getHost();
if( b && hostp )
{
- LLTabContainer* parent = (LLTabContainer*) getParent();
-
- // When this tab is displayed, you can stop flashing.
- parent->setTabPanelFlashing( this, FALSE );
+ hostp->setFloaterFlashing(this, FALSE);
/* Don't change containing floater title - leave it "Instant Message" JC
LLUIString title = sTitleString;
@@ -1392,7 +1600,7 @@ BOOL LLFloaterIMPanel::handleKeyHere( KEY key, MASK mask, BOOL called_from_paren
else if ( KEY_ESCAPE == key )
{
handled = TRUE;
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
// Close talk panel with escape
if( !gSavedSettings.getBOOL("PinTalkViewOpen") )
@@ -1573,14 +1781,14 @@ void LLFloaterIMPanel::onCommitChat(LLUICtrl* caller, void* userdata)
}
// static
-void LLFloaterIMPanel::onInputEditorFocusReceived( LLUICtrl* caller, void* userdata )
+void LLFloaterIMPanel::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
{
LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata;
self->mHistoryEditor->setCursorAndScrollToEnd();
}
// static
-void LLFloaterIMPanel::onInputEditorFocusLost(LLUICtrl* caller, void* userdata)
+void LLFloaterIMPanel::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
{
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
self->setTyping(FALSE);
@@ -1628,6 +1836,14 @@ void LLFloaterIMPanel::onClose(bool app_quitting)
destroy();
}
+void LLFloaterIMPanel::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility)
+ {
+ mNumUnreadMessages = 0;
+ }
+}
+
void deliver_message(const std::string& utf8_text,
const LLUUID& im_session_id,
const LLUUID& other_participant_id,
@@ -1739,19 +1955,37 @@ void LLFloaterIMPanel::sendMsg()
mSentTypingState = TRUE;
}
-void LLFloaterIMPanel::updateSpeakersList(LLSD speaker_updates)
-{
- mSpeakers->processSpeakerListUpdate(speaker_updates);
+void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
+{
+ mSpeakers->updateSpeakers(speaker_updates);
}
-void LLFloaterIMPanel::setSpeakersListFromMap(LLSD speaker_map)
+void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
{
- mSpeakers->processSpeakerMap(speaker_map);
+ if (
+ session_update.has("moderated_mode") &&
+ session_update["moderated_mode"].has("voice") )
+ {
+ BOOL voice_moderated = session_update["moderated_mode"]["voice"];
+
+ if (voice_moderated)
+ {
+ setTitle(mSessionLabel + LLString(" ") + getFormattedUIString("moderated_chat_label"));
+ }
+ else
+ {
+ setTitle(mSessionLabel);
+ }
+
+
+ //update the speakers dropdown too
+ mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+ }
}
-void LLFloaterIMPanel::setSpeakersList(LLSD speaker_list)
+void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
{
- mSpeakers->processSpeakerList(speaker_list);
+ mSpeakers->setSpeakers(speaker_list);
}
void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
@@ -1897,5 +2131,77 @@ void LLFloaterIMPanel::chatFromLogFile(LLString line, void* userdata)
//self->addHistoryLine(line, LLColor4::grey, FALSE);
self->mHistoryEditor->appendColoredText(line, false, true, LLColor4::grey);
+}
+
+void LLFloaterIMPanel::showSessionStartError(
+ const std::string& error_string)
+{
+ //the error strings etc. should be really be static and local
+ //to this file instead of in the LLFloaterIM
+ //but they were in llimview.cpp first and unfortunately
+ //some translations into non English languages already occurred
+ //thus making it a tad harder to change over to a
+ //"correct" solution. The best solution
+ //would be to store all of the misc. strings into
+ //their own XML file which would be read in by any LLIMPanel
+ //post build function instead of repeating the same info
+ //in the group, adhoc and normal IM xml files.
+ LLString::format_map_t args;
+ args["[REASON]"] =
+ LLFloaterIM::sErrorStringsMap[error_string];
+ args["[RECIPIENT]"] = getTitle();
+ gViewerWindow->alertXml(
+ "ChatterBoxSessionStartError",
+ args,
+ onConfirmForceCloseError,
+ this);
}
+
+void LLFloaterIMPanel::showSessionEventError(
+ const std::string& event_string,
+ const std::string& error_string)
+{
+ LLString::format_map_t args;
+ args["[REASON]"] =
+ LLFloaterIM::sErrorStringsMap[error_string];
+ args["[EVENT]"] =
+ LLFloaterIM::sEventStringsMap[event_string];
+ args["[RECIPIENT]"] = getTitle();
+
+ gViewerWindow->alertXml(
+ "ChatterBoxSessionEventError",
+ args);
+}
+
+void LLFloaterIMPanel::showSessionForceClose(
+ const std::string& reason_string)
+{
+ LLString::format_map_t args;
+
+ args["[NAME]"] = getTitle();
+ args["[REASON]"] = LLFloaterIM::sForceCloseSessionMap[reason_string];
+
+ gViewerWindow->alertXml(
+ "ForceCloseChatterBoxSession",
+ args,
+ LLFloaterIMPanel::onConfirmForceCloseError,
+ this);
+
+}
+
+//static
+void LLFloaterIMPanel::onKickSpeaker(void* user_data)
+{
+
+}
+
+void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data)
+{
+ //only 1 option really
+ LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data);
+
+ if ( floater ) floater->close(FALSE);
+}
+
+
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index c1ad18dd3c..ef36ff4a33 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -74,14 +74,20 @@ public:
virtual void getChannelInfo();
virtual BOOL isActive();
virtual BOOL callStarted();
+
+ const LLUUID getSessionID() { return mSessionID; }
EState getState() { return mState; }
void updateSessionID(const LLUUID& new_session_id);
+ const LLString::format_map_t& getNotifyArgs() { return mNotifyArgs; }
static LLVoiceChannel* getChannelByID(const LLUUID& session_id);
static LLVoiceChannel* getChannelByURI(LLString uri);
static LLVoiceChannel* getCurrentVoiceChannel() { return sCurrentVoiceChannel; }
static void initClass();
+
+ static void suspend();
+ static void resume();
protected:
virtual void setState(EState state);
@@ -103,13 +109,14 @@ protected:
static voice_channel_map_uri_t sVoiceChannelURIMap;
static LLVoiceChannel* sCurrentVoiceChannel;
+ static LLVoiceChannel* sSuspendedVoiceChannel;
+ static BOOL sSuspended;
};
class LLVoiceChannelGroup : public LLVoiceChannel
{
public:
LLVoiceChannelGroup(const LLUUID& session_id, const LLString& session_name);
- virtual ~LLVoiceChannelGroup();
/*virtual*/ void handleStatusChange(EStatusType status);
/*virtual*/ void handleError(EStatusType status);
@@ -132,8 +139,7 @@ class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoice
{
public:
LLVoiceChannelProximal();
- virtual ~LLVoiceChannelProximal();
-
+
/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
/*virtual*/ void handleStatusChange(EStatusType status);
/*virtual*/ void handleError(EStatusType status);
@@ -147,7 +153,6 @@ class LLVoiceChannelP2P : public LLVoiceChannelGroup
{
public:
LLVoiceChannelP2P(const LLUUID& session_id, const LLString& session_name, const LLUUID& other_user_id);
- virtual ~LLVoiceChannelP2P();
/*virtual*/ void handleStatusChange(EStatusType status);
/*virtual*/ void handleError(EStatusType status);
@@ -156,9 +161,13 @@ public:
void setSessionHandle(const LLString& handle);
+protected:
+ virtual void setState(EState state);
+
private:
LLString mSessionHandle;
LLUUID mOtherUserID;
+ BOOL mReceivedCall;
};
class LLFloaterIMPanel : public LLFloater
@@ -170,15 +179,11 @@ public:
// the default. For example, if you open a session though a
// calling card, a new session id will be generated, but the
// target_id will be the agent referenced by the calling card.
- LLFloaterIMPanel(const std::string& name,
- const LLRect& rect,
- const std::string& session_label,
+ LLFloaterIMPanel(const std::string& session_label,
const LLUUID& session_id,
const LLUUID& target_id,
EInstantMessage dialog);
- LLFloaterIMPanel(const std::string& name,
- const LLRect& rect,
- const std::string& session_label,
+ LLFloaterIMPanel(const std::string& session_label,
const LLUUID& session_id,
const LLUUID& target_id,
const LLDynamicArray<LLUUID>& ids,
@@ -189,8 +194,8 @@ public:
// Check typing timeout timer.
/*virtual*/ void draw();
-
/*virtual*/ void onClose(bool app_quitting = FALSE);
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
// add target ids to the session.
// Return TRUE if successful, otherwise FALSE.
@@ -209,14 +214,16 @@ public:
void selectNone();
void setVisible(BOOL b);
+ S32 getNumUnreadMessages() { return mNumUnreadMessages; }
+
BOOL handleKeyHere(KEY key, MASK mask, BOOL called_from_parent);
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type,
void *cargo_data, EAcceptance *accept,
LLString& tooltip_msg);
- static void onInputEditorFocusReceived( LLUICtrl* caller, void* userdata );
- static void onInputEditorFocusLost(LLUICtrl* caller, void* userdata);
+ static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
+ static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
static void onCommitChat(LLUICtrl* caller, void* userdata);
static void onTabClick( void* userdata );
@@ -229,16 +236,17 @@ public:
static void onClickSend( void* userdata );
static void onClickToggleActiveSpeakers( void* userdata );
static void* createSpeakersPanel(void* data);
+ static void onKickSpeaker(void* user_data);
//callbacks for P2P muting and volume control
- static void onClickMuteVoice(LLUICtrl* source, void* user_data);
+ static void onClickMuteVoice(void* user_data);
static void onVolumeChange(LLUICtrl* source, void* user_data);
const LLUUID& getSessionID() const { return mSessionUUID; }
const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
- void updateSpeakersList(LLSD speaker_updates);
- void setSpeakersListFromMap(LLSD speaker_list);
- void setSpeakersList(LLSD speaker_list);
+ void updateSpeakersList(const LLSD& speaker_updates);
+ void processSessionUpdate(const LLSD& update);
+ void setSpeakers(const LLSD& speaker_list);
LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
EInstantMessage getDialogType() const { return mDialog; }
@@ -250,6 +258,15 @@ public:
void processIMTyping(const LLIMInfo* im_info, BOOL typing);
static void chatFromLogFile(LLString line, void* userdata);
+ //show error statuses to the user
+ void showSessionStartError(const std::string& error_string);
+ void showSessionEventError(
+ const std::string& event_string,
+ const std::string& error_string);
+ void showSessionForceClose(const std::string& reason);
+
+ static void onConfirmForceCloseError(S32 option, void* data);
+
private:
// called by constructors
void init(const LLString& session_label);
@@ -289,6 +306,7 @@ private:
// 911 ==> Gaurdian_Angel_Group_ID ^ gAgent.getID()
LLUUID mSessionUUID;
+ LLString mSessionLabel;
LLVoiceChannel* mVoiceChannel;
BOOL mSessionInitialized;
@@ -318,6 +336,8 @@ private:
// Where does the "Starting session..." line start?
S32 mSessionStartMsgPos;
+ S32 mNumUnreadMessages;
+
BOOL mSentTypingState;
BOOL mShowSpeakersOnConnect;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9c37f1f333..f93f5810c5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -46,7 +46,6 @@
#include "llagent.h"
#include "llcallingcard.h"
#include "llchat.h"
-#include "llviewerwindow.h"
#include "llresmgr.h"
#include "llfloaterchat.h"
#include "llfloaterchatterbox.h"
@@ -65,6 +64,7 @@
#include "llcallingcard.h"
#include "lltoolbar.h"
#include "llviewermessage.h"
+#include "llviewerwindow.h"
#include "llnotify.h"
#include "llviewerregion.h"
@@ -84,11 +84,12 @@ LLIMMgr* gIMMgr = NULL;
//*FIXME: make these all either UIStrings or Strings
static LLString sOnlyUserMessage;
static LLUIString sOfflineMessage;
-
-static std::map<std::string,LLString> sEventStringsMap;
-static std::map<std::string,LLString> sErrorStringsMap;
-static std::map<std::string,LLString> sForceCloseSessionMap;
static LLUIString sInviteMessage;
+
+std::map<std::string,LLString> LLFloaterIM::sEventStringsMap;
+std::map<std::string,LLString> LLFloaterIM::sErrorStringsMap;
+std::map<std::string,LLString> LLFloaterIM::sForceCloseSessionMap;
+
//
// Helper Functions
//
@@ -160,22 +161,54 @@ BOOL LLFloaterIM::postBuild()
sOnlyUserMessage = getFormattedUIString("only_user_message");
sOfflineMessage = getUIString("offline_message");
- sErrorStringsMap["generic"] =
- getFormattedUIString("generic_request_error");
- sErrorStringsMap["unverified"] =
- getFormattedUIString("insufficient_perms_error");
- sErrorStringsMap["no_user_911"] =
- getFormattedUIString("user_no_help");
+ sInviteMessage = getUIString("invite_message");
- sEventStringsMap["add"] =
- getFormattedUIString("add_session_event");
- sEventStringsMap["message"] =
- getFormattedUIString("message_session_event");
+ if ( sErrorStringsMap.find("generic") == sErrorStringsMap.end() )
+ {
+ sErrorStringsMap["generic"] =
+ getFormattedUIString("generic_request_error");
+ }
- sForceCloseSessionMap["removed"] =
- getFormattedUIString("removed_from_group");
+ if ( sErrorStringsMap.find("unverified") ==
+ sErrorStringsMap.end() )
+ {
+ sErrorStringsMap["unverified"] =
+ getFormattedUIString("insufficient_perms_error");
+ }
+
+ if ( sErrorStringsMap.end() ==
+ sErrorStringsMap.find("does not exist") )
+ {
+ sErrorStringsMap["does not exist"] =
+ getFormattedUIString("session_does_not_exist_error");
+ }
+
+ if ( sEventStringsMap.end() == sEventStringsMap.find("add") )
+ {
+ sEventStringsMap["add"] =
+ getFormattedUIString("add_session_event");
+ }
+
+ if ( sEventStringsMap.end() == sEventStringsMap.find("message") )
+ {
+ sEventStringsMap["message"] =
+ getFormattedUIString("message_session_event");
+ }
+
+ if ( sForceCloseSessionMap.end() ==
+ sForceCloseSessionMap.find("removed") )
+ {
+ sForceCloseSessionMap["removed"] =
+ getFormattedUIString("removed_from_group");
+ }
+
+ if ( sForceCloseSessionMap.end() ==
+ sForceCloseSessionMap.find("no ability") )
+ {
+ sForceCloseSessionMap["no ability"] =
+ getFormattedUIString("close_on_no_ability");
+ }
- sInviteMessage = getUIString("invite_message");
return TRUE;
}
@@ -205,21 +238,31 @@ protected:
class LLIMMgr::LLIMSessionInvite
{
public:
- LLIMSessionInvite(const LLUUID& session_id, const LLString& session_name, const LLUUID& caller_id,const LLString& caller_name, EInstantMessage type, const LLString& session_handle, const LLString& notify_box) :
- mSessionID(session_id),
- mSessionName(session_name),
- mCallerID(caller_id),
- mCallerName(caller_name),
- mType(type),
- mSessionHandle(session_handle),
- mNotifyBox(notify_box)
- {};
+ LLIMSessionInvite(
+ const LLUUID& session_id,
+ const LLString& session_name,
+ const LLUUID& caller_id,
+ const LLString& caller_name,
+ EInstantMessage type,
+ EInvitationType inv_type,
+ const LLString& session_handle,
+ const LLString& notify_box) :
+ mSessionID(session_id),
+ mSessionName(session_name),
+ mCallerID(caller_id),
+ mCallerName(caller_name),
+ mType(type),
+ mInvType(inv_type),
+ mSessionHandle(session_handle),
+ mNotifyBox(notify_box)
+ {};
LLUUID mSessionID;
LLString mSessionName;
LLUUID mCallerID;
LLString mCallerName;
EInstantMessage mType;
+ EInvitationType mInvType;
LLString mSessionHandle;
LLString mNotifyBox;
};
@@ -309,7 +352,7 @@ LLIMMgr::LLIMMgr() :
LLFloaterIM* dummy_floater = new LLFloaterIM();
delete dummy_floater;
- mPendingVoiceInvitations = LLSD::emptyMap();
+ mPendingInvitations = LLSD::emptyMap();
mPendingAgentListUpdates = LLSD::emptyMap();
}
@@ -413,7 +456,6 @@ void LLIMMgr::addMessage(
if ( is_from_system ) // chat came from system
{
floater->addHistoryLine(
- other_participant_id,
msg,
gSavedSettings.getColor4("SystemChatColor"));
}
@@ -521,9 +563,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name,
// 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)
+LLUUID LLIMMgr::addSession(
+ const std::string& name,
+ EInstantMessage dialog,
+ const LLUUID& other_participant_id)
{
LLUUID session_id = computeSessionID(dialog, other_participant_id);
@@ -533,15 +576,16 @@ LLUUID LLIMMgr::addSession(const std::string& name,
LLDynamicArray<LLUUID> ids;
ids.put(other_participant_id);
- floater = createFloater(session_id,
- other_participant_id,
- name,
- ids,
- dialog,
- TRUE);
+ floater = createFloater(
+ session_id,
+ other_participant_id,
+ name,
+ ids,
+ dialog,
+ TRUE);
noteOfflineUsers(floater, ids);
- LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
+ LLFloaterChatterBox::showInstance(session_id);
}
else
{
@@ -554,36 +598,43 @@ LLUUID LLIMMgr::addSession(const std::string& name,
// 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)
+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);
+ LLUUID session_id = computeSessionID(
+ dialog,
+ other_participant_id);
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,
- ids,
- dialog,
- TRUE);
+ floater = createFloater(
+ session_id,
+ other_participant_id,
+ name,
+ ids,
+ dialog,
+ TRUE);
if ( !floater ) return LLUUID::null;
noteOfflineUsers(floater, ids);
+ LLFloaterChatterBox::showInstance(session_id);
+ }
+ else
+ {
+ floater->open();
}
- LLFloaterChatterBox::getInstance(LLSD())->showFloater(floater);
//mTabContainer->selectTabPanel(panel);
floater->setInputFocus(TRUE);
return floater->getSessionID();
@@ -599,6 +650,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
mFloaters.erase(floater->getHandle());
LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
//mTabContainer->removeTabPanel(floater);
+
+ clearPendingInviation(session_id);
+ clearPendingAgentListUpdates(session_id);
}
}
@@ -608,9 +662,10 @@ void LLIMMgr::inviteToSession(
const LLUUID& caller_id,
const LLString& caller_name,
EInstantMessage type,
+ EInvitationType inv_type,
const LLString& session_handle)
{
- //ignore voice invites from voice-muted residents
+ //ignore invites from muted residents
if (gMuteListp->isMuted(caller_id))
{
return;
@@ -621,17 +676,26 @@ void LLIMMgr::inviteToSession(
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))
+ else if ( gAgent.isInGroup(session_id) )
{
+ //only really old school groups have voice invitations
notify_box_type = "VoiceInviteGroup";
}
- else
+ 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;
+ }
LLIMSessionInvite* invite = new LLIMSessionInvite(
session_id,
@@ -639,6 +703,7 @@ void LLIMMgr::inviteToSession(
caller_id,
caller_name,
type,
+ inv_type,
session_handle,
notify_box_type);
@@ -666,7 +731,7 @@ void LLIMMgr::inviteToSession(
}
}
- if ( !mPendingVoiceInvitations.has(session_id.asString()) )
+ if ( !mPendingInvitations.has(session_id.asString()) )
{
if (caller_name.empty())
{
@@ -684,7 +749,7 @@ void LLIMMgr::inviteToSession(
(void*)invite);
}
- mPendingVoiceInvitations[session_id.asString()] = LLSD();
+ mPendingInvitations[session_id.asString()] = LLSD();
}
}
@@ -699,10 +764,11 @@ void LLIMMgr::onInviteNameLookup(const LLUUID& id, const char* first, const char
LLString::format_map_t args;
args["[NAME]"] = invite->mCallerName;
- LLNotifyBox::showXml(invite->mNotifyBox,
- args,
- inviteUserResponse,
- (void*)invite);
+ LLNotifyBox::showXml(
+ invite->mNotifyBox,
+ args,
+ inviteUserResponse,
+ (void*)invite);
}
class LLViewerChatterBoxInvitationAcceptResponder :
@@ -711,10 +777,10 @@ class LLViewerChatterBoxInvitationAcceptResponder :
public:
LLViewerChatterBoxInvitationAcceptResponder(
const LLUUID& session_id,
- bool is_voice_invitation)
+ LLIMMgr::EInvitationType invitation_type)
{
mSessionID = session_id;
- mIsVoiceInvitiation = is_voice_invitation;
+ mInvitiationType = invitation_type;
}
void result(const LLSD& content)
@@ -738,48 +804,67 @@ public:
//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.
- floaterp->setSpeakersList(content["agents"]);
+ floaterp->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
-
- //reapplying a user entrance will do nothing
- //reapplying a user leaving will not have the user
- //in our base. So it's all good
floaterp->updateSpeakersList(
gIMMgr->getPendingAgentListUpdates(mSessionID));
- if ( mIsVoiceInvitiation )
+ if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
{
floaterp->requestAutoConnect();
LLFloaterIMPanel::onClickStartCall(floaterp);
// always open IM window when connecting to voice
LLFloaterChatterBox::showInstance(TRUE);
}
+ else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
+ {
+ LLFloaterChatterBox::showInstance(TRUE);
+ }
}
gIMMgr->clearPendingAgentListUpdates(mSessionID);
- if ( mIsVoiceInvitiation )
- {
- gIMMgr->clearPendingVoiceInviation(mSessionID);
- }
+ gIMMgr->clearPendingInviation(mSessionID);
}
}
void error(U32 statusNum, const std::string& reason)
{
+
//throw something back to the viewer here?
- if ( gIMMgr && mIsVoiceInvitiation )
+ if ( gIMMgr )
{
- gIMMgr->clearPendingVoiceInviation(mSessionID);
+ gIMMgr->clearPendingAgentListUpdates(mSessionID);
+ gIMMgr->clearPendingInviation(mSessionID);
+
+ LLFloaterIMPanel* floaterp =
+ gIMMgr->findFloaterBySession(mSessionID);
+
+ if (floaterp)
+ {
+ std::string error_string;
+
+ if ( 404 == statusNum )
+ {
+ error_string = "does not exist";
+ }
+ else
+ {
+ error_string = "generic_request_error";
+ }
+
+ floaterp->showSessionStartError(
+ error_string);
+ }
}
}
private:
LLUUID mSessionID;
- bool mIsVoiceInvitiation;
+ LLIMMgr::EInvitationType mInvitiationType;
};
//static
@@ -807,10 +892,11 @@ void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
im_floater->requestAutoConnect();
LLFloaterIMPanel::onClickStartCall(im_floater);
// always open IM window when connecting to voice
- LLFloaterChatterBox::showInstance(TRUE);
+ LLFloaterChatterBox::showInstance(invitep->mSessionID);
}
-
- gIMMgr->clearPendingVoiceInviation(invitep->mSessionID);
+
+ gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
+ gIMMgr->clearPendingInviation(invitep->mSessionID);
}
else
{
@@ -830,34 +916,50 @@ void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
data,
new LLViewerChatterBoxInvitationAcceptResponder(
invitep->mSessionID,
- true));
+ invitep->mInvType));
}
}
break;
case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
+ {
+ // mute the sender of this invite
+ if (!gMuteListp->isMuted(invitep->mCallerID))
{
- // mute the sender of this invite
- if (!gMuteListp->isMuted(invitep->mCallerID))
- {
- LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
- gMuteListp->add(mute);
- }
+ LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
+ gMuteListp->add(mute);
}
+ }
/* FALLTHROUGH */
- case 1: // ignore
+ case 1: // decline
+ {
+ if (invitep->mType == IM_SESSION_P2P_INVITE)
{
- if (invitep->mType == IM_SESSION_P2P_INVITE)
+ if(gVoiceClient)
{
- if(gVoiceClient)
- {
- gVoiceClient->declineInvite(invitep->mSessionHandle);
- }
+ gVoiceClient->declineInvite(invitep->mSessionHandle);
}
}
- break;
+ else
+ {
+ std::string url = gAgent.getRegion()->getCapability(
+ "ChatSessionRequest");
+
+ LLSD data;
+ data["method"] = "decline invitation";
+ data["session-id"] = invitep->mSessionID;
+ LLHTTPClient::post(
+ url,
+ data,
+ NULL);
+ }
}
+ gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
+ gIMMgr->clearPendingInviation(invitep->mSessionID);
+ break;
+ }
+
delete invitep;
}
@@ -869,11 +971,11 @@ void LLIMMgr::setFloaterOpen(BOOL set_open)
{
if (set_open)
{
- LLFloaterChatterBox::showInstance(LLSD());
+ LLFloaterChatterBox::showInstance();
}
else
{
- LLFloaterChatterBox::hideInstance(LLSD());
+ LLFloaterChatterBox::hideInstance();
}
}
@@ -932,11 +1034,11 @@ BOOL LLIMMgr::hasSession(const LLUUID& session_id)
return (findFloaterBySession(session_id) != NULL);
}
-void LLIMMgr::clearPendingVoiceInviation(const LLUUID& session_id)
+void LLIMMgr::clearPendingInviation(const LLUUID& session_id)
{
- if ( mPendingVoiceInvitations.has(session_id.asString()) )
+ if ( mPendingInvitations.has(session_id.asString()) )
{
- mPendingVoiceInvitations.erase(session_id.asString());
+ mPendingInvitations.erase(session_id.asString());
}
}
@@ -958,13 +1060,57 @@ void LLIMMgr::addPendingAgentListUpdates(
{
LLSD::map_const_iterator iter;
- for ( iter = updates.beginMap();
- iter != updates.endMap();
- iter++)
+ if ( !mPendingAgentListUpdates.has(session_id.asString()) )
{
- //we only want to include the last update for a given agent
- mPendingAgentListUpdates[session_id.asString()][iter->first] =
- iter->second;
+ //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;
+ }
}
}
@@ -995,8 +1141,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
llinfos << "LLIMMgr::createFloater: from " << other_participant_id
<< " in session " << session_id << llendl;
LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
- LLRect(),
- session_label,
session_id,
other_participant_id,
dialog);
@@ -1022,8 +1166,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
llinfos << "LLIMMgr::createFloater: from " << other_participant_id
<< " in session " << session_id << llendl;
LLFloaterIMPanel* floater = new LLFloaterIMPanel(session_label,
- LLRect(),
- session_label,
session_id,
other_participant_id,
ids,
@@ -1034,8 +1176,9 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
return floater;
}
-void LLIMMgr::noteOfflineUsers(LLFloaterIMPanel* floater,
- const LLDynamicArray<LLUUID>& ids)
+void LLIMMgr::noteOfflineUsers(
+ LLFloaterIMPanel* floater,
+ const LLDynamicArray<LLUUID>& ids)
{
S32 count = ids.count();
if(count == 0)
@@ -1099,14 +1242,6 @@ LLFloaterChatterBox* LLIMMgr::getFloater()
return LLFloaterChatterBox::getInstance(LLSD());
}
-void onConfirmForceCloseError(S32 option, void* data)
-{
- //only 1 option really
- LLFloaterIMPanel* floater = ((LLFloaterIMPanel*) data);
-
- if ( floater ) floater->close(FALSE);
-}
-
class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
{
public:
@@ -1141,7 +1276,16 @@ public:
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
if (floaterp)
{
- floaterp->setSpeakersList(body["agents"]);
+ floaterp->setSpeakers(body);
+
+ //apply updates we've possibly received previously
+ floaterp->updateSpeakersList(
+ gIMMgr->getPendingAgentListUpdates(session_id));
+
+ if ( body.has("session_info") )
+ {
+ floaterp->processSessionUpdate(body["session_info"]);
+ }
//aply updates we've possibly received previously
floaterp->updateSpeakersList(
@@ -1155,20 +1299,14 @@ public:
//floater
LLFloaterIMPanel* floater =
gIMMgr->findFloaterBySession(temp_session_id);
- if (floater)
- {
- LLString::format_map_t args;
- args["[REASON]"] =
- sErrorStringsMap[body["error"].asString()];
- args["[RECIPIENT]"] = floater->getTitle();
-
- gViewerWindow->alertXml("ChatterBoxSessionStartError",
- args,
- onConfirmForceCloseError,
- floater);
+ if ( floater )
+ {
+ floater->showSessionStartError(body["error"].asString());
}
}
+
+ gIMMgr->clearPendingAgentListUpdates(session_id);
}
};
@@ -1200,17 +1338,12 @@ public:
//throw an error dialog
LLFloaterIMPanel* floater =
gIMMgr->findFloaterBySession(session_id);
+
if (floater)
{
- LLString::format_map_t args;
- args["[REASON]"] =
- sErrorStringsMap[body["error"].asString()];
- args["[EVENT]"] =
- sEventStringsMap[body["event"].asString()];
- args["[RECIPIENT]"] = floater->getTitle();
-
- gViewerWindow->alertXml("ChatterBoxSessionEventError",
- args);
+ floater->showSessionEventError(
+ body["event"].asString(),
+ body["error"].asString());
}
}
}
@@ -1234,15 +1367,7 @@ public:
if ( floater )
{
- LLString::format_map_t args;
-
- args["[NAME]"] = floater->getTitle();
- args["[REASON]"] = sForceCloseSessionMap[reason];
-
- gViewerWindow->alertXml("ForceCloseChatterBoxSession",
- args,
- onConfirmForceCloseError,
- floater);
+ floater->showSessionForceClose(reason);
}
}
};
@@ -1258,7 +1383,8 @@ public:
LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
if (floaterp)
{
- floaterp->updateSpeakersList(input["body"]["updates"]);
+ floaterp->updateSpeakersList(
+ input["body"]);
}
else
{
@@ -1267,11 +1393,28 @@ public:
//a start or an acceptance of an invitation. Race condition.
gIMMgr->addPendingAgentListUpdates(
input["body"]["session_id"].asUUID(),
- input["body"]["updates"]);
+ input["body"]);
+ }
+ }
+};
+
+class LLViewerChatterBoxSessionUpdate : public LLHTTPNode
+{
+public:
+ virtual void post(
+ ResponsePtr responder,
+ const LLSD& context,
+ const LLSD& input) const
+ {
+ LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
+ if (floaterp)
+ {
+ floaterp->processSessionUpdate(input["body"]["info"]);
}
}
};
+
class LLViewerChatterBoxInvitation : public LLHTTPNode
{
public:
@@ -1281,6 +1424,8 @@ public:
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") )
{
LLString capability = input["body"]["capabilities"]["call"].asString();
@@ -1397,8 +1542,8 @@ public:
url,
data,
new LLViewerChatterBoxInvitationAcceptResponder(
- input["body"]["session_id"],
- false));
+ input["body"]["session_id"].asUUID(),
+ LLIMMgr::INVITATION_TYPE_INSTANT_MESSAGE));
}
} //end if invitation has instant message
else if ( input["body"].has("voice") )
@@ -1419,7 +1564,18 @@ public:
input["body"]["session_name"].asString(),
input["body"]["from_id"].asUUID(),
input["body"]["from_name"].asString(),
- IM_SESSION_INVITE);
+ 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);
}
}
};
@@ -1440,6 +1596,10 @@ LLHTTPRegistration<LLViewerChatterBoxSessionAgentListUpdates>
gHTTPRegistrationMessageChatterboxsessionagentlistupdates(
"/message/ChatterBoxSessionAgentListUpdates");
+LLHTTPRegistration<LLViewerChatterBoxSessionUpdate>
+ gHTTPRegistrationMessageChatterBoxSessionUpdate(
+ "/message/ChatterBoxSessionUpdate");
+
LLHTTPRegistration<LLViewerChatterBoxInvitation>
gHTTPRegistrationMessageChatterBoxInvitation(
"/message/ChatterBoxInvitation");
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index f5356ef926..11a6905a63 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -45,6 +45,13 @@ class LLFloaterIM;
class LLIMMgr : public LLSingleton<LLIMMgr>
{
public:
+ enum EInvitationType
+ {
+ INVITATION_TYPE_INSTANT_MESSAGE = 0,
+ INVITATION_TYPE_VOICE = 1,
+ INVITATION_TYPE_IMMEDIATE = 2
+ };
+
LLIMMgr();
virtual ~LLIMMgr();
@@ -96,12 +103,14 @@ public:
// deleted.
void removeSession(const LLUUID& session_id);
- void inviteToSession(const LLUUID& session_id,
- const LLString& session_name,
- const LLUUID& caller,
- const LLString& caller_name,
- EInstantMessage type,
- const LLString& session_handle = LLString::null);
+ void inviteToSession(
+ const LLUUID& session_id,
+ const LLString& session_name,
+ const LLUUID& caller,
+ const LLString& caller_name,
+ EInstantMessage type,
+ EInvitationType inv_type,
+ const LLString& session_handle = LLString::null);
//Updates a given session's session IDs. Does not open,
//create or do anything new. If the old session doesn't
@@ -147,7 +156,7 @@ public:
static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id);
- void clearPendingVoiceInviation(const LLUUID& session_id);
+ void clearPendingInviation(const LLUUID& session_id);
LLSD getPendingAgentListUpdates(const LLUUID& session_id);
void addPendingAgentListUpdates(
@@ -155,6 +164,9 @@ public:
const LLSD& updates);
void clearPendingAgentListUpdates(const LLUUID& session_id);
+ //HACK: need a better way of enumerating existing session, or listening to session create/destroy events
+ const std::set<LLViewHandle>& getIMFloaterHandles() { return mFloaters; }
+
private:
class LLIMSessionInvite;
@@ -193,7 +205,7 @@ private:
// An IM has been received that you haven't seen yet.
BOOL mIMReceived;
- LLSD mPendingVoiceInvitations;
+ LLSD mPendingInvitations;
LLSD mPendingAgentListUpdates;
};
@@ -203,6 +215,10 @@ class LLFloaterIM : public LLMultiFloater
public:
LLFloaterIM();
/*virtual*/ BOOL postBuild();
+
+ static std::map<std::string,LLString> sEventStringsMap;
+ static std::map<std::string,LLString> sErrorStringsMap;
+ static std::map<std::string,LLString> sForceCloseSessionMap;
};
// Globals
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 9c9b1ad257..d8841afe22 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3165,7 +3165,7 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model
std::string(),
cb);
}
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
}
else if ("detach" == action)
{
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index ca65b879bc..7b27a830c4 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -2606,7 +2606,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
// }
//
// // restore keyboard focus
- // gFocusMgr.setKeyboardFocus(focus_view, callback);
+ // gFocusMgr.setKeyboardFocus(focus_view);
//}
}
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 20c4a25003..30106443c0 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -607,26 +607,26 @@ void LLJoystickCameraRotate::draw()
{
LLGLSUIDefault gls_ui;
- gl_draw_image( 0, 0, mImageUnselected );
+ mImageUnselected->draw( 0, 0 );
if( mInTop )
{
- drawRotatedImage( mImageSelected, 0 );
+ drawRotatedImage( mImageSelected->getImage(), 0 );
}
if( mInRight )
{
- drawRotatedImage( mImageSelected, 1 );
+ drawRotatedImage( mImageSelected->getImage(), 1 );
}
if( mInBottom )
{
- drawRotatedImage( mImageSelected, 2 );
+ drawRotatedImage( mImageSelected->getImage(), 2 );
}
if( mInLeft )
{
- drawRotatedImage( mImageSelected, 3 );
+ drawRotatedImage( mImageSelected->getImage(), 3 );
}
if (sDebugRects)
@@ -801,7 +801,7 @@ void LLJoystickCameraZoom::draw()
}
else
{
- gl_draw_image( 0, 0, mImageUnselected );
+ mImageUnselected->draw( 0, 0 );
}
if (sDebugRects)
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 4d02af8fae..60d39b62bd 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -52,10 +52,11 @@
#include <boost/tokenizer.hpp>
#include "llcrc.h"
+#include "lldir.h"
#include "lldispatcher.h"
+#include "llsdserialize.h"
#include "llxfermanager.h"
#include "message.h"
-#include "lldir.h"
#include "llagent.h"
#include "llfloatermute.h"
@@ -67,6 +68,9 @@
LLMuteList* gMuteListp = NULL;
+std::map<LLUUID, F32> LLMuteList::sUserVolumeSettings;
+
+
// "emptymutelist"
class LLDispatchEmptyMuteList : public LLDispatchHandler
{
@@ -168,6 +172,24 @@ LLMuteList::LLMuteList() :
msg->setHandlerFuncFast(_PREHASH_UseCachedMuteList, processUseCachedMuteList);
gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
+
+ // load per-resident voice volume information
+ // conceptually, this is part of the mute list information, although it is only stored locally
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
+
+ LLSD settings_llsd;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(settings_llsd, file);
+ }
+
+ for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+ iter != settings_llsd.endMap(); ++iter)
+ {
+ sUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));
+ }
}
//-----------------------------------------------------------------------------
@@ -175,6 +197,17 @@ LLMuteList::LLMuteList() :
//-----------------------------------------------------------------------------
LLMuteList::~LLMuteList()
{
+ std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
+ LLSD settings_llsd;
+
+ for(user_volume_map_t::iterator iter = sUserVolumeSettings.begin(); iter != sUserVolumeSettings.end(); ++iter)
+ {
+ settings_llsd[iter->first.asString()] = iter->second;
+ }
+
+ llofstream file;
+ file.open(filename.c_str());
+ LLSDSerialize::toPrettyXML(settings_llsd, file);
}
BOOL LLMuteList::isLinden(const LLString& name) const
@@ -588,6 +621,25 @@ void LLMuteList::cache(const LLUUID& agent_id)
}
}
+void LLMuteList::setSavedResidentVolume(const LLUUID& id, F32 volume)
+{
+ // store new value in volume settings file
+ sUserVolumeSettings[id] = volume;
+}
+
+F32 LLMuteList::getSavedResidentVolume(const LLUUID& id)
+{
+ const F32 DEFAULT_VOLUME = 0.5f;
+
+ user_volume_map_t::iterator found_it = sUserVolumeSettings.find(id);
+ if (found_it != sUserVolumeSettings.end())
+ {
+ return found_it->second;
+ }
+ //FIXME: assumes default, should get this from somewhere
+ return DEFAULT_VOLUME;
+}
+
//-----------------------------------------------------------------------------
// Static message handlers
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 23e0620ade..413a2933b3 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -112,6 +112,9 @@ public:
// call this method on logout to save everything.
void cache(const LLUUID& agent_id);
+ void setSavedResidentVolume(const LLUUID& id, F32 volume);
+ F32 getSavedResidentVolume(const LLUUID& id);
+
private:
BOOL loadFromFile(const LLString& filename);
BOOL saveToFile(const LLString& filename);
@@ -155,6 +158,9 @@ private:
BOOL mIsLoaded;
friend class LLDispatchEmptyMuteList;
+
+ typedef std::map<LLUUID, F32> user_volume_map_t;
+ static user_volume_map_t sUserVolumeSettings;
};
class LLMuteListObserver
diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp
index ba1280550f..1ca702b0a7 100644
--- a/indra/newview/llnameeditor.cpp
+++ b/indra/newview/llnameeditor.cpp
@@ -53,7 +53,7 @@ LLNameEditor::LLNameEditor(const std::string& name, const LLRect& rect,
S32 max_text_length,
void (*commit_callback)(LLUICtrl* caller, void* user_data),
void (*keystroke_callback)(LLLineEditor* caller, void* user_data),
- void (*focus_lost_callback)(LLUICtrl* caller, void* user_data),
+ void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data),
void* userdata,
LLLinePrevalidateFunc prevalidate_func,
LLViewBorder::EBevel border_bevel,
diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h
index 526b76b9c0..9c89454c33 100644
--- a/indra/newview/llnameeditor.h
+++ b/indra/newview/llnameeditor.h
@@ -53,7 +53,7 @@ public:
S32 max_text_length = 254,
void (*commit_callback)(LLUICtrl* caller, void* user_data) = NULL,
void (*keystroke_callback)(LLLineEditor* caller, void* user_data) = NULL,
- void (*focus_lost_callback)(LLUICtrl* caller, void* user_data) = NULL,
+ void (*focus_lost_callback)(LLFocusableElement* caller, void* user_data) = NULL,
void* userdata = NULL,
LLLinePrevalidateFunc prevalidate_func = NULL,
LLViewBorder::EBevel border_bevel = LLViewBorder::BEVEL_IN,
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index adcc141bb1..a47721be9d 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -224,7 +224,7 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& value, EAddPosition pos
LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
((LLScrollListText*)cell)->setText( fullname );
- updateMaxContentWidth(item);
+ calcMaxContentWidth(item);
// this column is resizable
LLScrollListColumn* columnp = getColumn(mNameColumnIndex);
@@ -277,7 +277,7 @@ void LLNameListCtrl::refresh(const LLUUID& id, const char* first,
cell = (LLScrollListCell*)item->getColumn(mNameColumnIndex);
((LLScrollListText*)cell)->setText( fullname );
- updateMaxContentWidth(item);
+ calcMaxContentWidth(item);
}
}
}
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index 15c993e552..e7c313638b 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -39,6 +39,7 @@
#include "audioengine.h"
#include "llagent.h"
#include "llbutton.h"
+#include "llchatbar.h"
#include "llfocusmgr.h"
#include "llimview.h"
#include "llmediaengine.h"
@@ -71,37 +72,14 @@ extern S32 MENU_BAR_HEIGHT;
//
-//static
-void* LLOverlayBar::createMasterRemote(void* userdata)
-{
- LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mMasterRemote = new LLMediaRemoteCtrl ( "master_volume",
- "volume",
- LLRect(),
- "panel_master_volume.xml");
- return self->mMasterRemote;
-}
void* LLOverlayBar::createMediaRemote(void* userdata)
{
LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mMediaRemote = new LLMediaRemoteCtrl ( "media_remote",
- "media",
- LLRect(),
- "panel_media_remote.xml");
+ self->mMediaRemote = new LLMediaRemoteCtrl ();
return self->mMediaRemote;
}
-void* LLOverlayBar::createMusicRemote(void* userdata)
-{
- LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mMusicRemote = new LLMediaRemoteCtrl ( "music_remote",
- "music",
- LLRect(),
- "panel_music_remote.xml" );
- return self->mMusicRemote;
-}
-
void* LLOverlayBar::createVoiceRemote(void* userdata)
{
LLOverlayBar *self = (LLOverlayBar*)userdata;
@@ -109,13 +87,14 @@ void* LLOverlayBar::createVoiceRemote(void* userdata)
return self->mVoiceRemote;
}
+void* LLOverlayBar::createChatBar(void* userdata)
+{
+ gChatBar = new LLChatBar();
+ return gChatBar;
+}
-
-
-LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect)
- : LLPanel(name, rect, FALSE), // not bordered
- mMasterRemote(NULL),
- mMusicRemote(NULL),
+LLOverlayBar::LLOverlayBar()
+ : LLPanel(),
mMediaRemote(NULL),
mVoiceRemote(NULL),
mMediaState(STOPPED),
@@ -127,25 +106,27 @@ LLOverlayBar::LLOverlayBar(const std::string& name, const LLRect& rect)
mBuilt = false;
LLCallbackMap::map_t factory_map;
- factory_map["master_volume"] = LLCallbackMap(LLOverlayBar::createMasterRemote, this);
factory_map["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
- factory_map["music_remote"] = LLCallbackMap(LLOverlayBar::createMusicRemote, this);
factory_map["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
+ factory_map["chat_bar"] = LLCallbackMap(LLOverlayBar::createChatBar, this);
gUICtrlFactory->buildPanel(this, "panel_overlaybar.xml", &factory_map);
-
+}
+
+BOOL LLOverlayBar::postBuild()
+{
childSetAction("IM Received",onClickIMReceived,this);
childSetAction("Set Not Busy",onClickSetNotBusy,this);
childSetAction("Release Keys",onClickReleaseKeys,this);
childSetAction("Mouselook",onClickMouselook,this);
childSetAction("Stand Up",onClickStandUp,this);
+ childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
mIsFocusRoot = TRUE;
mBuilt = true;
- // make overlay bar conform to window size
- setRect(rect);
layoutButtons();
+ return TRUE;
}
LLOverlayBar::~LLOverlayBar()
@@ -176,146 +157,45 @@ void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
void LLOverlayBar::layoutButtons()
{
- S32 width = mRect.getWidth();
- if (width > 1024) width = 1024;
-
- S32 count = getChildCount();
- const S32 PAD = gSavedSettings.getS32("StatusBarPad");
-
- const S32 num_media_controls = 3;
- S32 media_remote_width = mMediaRemote ? mMediaRemote->getRect().getWidth() : 0;
- S32 music_remote_width = mMusicRemote ? mMusicRemote->getRect().getWidth() : 0;
- S32 voice_remote_width = mVoiceRemote ? mVoiceRemote->getRect().getWidth() : 0;
- S32 master_remote_width = mMasterRemote ? mMasterRemote->getRect().getWidth() : 0;
-
- // total reserved width for all media remotes
- const S32 ENDPAD = 20;
- S32 remote_total_width = media_remote_width + PAD + music_remote_width + PAD + voice_remote_width + PAD + master_remote_width + ENDPAD;
+ LLView* state_buttons_panel = getChildByName("state_buttons", TRUE);
- // calculate button widths
- F32 segment_width = (F32)(width - remote_total_width) / (F32)(count - num_media_controls);
-
- S32 btn_width = lltrunc(segment_width - PAD);
-
- // Evenly space all views
- LLRect r;
- S32 i = 0;
- for (child_list_const_iter_t child_iter = getChildList()->begin();
- child_iter != getChildList()->end(); ++child_iter)
+ if (state_buttons_panel)
{
- LLView *view = *child_iter;
- r = view->getRect();
- r.mLeft = (width) - llround(remote_total_width + (i-num_media_controls+1)*segment_width);
- r.mRight = r.mLeft + btn_width;
- view->setRect(r);
- i++;
- }
+ LLViewQuery query;
+ LLWidgetTypeFilter widget_filter(WIDGET_TYPE_BUTTON);
+ query.addPreFilter(LLVisibleFilter::getInstance());
+ query.addPreFilter(LLEnabledFilter::getInstance());
+ query.addPreFilter(&widget_filter);
- // Fix up remotes to have constant width because they can't shrink
- S32 right = mRect.getWidth() - remote_total_width - PAD;
- if (mMediaRemote)
- {
- r = mMediaRemote->getRect();
- r.mLeft = right + PAD;
- right = r.mLeft + media_remote_width;
- r.mRight = right;
- mMediaRemote->setRect(r);
- }
- if (mMusicRemote)
- {
- r = mMusicRemote->getRect();
- r.mLeft = right + PAD;
- right = r.mLeft + music_remote_width;
- r.mRight = right;
- mMusicRemote->setRect(r);
- }
- if (mVoiceRemote)
- {
- r = mVoiceRemote->getRect();
- r.mLeft = right + PAD;
- right = r.mLeft + voice_remote_width;
- r.mRight = right;
- mVoiceRemote->setRect(r);
- }
- if (mMasterRemote)
- {
- r = mMasterRemote->getRect();
- r.mLeft = right + PAD;
- right = r.mLeft + master_remote_width;
- r.mRight = right;
- mMasterRemote->setRect(r);
- }
-
- updateRect();
-}
+ child_list_t button_list = query(state_buttons_panel);
-void LLOverlayBar::draw()
-{
- // retrieve rounded rect image
- LLUUID image_id;
- image_id.set(gViewerArt.getString("rounded_square.tga"));
- LLViewerImage* imagep = gImageList.getImage(image_id, MIPMAP_FALSE, TRUE);
+ const S32 MAX_BAR_WIDTH = 600;
+ S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH);
- if (imagep)
- {
- LLGLSTexture texture_enabled;
- LLViewerImage::bindTexture(imagep);
+ // calculate button widths
+ const S32 MAX_BUTTON_WIDTH = 150;
+ S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH);
+ S32 btn_width = segment_width - gSavedSettings.getS32("StatusBarPad");
- const S32 PAD = gSavedSettings.getS32("StatusBarPad");
+ // Evenly space all buttons, starting from left
+ S32 left = 0;
+ S32 bottom = 1;
- // draw rounded rect tabs behind all children
- LLRect r;
- // focus highlights
- LLColor4 color = gColors.getColor("FloaterFocusBorderColor");
- glColor4fv(color.mV);
- if(gFocusMgr.childHasKeyboardFocus(gBottomPanel))
- {
- for (child_list_const_iter_t child_iter = getChildList()->begin();
- child_iter != getChildList()->end(); ++child_iter)
- {
- LLView *view = *child_iter;
- if(view->getEnabled() && view->getVisible())
- {
- r = view->getRect();
- gl_segmented_rect_2d_tex(r.mLeft - PAD/3 - 1,
- r.mTop + 3,
- r.mRight + PAD/3 + 1,
- r.mBottom,
- imagep->getWidth(),
- imagep->getHeight(),
- 16,
- ROUNDED_RECT_TOP);
- }
- }
- }
-
- // main tabs
- for (child_list_const_iter_t child_iter = getChildList()->begin();
- child_iter != getChildList()->end(); ++child_iter)
+ for (child_list_reverse_iter_t child_iter = button_list.rbegin();
+ child_iter != button_list.rend(); ++child_iter)
{
LLView *view = *child_iter;
- if(view->getEnabled() && view->getVisible())
- {
- r = view->getRect();
- // draw a nice little pseudo-3D outline
- color = gColors.getColor("DefaultShadowDark");
- glColor4fv(color.mV);
- gl_segmented_rect_2d_tex(r.mLeft - PAD/3 + 1, r.mTop + 2, r.mRight + PAD/3, r.mBottom,
- imagep->getWidth(), imagep->getHeight(), 16, ROUNDED_RECT_TOP);
- color = gColors.getColor("DefaultHighlightLight");
- glColor4fv(color.mV);
- gl_segmented_rect_2d_tex(r.mLeft - PAD/3, r.mTop + 2, r.mRight + PAD/3 - 3, r.mBottom,
- imagep->getWidth(), imagep->getHeight(), 16, ROUNDED_RECT_TOP);
- // here's the main background. Note that it overhangs on the bottom so as to hide the
- // focus highlight on the bottom panel, thus producing the illusion that the focus highlight
- // continues around the tabs
- color = gColors.getColor("FocusBackgroundColor");
- glColor4fv(color.mV);
- gl_segmented_rect_2d_tex(r.mLeft - PAD/3 + 1, r.mTop + 1, r.mRight + PAD/3 - 1, r.mBottom - 1,
- imagep->getWidth(), imagep->getHeight(), 16, ROUNDED_RECT_TOP);
- }
+ LLRect r = view->getRect();
+ r.setOriginAndSize(left, bottom, btn_width, r.getHeight());
+ view->setRect(r);
+ left += segment_width;
}
}
+}
+
+void LLOverlayBar::draw()
+{
+ childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
// draw children on top
LLPanel::draw();
@@ -325,79 +205,74 @@ void LLOverlayBar::draw()
// Per-frame updates of visibility
void LLOverlayBar::refresh()
{
+ BOOL buttons_changed = FALSE;
+
BOOL im_received = gIMMgr->getIMReceived();
- childSetVisible("IM Received", im_received);
- childSetEnabled("IM Received", im_received);
+ LLButton* button = LLUICtrlFactory::getButtonByName(this, "IM Received");
+ if (button && button->getVisible() != im_received)
+ {
+ button->setVisible(im_received);
+ sendChildToFront(button);
+ moveChildToBackOfTabGroup(button);
+ buttons_changed = TRUE;
+ }
BOOL busy = gAgent.getBusy();
- childSetVisible("Set Not Busy", busy);
- childSetEnabled("Set Not Busy", busy);
+ button = LLUICtrlFactory::getButtonByName(this, "Set Not Busy");
+ if (button && button->getVisible() != busy)
+ {
+ button->setVisible(busy);
+ sendChildToFront(button);
+ moveChildToBackOfTabGroup(button);
+ buttons_changed = TRUE;
+ }
BOOL controls_grabbed = gAgent.anyControlGrabbed();
+ button = LLUICtrlFactory::getButtonByName(this, "Release Keys");
- childSetVisible("Release Keys", controls_grabbed);
- childSetEnabled("Release Keys", controls_grabbed);
-
+ if (button && button->getVisible() != controls_grabbed)
+ {
+ button->setVisible(controls_grabbed);
+ sendChildToFront(button);
+ moveChildToBackOfTabGroup(button);
+ buttons_changed = TRUE;
+ }
BOOL mouselook_grabbed;
mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)
|| gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX);
+ button = LLUICtrlFactory::getButtonByName(this, "Mouselook");
-
- childSetVisible("Mouselook", mouselook_grabbed);
- childSetEnabled("Mouselook", mouselook_grabbed);
+ if (button && button->getVisible() != mouselook_grabbed)
+ {
+ button->setVisible(mouselook_grabbed);
+ sendChildToFront(button);
+ moveChildToBackOfTabGroup(button);
+ buttons_changed = TRUE;
+ }
BOOL sitting = FALSE;
if (gAgent.getAvatarObject())
{
sitting = gAgent.getAvatarObject()->mIsSitting;
- childSetVisible("Stand Up", sitting);
- childSetEnabled("Stand Up", sitting);
-
}
+ button = LLUICtrlFactory::getButtonByName(this, "Stand Up");
- if ( mMusicRemote && gAudiop )
+ if (button && button->getVisible() != sitting)
{
- LLParcel* parcel = gParcelMgr->getAgentParcel();
- if (!parcel
- || parcel->getMusicURL().empty()
- || !gSavedSettings.getBOOL("AudioStreamingMusic"))
- {
- mMusicRemote->setVisible(FALSE);
- mMusicRemote->setEnabled(FALSE);
- }
- else
- {
- mMusicRemote->setVisible(TRUE);
- mMusicRemote->setEnabled(TRUE);
- }
+ button->setVisible(sitting);
+ sendChildToFront(button);
+ moveChildToBackOfTabGroup(button);
+ buttons_changed = TRUE;
}
- // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!)
- if ( mMediaRemote )
- {
- if (LLMediaEngine::getInstance () &&
- LLMediaEngine::getInstance ()->getUrl ().length () &&
- LLMediaEngine::getInstance ()->getImageUUID ().notNull () &&
- LLMediaEngine::getInstance ()->isEnabled () &&
- LLMediaEngine::getInstance ()->isAvailable () &&
- gSavedSettings.getBOOL ( "AudioStreamingVideo" ) )
- {
- // display remote control
- mMediaRemote->setVisible ( TRUE );
- mMediaRemote->setEnabled ( TRUE );
- }
- else
- {
- mMediaRemote->setVisible ( FALSE );
- mMediaRemote->setEnabled ( FALSE );
- }
- }
- if (mVoiceRemote)
- {
- mVoiceRemote->setVisible(LLVoiceClient::voiceEnabled());
- }
-
+ // update "remotes"
+ childSetVisible("voice_remote_container", LLVoiceClient::voiceEnabled());
+ enableMediaButtons();
+
+ moveChildToBackOfTabGroup(mMediaRemote);
+ moveChildToBackOfTabGroup(mVoiceRemote);
+
// turn off the whole bar in mouselook
if (gAgent.cameraMouselook())
{
@@ -407,6 +282,11 @@ void LLOverlayBar::refresh()
{
setVisible(TRUE);
}
+
+ if (buttons_changed)
+ {
+ layoutButtons();
+ }
}
//-----------------------------------------------------------------------
@@ -462,33 +342,25 @@ void LLOverlayBar::mediaPlay(void*)
{
return;
}
- gOverlayBar->mMediaState = PLAYING; // desired state
- LLParcel* parcel = gParcelMgr->getAgentParcel();
- if (parcel)
- {
- LLString path("");
- LLMediaEngine::getInstance()->convertImageAndLoadUrl( true, false, path );
- }
-}
-//static
-void LLOverlayBar::mediaPause(void*)
-{
- if (!gOverlayBar)
+
+ if (gOverlayBar->mMediaState != PLAYING)
{
- return;
+ gOverlayBar->mMediaState = PLAYING; // desired state
+ LLParcel* parcel = gParcelMgr->getAgentParcel();
+ if (parcel)
+ {
+ LLString path("");
+ LLMediaEngine::getInstance()->convertImageAndLoadUrl( true, false, path );
+ }
}
- gOverlayBar->mMediaState = PAUSED; // desired state
- LLMediaEngine::getInstance()->pause();
-}
-//static
-void LLOverlayBar::mediaStop(void*)
-{
- if (!gOverlayBar)
+ else
{
- return;
+ gOverlayBar->mMediaState = PAUSED; // desired state
+ LLMediaEngine::getInstance()->pause();
}
- gOverlayBar->mMediaState = STOPPED; // desired state
- LLMediaEngine::getInstance()->stop();
+
+ //gOverlayBar->mMediaState = STOPPED; // desired state
+ //LLMediaEngine::getInstance()->stop();
}
//static
@@ -498,116 +370,75 @@ void LLOverlayBar::musicPlay(void*)
{
return;
}
- gOverlayBar->mMusicState = PLAYING; // desired state
- if (gAudiop)
+
+ if (gOverlayBar->mMusicState != PLAYING)
{
- LLParcel* parcel = gParcelMgr->getAgentParcel();
- if ( parcel )
+ gOverlayBar->mMusicState = PLAYING; // desired state
+ if (gAudiop)
{
- // this doesn't work properly when crossing parcel boundaries - even when the
- // stream is stopped, it doesn't return the right thing - commenting out for now.
-// if ( gAudiop->isInternetStreamPlaying() == 0 )
+ LLParcel* parcel = gParcelMgr->getAgentParcel();
+ if ( parcel )
{
- gAudiop->startInternetStream(parcel->getMusicURL().c_str());
+ // this doesn't work properly when crossing parcel boundaries - even when the
+ // stream is stopped, it doesn't return the right thing - commenting out for now.
+ // if ( gAudiop->isInternetStreamPlaying() == 0 )
+ {
+ gAudiop->startInternetStream(parcel->getMusicURL().c_str());
+ }
}
}
}
-}
-//static
-void LLOverlayBar::musicPause(void*)
-{
- if (!gOverlayBar)
- {
- return;
- }
- gOverlayBar->mMusicState = PAUSED; // desired state
- if (gAudiop)
- {
- gAudiop->pauseInternetStream(1);
- }
-}
-//static
-void LLOverlayBar::musicStop(void*)
-{
- if (!gOverlayBar)
- {
- return;
- }
- gOverlayBar->mMusicState = STOPPED; // desired state
- if (gAudiop)
+ //else
+ //{
+ // gOverlayBar->mMusicState = PAUSED; // desired state
+ // if (gAudiop)
+ // {
+ // gAudiop->pauseInternetStream(1);
+ // }
+ //}
+ else
{
- gAudiop->stopInternetStream();
+ gOverlayBar->mMusicState = STOPPED; // desired state
+ if (gAudiop)
+ {
+ gAudiop->stopInternetStream();
+ }
}
}
-//static
-void LLOverlayBar::enableMusicButtons(LLPanel* panel)
-{
- BOOL play_enabled = FALSE;
- BOOL play_visible = TRUE;
- BOOL pause_visible = FALSE;
- BOOL stop_enabled = FALSE;
- if ( gAudiop && gOverlayBar && gSavedSettings.getBOOL("AudioStreamingMusic"))
+void LLOverlayBar::enableMediaButtons()
+{
+ if (mMediaRemote)
{
- play_enabled = TRUE;
- S32 is_playing = gAudiop->isInternetStreamPlaying();
- if (is_playing == 1)
+ // Music
+ LLParcel* parcel = gParcelMgr->getAgentParcel();
+ if (parcel
+ && gAudiop
+ && !parcel->getMusicURL().empty()
+ && gSavedSettings.getBOOL("AudioStreamingMusic"))
{
- play_visible = FALSE;
- pause_visible = TRUE;
- stop_enabled = TRUE;
+ mMediaRemote->childSetEnabled("music_play", TRUE);
}
- else if (is_playing == 2)
+ else
{
- play_visible = TRUE;
- pause_visible = FALSE;
- stop_enabled = TRUE;
+ mMediaRemote->childSetEnabled("music_play", FALSE);
}
- }
- panel->childSetEnabled("music_play", play_enabled);
- panel->childSetEnabled("music_pause", play_enabled);
- panel->childSetVisible("music_play", play_visible);
- panel->childSetVisible("music_pause", pause_visible);
- panel->childSetEnabled("music_stop", stop_enabled);
-}
-//static
-void LLOverlayBar::enableMediaButtons(LLPanel* panel)
-{
- // Media
- BOOL play_enabled = FALSE;
- BOOL play_visible = TRUE;
- BOOL pause_visible = FALSE;
- BOOL stop_enabled = FALSE;
-
- if ( LLMediaEngine::getInstance() && gOverlayBar && gSavedSettings.getBOOL("AudioStreamingVideo") )
- {
- play_enabled = TRUE;
- if (LLMediaEngine::getInstance()->getMediaRenderer())
+ // Media
+ // if there is a url and a texture and media is enabled and available and media streaming is on... (phew!)
+ if (LLMediaEngine::getInstance()
+ && LLMediaEngine::getInstance()->getUrl ().length ()
+ && LLMediaEngine::getInstance()->getImageUUID ().notNull ()
+ && LLMediaEngine::getInstance()->isEnabled ()
+ && LLMediaEngine::getInstance()->isAvailable ()
+ && gSavedSettings.getBOOL ( "AudioStreamingVideo" ) )
{
- if ( LLMediaEngine::getInstance()->getMediaRenderer()->isPlaying() ||
- LLMediaEngine::getInstance()->getMediaRenderer()->isLooping() )
- {
- play_visible = FALSE;
- pause_visible = TRUE;
- stop_enabled = TRUE;
- }
- else if ( LLMediaEngine::getInstance()->getMediaRenderer()->isPaused() )
- {
- play_visible = TRUE;
- pause_visible = FALSE;
- stop_enabled = TRUE;
- }
+ mMediaRemote->childSetEnabled("media_play", TRUE);
+ }
+ else
+ {
+ mMediaRemote->childSetEnabled("media_play", FALSE);
}
}
- panel->childSetEnabled("media_play", play_enabled);
- panel->childSetEnabled("media_pause", play_enabled);
- panel->childSetVisible("media_play", play_visible);
- panel->childSetVisible("media_pause", pause_visible);
- panel->childSetEnabled("media_stop", stop_enabled);
}
-void LLOverlayBar::toggleAudioVolumeFloater(void* user_data)
-{
- LLFloaterAudioVolume::toggleInstance(LLSD());
-}
diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h
index 229346340a..18ff07e71b 100644
--- a/indra/newview/lloverlaybar.h
+++ b/indra/newview/lloverlaybar.h
@@ -54,7 +54,7 @@ class LLOverlayBar
: public LLPanel
{
public:
- LLOverlayBar(const std::string& name, const LLRect& rect );
+ LLOverlayBar();
~LLOverlayBar();
virtual EWidgetType getWidgetType() const;
@@ -63,6 +63,7 @@ public:
/*virtual*/ void refresh();
/*virtual*/ void draw();
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
+ /*virtual*/ BOOL postBuild();
void layoutButtons();
@@ -79,27 +80,16 @@ public:
//static media helper functions
static void mediaPlay(void*);
- static void mediaPause(void*);
- static void mediaStop(void*);
-
static void musicPlay(void*);
- static void musicPause(void*);
- static void musicStop(void*);
- static void toggleAudioVolumeFloater(void*);
-
- static void enableMediaButtons(LLPanel* panel);
- static void enableMusicButtons(LLPanel* panel);
-
protected:
- static void* createMasterRemote(void* userdata);
- static void* createMusicRemote(void* userdata);
static void* createMediaRemote(void* userdata);
static void* createVoiceRemote(void* userdata);
+ static void* createChatBar(void* userdata);
+
+ void enableMediaButtons();
protected:
- LLMediaRemoteCtrl* mMasterRemote;
- LLMediaRemoteCtrl* mMusicRemote;
LLMediaRemoteCtrl* mMediaRemote;
LLVoiceRemoteCtrl* mVoiceRemote;
bool mBuilt; // dialog constructed yet?
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index c090fd9749..46af3ec74f 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -1638,7 +1638,7 @@ void LLPanelAvatar::onClickMute(void *userdata)
if (name_edit)
{
std::string agent_name = name_edit->getText();
- gFloaterMute->show();
+ LLFloaterMute::showInstance();
if (gMuteListp->isMuted(agent_id))
{
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 7163a71bc3..7263b11d96 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -189,14 +189,14 @@ BOOL LLPanelClassified::postBuild()
mNameEditor = LLViewerUICtrlFactory::getLineEditorByName(this, "given_name_editor");
mNameEditor->setMaxTextLength(DB_PARCEL_NAME_LEN);
mNameEditor->setCommitOnFocusLost(TRUE);
- mNameEditor->setFocusReceivedCallback(onFocusReceived);
+ mNameEditor->setFocusReceivedCallback(onFocusReceived, this);
mNameEditor->setCommitCallback(onCommitAny);
mNameEditor->setCallbackUserData(this);
mNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII );
mDescEditor = LLUICtrlFactory::getTextEditorByName(this, "desc_editor");
mDescEditor->setCommitOnFocusLost(TRUE);
- mDescEditor->setFocusReceivedCallback(onFocusReceived);
+ mDescEditor->setFocusReceivedCallback(onFocusReceived, this);
mDescEditor->setCommitCallback(onCommitAny);
mDescEditor->setCallbackUserData(this);
mDescEditor->setTabToNextField(TRUE);
@@ -929,10 +929,10 @@ void LLPanelClassified::onCommitAny(LLUICtrl* ctrl, void* data)
}
// static
-void LLPanelClassified::onFocusReceived(LLUICtrl* ctrl, void* data)
+void LLPanelClassified::onFocusReceived(LLFocusableElement* ctrl, void* data)
{
// allow the data to be saved
- onCommitAny(ctrl, data);
+ onCommitAny((LLUICtrl*)ctrl, data);
}
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index a2bb29b224..8884d1a25e 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -111,7 +111,7 @@ protected:
static void onClickProfile(void* data);
static void onClickSet(void* data);
- static void onFocusReceived(LLUICtrl* ctrl, void* data);
+ static void onFocusReceived(LLFocusableElement* ctrl, void* data);
static void onCommitAny(LLUICtrl* ctrl, void* data);
void sendClassifiedClickMessage(const char* type);
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 8dbe72fdfe..8ce2ae5d9c 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -870,7 +870,7 @@ void LLPanelFace::onClickApply(void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
- gFocusMgr.setKeyboardFocus( NULL, NULL );
+ gFocusMgr.setKeyboardFocus( NULL );
//F32 repeats_per_meter = self->mCtrlRepeatsPerMeter->get();
F32 repeats_per_meter = (F32)self->childGetValue( "rptctrl" ).asReal();//self->mCtrlRepeatsPerMeter->get();
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 3ad65b5e68..31688256f5 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -114,8 +114,8 @@ BOOL LLPanelGroupGeneral::postBuild()
if(mEditCharter)
{
mEditCharter->setCommitCallback(onCommitAny);
- mEditCharter->setFocusReceivedCallback(onCommitAny);
- mEditCharter->setFocusChangedCallback(onCommitAny);
+ mEditCharter->setFocusReceivedCallback(onFocusEdit, this);
+ mEditCharter->setFocusChangedCallback(onFocusEdit, this);
mEditCharter->setCallbackUserData(this);
}
@@ -259,6 +259,14 @@ BOOL LLPanelGroupGeneral::postBuild()
}
// static
+void LLPanelGroupGeneral::onFocusEdit(LLFocusableElement* ctrl, void* data)
+{
+ LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
+ self->mChanged = TRUE;
+ self->notifyObservers();
+}
+
+// static
void LLPanelGroupGeneral::onCommitAny(LLUICtrl* ctrl, void* data)
{
LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index e7a27b6c0b..b17a66d0a3 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -66,6 +66,7 @@ public:
virtual void draw();
private:
+ static void onFocusEdit(LLFocusableElement* ctrl, void* data);
static void onCommitAny(LLUICtrl* ctrl, void* data);
static void onCommitUserOnly(LLUICtrl* ctrl, void* data);
static void onCommitTitle(LLUICtrl* ctrl, void* data);
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 0152990798..dbe24d40e0 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -238,7 +238,7 @@ void LLPanelGroupLandMoney::impl::onMapButton()
F32 global_x = 0.f;
F32 global_y = 0.f;
- sscanf(cellp->getText().c_str(), "%f %f", &global_x, &global_y);
+ sscanf(cellp->getValue().asString().c_str(), "%f %f", &global_x, &global_y);
// Hack: Use the agent's z-height
F64 global_z = gAgent.getPositionGlobal().mdV[VZ];
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index ce824cbb6d..a67692afa6 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -790,7 +790,6 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl,
{
row["columns"][column_index]["column"] = "checkbox";
row["columns"][column_index]["type"] = "checkbox";
- row["columns"][column_index]["value"] = (*ra_it)->mName;
check_box_index = column_index;
++column_index;
}
@@ -1058,7 +1057,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
if (mi == gdatap->mMembers.end()) continue;
LLGroupMemberData* member_data = (*mi).second;
// Is the member an owner?
- if ( member_data->isInRole(gdatap->mOwnerRole) )
+ if ( member_data && member_data->isInRole(gdatap->mOwnerRole) )
{
// Can't remove other owners.
cb_enable = FALSE;
@@ -1870,7 +1869,7 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root)
mRoleDescription->setCommitOnFocusLost(TRUE);
mRoleDescription->setCallbackUserData(this);
mRoleDescription->setCommitCallback(onDescriptionCommit);
- mRoleDescription->setFocusReceivedCallback(onDescriptionCommit);
+ mRoleDescription->setFocusReceivedCallback(onDescriptionFocus, this);
setFooterEnabled(FALSE);
@@ -2329,6 +2328,16 @@ void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_dat
}
// static
+void LLPanelGroupRolesSubTab::onDescriptionFocus(LLFocusableElement* ctrl, void* user_data)
+{
+ LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
+ if (!self) return;
+
+ self->mHasRoleChange = TRUE;
+ self->notifyObservers();
+}
+
+// static
void LLPanelGroupRolesSubTab::onDescriptionCommit(LLUICtrl* ctrl, void* user_data)
{
LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data);
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index b0b635eb57..13d64d4edb 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -256,6 +256,7 @@ public:
static void onPropertiesKey(LLLineEditor*, void*);
static void onDescriptionCommit(LLUICtrl*, void*);
+ static void onDescriptionFocus(LLFocusableElement*, void*);
static void onMemberVisibilityChange(LLUICtrl*, void*);
void handleMemberVisibilityChange(bool value);
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index bc297354f7..74936dce0c 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -496,7 +496,7 @@ void LLPanelLogin::show(const LLRect &rect,
void (*callback)(S32 option, void* user_data),
void* callback_data)
{
- new LLPanelLogin(rect, show_server, callback, callback_data);
+ new LLPanelLogin(rect, show_server, callback, callback_data);
LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(sInstance, "login_html");
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index c3d949d3df..2463e62d7f 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -350,7 +350,7 @@ void LLPanelObject::getState( )
//forfeit focus
if (gFocusMgr.childHasKeyboardFocus(this))
{
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
}
// Disable all text input fields
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index c288c6aaed..e7b5e79377 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -171,7 +171,7 @@ void LLPanelVolume::getState( )
//forfeit focus
if (gFocusMgr.childHasKeyboardFocus(this))
{
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
}
// Disable all text input fields
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 9fa364a339..61bda9dfc0 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -1607,7 +1607,7 @@ void LLPreviewGesture::onClickAdd(void* data)
if (!library_item) return;
const LLScrollListCell* library_cell = library_item->getColumn(0);
- const std::string& library_text = library_cell->getText();
+ const std::string& library_text = library_cell->getValue().asString();
self->addStep(library_text);
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 6c377009f2..06286927d4 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -960,7 +960,7 @@ void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data)
S32 row = 0;
S32 column = 0;
const LLScrollListCell* cell = item->getColumn(0);
- LLString line(cell->getText());
+ LLString line(cell->getValue().asString());
line.erase(0, 1);
LLString::replaceChar(line, ',',' ');
LLString::replaceChar(line, ')',' ');
diff --git a/indra/newview/llpreviewsound.cpp b/indra/newview/llpreviewsound.cpp
index fae04871be..b92a6d58c8 100644
--- a/indra/newview/llpreviewsound.cpp
+++ b/indra/newview/llpreviewsound.cpp
@@ -106,7 +106,7 @@ void LLPreviewSound::auditionSound( void *userdata )
if(item && gAudiop)
{
LLVector3d lpos_global = gAgent.getPositionGlobal();
- F32 volume = SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX");
gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), volume, lpos_global);
}
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index f12f5763ef..b0b9fd33d1 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2304,7 +2304,7 @@ BOOL idle_startup()
audio_update_volume();
// reset keyboard focus to sane state of pointing at world
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
#if 0 // sjb: enable for auto-enabling timer display
gDebugView->mFastTimerView->setVisible(TRUE);
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 4d49d33184..8c4fc833db 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -100,7 +100,6 @@ const LLColor4 SIM_WARN_COLOR(1.f, 1.f, 0.f, 1.f);
const LLColor4 SIM_FULL_COLOR(1.f, 0.f, 0.f, 1.f);
const F32 ICON_TIMER_EXPIRY = 3.f; // How long the balance and health icons should flash after a change.
const F32 ICON_FLASH_FREQUENCY = 2.f;
-const S32 GRAPHIC_FUDGE = 4;
const S32 TEXT_HEIGHT = 18;
static void onClickParcelInfo(void*);
@@ -153,13 +152,13 @@ LLStatusBar::LLStatusBar(const std::string& name, const LLRect& rect)
childSetAction("scriptout", onClickScriptDebug, this);
childSetAction("health", onClickHealth, this);
- childSetAction("fly", onClickFly, this);
+ childSetAction("no_fly", onClickFly, this);
childSetAction("buyland", onClickBuyLand, this );
childSetAction("buycurrency", onClickBuyCurrency, this );
- childSetAction("build", onClickBuild, this );
- childSetAction("scripts", onClickScripts, this );
+ childSetAction("no_build", onClickBuild, this );
+ childSetAction("no_scripts", onClickScripts, this );
childSetAction("restrictpush", onClickPush, this );
- childSetAction("status_voice", onClickVoice, this );
+ childSetAction("status_no_voice", onClickVoice, this );
childSetCommitCallback("search_editor", onCommitSearch, this);
childSetAction("search_btn", onClickSearch, this);
@@ -304,7 +303,7 @@ void LLStatusBar::refresh()
// Health
childGetRect( "health", buttonRect );
- r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
+ r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
childSetRect("health", r);
x += buttonRect.getWidth();
@@ -324,27 +323,32 @@ void LLStatusBar::refresh()
(parcel && !parcel->getAllowFly()) )
{
// No Fly Zone
- childGetRect( "fly", buttonRect );
- childSetVisible( "fly", true );
- r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "fly", r );
+ childGetRect( "no_fly", buttonRect );
+ childSetVisible( "no_fly", true );
+ r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
+ childSetRect( "no_fly", r );
x += buttonRect.getWidth();
}
else
{
- childSetVisible("fly", false);
+ // Fly Zone
+ childSetVisible("no_fly", false);
}
BOOL no_build = parcel && !parcel->getAllowModify();
- childSetVisible("build", no_build);
if (no_build)
{
- childGetRect( "build", buttonRect );
+ childSetVisible("no_build", TRUE);
+ childGetRect( "no_build", buttonRect );
// No Build Zone
- r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "build", r );
+ r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
+ childSetRect( "no_build", r );
x += buttonRect.getWidth();
}
+ else
+ {
+ childSetVisible("no_build", FALSE);
+ }
BOOL no_scripts = FALSE;
if((region
@@ -354,35 +358,56 @@ void LLStatusBar::refresh()
{
no_scripts = TRUE;
}
- childSetVisible("scripts", no_scripts);
if (no_scripts)
{
// No scripts
- childGetRect( "scripts", buttonRect );
- r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "scripts", r );
+ childSetVisible("no_scripts", TRUE);
+ childGetRect( "no_scripts", buttonRect );
+ r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
+ childSetRect( "no_scripts", r );
x += buttonRect.getWidth();
}
+ else
+ {
+ // Yes scripts
+ childSetVisible("no_scripts", FALSE);
+ }
BOOL no_region_push = (region && region->getRestrictPushObject());
BOOL no_push = no_region_push || (parcel && parcel->getRestrictPushObject());
- childSetVisible("restrictpush", no_push);
if (no_push)
{
+ childSetVisible("restrictpush", TRUE);
childGetRect( "restrictpush", buttonRect );
- r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
+ r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
childSetRect( "restrictpush", r );
x += buttonRect.getWidth();
}
+ else
+ {
+ childSetVisible("restrictpush", FALSE);
+ }
+ BOOL voice_enabled = gVoiceClient->voiceEnabled();
BOOL have_voice = parcel && parcel->getVoiceEnabled();
- childSetVisible("status_voice", have_voice);
- if (have_voice)
+ if (!voice_enabled)
{
- childGetRect( "status_voice", buttonRect );
- r.setOriginAndSize( x, y-GRAPHIC_FUDGE, buttonRect.getWidth(), buttonRect.getHeight());
- childSetRect( "status_voice", r );
- x += buttonRect.getWidth();
+ childSetVisible("status_no_voice", FALSE);
+ }
+ else
+ {
+ if (have_voice)
+ {
+ childSetVisible("status_no_voice", FALSE);
+ }
+ else if (!have_voice)
+ {
+ childSetVisible("status_no_voice", TRUE);
+ childGetRect( "status_no_voice", buttonRect );
+ r.setOriginAndSize( x, y, buttonRect.getWidth(), buttonRect.getHeight());
+ childSetRect( "status_no_voice", r );
+ x += buttonRect.getWidth();
+ }
}
BOOL canBuyLand = parcel
@@ -512,7 +537,7 @@ void LLStatusBar::refresh()
mTextParcelName->setText(location_name);
// Adjust region name and parcel name
- x += 4;
+ x += 8;
const S32 PARCEL_RIGHT = llmin(mTextTime->getRect().mLeft, mTextParcelName->getTextPixelWidth() + x + 5);
r.set(x+4, mRect.getHeight() - 2, PARCEL_RIGHT, 0);
@@ -672,8 +697,7 @@ static void onClickPush(void* )
static void onClickVoice(void* )
{
- LLNotifyBox::showXml("VoiceAvailablity");
- //LLFirstUse::useVoice();
+ LLNotifyBox::showXml("NoVoice");
}
static void onClickBuild(void*)
@@ -708,7 +732,7 @@ static void onClickBuyLand(void*)
void LLStatusBar::setupDate()
{
// fill the day array with what's in the xui
- LLString day_list = childGetText("StatBarDaysOfWeek");
+ LLString day_list = getFormattedUIString("StatBarDaysOfWeek");
size_t length = day_list.size();
// quick input check
@@ -732,7 +756,7 @@ void LLStatusBar::setupDate()
}
// fill the day array with what's in the xui
- LLString month_list = childGetText( "StatBarMonthsOfYear" );
+ LLString month_list = getFormattedUIString( "StatBarMonthsOfYear" );
length = month_list.size();
// quick input check
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 06a4ea097f..465a40c1ef 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -373,7 +373,6 @@ public:
{
S32 line_height = (S32)(LLFontGL::sMonospace->getLineHeight() + .5f);
setRect(LLRect(0,0,100,line_height * 4));
- updateRect();
}
virtual EWidgetType getWidgetType() const { return WIDGET_TYPE_TEX_MEM_BAR; };
diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
index e7a5445ef6..c80edd0eab 100644
--- a/indra/newview/lltoolbar.cpp
+++ b/indra/newview/lltoolbar.cpp
@@ -60,6 +60,11 @@
#include "llvieweruictrlfactory.h"
#include "llviewerwindow.h"
#include "lltoolgrab.h"
+#include "llcombobox.h"
+#include "llfloaterchat.h"
+#include "llfloatermute.h"
+#include "llimpanel.h"
+#include "llscrolllistctrl.h"
#if LL_DARWIN
@@ -100,24 +105,20 @@ F32 LLToolBar::sInventoryAutoOpenTime = 1.f;
// Functions
//
-LLToolBar::LLToolBar(const std::string& name, const LLRect& r)
-: LLPanel(name, r, BORDER_NO)
+LLToolBar::LLToolBar()
+: LLPanel()
#if LL_DARWIN
, mResizeHandle(NULL)
#endif // LL_DARWIN
{
setIsChrome(TRUE);
- setFollows( FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
-
- gUICtrlFactory->buildPanel(this, "panel_toolbar.xml");
- mIsFocusRoot = TRUE;
-
+ setFocusRoot(TRUE);
}
BOOL LLToolBar::postBuild()
{
- childSetAction("communicate_btn", onClickCommunicate, this);
+ childSetCommitCallback("communicate_btn", onClickCommunicate, this);
childSetControlName("communicate_btn", "ShowCommunicate");
childSetAction("chat_btn", onClickChat, this);
@@ -270,29 +271,47 @@ void LLToolBar::layoutButtons()
}
#endif // LL_DARWIN
+ LLButton* chat_button = LLUICtrlFactory::getButtonByName(this, "chat_btn");
+ if (chat_button)
+ {
+ width -= chat_button->getRect().getWidth() + pad;
+ }
+
// We actually want to extend "pad" pixels off the right edge of the
// screen, such that the rightmost button is aligned.
- F32 segment_width = (F32)(width + pad) / (F32)count;
- S32 btn_width = lltrunc(segment_width - pad);
+ S32 segment_width = llround((F32)(width) / ((F32)count - 1.f));
+ S32 btn_width = segment_width - pad;
// Evenly space all views
S32 height = -1;
S32 i = count - 1;
- for (child_list_const_iter_t child_iter = getChildList()->begin();
- child_iter != getChildList()->end(); ++child_iter)
+ S32 x = pad;
+ for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
+ child_iter != getChildList()->rend(); ++child_iter)
{
LLView *btn_view = *child_iter;
- if(btn_view->getWidgetType() == WIDGET_TYPE_BUTTON)
+ if(btn_view->getWidgetType() == WIDGET_TYPE_BUTTON || btn_view->getWidgetType() == WIDGET_TYPE_FLYOUT_BUTTON)
{
if (height < 0)
{
height = btn_view->getRect().getHeight();
}
- S32 x = llround(i*segment_width);
- S32 y = 0;
- LLRect r;
- r.setOriginAndSize(x, y, btn_width, height);
- btn_view->setRect(r);
+
+ LLRect r;
+
+ if (btn_view->getName() == "chat_btn")
+ {
+ r.setOriginAndSize(x, 0, btn_view->getRect().getWidth(), height);
+ x += btn_view->getRect().getWidth() + pad;
+ }
+ else
+ {
+ r.setOriginAndSize(x, 0, btn_width, height);
+ x += segment_width;
+ }
+
+ btn_view->setOrigin(r.mLeft, r.mBottom);
+ btn_view->reshape(r.getWidth(), r.getHeight());
i--;
}
}
@@ -321,6 +340,7 @@ void LLToolBar::refresh()
childSetEnabled("build_btn", gParcelMgr->agentCanBuild() );
+
// Check to see if we're in build mode
BOOL build_mode = gToolMgr->inEdit();
// And not just clicking on a scripted object
@@ -329,13 +349,135 @@ void LLToolBar::refresh()
build_mode = FALSE;
}
gSavedSettings.setBOOL("BuildBtnState", build_mode);
+
+ updateCommunicateList();
+}
+
+void LLToolBar::updateCommunicateList()
+{
+ LLFlyoutButton* communicate_button = (LLFlyoutButton*)getChildByName("communicate_btn", TRUE);
+ if (communicate_button)
+ {
+ LLSD selected = communicate_button->getValue();
+
+ communicate_button->removeall();
+
+ LLFloater* frontmost_floater = LLFloaterChatterBox::getInstance()->getActiveFloater();
+ LLScrollListItem* itemp = NULL;
+
+ itemp = communicate_button->add(LLFloaterMyFriends::getInstance()->getShortTitle(), LLSD("contacts"), ADD_TOP);
+ if (LLFloaterMyFriends::getInstance() == frontmost_floater)
+ {
+ ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ // make sure current tab is selected in list
+ if (selected.isUndefined())
+ {
+ selected = itemp->getValue();
+ }
+ }
+ itemp = communicate_button->add(LLFloaterChat::getInstance()->getShortTitle(), LLSD("local chat"), ADD_TOP);
+ if (LLFloaterChat::getInstance() == frontmost_floater)
+ {
+ ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ if (selected.isUndefined())
+ {
+ selected = itemp->getValue();
+ }
+ }
+ communicate_button->addSeparator(ADD_TOP);
+ communicate_button->add(getUIString("Redock Windows"), LLSD("redock"), ADD_TOP);
+ communicate_button->addSeparator(ADD_TOP);
+ communicate_button->add(LLFloaterMute::getInstance()->getShortTitle(), LLSD("mute list"), ADD_TOP);
+
+ std::set<LLViewHandle>::const_iterator floater_handle_it;
+
+ if (gIMMgr->getIMFloaterHandles().size() > 0)
+ {
+ communicate_button->addSeparator(ADD_TOP);
+ }
+
+ for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it)
+ {
+ LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)LLFloater::getFloaterByHandle(*floater_handle_it);
+ if (im_floaterp)
+ {
+ LLString floater_title = im_floaterp->getNumUnreadMessages() > 0 ? "*" : "";
+ floater_title.append(im_floaterp->getShortTitle());
+ itemp = communicate_button->add(floater_title, im_floaterp->getSessionID(), ADD_TOP);
+ if (im_floaterp == frontmost_floater)
+ {
+ ((LLScrollListText*)itemp->getColumn(0))->setFontStyle(LLFontGL::BOLD);
+ if (selected.isUndefined())
+ {
+ selected = itemp->getValue();
+ }
+ }
+ }
+ }
+
+ communicate_button->setToggleState(gSavedSettings.getBOOL("ShowCommunicate"));
+ communicate_button->setValue(selected);
+ }
}
// static
-void LLToolBar::onClickCommunicate(void* user_data)
+void LLToolBar::onClickCommunicate(LLUICtrl* ctrl, void* user_data)
{
- LLFloaterChatterBox::toggleInstance(LLSD());
+ LLToolBar* toolbar = (LLToolBar*)user_data;
+ LLFlyoutButton* communicate_button = (LLFlyoutButton*)toolbar->getChildByName("communicate_btn", TRUE);
+
+ LLSD selected_option = communicate_button->getValue();
+
+ if (selected_option.asString() == "contacts")
+ {
+ LLFloaterMyFriends::showInstance();
+ }
+ else if (selected_option.asString() == "local chat")
+ {
+ LLFloaterChat::showInstance();
+ }
+ else if (selected_option.asString() == "redock")
+ {
+ LLFloaterChatterBox::getInstance()->addFloater(LLFloaterMyFriends::getInstance(), FALSE);
+ LLFloaterChatterBox::getInstance()->addFloater(LLFloaterChat::getInstance(), FALSE);
+ LLUUID session_to_show;
+
+ std::set<LLViewHandle>::const_iterator floater_handle_it;
+ for(floater_handle_it = gIMMgr->getIMFloaterHandles().begin(); floater_handle_it != gIMMgr->getIMFloaterHandles().end(); ++floater_handle_it)
+ {
+ LLFloater* im_floaterp = LLFloater::getFloaterByHandle(*floater_handle_it);
+ if (im_floaterp)
+ {
+ if (im_floaterp->isFrontmost())
+ {
+ session_to_show = ((LLFloaterIMPanel*)im_floaterp)->getSessionID();
+ }
+ LLFloaterChatterBox::getInstance()->addFloater(im_floaterp, FALSE);
+ }
+ }
+
+ LLFloaterChatterBox::showInstance(session_to_show);
+ }
+ else if (selected_option.asString() == "mute list")
+ {
+ LLFloaterMute::showInstance();
+ }
+ else if (selected_option.isUndefined()) // user just clicked the communicate button, treat as toggle
+ {
+ if (LLFloaterChatterBox::getInstance()->getFloaterCount() == 0)
+ {
+ LLFloaterMyFriends::toggleInstance();
+ }
+ else
+ {
+ LLFloaterChatterBox::toggleInstance();
+ }
+ }
+ else // otherwise selection_option is a specific IM session id
+ {
+ LLFloaterChatterBox::showInstance(selected_option);
+ }
}
diff --git a/indra/newview/lltoolbar.h b/indra/newview/lltoolbar.h
index c43c80b095..85adba8c55 100644
--- a/indra/newview/lltoolbar.h
+++ b/indra/newview/lltoolbar.h
@@ -47,7 +47,7 @@ class LLToolBar
: public LLPanel
{
public:
- LLToolBar(const std::string& name, const LLRect& rect );
+ LLToolBar();
~LLToolBar();
/*virtual*/ BOOL postBuild();
@@ -70,7 +70,7 @@ public:
void refresh();
// callbacks
- static void onClickCommunicate(void*);
+ static void onClickCommunicate(LLUICtrl*, void*);
static void onClickChat(void* data);
static void onClickAppearance(void* data);
static void onClickClothing(void* data);
@@ -86,8 +86,13 @@ public:
static F32 sInventoryAutoOpenTime;
private:
+ void updateCommunicateList();
+
+
+private:
BOOL mInventoryAutoOpen;
LLFrameTimer mInventoryAutoOpenTimer;
+ S32 mNumUnreadIMs;
#if LL_DARWIN
LLFakeResizeHandle *mResizeHandle;
#endif // LL_DARWIN
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index d26bdab921..a27053faa3 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -216,7 +216,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
// Play creation sound
if (gAudiop)
{
- F32 volume = gSavedSettings.getF32("AudioLevelUI");
+ F32 volume = gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI");
gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), volume);
}
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index ac90a06a57..8e742bd655 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -122,8 +122,10 @@ void audio_update_volume(bool force_update)
if (gAudiop)
{
F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
+ BOOL music_muted = gSavedSettings.getBOOL("MuteMusic");
music_volume = mute_volume * master_volume * (music_volume*music_volume);
- gAudiop->setInternetStreamGain ( music_volume );
+ gAudiop->setInternetStreamGain ( music_muted ? 0.f : music_volume );
+
}
// Streaming Media
@@ -131,7 +133,8 @@ void audio_update_volume(bool force_update)
{
F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
media_volume = mute_volume * master_volume * (media_volume*media_volume);
- LLMediaEngine::getInstance()->setVolume(media_volume);
+ BOOL media_muted = gSavedSettings.getBOOL("MuteMedia");
+ LLMediaEngine::getInstance()->setVolume(media_muted ? 0.f : media_volume);
}
// Voice
@@ -139,8 +142,9 @@ void audio_update_volume(bool force_update)
{
F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
voice_volume = mute_volume * master_volume * voice_volume;
- gVoiceClient->setVoiceVolume(voice_volume);
- gVoiceClient->setMicGain(gSavedSettings.getF32("AudioLevelMic"));
+ BOOL voice_mute = gSavedSettings.getBOOL("MuteVoice");
+ gVoiceClient->setVoiceVolume(voice_mute ? 0.f : voice_volume);
+ gVoiceClient->setMicGain(voice_mute ? 0.f : gSavedSettings.getF32("AudioLevelMic"));
if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
{
@@ -206,7 +210,7 @@ void audio_update_wind(bool force_update)
// don't use the setter setMaxWindGain() because we don't
// want to screw up the fade-in on startup by setting actual source gain
// outside the fade-in.
- gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelAmbient");
+ gAudiop->mMaxWindGain = gSavedSettings.getBOOL("MuteAmbient") ? 0.f : gSavedSettings.getF32("AudioLevelAmbient");
last_camera_water_height = camera_water_height;
gAudiop->updateWind(gRelativeWindVec, camera_water_height);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 2fccdcd153..fdc0047f95 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -2103,7 +2103,7 @@ class LLObjectMute : public view_listener_t
else
{
gMuteListp->add(mute);
- gFloaterMute->show();
+ LLFloaterMute::showInstance();
}
return true;
@@ -5309,7 +5309,7 @@ class LLShowFloater : public view_listener_t
}
else if (floater_name == "mute list")
{
- LLFloaterMute::toggle(NULL);
+ LLFloaterMute::toggleInstance();
}
else if (floater_name == "camera controls")
{
@@ -5355,7 +5355,7 @@ class LLShowFloater : public view_listener_t
}
else if (floater_name == "about region")
{
- LLFloaterRegionInfo::show((void *)NULL);
+ LLFloaterRegionInfo::showInstance();
}
else if (floater_name == "grid options")
{
@@ -5447,7 +5447,7 @@ class LLFloaterVisible : public view_listener_t
}
else if (floater_name == "mute list")
{
- new_value = LLFloaterMute::visible(NULL);
+ new_value = LLFloaterMute::instanceVisible();
}
else if (floater_name == "camera controls")
{
@@ -6963,13 +6963,12 @@ void handle_grab_texture(void* data)
if(view)
{
LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO);
view->getPanel()->openSelected();
//LLInventoryView::dumpSelectionInformation((void*)view);
// restore keyboard focus
- gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
+ gFocusMgr.setKeyboardFocus(focus_ctrl);
}
}
else
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ebb0da016f..8a4cd16c08 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -888,10 +888,8 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
//highlight item
LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
- LLFocusMgr::FocusLostCallback callback;
- callback = gFocusMgr.getFocusCallback();
view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO);
- gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
+ gFocusMgr.setKeyboardFocus(focus_ctrl);
}
}
@@ -920,7 +918,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
LLMute mute(blocked_id, from_name, type);
if (gMuteListp->add(mute))
{
- gFloaterMute->show();
+ LLFloaterMute::showInstance();
gFloaterMute->selectMute(blocked_id);
}
@@ -2192,9 +2190,13 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
BOOL is_linden = FALSE;
if (gMuteListp)
{
- is_muted = gMuteListp->isMuted(from_id, from_name, LLMute::flagTextChat)
- || gMuteListp->isMuted(owner_id, LLMute::flagTextChat);
- is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && gMuteListp->isLinden(from_name);
+ is_muted = gMuteListp->isMuted(
+ from_id,
+ from_name,
+ LLMute::flagTextChat)
+ || gMuteListp->isMuted(owner_id, LLMute::flagTextChat);
+ is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
+ gMuteListp->isLinden(from_name);
}
BOOL is_audible = (CHAT_AUDIBLE_FULLY == chat.mAudible);
@@ -2235,7 +2237,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
BOOL visible_in_chat_bubble = FALSE;
std::string verb;
- color.setVec(1,1,1,1);
+ color.setVec(1.f,1.f,1.f,1.f);
msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, DB_CHAT_MSG_BUF_SIZE, mesg);
BOOL ircstyle = FALSE;
@@ -3332,7 +3334,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
return;
}
- F32 volume = gain * gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (gain * gSavedSettings.getF32("AudioLevelSFX"));
gAudiop->triggerSound(sound_id, owner_id, volume, pos_global);
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 4c6f27944f..9243263794 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2717,7 +2717,7 @@ BOOL LLViewerObject::updateLOD()
// Update volume of looping sounds
if (mAudioSourcep && mAudioSourcep->isLoop())
{
- F32 volume = mAudioGain * gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (mAudioGain * gSavedSettings.getF32("AudioLevelSFX"));
mAudioSourcep->setGain(volume);
}
return FALSE;
@@ -4228,7 +4228,7 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow
{
BOOL queue = flags & LL_SOUND_FLAG_QUEUE;
mAudioGain = gain;
- F32 volume = gain * gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : gain * gSavedSettings.getF32("AudioLevelSFX");
mAudioSourcep->setGain(volume);
mAudioSourcep->setLoop(flags & LL_SOUND_FLAG_LOOP);
mAudioSourcep->setSyncMaster(flags & LL_SOUND_FLAG_SYNC_MASTER);
@@ -4267,7 +4267,7 @@ void LLViewerObject::adjustAudioGain(const F32 gain)
if (mAudioSourcep)
{
mAudioGain = gain;
- F32 volume = mAudioGain * gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : mAudioGain * gSavedSettings.getF32("AudioLevelSFX");
mAudioSourcep->setGain(volume);
}
}
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index b0d1d3daca..0ffa37525f 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -266,23 +266,6 @@ void LLViewerParcelMgr::getDisplayInfo(S32* area_out, S32* claim_out,
*dwell_out = dwell;
}
-void LLViewerParcelMgr::getPrimInfo(S32 &sw_max, S32 &sw_total, S32 &max, S32 &total, S32 &owner, S32 &group, S32 &other, S32& selected, F32 &parcel_object_bonus, S32 &other_clean)
-{
- if (mSelected && mCurrentParcel)
- {
- sw_max = mCurrentParcel->getSimWideMaxPrimCapacity();
- sw_total = mCurrentParcel->getSimWidePrimCount();
- max = llround(mCurrentParcel->getMaxPrimCapacity()*mCurrentParcel->getParcelPrimBonus());
- total = mCurrentParcel->getPrimCount();
- owner = mCurrentParcel->getOwnerPrimCount();
- group = mCurrentParcel->getGroupPrimCount();
- other = mCurrentParcel->getOtherPrimCount();
- selected = mCurrentParcel->getSelectedPrimCount();
- parcel_object_bonus = mCurrentParcel->getParcelPrimBonus();
- other_clean = mCurrentParcel->getCleanOtherTime();
- }
-}
-
S32 LLViewerParcelMgr::getSelectedArea() const
{
S32 rv = 0;
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 2dd4f28169..640c8c5c57 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -134,8 +134,6 @@ public:
void getDisplayInfo(S32* area, S32* claim, S32* rent, BOOL* for_sale, F32* dwell);
- void getPrimInfo(S32 &sw_max, S32 &sw_total, S32 &max, S32 &total, S32 &owner, S32 &group, S32 &other, S32& selected, F32 &parcel_object_bonus, S32 &other_clean);
-
// Returns selected area
S32 getSelectedArea() const;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ad4b6fd616..6001cd3e58 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -366,6 +366,11 @@ F32 LLViewerRegion::getWaterHeight() const
return mLandp->getWaterHeight();
}
+BOOL LLViewerRegion::isVoiceEnabled() const
+{
+ return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
+}
+
void LLViewerRegion::setRegionFlags(U32 flags)
{
mRegionFlags = flags;
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index a0953e561e..e42c0015df 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -109,6 +109,8 @@ public:
void setWaterHeight(F32 water_level);
F32 getWaterHeight() const;
+ BOOL isVoiceEnabled() const;
+
void setBillableFactor(F32 billable_factor) { mBillableFactor = billable_factor; }
F32 getBillableFactor() const { return mBillableFactor; }
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 81de1eb9a8..18f07efb44 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -605,54 +605,50 @@ void LLViewerTextEditor::makePristine()
BOOL LLViewerTextEditor::handleToolTip(S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen)
{
- if (pointInView(x, y) && getVisible())
+ for (child_list_const_iter_t child_iter = getChildList()->begin();
+ child_iter != getChildList()->end(); ++child_iter)
{
- for (child_list_const_iter_t child_iter = getChildList()->begin();
- child_iter != getChildList()->end(); ++child_iter)
+ LLView *viewp = *child_iter;
+ S32 local_x = x - viewp->getRect().mLeft;
+ S32 local_y = y - viewp->getRect().mBottom;
+ if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) )
{
- LLView *viewp = *child_iter;
- S32 local_x = x - viewp->getRect().mLeft;
- S32 local_y = y - viewp->getRect().mBottom;
- if( viewp->handleToolTip(local_x, local_y, msg, sticky_rect_screen ) )
- {
- return TRUE;
- }
+ return TRUE;
}
+ }
+
+ if( mSegments.empty() )
+ {
+ return TRUE;
+ }
- if( mSegments.empty() )
+ LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
+ if( cur_segment )
+ {
+ BOOL has_tool_tip = FALSE;
+ if( cur_segment->getStyle().getIsEmbeddedItem() )
{
- return TRUE;
+ LLWString wtip;
+ has_tool_tip = getEmbeddedItemToolTipAtPos(cur_segment->getStart(), wtip);
+ msg = wstring_to_utf8str(wtip);
}
-
- LLTextSegment* cur_segment = getSegmentAtLocalPos( x, y );
- if( cur_segment )
+ else
{
- BOOL has_tool_tip = FALSE;
- if( cur_segment->getStyle().getIsEmbeddedItem() )
- {
- LLWString wtip;
- has_tool_tip = getEmbeddedItemToolTipAtPos(cur_segment->getStart(), wtip);
- msg = wstring_to_utf8str(wtip);
- }
- else
- {
- has_tool_tip = cur_segment->getToolTip( msg );
- }
- if( has_tool_tip )
- {
- // Just use a slop area around the cursor
- // Convert rect local to screen coordinates
- S32 SLOP = 8;
- localPointToScreen(
- x - SLOP, y - SLOP,
- &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
- sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
- sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
- }
+ has_tool_tip = cur_segment->getToolTip( msg );
+ }
+ if( has_tool_tip )
+ {
+ // Just use a slop area around the cursor
+ // Convert rect local to screen coordinates
+ S32 SLOP = 8;
+ localPointToScreen(
+ x - SLOP, y - SLOP,
+ &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
+ sticky_rect_screen->mRight = sticky_rect_screen->mLeft + 2 * SLOP;
+ sticky_rect_screen->mTop = sticky_rect_screen->mBottom + 2 * SLOP;
}
- return TRUE;
}
- return FALSE;
+ return TRUE;
}
BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -759,9 +755,9 @@ BOOL LLViewerTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
handled = TRUE;
}
- if (mTakesFocus)
+ if (hasTabStop())
{
- setFocus( TRUE );
+ setFocus(TRUE);
handled = TRUE;
}
@@ -1016,11 +1012,7 @@ BOOL LLViewerTextEditor::handleDoubleClick(S32 x, S32 y, MASK mask)
}
}
- if (mTakesFocus)
- {
- setFocus( TRUE );
- }
-
+
setCursorAtLocalPos( x, y, FALSE );
deselect();
@@ -1390,7 +1382,7 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item )
const F32 SOUND_GAIN = 1.0f;
if(gAudiop)
{
- F32 volume = SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX"));
gAudiop->triggerSound(item->getAssetUUID(), gAgentID, volume, lpos_global);
}
showCopyToInvDialog( item );
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index a3611b2272..4c96083337 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -266,6 +266,8 @@ const S32 PICK_DIAMETER = 2 * PICK_HALF_WIDTH+1;
const F32 MIN_DISPLAY_SCALE = 0.85f;
+const S32 CONSOLE_BOTTOM_PAD = 20;
+
#ifdef SABINRIG
/// ALL RIG STUFF
bool rigControl = false;
@@ -663,18 +665,17 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
// Topmost view gets a chance before the hierarchy
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- BOOL mouse_over_top_ctrl = FALSE;
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
- mouse_over_top_ctrl = TRUE;
- if(top_ctrl->handleMouseDown(local_x, local_y, mask))
- {
- return TRUE;
- }
+ return top_ctrl->handleMouseDown(local_x, local_y, mask);
+ }
+ else
+ {
+ setTopCtrl(NULL);
}
}
@@ -686,11 +687,6 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
LLView::sMouseHandlerMessage = "";
}
- if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
return TRUE;
}
else if (LLView::sDebugMouseHandling)
@@ -698,12 +694,6 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
llinfos << "Left Mouse Down not handled by view" << llendl;
}
- if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
-
if (gDisconnected)
{
return FALSE;
@@ -716,7 +706,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask
// This is necessary to force clicks in the world to cause edit
// boxes that might have keyboard focus to relinquish it, and hence
// cause a commit to update their value. JC
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
return TRUE;
}
}
@@ -760,18 +750,17 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
// Check for hit on UI.
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- BOOL mouse_over_top_ctrl = FALSE;
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
- mouse_over_top_ctrl = TRUE;
- if(top_ctrl->handleDoubleClick(local_x, local_y, mask))
- {
- return TRUE;
- }
+ return top_ctrl->handleDoubleClick(local_x, local_y, mask);
+ }
+ else
+ {
+ setTopCtrl(NULL);
}
}
@@ -782,11 +771,6 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
llinfos << "Left Mouse Down" << LLView::sMouseHandlerMessage << llendl;
LLView::sMouseHandlerMessage = "";
}
- if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
return TRUE;
}
else if (LLView::sDebugMouseHandling)
@@ -794,12 +778,6 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma
llinfos << "Left Mouse Down not handled by view" << llendl;
}
- if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
-
// Why is this here? JC 9/3/2002
if (gNoRender)
{
@@ -970,18 +948,17 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
}
LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
- BOOL mouse_over_top_ctrl = FALSE;
if (top_ctrl)
{
S32 local_x, local_y;
top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
if (top_ctrl->pointInView(local_x, local_y))
{
- mouse_over_top_ctrl = TRUE;
- if(top_ctrl->handleRightMouseDown(local_x, local_y, mask))
- {
- return TRUE;
- }
+ return top_ctrl->handleRightMouseDown(local_x, local_y, mask);
+ }
+ else
+ {
+ setTopCtrl(NULL);
}
}
@@ -992,11 +969,6 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
llinfos << "Right Mouse Down" << LLView::sMouseHandlerMessage << llendl;
LLView::sMouseHandlerMessage = "";
}
- if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
return TRUE;
}
else if (LLView::sDebugMouseHandling)
@@ -1004,12 +976,6 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
llinfos << "Right Mouse Down not handled by view" << llendl;
}
- if (top_ctrl && top_ctrl->hasFocus() && !mouse_over_top_ctrl)
- {
- // always defocus top view if we click off of it
- top_ctrl->setFocus(FALSE);
- }
-
if (gToolMgr)
{
if(gToolMgr->getCurrentTool()->handleRightMouseDown( x, y, mask ) )
@@ -1017,7 +983,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK
// This is necessary to force clicks in the world to cause edit
// boxes that might have keyboard focus to relinquish it, and hence
// cause a commit to update their value. JC
- gFocusMgr.setKeyboardFocus(NULL, NULL);
+ gFocusMgr.setKeyboardFocus(NULL);
return TRUE;
}
}
@@ -1266,7 +1232,7 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
// JC - Leave keyboard focus, so if you're popping in and out editing
// a script, you don't have to click in the editor again and again.
- // gFocusMgr.setKeyboardFocus( NULL, NULL );
+ // gFocusMgr.setKeyboardFocus( NULL );
gShowTextEditCursor = FALSE;
// If losing focus while keys are down, reset them.
@@ -1746,14 +1712,6 @@ void LLViewerWindow::initBase()
gDebugView->setVisible(TRUE);
mRootView->addChild(gDebugView);
- // HUD elements just below floaters
- LLRect hud_rect = full_window;
- hud_rect.mTop -= 24;
- hud_rect.mBottom += STATUS_BAR_HEIGHT;
- gHUDView = new LLHUDView("hud_view", hud_rect);
- gHUDView->setFollowsAll();
- mRootView->addChild(gHUDView);
-
// Add floater view at the end so it will be on top, and give it tab priority over others
mRootView->addChild(gFloaterView, -1);
mRootView->addChild(gSnapshotFloaterView);
@@ -1871,27 +1829,10 @@ void LLViewerWindow::initWorldUI()
S32 width = mRootView->getRect().getWidth();
LLRect full_window(0, height, width, 0);
- if ( gToolBar == NULL ) // Don't re-enter if objects are alreay created
+ if ( gBottomPanel == NULL ) // Don't re-enter if objects are alreay created
{
- LLRect bar_rect(-1, STATUS_BAR_HEIGHT, width+1, -1);
- gToolBar = new LLToolBar("toolbar", bar_rect);
-
- LLRect chat_bar_rect(-1,CHAT_BAR_HEIGHT, width+1, -1);
- chat_bar_rect.translate(0, STATUS_BAR_HEIGHT-1);
- gChatBar = new LLChatBar("chat", chat_bar_rect);
-
- bar_rect.translate(0, STATUS_BAR_HEIGHT-1);
- bar_rect.translate(0, CHAT_BAR_HEIGHT-1);
- gOverlayBar = new LLOverlayBar("overlay", bar_rect);
-
// panel containing chatbar, toolbar, and overlay, over floaters
- LLRect bottom_rect(-1, 2*STATUS_BAR_HEIGHT + CHAT_BAR_HEIGHT, width+1, -1);
- gBottomPanel = new LLBottomPanel("bottom panel", bottom_rect);
-
- // the order here is important
- gBottomPanel->addChild(gChatBar);
- gBottomPanel->addChild(gToolBar);
- gBottomPanel->addChild(gOverlayBar);
+ gBottomPanel = new LLBottomPanel(mRootView->getRect());
mRootView->addChild(gBottomPanel);
// View for hover information
@@ -1933,8 +1874,7 @@ void LLViewerWindow::initWorldUI()
mRootView->addChild(gMorphView);
gMorphView->setVisible(FALSE);
- gFloaterMute = new LLFloaterMute();
- gFloaterMute->setVisible(FALSE);
+ gFloaterMute = LLFloaterMute::getInstance();
LLWorldMapView::initClass();
@@ -2450,6 +2390,12 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
if(LLMenuGL::getKeyboardMode())
LLMenuGL::setKeyboardMode(FALSE);
+ if (gFocusMgr.getTopCtrl())
+ {
+ gFocusMgr.setTopCtrl(NULL);
+ return TRUE;
+ }
+
// *TODO: get this to play well with mouselook and hidden
// cursor modes, etc, and re-enable.
//if (gFocusMgr.getMouseCapture())
@@ -2979,23 +2925,9 @@ BOOL LLViewerWindow::handlePerFrameHover()
}
// Update rectangles for the various toolbars
- if (gToolBar && gChatBar && gOverlayBar && gNotifyBoxView && gConsole)
+ if (gOverlayBar && gNotifyBoxView && gConsole)
{
LLRect bar_rect(-1, STATUS_BAR_HEIGHT, getWindowWidth()+1, -1);
- if (gToolBar->getVisible())
- {
- gToolBar->setRect(bar_rect);
- bar_rect.translate(0, STATUS_BAR_HEIGHT-1);
- }
-
- if (gChatBar->getVisible())
- {
- // fix up the height
- LLRect chat_bar_rect = bar_rect;
- chat_bar_rect.mTop = chat_bar_rect.mBottom + CHAT_BAR_HEIGHT + 1;
- gChatBar->setRect(chat_bar_rect);
- bar_rect.translate(0, CHAT_BAR_HEIGHT-1);
- }
LLRect notify_box_rect = gNotifyBoxView->getRect();
notify_box_rect.mBottom = bar_rect.mBottom;
@@ -3015,42 +2947,16 @@ BOOL LLViewerWindow::handlePerFrameHover()
if (gOverlayBar->getVisible())
{
- LLRect overlay_rect = bar_rect;
- overlay_rect.mTop = overlay_rect.mBottom + OVERLAY_BAR_HEIGHT;
-
- // Fitt's Law: Push buttons flush with bottom of screen if
- // nothing else visible.
- if (!gToolBar->getVisible()
- && !gChatBar->getVisible())
- {
- // *NOTE: this is highly depenent on the XML
- // describing the position of the buttons
- overlay_rect.translate(0, 0);
- }
-
- gOverlayBar->setRect(overlay_rect);
- gOverlayBar->updateRect();
- bar_rect.translate(0, gOverlayBar->getRect().getHeight());
-
- gFloaterView->setSnapOffsetBottom(OVERLAY_BAR_HEIGHT);
+ gFloaterView->setSnapOffsetBottom(gHUDView->getRect().mBottom);
}
else
{
gFloaterView->setSnapOffsetBottom(0);
}
- // fix rectangle of bottom panel focus indicator
- if(gBottomPanel && gBottomPanel->getFocusIndicator())
- {
- LLRect focus_rect = gBottomPanel->getFocusIndicator()->getRect();
- focus_rect.mTop = (gToolBar->getVisible() ? STATUS_BAR_HEIGHT : 0) +
- (gChatBar->getVisible() ? CHAT_BAR_HEIGHT : 0) - 2;
- gBottomPanel->getFocusIndicator()->setRect(focus_rect);
- }
-
// Always update console
LLRect console_rect = gConsole->getRect();
- console_rect.mBottom = bar_rect.mBottom + 8;
+ console_rect.mBottom = gHUDView->getRect().mBottom + CONSOLE_BOTTOM_PAD;
gConsole->reshape(console_rect.getWidth(), console_rect.getHeight());
gConsole->setRect(console_rect);
}
@@ -3628,13 +3534,6 @@ void LLViewerWindow::performPick()
// if you are the parent
parent = objectp;
}
- std::vector<LLPointer<LLViewerObject>,std::allocator<LLPointer<LLViewerObject> > > children = parent->getChildren();
- for( std::vector<LLPointer<LLViewerObject>,std::allocator<LLPointer<LLViewerObject> > >::iterator i= children.begin(); i!= children.end(); ++i )
- {
- //go through
- LLViewerObject* foo = *i;
- foo->getRotation();
- }
if (objectp->mbCanSelect)
{
te_offset = (te_offset == 16) ? NO_FACE : te_offset;
@@ -4561,9 +4460,9 @@ void LLViewerWindow::drawMouselookInstructions()
// These functions are here only because LLViewerWindow used to do the work that gFocusMgr does now.
// They let other objects continue to work without change.
-void LLViewerWindow::setKeyboardFocus(LLUICtrl* new_focus,void (*on_focus_lost)(LLUICtrl* old_focus))
+void LLViewerWindow::setKeyboardFocus(LLUICtrl* new_focus)
{
- gFocusMgr.setKeyboardFocus( new_focus, on_focus_lost );
+ gFocusMgr.setKeyboardFocus( new_focus );
}
LLUICtrl* LLViewerWindow::getKeyboardFocus()
@@ -5033,7 +4932,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
}
mIgnoreActivate = FALSE;
- gFocusMgr.setKeyboardFocus(keyboard_focus, NULL);
+ gFocusMgr.setKeyboardFocus(keyboard_focus);
mWantFullscreen = mWindow->getFullscreen();
mShowFullscreenProgress = FALSE;
@@ -5233,16 +5132,22 @@ LLAlertDialog* LLViewerWindow::alertXmlEditText(const std::string& xml_filename,
////////////////////////////////////////////////////////////////////////////
-LLBottomPanel::LLBottomPanel(const LLString &name, const LLRect &rect) :
- LLPanel(name, rect, FALSE),
+LLBottomPanel::LLBottomPanel(const LLRect &rect) :
+ LLPanel("", rect, FALSE),
mIndicator(NULL)
{
// bottom panel is focus root, so Tab moves through the toolbar and button bar, and overlay
setFocusRoot(TRUE);
- // don't capture mouse clicks that don't hit a child
- setMouseOpaque(FALSE);
- setFollows(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
+ // flag this panel as chrome so buttons don't grab keyboard focus
setIsChrome(TRUE);
+
+ mFactoryMap["toolbar"] = LLCallbackMap(createToolBar, NULL);
+ mFactoryMap["overlay"] = LLCallbackMap(createOverlayBar, NULL);
+ mFactoryMap["hud"] = LLCallbackMap(createHUD, NULL);
+ gUICtrlFactory->buildPanel(this, "panel_bars.xml", &getFactoryMap());
+
+ setOrigin(rect.mLeft, rect.mBottom);
+ reshape(rect.getWidth(), rect.getHeight());
}
void LLBottomPanel::setFocusIndicator(LLView * indicator)
@@ -5260,3 +5165,25 @@ void LLBottomPanel::draw()
}
LLPanel::draw();
}
+
+void* LLBottomPanel::createHUD(void* data)
+{
+ delete gHUDView;
+ gHUDView = new LLHUDView();
+ return gHUDView;
+}
+
+
+void* LLBottomPanel::createOverlayBar(void* data)
+{
+ delete gOverlayBar;
+ gOverlayBar = new LLOverlayBar();
+ return gOverlayBar;
+}
+
+void* LLBottomPanel::createToolBar(void* data)
+{
+ delete gToolBar;
+ gToolBar = new LLToolBar();
+ return gToolBar;
+}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index faab518879..36225cb7d3 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -185,7 +185,7 @@ public:
// Handle the application becoming active (frontmost) or inactive
//BOOL handleActivate(BOOL activate);
- void setKeyboardFocus(LLUICtrl* new_focus,void (*on_focus_lost)(LLUICtrl* old_focus)); // new_focus = NULL to release the focus.
+ void setKeyboardFocus(LLUICtrl* new_focus); // new_focus = NULL to release the focus.
LLUICtrl* getKeyboardFocus();
BOOL hasKeyboardFocus( const LLUICtrl* possible_focus ) const;
BOOL childHasKeyboardFocus( const LLView* parent ) const;
@@ -363,10 +363,15 @@ protected:
class LLBottomPanel : public LLPanel
{
public:
- LLBottomPanel(const LLString& name, const LLRect& rect);
+ LLBottomPanel(const LLRect& rect);
void setFocusIndicator(LLView * indicator);
LLView * getFocusIndicator() { return mIndicator; }
/*virtual*/ void draw();
+
+ static void* createHUD(void* data);
+ static void* createOverlayBar(void* data);
+ static void* createToolBar(void* data);
+
protected:
LLView * mIndicator;
};
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index fc159ddc48..c6a3ff192b 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3426,7 +3426,7 @@ void LLVOAvatar::updateCharacter(LLAgent &agent)
// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
- F32 gain = .30f * gSavedSettings.getF32("AudioLevelAmbient");
+ F32 gain = gSavedSettings.getBOOL("MuteAmbient") ? 0.f : (.30f * gSavedSettings.getF32("AudioLevelAmbient"));
LLUUID& step_sound_id = getStepSound();
LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
@@ -4401,7 +4401,7 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
//else
{
LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
- F32 volume = gSavedSettings.getF32("AudioLevelSFX");
+ F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : gSavedSettings.getF32("AudioLevelSFX");
gAudiop->triggerSound(sound_id, getID(), volume, char_pos_global);
}
}
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index cf6b13e74c..1cbb1adada 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -43,7 +43,6 @@
#include "llcallbacklist.h"
#include "llviewerregion.h"
#include "llviewernetwork.h" // for gGridChoice
-#include "llfloateractivespeakers.h" // for LLSpeakerMgr
#include "llbase64.h"
#include "llviewercontrol.h"
#include "llkeyboard.h"
@@ -532,7 +531,7 @@ void LLVivoxProtocolParser::CharData(const char *buffer, int length)
void LLVivoxProtocolParser::processResponse(std::string tag)
{
-// llinfos << tag << llendl;
+ //llinfos << tag << llendl;
if (isEvent)
{
@@ -768,7 +767,7 @@ static HANDLE sGatewayHandle = 0;
static bool isGatewayRunning()
{
bool result = false;
- if(sGatewayHandle != 0)
+ if(sGatewayHandle != 0)
{
DWORD waitresult = WaitForSingleObject(sGatewayHandle, 0);
if(waitresult != WAIT_OBJECT_0)
@@ -854,7 +853,7 @@ LLVoiceClient::LLVoiceClient()
setPTTKey(keyString);
mPTTIsToggle = gSavedSettings.getBOOL("PushToTalkToggle");
mEarLocation = gSavedSettings.getS32("VoiceEarLocation");
- setVoiceVolume(gSavedSettings.getF32("AudioLevelVoice"));
+ setVoiceVolume(gSavedSettings.getBOOL("MuteVoice") ? 0.f : gSavedSettings.getF32("AudioLevelVoice"));
std::string captureDevice = gSavedSettings.getString("VoiceInputAudioDevice");
setCaptureDevice(captureDevice);
std::string renderDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
@@ -876,7 +875,6 @@ LLVoiceClient::LLVoiceClient()
mTuningMicVolumeDirty = true;
mTuningSpeakerVolume = 0;
mTuningSpeakerVolumeDirty = true;
- mTuningCaptureRunning = false;
// gMuteListp isn't set up at this point, so we defer this until later.
// gMuteListp->addObserver(&mutelist_listener);
@@ -1138,14 +1136,15 @@ const char *LLVoiceClient::state2string(LLVoiceClient::state inState)
CASE(stateConnectorStart);
CASE(stateConnectorStarting);
CASE(stateConnectorStarted);
- CASE(stateMicTuningNoLogin);
CASE(stateLoginRetry);
CASE(stateLoginRetryWait);
CASE(stateNeedsLogin);
CASE(stateLoggingIn);
CASE(stateLoggedIn);
CASE(stateNoChannel);
- CASE(stateMicTuningLoggedIn);
+ CASE(stateMicTuningStart);
+ CASE(stateMicTuningRunning);
+ CASE(stateMicTuningStop);
CASE(stateSessionCreate);
CASE(stateSessionConnect);
CASE(stateJoiningSession);
@@ -1164,6 +1163,7 @@ const char *LLVoiceClient::state2string(LLVoiceClient::state inState)
CASE(stateJoinSessionFailed);
CASE(stateJoinSessionFailedWaiting);
CASE(stateJail);
+ CASE(stateMicTuningNoLogin);
}
#undef CASE
@@ -1483,7 +1483,8 @@ void LLVoiceClient::stateMachine()
}
else if(mTuningMode)
{
- setState(stateMicTuningNoLogin);
+ mTuningExitState = stateConnectorStart;
+ setState(stateMicTuningStart);
}
break;
@@ -1515,24 +1516,63 @@ void LLVoiceClient::stateMachine()
}
break;
- case stateMicTuningNoLogin:
- case stateMicTuningLoggedIn:
- {
- // Both of these behave essentially the same. The only difference is where the exit transition goes to.
- if(mTuningMode && mVoiceEnabled && !mSessionTerminateRequested)
- {
- if(!mTuningCaptureRunning)
+ case stateMicTuningStart:
+ if(mUpdateTimer.hasExpired())
+ {
+ if(mCaptureDeviceDirty || mRenderDeviceDirty)
+ {
+ // These can't be changed while in tuning mode. Set them before starting.
+ std::ostringstream stream;
+
+ if(mCaptureDeviceDirty)
+ {
+ buildSetCaptureDevice(stream);
+ }
+
+ if(mRenderDeviceDirty)
+ {
+ buildSetRenderDevice(stream);
+ }
+
+ mCaptureDeviceDirty = false;
+ mRenderDeviceDirty = false;
+
+ if(!stream.str().empty())
+ {
+ writeString(stream.str());
+ }
+
+ // This will come around again in the same state and start the capture, after the timer expires.
+ mUpdateTimer.start();
+ mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
+ }
+ else
{
// duration parameter is currently unused, per Mike S.
tuningCaptureStartSendMessage(10000);
+
+ setState(stateMicTuningRunning);
}
-
- if(mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty || mCaptureDeviceDirty || mRenderDeviceDirty)
+ }
+
+ break;
+
+ case stateMicTuningRunning:
+ if(!mTuningMode || !mVoiceEnabled || mSessionTerminateRequested || mCaptureDeviceDirty || mRenderDeviceDirty)
+ {
+ // All of these conditions make us leave tuning mode.
+ setState(stateMicTuningStop);
+ }
+ else
+ {
+ // process mic/speaker volume changes
+ if(mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty)
{
std::ostringstream stream;
if(mTuningMicVolumeDirty)
{
+ llinfos << "setting tuning mic level to " << mTuningMicVolume << llendl;
stream
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetMicLevel.1\">"
<< "<Level>" << mTuningMicVolume << "</Level>"
@@ -1547,20 +1587,8 @@ void LLVoiceClient::stateMachine()
<< "</Request>\n\n\n";
}
- if(mCaptureDeviceDirty)
- {
- buildSetCaptureDevice(stream);
- }
-
- if(mRenderDeviceDirty)
- {
- buildSetRenderDevice(stream);
- }
-
mTuningMicVolumeDirty = false;
mTuningSpeakerVolumeDirty = false;
- mCaptureDeviceDirty = false;
- mRenderDeviceDirty = false;
if(!stream.str().empty())
{
@@ -1568,23 +1596,19 @@ void LLVoiceClient::stateMachine()
}
}
}
- else
- {
- // transition out of mic tuning
- if(mTuningCaptureRunning)
- {
- tuningCaptureStopSendMessage();
- }
-
- if(getState() == stateMicTuningNoLogin)
- {
- setState(stateConnectorStart);
- }
- else
- {
- setState(stateNoChannel);
- }
- }
+ break;
+
+ case stateMicTuningStop:
+ {
+ // transition out of mic tuning
+ tuningCaptureStopSendMessage();
+
+ setState(mTuningExitState);
+
+ // if we exited just to change devices, this will keep us from re-entering too fast.
+ mUpdateTimer.start();
+ mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
+
}
break;
@@ -1654,7 +1678,8 @@ void LLVoiceClient::stateMachine()
}
else if(mTuningMode)
{
- setState(stateMicTuningLoggedIn);
+ mTuningExitState = stateNoChannel;
+ setState(stateMicTuningStart);
}
else if(!mNextSessionHandle.empty())
{
@@ -1880,6 +1905,12 @@ void LLVoiceClient::stateMachine()
case stateJail:
// We have given up. Do nothing.
break;
+
+ case stateMicTuningNoLogin:
+ // *TODO: Implement me.
+ llwarns << "stateMicTuningNoLogin not handled"
+ << llendl;
+ break;
}
if(mParticipantMapChanged)
@@ -2183,9 +2214,9 @@ bool LLVoiceClient::inTuningMode()
bool result = false;
switch(getState())
{
- case stateMicTuningNoLogin:
- case stateMicTuningLoggedIn:
+ case stateMicTuningRunning:
result = true;
+ break;
default:
break;
}
@@ -2193,10 +2224,7 @@ bool LLVoiceClient::inTuningMode()
}
void LLVoiceClient::tuningRenderStartSendMessage(const std::string& name, bool loop)
-{
- if(!inTuningMode())
- return;
-
+{
mTuningAudioFile = name;
std::ostringstream stream;
stream
@@ -2210,9 +2238,6 @@ void LLVoiceClient::tuningRenderStartSendMessage(const std::string& name, bool l
void LLVoiceClient::tuningRenderStopSendMessage()
{
- if(!inTuningMode())
- return;
-
std::ostringstream stream;
stream
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.RenderAudioStop.1\">"
@@ -2224,9 +2249,8 @@ void LLVoiceClient::tuningRenderStopSendMessage()
void LLVoiceClient::tuningCaptureStartSendMessage(int duration)
{
- if(!inTuningMode())
- return;
-
+ llinfos << "sending CaptureAudioStart" << llendl;
+
std::ostringstream stream;
stream
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStart.1\">"
@@ -2234,15 +2258,12 @@ void LLVoiceClient::tuningCaptureStartSendMessage(int duration)
<< "</Request>\n\n\n";
writeString(stream.str());
-
- mTuningCaptureRunning = true;
}
void LLVoiceClient::tuningCaptureStopSendMessage()
{
- if(!inTuningMode())
- return;
-
+ llinfos << "sending CaptureAudioStop" << llendl;
+
std::ostringstream stream;
stream
<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStop.1\">"
@@ -2250,7 +2271,7 @@ void LLVoiceClient::tuningCaptureStopSendMessage()
writeString(stream.str());
- mTuningCaptureRunning = false;
+ mTuningEnergy = 0.0f;
}
void LLVoiceClient::tuningSetMicVolume(float volume)
@@ -2914,12 +2935,16 @@ void LLVoiceClient::sessionNewEvent(
LLUUID caller_id;
if(IDFromName(nameString, caller_id))
{
- gIMMgr->inviteToSession(LLIMMgr::computeSessionID(IM_SESSION_P2P_INVITE, caller_id),
- LLString::null,
- caller_id,
- LLString::null,
- IM_SESSION_P2P_INVITE,
- eventSessionHandle);
+ gIMMgr->inviteToSession(
+ LLIMMgr::computeSessionID(
+ IM_SESSION_P2P_INVITE,
+ caller_id),
+ LLString::null,
+ caller_id,
+ LLString::null,
+ IM_SESSION_P2P_INVITE,
+ LLIMMgr::INVITATION_TYPE_VOICE,
+ eventSessionHandle);
}
else
{
@@ -2985,6 +3010,7 @@ void LLVoiceClient::participantPropertiesEvent(
{
participant->mPTT = !isLocallyMuted;
participant->mIsSpeaking = isSpeaking;
+ participant->mIsModeratorMuted = isModeratorMuted;
if (isSpeaking)
{
participant->mSpeakingTimeout.reset();
@@ -3022,7 +3048,7 @@ void LLVoiceClient::muteListChanged()
/////////////////////////////
// Managing list of participants
LLVoiceClient::participantState::participantState(const std::string &uri) :
- mURI(uri), mPTT(false), mIsSpeaking(false), mPower(0.0), mServiceType(serviceTypeUnknown),
+ mURI(uri), mPTT(false), mIsSpeaking(false), mIsModeratorMuted(false), mPower(0.0), mServiceType(serviceTypeUnknown),
mOnMuteList(false), mUserVolume(100), mVolumeDirty(false), mAvatarIDValid(false)
{
}
@@ -3265,6 +3291,7 @@ void LLVoiceClient::switchChannel(
{
// Leave any channel we may be in
llinfos << "leaving channel" << llendl;
+ notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED);
}
else
{
@@ -3786,6 +3813,19 @@ BOOL LLVoiceClient::getIsSpeaking(const LLUUID& id)
return result;
}
+BOOL LLVoiceClient::getIsModeratorMuted(const LLUUID& id)
+{
+ BOOL result = FALSE;
+
+ participantState *participant = findParticipantByID(id);
+ if(participant)
+ {
+ result = participant->mIsModeratorMuted;
+ }
+
+ return result;
+}
+
F32 LLVoiceClient::getCurrentPower(const LLUUID& id)
{
F32 result = 0;
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index ed256b6f8c..5179bc099c 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -63,6 +63,7 @@ public:
STATUS_JOINING,
STATUS_JOINED,
STATUS_LEFT_CHANNEL,
+ STATUS_VOICE_DISABLED,
BEGIN_ERROR_STATUS,
ERROR_CHANNEL_FULL,
ERROR_CHANNEL_LOCKED,
@@ -139,6 +140,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
void tuningStart();
void tuningStop();
bool inTuningMode();
+ bool inTuningStates();
void tuningRenderStartSendMessage(const std::string& name, bool loop);
void tuningRenderStopSendMessage();
@@ -218,6 +220,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
// Accessors for data related to nearby speakers
BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar
BOOL getIsSpeaking(const LLUUID& id);
+ BOOL getIsModeratorMuted(const LLUUID& id);
F32 getCurrentPower(const LLUUID& id); // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is...
BOOL getPTTPressed(const LLUUID& id); // This is the inverse of the "locally muted" property.
BOOL getOnMuteList(const LLUUID& id);
@@ -242,6 +245,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
std::string mDisplayName;
bool mPTT;
bool mIsSpeaking;
+ bool mIsModeratorMuted;
LLFrameTimer mSpeakingTimeout;
F32 mLastSpokeTimestamp;
F32 mPower;
@@ -316,7 +320,9 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
stateLoggingIn, // waiting for account handle
stateLoggedIn, // account handle received
stateNoChannel, //
- stateMicTuningLoggedIn, // mic tuning for a logged in user
+ stateMicTuningStart,
+ stateMicTuningRunning,
+ stateMicTuningStop,
stateSessionCreate, // need to send Session.Create command
stateSessionConnect, // need to send Session.Connect command
stateJoiningSession, // waiting for session handle
@@ -387,7 +393,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
bool mTuningMicVolumeDirty;
int mTuningSpeakerVolume;
bool mTuningSpeakerVolumeDirty;
- bool mTuningCaptureRunning;
+ state mTuningExitState; // state to return to when we leave tuning mode.
std::string mSpatialSessionURI;
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index e6676639e2..39f2f63066 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -111,7 +111,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
{
mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
- mSoundSymbol.mTexture [i] = gImageList.getUIImageByID(sound_level_img[i]);
+ mSoundSymbol.mTexture [i] = gImageList.getImageByID(sound_level_img[i]);
mSoundSymbol.mWaveActive [i] = false;
mSoundSymbol.mWaveOpacity [i] = 1.0f;
mSoundSymbol.mWaveExpansion [i] = 1.0f;
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index dac693885f..ec277b1a1b 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1117,11 +1117,6 @@ LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, LLString& msg, LLRect* sticky_rect_screen )
{
- if( !getVisible() || !pointInView( x, y ) )
- {
- return FALSE;
- }
-
LLVector3d pos_global = viewPosToGlobal(x, y);
LLSimInfo* info = gWorldMap->simInfoFromPosGlobal(pos_global);
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 7bb12f7853..5775af68a1 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -435,7 +435,7 @@ class DarwinManifest(ViewerManifest):
self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
# Unmount the image
- self.run_command('hdiutil detach "' + devfile + '"')
+ self.run_command('hdiutil detach -force "' + devfile + '"')
print "Converting temp disk image to final disk image"
self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})