diff options
Diffstat (limited to 'indra/newview/llimconversation.cpp')
-rw-r--r-- | indra/newview/llimconversation.cpp | 193 |
1 files changed, 175 insertions, 18 deletions
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp index b687e18cae..920666ef90 100644 --- a/indra/newview/llimconversation.cpp +++ b/indra/newview/llimconversation.cpp @@ -49,7 +49,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) @@ -73,11 +74,13 @@ LLIMConversation::LLIMConversation(const LLSD& session_id) LLIMConversation::~LLIMConversation() { + /* if (mParticipantList) { delete mParticipantList; mParticipantList = NULL; } + */ delete mRefreshTimer; } @@ -176,11 +179,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(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"); @@ -193,7 +224,7 @@ BOOL LLIMConversation::postBuild() setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); - buildParticipantList(); + buildConversationViewParticipant(); updateHeaderAndToolbar(); @@ -216,15 +247,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(); @@ -314,30 +350,144 @@ 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) + LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); + mConversationsWidgets[uuid] = participant_view; + participant_view->addToFolder(mConversationsRoot); + participant_view->setVisible(TRUE); + refreshConversation(); + } +} + +void LLIMConversation::removeConversationViewParticipant(const LLUUID& participant_id) +{ + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); + if (widget) + { + mConversationsRoot->extractItem(widget); + delete widget; + mConversationsWidgets.erase(participant_id); + refreshConversation(); + } +} + +void LLIMConversation::updateConversationViewParticipant(const LLUUID& participant_id) +{ + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); + if (widget) + { + widget->refresh(); + refreshConversation(); + } +} + +void LLIMConversation::refreshConversation() +{ + // Debug : Check that all participant models do have a view (debug consistency check) + /* + LLParticipantList* item = getParticipantList(); + llinfos << "Merov debug : Start consistency check" << llendl; + 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) + { + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + if (participant_model != NULL) + { + LLUUID uuid = participant_model->getUUID(); + LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid); + if (!widget) + { + llinfos << "Merov debug : Consistency error! Couldn't find widget for " << participant_model->getName() << llendl; + } + else + { + llinfos << "Merov debug : Consistency check pass for " << participant_model->getName() << llendl; + } + } + else { - 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); + llinfos << "Merov debug : Consistency check, skip non participant child" << llendl; } + current_participant_model++; } - updateHeaderAndToolbar(); + llinfos << "Merov debug : End consistency check" << llendl; + */ + + conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); + while (widget_it != mConversationsWidgets.end()) + { + widget_it->second->refresh(); + widget_it->second->setVisible(TRUE); + ++widget_it; + } + 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::onSortMenuItemClicked(const LLSD& userdata) { // TODO: Check this code when sort order menu will be added. (EM) - if (!mParticipantList) + if (!getParticipantList()) { return; } @@ -346,7 +496,7 @@ void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata) if (chosen_item == "sort_name") { - mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME); + getParticipantList()->setSortOrder(LLParticipantList::E_SORT_BY_NAME); } } @@ -407,6 +557,12 @@ void LLIMConversation::hideOrShowTitle() floater_contents->setShape(contents_rect); } +void LLIMConversation::updateSessionName(const std::string& name) +{ + llinfos << "Merov debug : updateSessionName, name = " << name << llendl; + mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name); +} + void LLIMConversation::hideAllStandardButtons() { for (S32 i = 0; i < BUTTON_COUNT; i++) @@ -565,6 +721,7 @@ void LLIMConversation::onTearOffClicked() initRectControl(); LLFloater::onClickTearOff(this); updateHeaderAndToolbar(); + refreshConversation(); } // static |