summaryrefslogtreecommitdiff
path: root/indra/newview/llimconversation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llimconversation.cpp')
-rw-r--r--indra/newview/llimconversation.cpp198
1 files changed, 172 insertions, 26 deletions
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 827059513f..e031b0e829 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -29,6 +29,8 @@
#include "llimconversation.h"
+#include "llagent.h"
+#include "llavataractions.h"
#include "llchatentry.h"
#include "llchathistory.h"
#include "llchiclet.h"
@@ -49,7 +51,8 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
, mTearOffBtn(NULL)
, mCloseBtn(NULL)
, mSessionID(session_id.asUUID())
- , mParticipantList(NULL)
+// , mParticipantList(NULL)
+ , mConversationsRoot(NULL)
, mChatHistory(NULL)
, mInputEditor(NULL)
, mInputEditorTopPad(0)
@@ -74,11 +77,13 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
LLIMConversation::~LLIMConversation()
{
+ /*
if (mParticipantList)
{
delete mParticipantList;
mParticipantList = NULL;
}
+ */
delete mRefreshTimer;
}
@@ -178,7 +183,8 @@ void LLIMConversation::addToHost(const LLUUID& session_id)
conversp->setHost(floater_container);
conversp->setHost(NULL);
}
-
+ // Added floaters share some state (like sort order) with their host
+ conversp->setSortOrder(floater_container->getSortOrder());
}
}
}
@@ -193,11 +199,39 @@ BOOL LLIMConversation::postBuild()
mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
- mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
-
mTearOffBtn = getChild<LLButton>("tear_off_btn");
mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
+ 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);
+
+
mChatHistory = getChild<LLChatHistory>("chat_history");
mInputEditor = getChild<LLChatEntry>("chat_editor");
@@ -210,7 +244,7 @@ BOOL LLIMConversation::postBuild()
setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
- buildParticipantList();
+ buildConversationViewParticipant();
updateHeaderAndToolbar();
@@ -233,15 +267,20 @@ BOOL LLIMConversation::postBuild()
return result;
}
+LLParticipantList* LLIMConversation::getParticipantList()
+{
+ return dynamic_cast<LLParticipantList*>(LLIMFloaterContainer::getInstance()->getSessionModel(mSessionID));
+}
+
void LLIMConversation::draw()
{
LLTransientDockableFloater::draw();
if (mRefreshTimer->hasExpired())
{
- if (mParticipantList)
+ if (getParticipantList())
{
- mParticipantList->update();
+ getParticipantList()->update();
}
refresh();
@@ -336,41 +375,142 @@ void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
}
-void LLIMConversation::buildParticipantList()
+void LLIMConversation::buildConversationViewParticipant()
+{
+ // Clear the widget list since we are rebuilding afresh from the model
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ while (widget_it != mConversationsWidgets.end())
+ {
+ removeConversationViewParticipant(widget_it->first);
+ // Iterators are invalidated by erase so we need to pick begin again
+ widget_it = mConversationsWidgets.begin();
+ }
+
+ // Get the model list
+ LLParticipantList* item = getParticipantList();
+ if (!item)
+ {
+ // Nothing to do if the model list is empty
+ return;
+ }
+
+ // 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();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+ addConversationViewParticipant(participant_model);
+ current_participant_model++;
+ }
+}
+
+void LLIMConversation::addConversationViewParticipant(LLConversationItem* participant_model)
{
- if (mIsNearbyChat)
+ // Check if the model already has an associated view
+ LLUUID uuid = participant_model->getUUID();
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+
+ // If not already present, create the participant view and attach it to the root, otherwise, just refresh it
+ if (widget)
{
- LLLocalSpeakerMgr* speaker_manager = LLLocalSpeakerMgr::getInstance();
- mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
+ updateConversationViewParticipant(uuid); // overkill?
}
else
{
- LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
- // for group and ad-hoc chat we need to include agent into list
- if(!mIsP2PChat && mSessionID.notNull() && speaker_manager)
- {
- delete mParticipantList; // remove the old list and create a new one if the session id has changed
- mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
- }
+ LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+ mConversationsWidgets[uuid] = participant_view;
+ participant_view->addToFolder(mConversationsRoot);
+ participant_view->setVisible(TRUE);
+ refreshConversation();
}
- updateHeaderAndToolbar();
}
-void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
+void LLIMConversation::removeConversationViewParticipant(const LLUUID& participant_id)
{
- // TODO: Check this code when sort order menu will be added. (EM)
- if (!mParticipantList)
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+ if (widget)
{
- return;
+ mConversationsRoot->extractItem(widget);
+ delete widget;
+ mConversationsWidgets.erase(participant_id);
+ refreshConversation();
}
+}
- std::string chosen_item = userdata.asString();
+void LLIMConversation::updateConversationViewParticipant(const LLUUID& participant_id)
+{
+ LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+ if (widget)
+ {
+ widget->refresh();
+ }
+ refreshConversation();
+}
- if (chosen_item == "sort_name")
+void LLIMConversation::refreshConversation()
+{
+ // Note: We collect participants names to change the session name only in the case of ad-hoc conversations
+ bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
+ uuid_vec_t participants_uuids; // uuids vector for building the added participants name string
+ // For P2P chat, we still need to update the session name who may have changed (switch display name for instance)
+ if (mIsP2PChat && mSession)
{
- mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
+ participants_uuids.push_back(mSession->mOtherParticipantID);
}
+ conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+ while (widget_it != mConversationsWidgets.end())
+ {
+ // Add the participant to the list except if it's the agent itself (redundant)
+ if (is_ad_hoc && (widget_it->first != gAgentID))
+ {
+ participants_uuids.push_back(widget_it->first);
+ }
+ widget_it->second->refresh();
+ widget_it->second->setVisible(TRUE);
+ ++widget_it;
+ }
+ if (is_ad_hoc || mIsP2PChat)
+ {
+ // Build the session name and update it
+ std::string session_name;
+ if (participants_uuids.size() != 0)
+ {
+ LLAvatarActions::buildResidentsString(participants_uuids, session_name);
+ }
+ else
+ {
+ session_name = LLIMModel::instance().getName(mSessionID);
+ }
+ updateSessionName(session_name);
+ }
+ mConversationViewModel.requestSortAll();
+ mConversationsRoot->arrangeAll();
+ mConversationsRoot->update();
+}
+
+// Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
+LLConversationViewParticipant* LLIMConversation::createConversationViewParticipant(LLConversationItem* item)
+{
+ LLRect panel_rect = mParticipantListPanel->getRect();
+
+ LLConversationViewParticipant::Params params;
+ params.name = item->getDisplayName();
+ params.root = mConversationsRoot;
+ params.listener = item;
+ params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24
+ params.tool_tip = params.name;
+ params.participant_id = item->getUUID();
+
+ return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+void LLIMConversation::setSortOrder(const LLConversationSort& order)
+{
+ mConversationViewModel.setSorter(order);
+ mConversationsRoot->arrangeAll();
+ refreshConversation();
}
void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
@@ -429,6 +569,11 @@ void LLIMConversation::hideOrShowTitle()
floater_contents->setShape(contents_rect);
}
+void LLIMConversation::updateSessionName(const std::string& name)
+{
+ mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
+}
+
void LLIMConversation::hideAllStandardButtons()
{
for (S32 i = 0; i < BUTTON_COUNT; i++)
@@ -587,6 +732,7 @@ void LLIMConversation::onTearOffClicked()
initRectControl();
LLFloater::onClickTearOff(this);
updateHeaderAndToolbar();
+ refreshConversation();
}
// static