summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llconversationmodel.cpp14
-rwxr-xr-xindra/newview/llconversationmodel.h2
-rw-r--r--indra/newview/llimfloatercontainer.cpp62
-rw-r--r--indra/newview/llimfloatercontainer.h3
4 files changed, 70 insertions, 11 deletions
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 5fc305da81..0f29ffe77f 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
+#include "llevents.h"
#include "llconversationmodel.h"
#include "llimview.h" //For LLIMModel
@@ -64,6 +65,16 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
{
}
+void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemParticipant* participant)
+{
+ LLSD event;
+ event["type"] = event_type;
+ event["session_uuid"] = getUUID();
+ event["participant_name"] = participant->getName();
+ event["participant_uuid"] = participant->getUUID();
+ LLEventPumps::instance().obtain("ConversationsEvents").post(event);
+}
+
// Virtual action callbacks
void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
{
@@ -130,12 +141,14 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
addChild(participant);
mIsLoaded = true;
mNeedsRefresh = true;
+ postEvent("add_participant", participant);
}
void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
{
removeChild(participant);
mNeedsRefresh = true;
+ postEvent("remove_participant", participant);
}
void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
@@ -328,6 +341,7 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
mNeedsRefresh = true;
+ postEvent("update_participant", this);
if (mParent)
{
mParent->requestSort();
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index bc72cd96ea..7218cdf25a 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -126,6 +126,8 @@ public:
void resetRefresh() { mNeedsRefresh = false; }
bool needsRefresh() { return mNeedsRefresh; }
+ void postEvent(const std::string& event_type, LLConversationItemParticipant* participant);
+
void buildParticipantMenuOptions(menuentry_vec_t& items);
protected:
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 5a323583b8..da4d1afb2b 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),
+ mStream("ConversationsEvents"),
mInitialized(false)
{
mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
@@ -155,6 +157,9 @@ BOOL LLIMFloaterContainer::postBuild()
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ // Add listener to conversation model events
+ mStream.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,18 +402,47 @@ 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
+ // 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()).
+
+ // Note: For the moment, we're not very smart about the event parameter and we just refresh the whole set of views/widgets
+ // according to the current state of the whole model.
+ // We should at least analyze the event payload and do things differently for a handful of cases:
+ // - add session or participant
+ // - remove session or participant
+ // - update session or participant (e.g. rename, change sort order, etc...)
+ // Please see LLConversationItem::postEvent() for the payload formatting.
+ // *TODO: Add handling for various event signatures (add, remove, update, resort)
+
+ std::string type = event.get("type").asString();
+ if (type == "remove_participant")
+ {
+ LLUUID session_id = event.get("session_uuid").asUUID();
+ LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+ LLUUID participant_id = event.get("participant_uuid").asUUID();
+ LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+ if (participant_view)
+ {
+ session_view->extractItem(participant_view);
+ delete participant_view;
+ session_view->refresh();
+ mConversationsRoot->arrangeAll();
+ }
+ }
+ else
+ {
// On each session in mConversationsItems
for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
{
@@ -437,7 +471,7 @@ void LLIMFloaterContainer::draw()
participant_view->setVisible(TRUE);
}
else
- // Else, see if it needs refresh
+ // Else, see if it needs refresh
{
if (participant_model->needsRefresh())
{
@@ -452,7 +486,13 @@ void LLIMFloaterContainer::draw()
current_participant_model++;
}
}
+ }
+ return false;
+}
+
+void LLIMFloaterContainer::draw()
+{
if (mTabContainer->getTabCount() == 0)
{
// Do not close the container when every conversation is torn off because the user
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 081c733884..5702b88a48 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -31,6 +31,7 @@
#include <vector>
#include "llimview.h"
+#include "llevents.h"
#include "llfloater.h"
#include "llmultifloater.h"
#include "llavatarpropertiesprocessor.h"
@@ -140,6 +141,7 @@ public:
private:
LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+ bool onConversationModelEvent(const LLSD& event);
// Conversation list data
LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to
@@ -147,6 +149,7 @@ private:
conversations_widgets_map mConversationsWidgets;
LLConversationViewModel mConversationViewModel;
LLFolderView* mConversationsRoot;
+ LLEventStream mStream;
};
#endif // LL_LLIMFLOATERCONTAINER_H