summaryrefslogtreecommitdiff
path: root/indra/newview/llimfloatercontainer.cpp
diff options
context:
space:
mode:
authorGilbert Gonzales <gilbert@lindenlab.com>2012-10-11 12:18:35 -0700
committerGilbert Gonzales <gilbert@lindenlab.com>2012-10-11 12:18:35 -0700
commitb871d67710cc4168752dee976725e190c0cd9960 (patch)
treef6c56ec4da61c6bcb7331ba5d16aa133742e4eb6 /indra/newview/llimfloatercontainer.cpp
parent375f380ea388b37c34ace9570822d0c117b3d2f1 (diff)
parent0ff5a0c8ceebfab0d786aaf027c7c548170afe8d (diff)
merging in latest changes
Diffstat (limited to 'indra/newview/llimfloatercontainer.cpp')
-rw-r--r--indra/newview/llimfloatercontainer.cpp136
1 files changed, 91 insertions, 45 deletions
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4af170b3db..5f111b39d4 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -50,6 +50,7 @@
#include "llcallbacklist.h"
#include "llworld.h"
+#include "llsdserialize.h"
//
// LLIMFloaterContainer
//
@@ -57,6 +58,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
: LLMultiFloater(seed),
mExpandCollapseBtn(NULL),
mConversationsRoot(NULL),
+ mConversationsEventStream("ConversationsEvents"),
mInitialized(false)
{
mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
@@ -77,6 +79,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
LLIMFloaterContainer::~LLIMFloaterContainer()
{
+ mConversationsEventStream.stopListening("ConversationsRefresh");
+
gIdleCallbacks.deleteFunction(idle, this);
mNewMessageConnection.disconnect();
@@ -155,6 +159,9 @@ BOOL LLIMFloaterContainer::postBuild()
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ // Add listener to conversation model events
+ mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLIMFloaterContainer::onConversationModelEvent, this, _1));
+
// a scroller for folder view
LLRect scroller_view_rect = mConversationsListPanel->getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
@@ -397,62 +404,81 @@ void LLIMFloaterContainer::idle(void* user_data)
self->mConversationsRoot->update();
}
-void LLIMFloaterContainer::draw()
+bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
{
- // CHUI Notes
- // Currently, the model is not responsible for creating the view which is a good thing. This means that
- // the model could change substantially and the view could decide to echo only a portion of this model.
- // Consequently, the participant views need to be created either by the session view or by the container panel.
- // For the moment, we create them here (which makes for complicated code...) to conform to the pattern
- // implemented in llinventorypanel.cpp (see LLInventoryPanel::buildNewViews()).
- // The best however would be to have an observer on the model so that we would not pool on each draw to know
- // if the view needs refresh. The current implementation (testing for change on draw) is less
- // efficient perf wise than a listener/observer scheme. We will implement that shortly.
+ // For debug only
+ //std::ostringstream llsd_value;
+ //llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
+ //llinfos << "Merov debug : onConversationModelEvent, event = " << llsd_value.str() << llendl;
+ // end debug
- // On each session in mConversationsItems
- for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+ // Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
+ // the model could change substantially and the view could echo only a portion of this model (though currently the
+ // conversation view does echo the conversation model 1 to 1).
+ // Consequently, the participant views need to be created either by the session view or by the container panel.
+ // For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp
+ // (see LLInventoryPanel::buildNewViews()).
+
+ std::string type = event.get("type").asString();
+ LLUUID session_id = event.get("session_uuid").asUUID();
+ LLUUID participant_id = event.get("participant_uuid").asUUID();
+
+ LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+ if (!session_view)
{
- // Get the current session descriptors
- LLConversationItem* session_model = it_session->second;
- LLUUID session_id = it_session->first;
- LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
- // If the session model has been changed, refresh the corresponding view
- if (session_model->needsRefresh())
+ // We skip events that are not associated to a session
+ return false;
+ }
+ LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+
+ if (type == "remove_participant")
+ {
+ if (participant_view)
{
+ session_view->extractItem(participant_view);
+ delete participant_view;
session_view->refresh();
+ mConversationsRoot->arrangeAll();
}
- // Iterate through each model participant child
- LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
- LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
- while (current_participant_model != end_participant_model)
+ }
+ else if (type == "add_participant")
+ {
+ if (!participant_view)
{
- LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
- LLUUID participant_id = participant_model->getUUID();
- LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
- // Is there a corresponding view? If not create it
- if (!participant_view)
- {
- participant_view = createConversationViewParticipant(participant_model);
- participant_view->addToFolder(session_view);
- participant_view->setVisible(TRUE);
- }
- else
- // Else, see if it needs refresh
+ LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+ if (session_model)
{
- if (participant_model->needsRefresh())
+ LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
+ if (participant_model)
{
- participant_view->refresh();
+ participant_view = createConversationViewParticipant(participant_model);
+ participant_view->addToFolder(session_view);
+ participant_view->setVisible(TRUE);
}
}
- // Reset the need for refresh
- session_model->resetRefresh();
- mConversationViewModel.requestSortAll();
- mConversationsRoot->arrangeAll();
- // Next participant
- current_participant_model++;
+
+ }
+ }
+ else if (type == "update_participant")
+ {
+ if (participant_view)
+ {
+ participant_view->refresh();
}
}
+ else if (type == "update_session")
+ {
+ session_view->refresh();
+ }
+
+ mConversationViewModel.requestSortAll();
+ mConversationsRoot->arrangeAll();
+ return false;
+}
+
+void LLIMFloaterContainer::draw()
+{
if (mTabContainer->getTabCount() == 0)
{
// Do not close the container when every conversation is torn off because the user
@@ -527,12 +553,25 @@ void LLIMFloaterContainer::collapseMessagesPane(bool collapse)
gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
}
+ // Save left pane rectangle before collapsing/expanding right pane.
+ LLRect prevRect = mConversationsPane->getRect();
+
// Show/hide the messages pane.
mConversationsStack->collapsePanel(mMessagesPane, collapse);
+ if (!collapse)
+ {
+ // Make sure layout is updated before resizing conversation pane.
+ mConversationsStack->updateLayout();
+ }
+
updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+ if (!collapse)
+ {
+ // Restore conversation's pane previous width after expanding messages pane.
+ mConversationsPane->setTargetDim(prevRect.getWidth());
+ }
}
-
void LLIMFloaterContainer::collapseConversationsPane(bool collapse)
{
if (mConversationsPane->isCollapsed() == collapse)
@@ -862,7 +901,13 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command,
}
else if("chat_history" == command)
{
- LLAvatarActions::viewChatHistory(conversationItem->getUUID());
+ const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(conversationItem->getUUID());
+
+ if (NULL != session)
+ {
+ const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+ LLFloaterReg::showInstance("preview_conversation", session_id, true);
+ }
}
else
{
@@ -1089,7 +1134,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
removeConversationListItem(uuid,false);
// Create a conversation session model
- LLConversationItem* item = NULL;
+ LLConversationItemSession* item = NULL;
LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
if (speaker_manager)
{
@@ -1101,6 +1146,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
return;
}
item->renameItem(display_name);
+ item->updateParticipantName(NULL);
mConversationsItems[uuid] = item;