From 390bef2091b3458d93d009a98728e9115ead9302 Mon Sep 17 00:00:00 2001
From: Alexei Arabadji <aarabadji@productengine.com>
Date: Wed, 21 Jul 2010 09:54:25 +0300
Subject: EXT-6527 FIXED Avoided show agent/group SLURL icon in plain text
 mode. reviewed by Richard Nelson at
 https://codereview.productengine.com/secondlife/r/773/

--HG--
branch : product-engine
---
 indra/newview/llappviewer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 296e3b7e86..58b651ec39 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -357,7 +357,7 @@ static void ui_audio_callback(const LLUUID& uuid)
 
 bool	create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
 {
-	if(!match || !base)
+	if(!match || !base || base->getPlainText())
 		return false;
 
 	LLUUID match_id = match->getID();
-- 
cgit v1.2.3


From 576e70aab2a95da38ffd7aa780ace5ed41e12fc7 Mon Sep 17 00:00:00 2001
From: Paul Guslisty <pguslisty@productengine.com>
Date: Wed, 21 Jul 2010 14:52:02 +0300
Subject: EXT-8412 FIXED (Group Profile > Notices > Add label to + button, move
 header down)

- Added a text label to the + button reading \"New Notice\"
- Add more padding between button and content below

Reviewed by Mike Antipov at https://codereview.productengine.com/secondlife/r/766/

--HG--
branch : product-engine
---
 indra/newview/skins/default/xui/en/panel_group_notices.xml | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 6523b0d491..41f2b28004 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -76,19 +76,22 @@ Maximum 200 per group daily
        follows="top|left"
        height="23"
        image_overlay="AddItem_Off"
+       image_overlay_alignment="left"
+       imgoverlay_label_space="-10"
+       label="New Notice"
        layout="topleft"
        left="5"
        name="create_new_notice"
        tool_tip="Create a new notice"
-       top_delta="-3"
-       width="23" />
+       top_delta="0"
+       width="93" />
      <button
      follows="top|left"
      height="23"
      image_overlay="Refresh_Off"
      layout="topleft"
      name="refresh_notices"
-     left_pad="230"
+     left="260"
      tool_tip="Refresh list of notices"
      top_delta="0"
      width="23" />
@@ -113,7 +116,7 @@ Maximum 200 per group daily
          mouse_opaque="false"
          name="lbl"
          text_color="EmphasisColor"
-         top="0"
+         top="5"
          width="200">
             Create a Notice
         </text>
@@ -270,7 +273,7 @@ Maximum 200 per group daily
          mouse_opaque="false"
          name="lbl"
          text_color="EmphasisColor"
-         top_pad="0"
+         top_pad="5"
          width="265">
             Archived Notice
         </text>
-- 
cgit v1.2.3


From 258f67cd02627b8ab2b03f940f8f4fefe9f9848f Mon Sep 17 00:00:00 2001
From: Paul Guslisty <pguslisty@productengine.com>
Date: Wed, 21 Jul 2010 17:03:00 +0300
Subject: EXT-8205 FIXED (Items in \"Add more\" panel are not sorted by name)

- Modified LLWearableItemTypeNameComparator so that it can be more reusable and adjustable
- Set LLWearableItemTypeNameComparator for WearableItemsList ('List view' of 'Add More' panel) due to sort clothings by name
- Modified and applied patch form https://codereview.productengine.com/secondlife/r/620/diff/2/#index_header. This patch was discarded because specification was changed

Reviewed by Mike Antipov and Vadim Savchuk at https://codereview.productengine.com/secondlife/r/765/

--HG--
branch : product-engine
---
 indra/newview/llpaneloutfitedit.cpp   | 15 +++++++
 indra/newview/llpaneloutfitedit.h     |  2 +
 indra/newview/llwearableitemslist.cpp | 78 ++++++++++++++++++++++++++++-------
 indra/newview/llwearableitemslist.h   | 73 +++++++++++++++++++++++++-------
 4 files changed, 137 insertions(+), 31 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 767b01f039..e12344ce9d 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -283,6 +283,8 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()
 
 	delete mCOFDragAndDropObserver;
 
+	delete mWearableListViewItemsComparator;
+
 	while (!mListViewItemTypes.empty()) {
 		delete mListViewItemTypes.back();
 		mListViewItemTypes.pop_back();
@@ -386,11 +388,24 @@ BOOL LLPanelOutfitEdit::postBuild()
 
 	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
 
+	/*
+	 * By default AT_CLOTHING are sorted by (in in MY OUTFITS):
+	 *  - by type (types order determined in LLWearableType::EType)
+	 *  - each LLWearableType::EType by outer layer on top
+	 *
+	 * In Add More panel AT_CLOTHING should be sorted in a such way:
+	 *  - by type (types order determined in LLWearableType::EType)
+	 *  - each LLWearableType::EType by name (EXT-8205)
+	*/
+	mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator();
+	mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true);
+
 	mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel");
 	mWearableItemsList = getChild<LLInventoryItemsList>("list_view");
 	mWearableItemsList->setCommitOnSelectionChange(true);
 	mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));
 	mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
+	mWearableItemsList->setComparator(mWearableListViewItemsComparator);
 
 	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
 	return TRUE;
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index fe10215f27..ad128b1055 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -64,6 +64,7 @@ class LLMenuGL;
 class LLFindNonLinksByMask;
 class LLFindWearablesOfType;
 class LLSaveOutfitComboBtn;
+class LLWearableItemTypeNameComparator;
 
 class LLPanelOutfitEdit : public LLPanel
 {
@@ -222,6 +223,7 @@ private:
 	LLFilteredWearableListManager* 	mWearableListManager;
 	LLInventoryItemsList* 			mWearableItemsList;
 	LLPanel*						mWearablesListViewPanel;
+	LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;
 
 	LLCOFDragAndDropObserver* mCOFDragAndDropObserver;
 
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 35abbc0c4d..24f3b5b80b 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -465,6 +465,29 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+LLWearableItemTypeNameComparator::LLWearableTypeOrder::LLWearableTypeOrder(LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name):
+		mOrderPriority(order_priority),
+		mSortAssetTypeByName(sort_asset_by_name),
+		mSortWearableTypeByName(sort_wearable_by_name)
+{
+}
+
+LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
+{
+	// By default the sort order conforms the order by spec of MY OUTFITS items list:
+	// 1. CLOTHING - sorted by name
+	// 2. OBJECT   - sorted by type
+	// 3. BODYPART - sorted by name
+	mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
+	mWearableOrder[LLAssetType::AT_OBJECT]   = LLWearableTypeOrder(ORDER_RANK_2, true, true);
+	mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
+}
+
+void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type,  LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
+{
+	mWearableOrder[items_of_type] = LLWearableTypeOrder(order_priority, sort_asset_items_by_name, sort_wearable_items_by_name);
+}
+
 /*virtual*/
 bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const
 {
@@ -493,7 +516,7 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
 		return item_type_order1 < item_type_order2;
 	}
 
-	if (item_type_order1 & TLO_SORTABLE_BY_NAME)
+	if (sortAssetTypeByName(item_type1))
 	{
 		// If both items are of the same asset type except AT_CLOTHING and AT_BODYPART
 		// we can compare them by name.
@@ -505,38 +528,61 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
 
 	if (item_wearable_type1 != item_wearable_type2)
 	{
-		// If items are of different clothing types they are compared
-		// by clothing types order determined in LLWearableType::EType.
+		// If items are of different LLWearableType::EType types they are compared
+		// by LLWearableType::EType. types order determined in LLWearableType::EType.
 		return item_wearable_type1 < item_wearable_type2;
 	}
 	else
 	{
 		// If both items are of the same clothing type they are compared
-		// by description and place in reverse order i.e. outer layer item
-		// on top.
+		// by description and place in reverse order (i.e. outer layer item
+		// on top) OR by name
+		if(sortWearableTypeByName(item_type1))
+		{
+			return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2);
+		}
 		return wearable_item1->getDescription() > wearable_item2->getDescription();
 	}
 }
 
-// static
-LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type)
+LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type) const
 {
-	switch (item_type)
+	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
+
+	if(const_it == mWearableOrder.end())
 	{
-	case LLAssetType::AT_OBJECT:
-		return TLO_ATTACHMENT;
+		llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+		return ORDER_RANK_UNKNOWN;
+	}
 
-	case LLAssetType::AT_CLOTHING:
-		return TLO_CLOTHING;
+	return const_it->second.mOrderPriority;
+}
 
-	case LLAssetType::AT_BODYPART:
-		return TLO_BODYPART;
+bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType item_type) const
+{
+	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
 
-	default:
-		return TLO_UNKNOWN;
+	if(const_it == mWearableOrder.end())
+	{
+		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+		return true;
 	}
+
+	return const_it->second.mSortAssetTypeByName;
 }
 
+bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const
+{
+	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
+
+	if(const_it == mWearableOrder.end())
+	{
+		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
+		return true;
+	}
+
+	return const_it->second.mSortWearableTypeByName;
+}
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 367b648b3d..f2f81968ee 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -307,33 +307,76 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
 	LOG_CLASS(LLWearableItemTypeNameComparator);
 
 public:
-	LLWearableItemTypeNameComparator() {};
+
+	LLWearableItemTypeNameComparator();
 	virtual ~LLWearableItemTypeNameComparator() {};
 
+	enum ETypeListOrder
+	{
+		ORDER_RANK_1 = 1,
+		ORDER_RANK_2,
+		ORDER_RANK_3,
+		ORDER_RANK_UNKNOWN
+	};
+
+	void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name);
+
 protected:
 	/**
-	 * Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following:
-	 *   - Attachments (abc order)
-	 *   - Clothing
-	 *         - by type (types order determined in LLWearableType::EType)
-	 *         - outer layer on top
-	 *   - Body Parts (abc order),
-	 * "false" otherwise.
+	 * All information about sort order is stored in mWearableOrder map
+	 *
+	 * mWearableOrder :      KYES              VALUES
+	 *                  [LLAssetType] [struct LLWearableTypeOrder]
+	 *
+	 *---------------------------------------------------------------------------------------------
+	 * I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list.
+	 *     For example by spec in MY OUTFITS the order is:
+	 *     1. AT_CLOTHING (ORDER_RANK_1)
+	 *     2. AT_OBJECT   (ORDER_RANK_2)
+	 *     3. AT_BODYPART (ORDER_RANK_3)
+	 *
+	 * II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType)
+	 *     For example by spec in MY OUTFITS the order within each items type(LLAssetType) is:
+	 *     1. AT_OBJECTS (abc order)
+	 *     2. AT_CLOTHINGS
+	 *       - by type (types order determined in LLWearableType::EType)
+	 *       - outer layer on top
+	 *     3. AT_BODYPARTS  (abc order)
+	 *---------------------------------------------------------------------------------------------
+	 *
+	 * For each LLAssetType (KEYS in mWearableOrder) the information about:
+	 *
+	 *                                             I.  ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority)
+	 *
+	 *                                             II. whether items of this LLAssetType type should be ordered
+	 *                                                 by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName)
+	 *
+	 *                                             III.whether items of LLWearableType type within this LLAssetType
+	 *                                                 should be ordered by name (the flag is LLWearableTypeOrder::mSortWearableTypeByName)
+	 *
+	 *  holds in mWearableOrder map as VALUES (struct LLWearableTypeOrder).
 	 */
 	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;
 
 private:
-	enum ETypeListOrder
+
+	struct LLWearableTypeOrder
 	{
-		TLO_CLOTHING	= 0x01,
-		TLO_ATTACHMENT	= 0x02,
-		TLO_BODYPART	= 0x04,
-		TLO_UNKNOWN		= 0x08,
+		ETypeListOrder mOrderPriority;
+		bool mSortAssetTypeByName;
+		bool mSortWearableTypeByName;
 
-		TLO_SORTABLE_BY_NAME = TLO_ATTACHMENT | TLO_UNKNOWN
+		LLWearableTypeOrder(ETypeListOrder order_priority, bool sort_asset_by_name, bool sort_wearable_by_name);
+		LLWearableTypeOrder(){};
 	};
 
-	static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type);
+	ETypeListOrder getTypeListOrder(LLAssetType::EType item_type) const;
+
+	bool sortAssetTypeByName(LLAssetType::EType item_type) const;
+	bool sortWearableTypeByName(LLAssetType::EType item_type) const;
+
+	typedef std::map<LLAssetType::EType,LLWearableTypeOrder> wearable_type_order_map_t;
+	wearable_type_order_map_t mWearableOrder;
 };
 
 /**
-- 
cgit v1.2.3


From a96f47db68dd52fa94bc3e9f652623583f85c60a Mon Sep 17 00:00:00 2001
From: Andrew Polunin <apolunin@productengine.com>
Date: Wed, 21 Jul 2010 19:00:57 +0300
Subject: EXT-8164 FIXED (Accordions should be reset to default state after
 Edit Outfit panel reopening)

Now accordion on panels 'Edit Outfit', 'Editing Shape', 'Editing Hair', 'Editing Eyes', 'Editing Skin', 'Group Profile' and 'Place Profile' are reset when the panels are closed and then opened again.

Reviewed by Vadim Savchuk at https://codereview.productengine.com/secondlife/r/782/

--HG--
branch : product-engine
---
 indra/newview/llcofwearables.cpp        | 34 +++++++++++++++++++++++------
 indra/newview/llcofwearables.h          |  4 ++++
 indra/newview/llpaneleditwearable.cpp   | 38 +++++++++++++++++++++++++++++++++
 indra/newview/llpaneleditwearable.h     |  5 +++++
 indra/newview/llpanelgroup.cpp          | 12 +++++++++++
 indra/newview/llpanelgroup.h            |  3 ++-
 indra/newview/llpaneloutfitedit.cpp     | 12 +++++++++++
 indra/newview/llpaneloutfitedit.h       |  2 ++
 indra/newview/llpanelplaceprofile.cpp   |  9 +++++++-
 indra/newview/llpanelplaceprofile.h     |  2 ++
 indra/newview/llsidepanelappearance.cpp | 21 ++++++++++++++++--
 11 files changed, 131 insertions(+), 11 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index f75ea23351..f356a04fa4 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -284,7 +284,8 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),
 	mAttachmentsTab(NULL),
 	mBodyPartsTab(NULL),
 	mLastSelectedTab(NULL),
-	mCOFVersion(-1)
+	mCOFVersion(-1),
+	mAccordionCtrl(NULL)
 {
 	mClothingMenu = new CofClothingContextMenu(this);
 	mAttachmentMenu = new CofAttachmentContextMenu(this);
@@ -336,6 +337,8 @@ BOOL LLCOFWearables::postBuild()
 	mTab2AssetType[mAttachmentsTab] = LLAssetType::AT_OBJECT;
 	mTab2AssetType[mBodyPartsTab] = LLAssetType::AT_BODYPART;
 
+	mAccordionCtrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
+
 	return LLPanel::postBuild();
 }
 
@@ -652,18 +655,35 @@ LLAssetType::EType LLCOFWearables::getExpandedAccordionAssetType()
 	typedef std::map<std::string, LLAssetType::EType> type_map_t;
 
 	static type_map_t type_map;
-	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
-	const LLAccordionCtrlTab* expanded_tab = accordion_ctrl->getExpandedTab();
 
-	return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);
+	if (mAccordionCtrl != NULL)
+	{
+		const LLAccordionCtrlTab* expanded_tab = mAccordionCtrl->getExpandedTab();
+
+		return get_if_there(mTab2AssetType, expanded_tab, LLAssetType::AT_NONE);
 	}
 
+	return LLAssetType::AT_NONE;
+}
+
 LLAssetType::EType LLCOFWearables::getSelectedAccordionAssetType()
+{
+	if (mAccordionCtrl != NULL)
 	{
-	static LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("cof_wearables_accordion");
-	const LLAccordionCtrlTab* selected_tab = accordion_ctrl->getSelectedTab();
+		const LLAccordionCtrlTab* selected_tab = mAccordionCtrl->getSelectedTab();
 
-	return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);
+		return get_if_there(mTab2AssetType, selected_tab, LLAssetType::AT_NONE);
+	}
+
+	return LLAssetType::AT_NONE;
+}
+
+void LLCOFWearables::expandDefaultAccordionTab()
+{
+	if (mAccordionCtrl != NULL)
+	{
+		mAccordionCtrl->expandDefaultTab();
+	}
 }
 
 void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContextMenu* menu)
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index d005b75eaa..cd7cc060e5 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -40,6 +40,7 @@
 #include "llappearancemgr.h"
 #include "llinventorymodel.h"
 
+class LLAccordionCtrl;
 class LLAccordionCtrlTab;
 class LLListContextMenu;
 class LLPanelClothingListItem;
@@ -87,6 +88,7 @@ public:
 
 	LLAssetType::EType getExpandedAccordionAssetType();
 	LLAssetType::EType getSelectedAccordionAssetType();
+	void expandDefaultAccordionTab();
 
 	LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; }
 
@@ -125,6 +127,8 @@ protected:
 	LLListContextMenu* mAttachmentMenu;
 	LLListContextMenu* mBodyPartMenu;
 
+	LLAccordionCtrl*	mAccordionCtrl;
+
 	/* COF category version since last refresh */
 	S32 mCOFVersion;
 };
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index ec685405ed..62e6cdc79d 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -47,6 +47,7 @@
 #include "llvoavatarself.h"
 #include "lltexteditor.h"
 #include "lltextbox.h"
+#include "llaccordionctrl.h"
 #include "llaccordionctrltab.h"
 #include "llagentwearables.h"
 #include "llscrollingpanelparam.h"
@@ -666,6 +667,35 @@ void LLPanelEditWearable::updateAvatarHeightLabel()
 	mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param);
 }
 
+void LLPanelEditWearable::onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
+{
+	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
+	{
+		accordion_ctrl->expandDefaultTab();
+	}
+}
+
+void LLPanelEditWearable::setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel)
+{
+	if (bodypart_panel != NULL)
+	{
+		LLAccordionCtrl* accordion_ctrl = bodypart_panel->getChild<LLAccordionCtrl>("wearable_accordion");
+
+		if (accordion_ctrl != NULL)
+		{
+			bodypart_panel->setVisibleCallback(
+					boost::bind(&LLPanelEditWearable::onWearablePanelVisibilityChange, this, _2, accordion_ctrl));
+		}
+		else
+		{
+			llwarns << "accordion_ctrl is NULL" << llendl;
+		}
+	}
+	else
+	{
+		llwarns << "bodypart_panel is NULL" << llendl;
+	}
+}
 
 // virtual 
 BOOL LLPanelEditWearable::postBuild()
@@ -695,6 +725,14 @@ BOOL LLPanelEditWearable::postBuild()
 	mPanelEyes = getChild<LLPanel>("edit_eyes_panel");
 	mPanelHair = getChild<LLPanel>("edit_hair_panel");
 
+	// Setting the visibility callback is applied only to the bodyparts panel
+	// because currently they are the only ones whose 'wearable_accordion' has
+	// multiple accordion tabs (see EXT-8164 for details).
+	setWearablePanelVisibilityChangeCallback(mPanelShape);
+	setWearablePanelVisibilityChangeCallback(mPanelSkin);
+	setWearablePanelVisibilityChangeCallback(mPanelEyes);
+	setWearablePanelVisibilityChangeCallback(mPanelHair);
+
 	//clothes
 	mPanelShirt = getChild<LLPanel>("edit_shirt_panel");
 	mPanelPants = getChild<LLPanel>("edit_pants_panel");
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index dbda90fe9f..c0823dd3fa 100644
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -39,6 +39,7 @@
 #include "llvoavatardefines.h"
 #include "llwearabletype.h"
 
+class LLAccordionCtrl;
 class LLCheckBoxCtrl;
 class LLWearable;
 class LLTextBox;
@@ -113,6 +114,10 @@ private:
 	// updates avatar height label
 	void updateAvatarHeightLabel();
 
+	void onWearablePanelVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
+
+	void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel);
+
 	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.
 	LLWearable *mWearablePtr;
 	LLViewerInventoryItem* mWearableItem;
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index d997b83cbb..38e776b195 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -182,6 +182,11 @@ BOOL LLPanelGroup::postBuild()
 	LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
 	LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
 
+	if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion"))
+	{
+		setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl));
+	}
+
 	if(panel_general)	mTabs.push_back(panel_general);
 	if(panel_roles)		mTabs.push_back(panel_roles);
 	if(panel_notices)	mTabs.push_back(panel_notices);
@@ -305,6 +310,13 @@ void LLPanelGroup::onBtnCancel()
 	onBackBtnClick();
 }
 
+void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
+{
+	if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
+	{
+		accordion_ctrl->expandDefaultTab();
+	}
+}
 
 void LLPanelGroup::changed(LLGroupChange gc)
 {
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 13a03b0713..2b21e9895a 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -42,6 +42,7 @@ class LLOfferInfo;
 const S32 UPDATE_MEMBERS_PER_FRAME = 500;
 
 // Forward declares
+class LLAccordionCtrl;
 class LLPanelGroupTab;
 class LLTabContainer;
 class LLAgent;
@@ -102,6 +103,7 @@ protected:
 	void onBackBtnClick();
 	void onBtnJoin();
 	void onBtnCancel();
+	void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
 
 	static void onBtnApply(void*);
 	static void onBtnRefresh(void*);
@@ -126,7 +128,6 @@ protected:
 
 	LLButton*		mButtonJoin;
 	LLUICtrl*		mJoinText;
-
 };
 
 class LLPanelGroupTab : public LLPanel
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index e12344ce9d..c09aff44da 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -1027,6 +1027,18 @@ bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch
 	return false;
 }
 
+void LLPanelOutfitEdit::resetAccordionState()
+{
+	if (mCOFWearables != NULL)
+	{
+		mCOFWearables->expandDefaultAccordionTab();
+	}
+	else
+	{
+		llwarns << "mCOFWearables is NULL" << llendl;
+	}
+}
+
 void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
 {
 	if(!mGearMenu)
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index ad128b1055..13ceda98a6 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -183,6 +183,8 @@ public:
 	 */
 	bool switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel);
 
+	void resetAccordionState();
+
 	virtual BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									  EDragAndDropType cargo_type,
 									  void* cargo_data,
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 1f979b0ef1..08835dc2b8 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -79,7 +79,8 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()
 :	LLPanelPlaceInfo(),
 	mForSalePanel(NULL),
 	mYouAreHerePanel(NULL),
-	mSelectedParcelID(-1)
+	mSelectedParcelID(-1),
+	mAccordionCtrl(NULL)
 {}
 
 // virtual
@@ -139,6 +140,7 @@ BOOL LLPanelPlaceProfile::postBuild()
 	mSubdivideText = getChild<LLTextEditor>("subdivide");
 	mResaleText = getChild<LLTextEditor>("resale");
 	mSaleToText = getChild<LLTextBox>("sale_to");
+	mAccordionCtrl = getChild<LLAccordionCtrl>("advanced_info_accordion");
 
 	icon_pg = getString("icon_PG");
 	icon_m = getString("icon_M");
@@ -278,6 +280,11 @@ void LLPanelPlaceProfile::handleVisibilityChange(BOOL new_visibility)
 			parcel_mgr->deselectUnused();
 		}
 	}
+
+	if (mAccordionCtrl != NULL)
+	{
+		mAccordionCtrl->expandDefaultTab();
+	}
 }
 
 void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index e77b441567..49c13ff5e3 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -35,6 +35,7 @@
 
 #include "llpanelplaceinfo.h"
 
+class LLAccordionCtrl;
 class LLIconCtrl;
 class LLTextEditor;
 
@@ -118,6 +119,7 @@ private:
 	LLTextEditor*		mSubdivideText;
 	LLTextEditor*		mResaleText;
 	LLTextBox*			mSaleToText;
+	LLAccordionCtrl*	mAccordionCtrl;
 };
 
 #endif // LL_LLPANELPLACEPROFILE_H
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 7a7ffb9983..98cd0b88eb 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -190,13 +190,16 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
 {
 	if (new_visibility.asBoolean())
 	{
-		if ((mOutfitEdit && mOutfitEdit->getVisible()) || (mEditWearable && mEditWearable->getVisible()))
+		bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible();
+		bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible();
+
+		if (is_outfit_edit_visible || is_wearable_edit_visible)
 		{
 			if (!gAgentCamera.cameraCustomizeAvatar() && gSavedSettings.getBOOL("AppearanceCameraMovement"))
 			{
 				gAgentCamera.changeCameraToCustomizeAvatar();
 			}
-			if (mEditWearable && mEditWearable->getVisible())
+			if (is_wearable_edit_visible)
 			{
 				LLWearable *wearable_ptr = mEditWearable->getWearable();
 				if (gAgentWearables.getWearableIndex(wearable_ptr) == LLAgentWearables::MAX_CLOTHING_PER_TYPE)
@@ -205,6 +208,11 @@ void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
 					showOutfitEditPanel();
 				}
 			}
+
+			if (is_outfit_edit_visible)
+			{
+				mOutfitEdit->resetAccordionState();
+			}
 		}
 	}
 	else
@@ -283,6 +291,15 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()
 
 void LLSidepanelAppearance::showOutfitEditPanel()
 {
+	// Accordion's state must be reset in all cases except the one when user
+	// is returning back to the mOutfitEdit panel from the mEditWearable panel.
+	// The simplest way to control this is to check the visibility state of the mEditWearable
+	// BEFORE it is changed by the call to the toggleWearableEditPanel(FALSE, NULL, TRUE).
+	if (mEditWearable != NULL && !mEditWearable->getVisible() && mOutfitEdit != NULL)
+	{
+		mOutfitEdit->resetAccordionState();
+	}
+
 	togglMyOutfitsPanel(FALSE);
 	toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
 	toggleOutfitEditPanel(TRUE);
-- 
cgit v1.2.3