summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llconversationmodel.cpp28
-rwxr-xr-xindra/newview/llconversationmodel.h3
-rwxr-xr-xindra/newview/llconversationview.cpp51
-rwxr-xr-xindra/newview/llconversationview.h9
-rw-r--r--indra/newview/llfloaterimcontainer.cpp29
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp73
-rw-r--r--indra/newview/llfloaterimsessiontab.h1
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp5
-rw-r--r--indra/newview/llspeakingindicatormanager.cpp33
-rw-r--r--indra/newview/llspeakingindicatormanager.h5
10 files changed, 158 insertions, 79 deletions
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 47a82bfe17..1c56bd672d 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -349,15 +349,21 @@ const bool LLConversationItemSession::getTime(F64& time) const
return has_time;
}
-void LLConversationItemSession::dumpDebugData()
+void LLConversationItemSession::dumpDebugData(bool dump_children)
{
+ // Session info
llinfos << "Merov debug : session " << this << ", uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
- LLConversationItemParticipant* participant = NULL;
- child_list_t::iterator iter;
- for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ // Children info
+ if (dump_children)
{
- participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
- participant->dumpDebugData();
+ for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++)
+ {
+ LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+ if (participant)
+ {
+ participant->dumpDebugData();
+ }
+ }
}
}
@@ -440,6 +446,16 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
}
}
+LLConversationItemSession* LLConversationItemParticipant::getParentSession()
+{
+ LLConversationItemSession* parent_session = NULL;
+ if (hasParent())
+ {
+ parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+ }
+ return parent_session;
+}
+
void LLConversationItemParticipant::dumpDebugData()
{
llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 481d46af58..dd849210a8 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -168,7 +168,7 @@ public:
void addVoiceOptions(menuentry_vec_t& items);
virtual const bool getTime(F64& time) const;
- void dumpDebugData();
+ void dumpDebugData(bool dump_children = false);
private:
bool mIsLoaded; // true if at least one participant has been added to the session, false otherwise
@@ -195,6 +195,7 @@ public:
virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
void fetchAvatarName();
+ LLConversationItemSession* getParentSession();
void dumpDebugData();
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d1649a93b1..4c52794e4c 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -307,7 +307,8 @@ void LLConversationViewSession::refresh()
mSessionTitle->setText(vmi->getDisplayName());
}
- // Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
+ // Update all speaking indicators
+ LLSpeakingIndicatorManager::updateSpeakingIndicators();
// Do the regular upstream refresh
LLFolderViewFolder::refresh();
@@ -366,6 +367,11 @@ LLConversationViewParticipant::LLConversationViewParticipant( const LLConversati
{
}
+LLConversationViewParticipant::~LLConversationViewParticipant()
+{
+ mActiveVoiceChannelConnection.disconnect();
+}
+
void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
{
LLAvatarIconCtrl::Params avatar_icon_params(params.avatar_icon());
@@ -392,6 +398,7 @@ BOOL LLConversationViewParticipant::postBuild()
mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
mInfoBtn->setVisible(false);
+ mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewParticipant::onCurrentVoiceSessionChanged, this, _1));
mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
if (!sStaticInitialized)
@@ -457,14 +464,29 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
return arranged;
}
+void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& session_id)
+{
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
+
+ if (participant_model)
+ {
+ LLConversationItemSession* parent_session = participant_model->getParentSession();
+ if (parent_session)
+ {
+ bool is_active = (parent_session->getUUID() == session_id);
+ mSpeakingIndicator->switchIndicator(is_active);
+ }
+ }
+}
+
void LLConversationViewParticipant::refresh()
{
// Refresh the participant view from its model data
- LLConversationItemParticipant* vmi = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
- vmi->resetRefresh();
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
+ participant_model->resetRefresh();
// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
- mSpeakingIndicator->setIsMuted(vmi->isMuted());
+ mSpeakingIndicator->setIsMuted(participant_model->isMuted());
// Do the regular upstream refresh
LLFolderViewItem::refresh();
@@ -472,21 +494,26 @@ void LLConversationViewParticipant::refresh()
void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
{
- //Add the item to the folder (conversation)
+ // Add the item to the folder (conversation)
LLFolderViewItem::addToFolder(folder);
- //Now retrieve the folder (conversation) UUID, which is the speaker session
+ // Retrieve the folder (conversation) UUID, which is also the speaker session UUID
LLConversationItem* vmi = this->getParentFolder() ? dynamic_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
- if(vmi)
+ if (vmi)
{
- //Allows speaking icon image to be loaded based on mUUID
- mAvatarIcon->setValue(mUUID);
-
- //Allows the speaker indicator to be activated based on the user and conversation
- mSpeakingIndicator->setSpeakerId(mUUID, vmi->getUUID());
+ addToSession(vmi->getUUID());
}
}
+void LLConversationViewParticipant::addToSession(const LLUUID& session_id)
+{
+ //Allows speaking icon image to be loaded based on mUUID
+ mAvatarIcon->setValue(mUUID);
+
+ //Allows the speaker indicator to be activated based on the user and conversation
+ mSpeakingIndicator->setSpeakerId(mUUID, session_id);
+}
+
void LLConversationViewParticipant::onInfoBtnClick()
{
LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index cc6995c207..1baa8bb5ec 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -94,7 +94,7 @@ private:
bool mMinimizedMode;
LLVoiceClientStatusObserver* mVoiceClientObserver;
-
+
boost::signals2::connection mActiveVoiceChannelConnection;
};
@@ -116,11 +116,12 @@ public:
Params();
};
- virtual ~LLConversationViewParticipant( void ) { }
+ virtual ~LLConversationViewParticipant( void );
bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
virtual void refresh();
void addToFolder(LLFolderViewFolder* folder);
+ void addToSession(const LLUUID& session_id);
/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
@@ -140,6 +141,8 @@ protected:
void onInfoBtnClick();
private:
+ void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+
LLAvatarIconCtrl* mAvatarIcon;
LLButton * mInfoBtn;
LLOutputMonitorCtrl* mSpeakingIndicator;
@@ -156,6 +159,8 @@ private:
static void initChildrenWidths(LLConversationViewParticipant* self);
void updateChildren();
LLView* getItemChildView(EAvatarListItemChildIndex child_view_index);
+
+ boost::signals2::connection mActiveVoiceChannelConnection;
};
#endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ec1068d191..aebfdb5bce 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -98,6 +98,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
{
+ llinfos << "Merov debug : sessionAdded, uuid = " << session_id << ", name = " << name << llendl;
addConversationListItem(session_id);
LLFloaterIMSessionTab::addToHost(session_id);
}
@@ -115,8 +116,20 @@ void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
{
- // *TODO: We should do this *without* delete and recreate
- addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
+ // The general strategy when a session id is modified is to delete all related objects and create them anew.
+
+ // Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived()
+ // and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress
+ // its related mSessions record as it's indexed with the wrong id.
+ // Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem().
+ mSessions.erase(old_session_id);
+
+ // Delete the model and participants related to the old session
+ bool change_focus = removeConversationListItem(old_session_id);
+
+ // Create a new conversation with the new id
+ addConversationListItem(new_session_id, change_focus);
+ LLFloaterIMSessionTab::addToHost(new_session_id);
}
void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id)
@@ -463,14 +476,14 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
else if (type == "update_session")
{
session_view->refresh();
- if (conversation_floater)
- {
- conversation_floater->refreshConversation();
- }
}
mConversationViewModel.requestSortAll();
mConversationsRoot->arrangeAll();
+ if (conversation_floater)
+ {
+ conversation_floater->refreshConversation();
+ }
return false;
}
@@ -1236,10 +1249,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
return item_it->second;
}
- // Remove the conversation item that might exist already: it'll be recreated anew further down anyway
- // and nothing wrong will happen removing it if it doesn't exist
- removeConversationListItem(uuid,false);
-
// Create a conversation session model
LLConversationItemSession* item = NULL;
LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index da77ca0079..69b42cdd6d 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -52,6 +52,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
, mCloseBtn(NULL)
, mSessionID(session_id.asUUID())
, mConversationsRoot(NULL)
+ , mScroller(NULL)
, mChatHistory(NULL)
, mInputEditor(NULL)
, mInputEditorTopPad(0)
@@ -68,10 +69,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck, this, _2));
mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable, this, _2));
-
- // Zero expiry time is set only once to allow initial update.
- mRefreshTimer->setTimerExpirySec(0);
- mRefreshTimer->start();
}
LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
@@ -200,33 +197,16 @@ BOOL LLFloaterIMSessionTab::postBuild()
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
- // Create a root view folder for all participants
- LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
- LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
- p.rect = LLRect(0, 0, getRect().getWidth(), 0);
- p.parent_panel = mParticipantListPanel;
- p.listener = base_item;
- p.view_model = &mConversationViewModel;
- p.root = NULL;
- p.use_ellipses = true;
- mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
- mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-
// Add a scroller for the folder (participant) view
LLRect scroller_view_rect = mParticipantListPanel->getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
scroller_params.rect(scroller_view_rect);
- LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
- scroller->setFollowsAll();
-
- // Insert that scroller into the panel widgets hierarchy and folder view
- mParticipantListPanel->addChild(scroller);
- scroller->addChild(mConversationsRoot);
- mConversationsRoot->setScrollContainer(scroller);
- mConversationsRoot->setFollowsAll();
- mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+ mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+ mScroller->setFollowsAll();
+ // Insert that scroller into the panel widgets hierarchy
+ mParticipantListPanel->addChild(mScroller);
mChatHistory = getChild<LLChatHistory>("chat_history");
@@ -240,8 +220,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
- buildConversationViewParticipant();
-
mSaveRect = isTornOff();
initRectControl();
@@ -254,8 +232,14 @@ BOOL LLFloaterIMSessionTab::postBuild()
result = LLDockableFloater::postBuild();
}
+ // Now ready to build the conversation and participants list
+ buildConversationViewParticipant();
refreshConversation();
-
+
+ // Zero expiry time is set only once to allow initial update.
+ mRefreshTimer->setTimerExpirySec(0);
+ mRefreshTimer->start();
+
return result;
}
@@ -281,9 +265,8 @@ void LLFloaterIMSessionTab::draw()
{
buildConversationViewParticipant();
}
+ refreshConversation();
}
-
- refreshConversation();
// Restart the refresh timer
mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
@@ -395,7 +378,31 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
// Nothing to do if the model list is inexistent
return;
}
-
+
+ // Create or recreate the root folder: this is a dummy folder (not shown) but required by the LLFolderView architecture
+ // We need to redo this when rebuilding as the session id (mSessionID) *may* have changed
+ if (mConversationsRoot)
+ {
+ // Remove the old root if any
+ mScroller->removeChild(mConversationsRoot);
+ }
+ // Create the root using an ad-hoc base item
+ LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+ LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+ p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+ p.parent_panel = mParticipantListPanel;
+ p.listener = base_item;
+ p.view_model = &mConversationViewModel;
+ p.root = NULL;
+ p.use_ellipses = true;
+ mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+ mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ // Attach that root to the scroller
+ mScroller->addChild(mConversationsRoot);
+ mConversationsRoot->setScrollContainer(mScroller);
+ mConversationsRoot->setFollowsAll();
+ mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
// Create the participants widgets now
LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
@@ -423,8 +430,8 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p
LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
mConversationsWidgets[uuid] = participant_view;
participant_view->addToFolder(mConversationsRoot);
+ participant_view->addToSession(mSessionID);
participant_view->setVisible(TRUE);
- refreshConversation();
}
}
@@ -436,7 +443,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
mConversationsRoot->extractItem(widget);
delete widget;
mConversationsWidgets.erase(participant_id);
- refreshConversation();
}
}
@@ -447,7 +453,6 @@ void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& part
{
widget->refresh();
}
- refreshConversation();
}
void LLFloaterIMSessionTab::refreshConversation()
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 8f5a8c2c1b..b765d121de 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -146,6 +146,7 @@ protected:
conversations_widgets_map mConversationsWidgets;
LLConversationViewModel mConversationViewModel;
LLFolderView* mConversationsRoot;
+ LLScrollContainer* mScroller;
LLChatHistory* mChatHistory;
LLChatEntry* mInputEditor;
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 4a9a50d96a..e4621a7fc3 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -283,7 +283,10 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
}
- if (speaker_id.isNull() || speaker_id == mSpeakerId) return;
+ if (speaker_id.isNull() || (speaker_id == mSpeakerId))
+ {
+ return;
+ }
if (mSpeakerId.notNull())
{
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 900379ae1e..76da7d1aee 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -74,6 +74,16 @@ public:
*/
void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+ /**
+ * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
+ *
+ * Switches off indicators had been switched on and switches on indicators of current participants list.
+ * There is only a few indicators in lists should be switched off/on.
+ * So, method does not calculate difference between these list it only switches off already
+ * switched on indicators and switches on indicators of voice channel participants
+ */
+ void onParticipantsChanged();
+
private:
typedef std::set<LLUUID> speaker_ids_t;
typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
@@ -94,16 +104,6 @@ private:
void sOnCurrentChannelChanged(const LLUUID& session_id);
/**
- * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
- *
- * Switches off indicators had been switched on and switches on indicators of current participants list.
- * There is only a few indicators in lists should be switched off/on.
- * So, method does not calculate difference between these list it only switches off already
- * switched on indicators and switches on indicators of voice channel participants
- */
- void onParticipantsChanged();
-
- /**
* Changes state of indicators specified by LLUUIDs
*
* @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched
@@ -249,16 +249,15 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
was_switched_on = was_switched_on || switch_current_on;
indicator->switchIndicator(switch_current_on);
-
}
if (was_found)
{
- LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;
+ LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators were found" << LL_ENDL;
if (switch_on && !was_switched_on)
{
- LL_DEBUGS("SpeakingIndicator") << "but non of them where switched on" << LL_ENDL;
+ LL_DEBUGS("SpeakingIndicator") << "but none of them were switched on" << LL_ENDL;
}
if (was_switched_on)
@@ -314,5 +313,13 @@ void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speak
}
}
+void LLSpeakingIndicatorManager::updateSpeakingIndicators()
+{
+ if(SpeakingIndicatorManager::instanceExists())
+ {
+ SpeakingIndicatorManager::instance().onParticipantsChanged();
+ }
+}
+
// EOF
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
index b0a147865b..e5afcd1cb7 100644
--- a/indra/newview/llspeakingindicatormanager.h
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -78,6 +78,11 @@ namespace LLSpeakingIndicatorManager
* @param speaking_indicator instance of the speaker indicator to be unregistered.
*/
void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+
+ /**
+ * Switch on/off registered speaking indicator according to the most current voice client status
+ */
+ void updateSpeakingIndicators();
}
#endif // LL_LLSPEAKINGINDICATORMANAGER_H