From 2f21ec48a222662351c9f8e7243673eb6a31b457 Mon Sep 17 00:00:00 2001
From: Leslie Linden <leslie@lindenlab.com>
Date: Tue, 5 Jul 2011 12:32:12 -0700
Subject: [PATCH] EXP-860 FIX -- Display NEW for items added to inbox

* Added createFolderView, createFolderViewFolder and createFolderViewItem virtuals
  to LLInventoryPanel so these can be overridden by a derived class for custom display.
* Added new LLInboxInventoryPanel class that overrides createFolderViewFolder with a
  LLInboxFolderViewFolder for custom display with NEW tags.
* LLInboxFolderViewFolder NEW tag is tied to the mFresh variable that currently has
  no logic attached to it, meaning it remains off all the time.

Reviewed by Richard.
---
 indra/llui/llbadgeowner.cpp                   |   8 +
 indra/llui/llbadgeowner.h                     |   3 +
 indra/newview/CMakeLists.txt                  |  10 +-
 indra/newview/llinventorypanel.cpp            | 120 +++++++-----
 indra/newview/llinventorypanel.h              |   5 +
 .../llpanelmarketplaceinboxinventory.cpp      | 178 ++++++++++++++++++
 .../llpanelmarketplaceinboxinventory.h        |  78 ++++++++
 .../default/xui/en/panel_inbox_inventory.xml  |   6 +-
 .../en/widgets/inbox_folder_view_folder.xml   |  10 +
 9 files changed, 365 insertions(+), 53 deletions(-)
 create mode 100644 indra/newview/llpanelmarketplaceinboxinventory.cpp
 create mode 100644 indra/newview/llpanelmarketplaceinboxinventory.h
 create mode 100644 indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml

diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp
index 3d63fc7f60d..77f15567bf6 100644
--- a/indra/llui/llbadgeowner.cpp
+++ b/indra/llui/llbadgeowner.cpp
@@ -73,6 +73,14 @@ void LLBadgeOwner::setBadgeLabel(const LLStringExplicit& label)
 	}
 }
 
+void LLBadgeOwner::setBadgeVisibility(bool visible)
+{
+	if (mBadge)
+	{
+		mBadge->setVisible(visible);
+	}
+}
+
 void LLBadgeOwner::addBadgeToParentPanel()
 {
 	LLView * owner_view = mBadgeOwnerView.get();
diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h
index 456ef90c130..a2399189a55 100644
--- a/indra/llui/llbadgeowner.h
+++ b/indra/llui/llbadgeowner.h
@@ -42,8 +42,11 @@ class LLBadgeOwner
 
 	void initBadgeParams(const LLBadge::Params& p);
 	void addBadgeToParentPanel();
+	
+	bool badgeHasParent() const { return (mBadge && mBadge->getParent()); }
 
 	void setBadgeLabel(const LLStringExplicit& label);
+	void setBadgeVisibility(bool visible);
 
 private:
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d79d3f1f727..a78fe3aab59 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -361,8 +361,9 @@ set(viewer_SOURCE_FILES
     llpanellogin.cpp
     llpanelloginlistener.cpp
     llpanelmaininventory.cpp
-	llpanelmarketplaceinbox.cpp
-	llpanelmarketplaceoutbox.cpp
+    llpanelmarketplaceinbox.cpp
+    llpanelmarketplaceinboxinventory.cpp
+    llpanelmarketplaceoutbox.cpp
     llpanelmediasettingsgeneral.cpp
     llpanelmediasettingspermissions.cpp
     llpanelmediasettingssecurity.cpp
@@ -911,8 +912,9 @@ set(viewer_HEADER_FILES
     llpanellogin.h
     llpanelloginlistener.h
     llpanelmaininventory.h
-	llpanelmarketplaceinbox.h
-	llpanelmarketplaceoutbox.h
+    llpanelmarketplaceinbox.h
+    llpanelmarketplaceinboxinventory.h
+    llpanelmarketplaceoutbox.h
     llpanelmediasettingsgeneral.h
     llpanelmediasettingspermissions.h
     llpanelmediasettingssecurity.h
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 864e6a181ea..49170caee81 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -216,26 +216,15 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 		llwarns << "No category found that matches start_folder: " << start_folder_name << llendl;
 		root_id = LLUUID::generateNewID();
 	}
-
-	LLRect folder_rect(0,
-						0,
-						getRect().getWidth(),
-						0);
-	LLFolderView::Params p;
-	p.name = getName();
-	p.title = getLabel();
-	p.rect = folder_rect;
-	p.parent_panel = this;
-	p.tool_tip = p.name;
-	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-													LLAssetType::AT_CATEGORY,
-													LLInventoryType::IT_CATEGORY,
-													this,
-													NULL,
-													root_id);
-	p.use_label_suffix = params.use_label_suffix;
-	p.allow_multiselect = mAllowMultiSelect;
-	mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
+	
+	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+																	LLAssetType::AT_CATEGORY,
+																	LLInventoryType::IT_CATEGORY,
+																	this,
+																	NULL,
+																	root_id);
+	
+	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
 }
 
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
@@ -611,6 +600,69 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 	buildNewViews(id);
 }
 
+LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
+{
+	LLRect folder_rect(0,
+					   0,
+					   getRect().getWidth(),
+					   0);
+
+	LLFolderView::Params p;
+	
+	p.name = getName();
+	p.title = getLabel();
+	p.rect = folder_rect;
+	p.parent_panel = this;
+	p.tool_tip = p.name;
+	p.listener =  bridge;
+	p.use_label_suffix = useLabelSuffix;
+	p.allow_multiselect = mAllowMultiSelect;
+
+	return LLUICtrlFactory::create<LLFolderView>(p);
+}
+
+LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
+{
+	LLFolderViewFolder::Params params;
+
+	params.name = bridge->getDisplayName();
+	params.icon = bridge->getIcon();
+	params.icon_open = bridge->getOpenIcon();
+
+	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+	{
+		params.icon_overlay = LLUI::getUIImage("Inv_Link");
+	}
+	
+	params.root = mFolderRoot;
+	params.listener = bridge;
+	params.tool_tip = params.name;
+
+	return LLUICtrlFactory::create<LLFolderViewFolder>(params);
+}
+
+LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
+{
+	LLFolderViewItem::Params params;
+	
+	params.name = bridge->getDisplayName();
+	params.icon = bridge->getIcon();
+	params.icon_open = bridge->getOpenIcon();
+
+	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+	{
+		params.icon_overlay = LLUI::getUIImage("Inv_Link");
+	}
+
+	params.creation_date = bridge->getCreationDate();
+	params.root = mFolderRoot;
+	params.listener = bridge;
+	params.rect = LLRect (0, 0, 0, 0);
+	params.tool_tip = params.name;
+	
+	return LLUICtrlFactory::create<LLFolderViewItem>(params);
+}
+
 void LLInventoryPanel::buildNewViews(const LLUUID& id)
 {
  	LLInventoryObject const* objectp = gInventory.getObject(id);
@@ -649,18 +701,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
   																				objectp->getUUID());
   				if (new_listener)
   				{
-  					LLFolderViewFolder::Params params;
-  					params.name = new_listener->getDisplayName();
-  					params.icon = new_listener->getIcon();
-  					params.icon_open = new_listener->getOpenIcon();
-  					if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-  					{
-  						params.icon_overlay = LLUI::getUIImage("Inv_Link");
-  					}
-  					params.root = mFolderRoot;
-  					params.listener = new_listener;
-  					params.tool_tip = params.name;
-  					LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
+					LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
   					folderp->setItemSortOrder(mFolderRoot->getSortOrder());
   					itemp = folderp;
   				}
@@ -679,20 +720,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
  
   				if (new_listener)
   				{
-  					LLFolderViewItem::Params params;
-  					params.name = new_listener->getDisplayName();
-  					params.icon = new_listener->getIcon();
-  					params.icon_open = new_listener->getOpenIcon();
-  					if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-  					{
-  						params.icon_overlay = LLUI::getUIImage("Inv_Link");
-  					}
-  					params.creation_date = new_listener->getCreationDate();
-  					params.root = mFolderRoot;
-  					params.listener = new_listener;
-  					params.rect = LLRect (0, 0, 0, 0);
-  					params.tool_tip = params.name;
-  					itemp = LLUICtrlFactory::create<LLFolderViewItem> (params);
+					itemp = createFolderViewItem(new_listener);
   				}
   			}
  
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 4b915484f89..4d06573ad9c 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -39,6 +39,7 @@
 #include "lluictrlfactory.h"
 #include <set>
 
+class LLFolderViewFolder;
 class LLFolderViewItem;
 class LLInventoryFilter;
 class LLInventoryModel;
@@ -221,6 +222,10 @@ class LLInventoryPanel : public LLPanel
 	virtual void		buildFolderView(const LLInventoryPanel::Params& params);
 	virtual void		buildNewViews(const LLUUID& id);
 	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
+	
+	virtual LLFolderView*		createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
+	virtual LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge);
+	virtual LLFolderViewItem*	createFolderViewItem(LLInvFVBridge * bridge);
 private:
 	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
 	BOOL				mViewsInitialized; // Views have been generated
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
new file mode 100644
index 00000000000..50f3451b6fd
--- /dev/null
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -0,0 +1,178 @@
+/** 
+ * @file llpanelmarketplaceinboxinventory.cpp
+ * @brief LLInboxInventoryPanel  class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpanelmarketplaceinboxinventory.h"
+
+#include "llfolderview.h"
+#include "llfoldervieweventlistener.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llpanellandmarks.h"
+#include "llplacesinventorybridge.h"
+#include "llviewerfoldertype.h"
+
+
+//
+// statics
+//
+
+static LLDefaultChildRegistry::Register<LLInboxInventoryPanel> r1("inbox_inventory_panel");
+static LLDefaultChildRegistry::Register<LLInboxFolderViewFolder> r2("inbox_folder_view_folder");
+
+
+//
+// LLInboxInventoryPanel Implementation
+//
+
+LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
+	: LLInventoryPanel(p)
+{
+}
+
+LLInboxInventoryPanel::~LLInboxInventoryPanel()
+{
+}
+
+// virtual
+void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
+{
+	// Determine the root folder in case specified, and
+	// build the views starting with that folder.
+	
+	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
+	
+	// leslie -- temporary HACK to work around sim not creating inbox and outbox with proper system folder type
+	if (root_id.isNull())
+	{
+		std::string start_folder_name(params.start_folder());
+		
+		LLInventoryModel::cat_array_t* cats;
+		LLInventoryModel::item_array_t* items;
+		
+		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
+		
+		if (cats)
+		{
+			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
+			{
+				LLInventoryCategory* cat = *cat_it;
+				
+				if (cat->getName() == start_folder_name)
+				{
+					root_id = cat->getUUID();
+					break;
+				}
+			}
+		}
+		
+		if (root_id == LLUUID::null)
+		{
+			llwarns << "No category found that matches inbox inventory panel start_folder: " << start_folder_name << llendl;
+		}
+	}
+	// leslie -- end temporary HACK
+	
+	if (root_id == LLUUID::null)
+	{
+		llwarns << "Inbox inventory panel has no root folder!" << llendl;
+		root_id = LLUUID::generateNewID();
+	}
+	
+	LLRect folder_rect(0, 0, getRect().getWidth(), 0);
+
+	LLFolderView::Params p;
+
+	p.name = getName();
+	p.title = getLabel();
+	p.rect = folder_rect;
+	p.parent_panel = this;
+	p.tool_tip = p.name;
+	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+													LLAssetType::AT_CATEGORY,
+													LLInventoryType::IT_CATEGORY,
+													this,
+													NULL,
+													root_id);
+	p.use_label_suffix = params.use_label_suffix;
+	p.allow_multiselect = mAllowMultiSelect;
+	
+	mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
+}
+
+LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
+{
+	LLInboxFolderViewFolder::Params params;
+	
+	params.name = bridge->getDisplayName();
+	params.icon = bridge->getIcon();
+	params.icon_open = bridge->getOpenIcon();
+	
+	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
+	{
+		params.icon_overlay = LLUI::getUIImage("Inv_Link");
+	}
+	
+	params.root = mFolderRoot;
+	params.listener = bridge;
+	params.tool_tip = params.name;
+	
+	return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
+}
+
+
+//
+// LLInboxFolderViewFolder Implementation
+//
+
+LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
+	: LLFolderViewFolder(p)
+	, LLBadgeOwner(getHandle())
+	, mFresh(false)
+{
+	initBadgeParams(p.new_badge());
+}
+
+LLInboxFolderViewFolder::~LLInboxFolderViewFolder()
+{
+}
+
+// virtual
+void LLInboxFolderViewFolder::draw()
+{
+	if (!badgeHasParent())
+	{
+		addBadgeToParentPanel();
+	}
+	
+	setBadgeVisibility(mFresh);
+
+	LLFolderViewFolder::draw();
+}
+
+
+// eof
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
new file mode 100644
index 00000000000..71b8d0be67a
--- /dev/null
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -0,0 +1,78 @@
+/** 
+ * @file llpanelmarketplaceinboxinventory.h
+ * @brief LLInboxInventoryPanel class declaration
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_INBOXINVENTORYPANEL_H
+#define LL_INBOXINVENTORYPANEL_H
+
+
+#include "llbadgeowner.h"
+#include "llinventorypanel.h"
+#include "llfolderviewitem.h"
+
+
+class LLInboxInventoryPanel : public LLInventoryPanel
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
+	{
+		Params() {}
+	};
+	
+	LLInboxInventoryPanel(const Params& p);
+	~LLInboxInventoryPanel();
+
+	// virtual
+	void buildFolderView(const LLInventoryPanel::Params& params);
+
+	// virtual
+	LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge);
+};
+
+
+class LLInboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
+	{
+		Optional<LLBadge::Params>	new_badge;
+		
+		Params()
+		: new_badge("new_badge")
+		{
+		}
+	};
+	
+	LLInboxFolderViewFolder(const Params& p);
+	~LLInboxFolderViewFolder();
+	
+	void draw();
+	
+protected:
+	bool	mFresh;
+};
+
+
+#endif //LL_INBOXINVENTORYPANEL_H
diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
index 49abbcde714..d06190ec548 100644
--- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inventory_panel
+<inbox_inventory_panel
     name="inventory_inbox"
-    start_folder="Inbox"
+    start_folder="Received Items"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
 	top_pad="0"
@@ -14,4 +14,4 @@
     show_item_link_overlays="true"
     >
     <scroll reserve_scroll_corner="false" />
-</inventory_panel>
+</inbox_inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
new file mode 100644
index 00000000000..2c987b158da
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<inbox_folder_view_folder
+  folder_arrow_image="Folder_Arrow"
+  folder_indentation="8"
+  item_height="20" 
+  item_top_pad="4"
+  selection_image="Rounded_Square"
+  >
+	<new_badge label="New" location="right" location_percent_hcenter="70" />
+</inbox_folder_view_folder>
-- 
GitLab