From d1751df1cc5d9bf853f29555de94faec1912e19f Mon Sep 17 00:00:00 2001
From: Sergei Litovchuk <slitovchuk@productengine.com>
Date: Fri, 4 Jun 2010 21:52:38 +0300
Subject: [PATCH] EXT-7610 FIXED Added sorting outfit tabs by name (case
 insensitive).

Reviewed by Neal Orman at https://codereview.productengine.com/secondlife/r/523/.

--HG--
branch : product-engine
---
 indra/llui/llaccordionctrl.cpp    | 13 ++++++++++++
 indra/llui/llaccordionctrl.h      | 35 ++++++++++++++++++++++++++++++-
 indra/llui/llaccordionctrltab.cpp |  2 +-
 indra/llui/llaccordionctrltab.h   |  2 +-
 indra/newview/lloutfitslist.cpp   | 17 ++++++++++++++-
 indra/newview/lloutfitslist.h     | 18 +++++++++++++++-
 6 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index 5f866c49e60..6bf13475148 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -66,6 +66,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
  , mAutoScrolling( false )
  , mAutoScrollRate( 0.f )
  , mSelectedTab( NULL )
+ , mTabComparator( NULL )
  , mNoVisibleTabsHelpText(NULL)
 {
 	initNoTabsWidget(params.empty_accordion_text);
@@ -799,6 +800,18 @@ void	LLAccordionCtrl::reset		()
 		mScrollbar->setDocPos(0);
 }
 
+void LLAccordionCtrl::sort()
+{
+	if (!mTabComparator)
+	{
+		llwarns << "No comparator specified for sorting accordion tabs." << llendl;
+		return;
+	}
+
+	std::sort(mAccordionTabs.begin(), mAccordionTabs.end(), LLComparatorAdaptor(*mTabComparator));
+	arrange();
+}
+
 void	LLAccordionCtrl::setFilterSubString(const std::string& filter_string)
 {
 	LLStringUtil::format_map_t args;
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 2f483eafb2f..fc6f2d896c7 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -57,6 +57,19 @@ class LLAccordionCtrl: public LLPanel
 
 
 public:
+	/**
+	 * Abstract comparator for accordion tabs.
+	 */
+	class LLTabComparator
+	{
+	public:
+		LLTabComparator() {};
+		virtual ~LLTabComparator() {};
+
+		/** Returns true if tab1 < tab2, false otherwise */
+		virtual bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const = 0;
+	};
+
 	struct Params 
 		: public LLInitParam::Block<Params, LLPanel::Params>
 	{
@@ -108,6 +121,9 @@ class LLAccordionCtrl: public LLPanel
 
 	void	reset		();
 
+	void	setComparator(const LLTabComparator* comp) { mTabComparator = comp; }
+	void	sort();
+
 	/**
 	 * Sets filter substring as a search_term for help text when there are no any visible tabs.
 	 */
@@ -134,6 +150,21 @@ class LLAccordionCtrl: public LLPanel
 
 	BOOL	autoScroll				(S32 x, S32 y);
 
+	/**
+	 * An adaptor for LLTabComparator
+	 */
+	struct LLComparatorAdaptor
+	{
+		LLComparatorAdaptor(const LLTabComparator& comparator) : mComparator(comparator) {};
+
+		bool operator()(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2)
+		{
+			return mComparator.compare(tab1, tab2);
+		}
+
+		const LLTabComparator& mComparator;
+	};
+
 private:
 	LLRect			mInnerRect;
 	LLScrollbar*	mScrollbar;
@@ -141,9 +172,11 @@ class LLAccordionCtrl: public LLPanel
 	bool			mFitParent;
 	bool			mAutoScrolling;
 	F32				mAutoScrollRate;
-	LLAccordionCtrlTab* mSelectedTab;
 	LLTextBox*		mNoVisibleTabsHelpText;
 	std::string		mNoVisibleTabsOrigString;
+
+	LLAccordionCtrlTab*		mSelectedTab;
+	const LLTabComparator*	mTabComparator;
 };
 
 
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 83fcc77f2a2..1bc8086a276 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -473,7 +473,7 @@ void LLAccordionCtrlTab::setAccordionView(LLView* panel)
 	addChild(panel,0);
 }
 
-std::string LLAccordionCtrlTab::getTitle()
+std::string LLAccordionCtrlTab::getTitle() const
 {
 	LLAccordionCtrlTabHeader* header = findChild<LLAccordionCtrlTabHeader>(DD_HEADER_NAME);
 	if (header)
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index be8b464b8e5..82e0234bfc3 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -115,7 +115,7 @@ class LLAccordionCtrlTab : public LLUICtrl
 	void		setAccordionView(LLView* panel);
 	LLView*		getAccordionView() { return mContainerPanel; };
 
-	std::string getTitle();
+	std::string getTitle() const;
 
 	// Set text and highlight substring in LLAccordionCtrlTabHeader
 	void setTitle(const std::string& title, const std::string& hl = LLStringUtil::null);
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index a4ae957c76c..e20b2e26be6 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -53,6 +53,20 @@
 
 static bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y);
 
+static const LLOutfitTabNameComparator OUTFIT_TAB_NAME_COMPARATOR;
+
+/*virtual*/
+bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const
+{
+	std::string name1 = tab1->getTitle();
+	std::string name2 = tab2->getTitle();
+
+	LLStringUtil::toUpper(name1);
+	LLStringUtil::toUpper(name2);
+
+	return name1 < name2;
+}
+
 //////////////////////////////////////////////////////////////////////////
 
 class OutfitContextMenu : public LLListContextMenu
@@ -158,6 +172,7 @@ LLOutfitsList::~LLOutfitsList()
 BOOL LLOutfitsList::postBuild()
 {
 	mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
+	mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR);
 
 	return TRUE;
 }
@@ -328,7 +343,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)
 		updateOutfitTab(*items_iter);
 	}
 
-	mAccordion->arrange();
+	mAccordion->sort();
 }
 
 void LLOutfitsList::onSelectionChange(LLUICtrl* ctrl)
diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h
index 44f6ec908b6..bb516446d2d 100644
--- a/indra/newview/lloutfitslist.h
+++ b/indra/newview/lloutfitslist.h
@@ -32,17 +32,33 @@
 #ifndef LL_LLOUTFITSLIST_H
 #define LL_LLOUTFITSLIST_H
 
+#include "llaccordionctrl.h"
 #include "llpanel.h"
 
 // newview
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 
-class LLAccordionCtrl;
 class LLAccordionCtrlTab;
 class LLWearableItemsList;
 class LLListContextMenu;
 
+/**
+ * @class LLOutfitTabNameComparator
+ *
+ * Comparator of outfit tabs.
+ */
+class LLOutfitTabNameComparator : public LLAccordionCtrl::LLTabComparator
+{
+	LOG_CLASS(LLOutfitTabNameComparator);
+
+public:
+	LLOutfitTabNameComparator() {};
+	virtual ~LLOutfitTabNameComparator() {};
+
+	/*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const;
+};
+
 /**
  * @class LLOutfitsList
  *
-- 
GitLab