diff options
-rw-r--r-- | indra/newview/llconversationmodel.cpp | 14 | ||||
-rwxr-xr-x | indra/newview/llconversationmodel.h | 2 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.cpp | 62 | ||||
-rw-r--r-- | indra/newview/llimfloatercontainer.h | 3 |
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 |