diff options
| -rw-r--r-- | indra/newview/llfloaterimcontainer.cpp | 42 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsessiontab.cpp | 72 | ||||
| -rw-r--r-- | indra/newview/llfloaterimsessiontab.h | 1 | 
3 files changed, 55 insertions, 60 deletions
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index af090338d7..bd692aa850 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -117,26 +117,20 @@ void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)  void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)  { -	llinfos << "Merov debug : sessionIDUpdated, old_session_id = " << old_session_id << ", new_session_id = " << new_session_id << llendl; -	// Retrieve the session LLFloaterIMSessionTab -	// just close it: that should erase the mSession, close the tab and remove the list item -	// *TODO : take the mSessions element (pointing to the tab) out of the list -	//bool change_focus = removeConversationListItem(old_session_id); -	// *TODO : detach the old tab from the host -	// *TODO : delete the tab (that's one thing that's reentrant) -	LLFloater* floaterp = get_ptr_in_map(mSessions, old_session_id); -	if (floaterp) -	{ -		llinfos << "Merov debug : closeFloater, start" << llendl; -		floaterp->closeFloater(); -		llinfos << "Merov debug : closeFloater, end" << llendl; -	} -	bool change_focus = false; -	llinfos << "Merov debug : addConversationListItem" << llendl; +	// The general strategy when a session id is modified is to delete all related objects and create them anew. +	 +	// Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived()  +	// and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress  +	// its related mSessions record as it's indexed with the wrong id. +	// Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem(). +	mSessions.erase(old_session_id); + +	// Delete the model and participants related to the old session +	bool change_focus = removeConversationListItem(old_session_id); + +	// Create a new conversation with the new id  	addConversationListItem(new_session_id, change_focus); -	llinfos << "Merov debug : addToHost" << llendl;  	LLFloaterIMSessionTab::addToHost(new_session_id); -	llinfos << "Merov debug : end sessionIDUpdated" << llendl;  }  void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id) @@ -483,14 +477,14 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)  	else if (type == "update_session")  	{  		session_view->refresh(); -		if (conversation_floater) -		{ -			conversation_floater->refreshConversation(); -		}  	}  	mConversationViewModel.requestSortAll();  	mConversationsRoot->arrangeAll(); +	if (conversation_floater) +	{ +		conversation_floater->refreshConversation(); +	}  	return false;  } @@ -1253,10 +1247,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&  		return item_it->second;  	} -	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway -	// and nothing wrong will happen removing it if it doesn't exist -	removeConversationListItem(uuid,false); -  	// Create a conversation session model  	LLConversationItemSession* item = NULL;  	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid)); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 6fbc713590..22131eac49 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -52,6 +52,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)    ,  mCloseBtn(NULL)    ,  mSessionID(session_id.asUUID())    , mConversationsRoot(NULL) +  , mScroller(NULL)    , mChatHistory(NULL)    , mInputEditor(NULL)    , mInputEditorTopPad(0) @@ -68,10 +69,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)  			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));  	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",  			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2)); - -	// Zero expiry time is set only once to allow initial update. -	mRefreshTimer->setTimerExpirySec(0); -	mRefreshTimer->start();  }  LLFloaterIMSessionTab::~LLFloaterIMSessionTab() @@ -195,33 +192,16 @@ BOOL LLFloaterIMSessionTab::postBuild()  	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); +	mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); +	mScroller->setFollowsAll(); +	// Insert that scroller into the panel widgets hierarchy +	mParticipantListPanel->addChild(mScroller);	  	mChatHistory = getChild<LLChatHistory>("chat_history"); @@ -235,8 +215,6 @@ BOOL LLFloaterIMSessionTab::postBuild()  	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE); -	buildConversationViewParticipant(); -  	mSaveRect = isTornOff();  	initRectControl(); @@ -249,8 +227,14 @@ BOOL LLFloaterIMSessionTab::postBuild()  		result = LLDockableFloater::postBuild();  	} +	// Now ready to build the conversation and participants list +	buildConversationViewParticipant();  	refreshConversation(); -	 +		 +	// Zero expiry time is set only once to allow initial update. +	mRefreshTimer->setTimerExpirySec(0); +	mRefreshTimer->start(); +  	return result;  } @@ -276,9 +260,8 @@ void LLFloaterIMSessionTab::draw()  			{  				buildConversationViewParticipant();  			} +			refreshConversation();  		} -		 -		refreshConversation();  		// Restart the refresh timer  		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL); @@ -390,7 +373,31 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()  		// Nothing to do if the model list is inexistent  		return;  	} - +	 +	// Create or recreate the root folder: this is a dummy folder (not shown) but required by the LLFolderView architecture  +	// We need to redo this when rebuilding as the session id (mSessionID) *may* have changed +	if (mConversationsRoot) +	{ +		// Remove the old root if any +		mScroller->removeChild(mConversationsRoot); +	} +	// Create the root using an ad-hoc base item +	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); +	// Attach that root to the scroller +	mScroller->addChild(mConversationsRoot); +	mConversationsRoot->setScrollContainer(mScroller); +	mConversationsRoot->setFollowsAll(); +	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox); +	  	// 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(); @@ -420,7 +427,6 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p  		participant_view->addToFolder(mConversationsRoot);  		participant_view->addToSession(mSessionID);  		participant_view->setVisible(TRUE); -		refreshConversation();  	}  } @@ -432,7 +438,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part  		mConversationsRoot->extractItem(widget);  		delete widget;  		mConversationsWidgets.erase(participant_id); -		refreshConversation();  	}  } @@ -443,7 +448,6 @@ void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& part  	{  		widget->refresh();  	} -	refreshConversation();  }  void LLFloaterIMSessionTab::refreshConversation() diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 8f5a8c2c1b..b765d121de 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -146,6 +146,7 @@ protected:  	conversations_widgets_map mConversationsWidgets;  	LLConversationViewModel mConversationViewModel;  	LLFolderView* mConversationsRoot; +	LLScrollContainer* mScroller;  	LLChatHistory* mChatHistory;  	LLChatEntry* mInputEditor;  | 
