From ec15ff6350c0997421cf2884e40aa9feaa070d4d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 5 Jul 2012 16:42:20 -0700
Subject: [PATCH] CHUI-98 : WIP, use the refactored folder view for
 conversation view list

---
 indra/llui/llfolderview.cpp            | 36 +++++++----
 indra/newview/llimfloatercontainer.cpp | 23 ++++++-
 indra/newview/llimfloatercontainer.h   | 83 ++++++++++++++++++++++++++
 3 files changed, 128 insertions(+), 14 deletions(-)

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 990b79a30bc..92e3b7a8e9e 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -320,10 +320,10 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
 
 	LLFolderViewFolder::arrange(&mMinWidth, &target_height);
 
-	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
+	LLRect scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
 
-	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
+	LLRect new_scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
 	{
 		reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
@@ -945,7 +945,7 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 	mAutoOpenItems.push(item);
 	
 	item->setOpen(TRUE);
-	LLRect content_rect = mScrollContainer->getContentWindowRect();
+	LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
 	scrollToShowItem(item, constraint_rect);
 }
@@ -1225,25 +1225,37 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 
 	case KEY_PAGE_UP:
 		mSearchString.clear();
-		mScrollContainer->pageUp(30);
+		if (mScrollContainer)
+		{
+			mScrollContainer->pageUp(30);
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_PAGE_DOWN:
 		mSearchString.clear();
-		mScrollContainer->pageDown(30);
+		if (mScrollContainer)
+		{
+			mScrollContainer->pageDown(30);
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_HOME:
 		mSearchString.clear();
-		mScrollContainer->goToTop();
+		if (mScrollContainer)
+		{
+			mScrollContainer->goToTop();
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_END:
 		mSearchString.clear();
-		mScrollContainer->goToBottom();
+		if (mScrollContainer)
+		{
+			mScrollContainer->goToBottom();
+		}
 		break;
 
 	case KEY_DOWN:
@@ -1719,8 +1731,8 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 
 LLRect LLFolderView::getVisibleRect()
 {
-	S32 visible_height = mScrollContainer->getRect().getHeight();
-	S32 visible_width = mScrollContainer->getRect().getWidth();
+	S32 visible_height = (mScrollContainer ? mScrollContainer->getRect().getHeight() : 0);
+	S32 visible_width  = (mScrollContainer ? mScrollContainer->getRect().getWidth()  : 0);
 	LLRect visible_rect;
 	visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
 	return visible_rect;
@@ -1816,7 +1828,7 @@ void LLFolderView::update()
 			// lets pin it!
 			mPinningSelectedItem = TRUE;
 
-			LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
+			LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect());
 			LLFolderViewItem* selected_item = mSelectedItems.back();
 
 			LLRect item_rect;
@@ -1831,7 +1843,7 @@ void LLFolderView::update()
 			else
 			{
 				// otherwise we just want it onscreen somewhere
-				LLRect content_rect = mScrollContainer->getContentWindowRect();
+				LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 				mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 			}
 		}
@@ -1854,7 +1866,7 @@ void LLFolderView::update()
 	else
 	{
 		// during normal use (page up/page down, etc), just try to fit item on screen
-		LLRect content_rect = mScrollContainer->getContentWindowRect();
+		LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 	}
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 2b943df48f9..be38eddbaf6 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -91,12 +91,14 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
+	mRoot = new LLConversationItem();
 	LLFolderView::Params p;
-	//TODO RN: define view model for conversations
-	//p.view_model = ?;
+	// CHUI-98 : View Model for conversations
+	p.view_model = &mConversationViewModel;
 	p.parent_panel = mConversationsListPanel;
 	p.rect = mConversationsListPanel->getLocalRect();
 	p.follows.flags = FOLLOWS_ALL;
+	p.listener = mRoot;
 
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	mConversationsListPanel->addChild(mFolders);
@@ -544,6 +546,15 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
 		mName = "Nearby Chat";
 }
 
+LLConversationItem::LLConversationItem() :
+	mName(""),
+	mUUID(),
+	mFloater(NULL),
+	mContainer(NULL)
+{
+}
+
+
 // Virtual action callbacks
 void LLConversationItem::selectItem(void)
 {
@@ -589,4 +600,12 @@ void LLConversationItem::showProperties(void)
 {
 }
 
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+	// We compare only by name for the moment
+	// *TODO : Implement the sorting by date
+	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+	return (compare < 0);
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 890a115a049..f146e658971 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -57,6 +57,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
 	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
+	LLConversationItem();
 	virtual ~LLConversationItem() {}
 
 	// Stub those things we won't really be using in this conversation context
@@ -120,6 +121,86 @@ class LLConversationItem : public LLFolderViewModelItemCommon
     LLFloater* mFloater;
     LLIMFloaterContainer* mContainer;
 };
+
+// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
+// We just stubb everything for the moment.
+class LLConversationFilter : public LLFolderViewFilter
+{
+public:
+		
+	enum ESortOrderType
+	{
+		SO_NAME = 0,						// Sort inventory by name
+		SO_DATE = 0x1,						// Sort inventory by date
+	};
+
+	LLConversationFilter() { mEmpty = ""; }
+	~LLConversationFilter() {}
+		
+	bool 				check(const LLFolderViewModelItem* item) { return true; }
+	bool				checkFolder(const LLFolderViewModelItem* folder) const { return true; }
+	void 				setEmptyLookupMessage(const std::string& message) { }
+	std::string			getEmptyLookupMessage() const { return mEmpty; }
+	bool				showAllResults() const { return true; }
+		
+	bool 				isActive() const { return false; }
+	bool 				isModified() const { return false; }
+	void 				clearModified() { }
+	const std::string& 	getName() const { return mEmpty; }
+	const std::string& 	getFilterText() { return mEmpty; }
+	void 				setModified(EFilterModified behavior = FILTER_RESTART) { }
+		
+	void 				setFilterCount(S32 count) { }
+	S32 				getFilterCount() const { return 0; }
+	void 				decrementFilterCount() { }
+		
+	bool 				isDefault() const { return true; }
+	bool 				isNotDefault() const { return false; }
+	void 				markDefault() { }
+	void 				resetDefault() { }
+		
+	S32 				getCurrentGeneration() const { return 0; }
+	S32 				getFirstSuccessGeneration() const { return 0; }
+	S32 				getFirstRequiredGeneration() const { return 0; }
+private:
+	std::string mEmpty;
+};
+
+class LLConversationSort
+{
+public:
+	LLConversationSort(U32 order = 0)
+	:	mSortOrder(order),
+	mByDate(false),
+	mByName(false)
+	{
+		mByDate = (order & LLConversationFilter::SO_DATE);
+		mByName = (order & LLConversationFilter::SO_NAME);
+	}
+	
+	bool isByDate() const { return mByDate; }
+	U32 getSortOrder() const { return mSortOrder; }
+	
+	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mByName;
+};
+
+class LLConversationViewModel
+:	public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
+{
+public:
+	typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
+	
+	void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort
+	bool contentsReady() { return true; }	// *TODO : we need to check that participants names are available somewhat
+	bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
+	
+private:
+};
+
 // CHUI-137 : End
 
 class LLIMFloaterContainer
@@ -189,6 +270,8 @@ class LLIMFloaterContainer
 	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
 	LLFloater* findConversationItem(LLUUID& uuid);
 private:
+	LLConversationViewModel mConversationViewModel;
+	LLConversationItem* mRoot; 
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
-- 
GitLab