Commits

dessie linden committed 8235c76 Merge

Merged from q/viewer-release

Comments (0)

Files changed (95)

indra/llui/llflatlistview.cpp

 	allow_select("allow_select"),
 	multi_select("multi_select"),
 	keep_one_selected("keep_one_selected"),
+	keep_selection_visible_on_reshape("keep_selection_visible_on_reshape",false),
 	no_items_text("no_items_text")
 {};
 
 void LLFlatListView::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
 {
+	S32 delta = height - getRect().getHeight();
 	LLScrollContainer::reshape(width, height, called_from_parent);
 	setItemsNoScrollWidth(width);
 	rearrangeItems();
+	
+	if(delta!= 0 && mKeepSelectionVisibleOnReshape)
+	{
+		ensureSelectedVisible();
+	}
 }
 
 const LLRect& LLFlatListView::getItemsRect() const
   , mPrevNotifyParentRect(LLRect())
   , mNoItemsCommentTextbox(NULL)
   , mIsConsecutiveSelection(false)
+  , mKeepSelectionVisibleOnReshape(p.keep_selection_visible_on_reshape)
 {
 	mBorderThickness = getBorderWidth();
 
 :	LLFlatListView(p)
 , mNoFilteredItemsMsg(p.no_filtered_items_msg)
 , mNoItemsMsg(p.no_items_msg)
+, mForceShowingUnmatchedItems(false)
+, mLastFilterSucceded(false)
 {
 
 }
 
 }
 
+bool LLFlatListViewEx::getForceShowingUnmatchedItems()
+{
+	return mForceShowingUnmatchedItems;
+}
+
+void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
+{
+	mForceShowingUnmatchedItems = show;
+}
+
 void LLFlatListViewEx::setFilterSubString(const std::string& filter_str)
 {
 	if (0 != LLStringUtil::compareInsensitive(filter_str, mFilterSubString))
 	item_panel_list_t items;
 	getItems(items);
 
+	mLastFilterSucceded = false;
 	for (item_panel_list_t::iterator
 			 iter = items.begin(),
 			 iter_end = items.end();
 		// i.e. we don't hide items that don't support 'match_filter' action, separators etc.
 		if (0 == pItem->notify(action))
 		{
+			mLastFilterSucceded = true;
 			pItem->setVisible(true);
 		}
 		else
 		{
 			// TODO: implement (re)storing of current selection.
 			selectItem(pItem, false);
-			pItem->setVisible(false);
+			pItem->setVisible(mForceShowingUnmatchedItems);
 		}
 	}
 
 	notifyParentItemsRectChanged();
 }
 
+bool LLFlatListViewEx::wasLasFilterSuccessfull()
+{
+	return mLastFilterSucceded;
+}
+
 //EOF

indra/llui/llflatlistview.h

 		/** don't allow to deselect all selected items (for mouse events on items only) */
 		Optional<bool> keep_one_selected;
 
+		/** try to keep selection visible after reshape */
+		Optional<bool> keep_selection_visible_on_reshape;
+
 		/** padding between items */
 		Optional<U32> item_pad; 
 
 
 	bool mIsConsecutiveSelection;
 
+	bool mKeepSelectionVisibleOnReshape;
+
 	/** All pairs of the list */
 	pairs_list_t mItemPairs;
 
 	void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; }
 	void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; }
 
+	bool getForceShowingUnmatchedItems();
+
+	void setForceShowingUnmatchedItems(bool show);
+
 	/**
 	 * Sets up new filter string and filters the list.
 	 */
 	 */
 	void filterItems();
 
+	/**
+	 * Returns true if last call of filterItems() found at least one matching item
+	 */
+	bool wasLasFilterSuccessfull();
+
 protected:
 	LLFlatListViewEx(const Params& p);
 
 	std::string mNoFilteredItemsMsg;
 	std::string mNoItemsMsg;
 	std::string	mFilterSubString;
+	/**
+	 * Show list items that don't match current filter
+	 */
+	bool mForceShowingUnmatchedItems;
+	/**
+	 * True if last call of filterItems() found at least one matching item
+	 */
+	bool mLastFilterSucceded;
 };
 
 #endif

indra/newview/CMakeLists.txt

     llpaneltopinfobar.cpp
     llpanelvolume.cpp
     llpanelvolumepulldown.cpp
+    llpanelwearing.cpp
     llparcelselection.cpp
     llparticipantlist.cpp
     llpatchvertexarray.cpp
     lloutfitslist.h
     lloutfitobserver.h
     lloutputmonitorctrl.h
+    llpanelappearancetab.h
     llpanelavatar.h
     llpanelavatartag.h
     llpanelblockedlist.h
     llpaneltopinfobar.h
     llpanelvolume.h
     llpanelvolumepulldown.h
+    llpanelwearing.h
     llparcelselection.h
     llparticipantlist.h
     llpatchvertexarray.h

indra/newview/llagentcamera.cpp

 const F32 APPEARANCE_MIN_ZOOM = 0.39f;
 const F32 APPEARANCE_MAX_ZOOM = 8.f;
 
+const F32 CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST = 3.5f;
+
 const F32 GROUND_TO_AIR_CAMERA_TRANSITION_TIME = 0.5f;
 const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f;
 
 	mFocusObjectOffset(),
 	mFocusDotRadius( 0.1f ),			// meters
 	mTrackFocusObject(TRUE),
-	mUIOffset(0.f),
 
 	mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
 	mWalkKey(0), // like AtKey, but causes less forward thrust
 
 //	llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl;
 
-	F32 ui_offset = 0.f;
-	if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
-	{
-		ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global );
-	}
-
-
 	LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal);
 	
 	mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global);
 	LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
 	//LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
 	//end Ventrella
-
-	//RN: translate UI offset after camera is oriented properly
-	LLViewerCamera::getInstance()->translate(LLViewerCamera::getInstance()->getLeftAxis() * ui_offset);
 	
 	// Change FOV
 	LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
 }
 
 //-----------------------------------------------------------------------------
-// calcCustomizeAvatarUIOffset()
-//-----------------------------------------------------------------------------
-F32 LLAgentCamera::calcCustomizeAvatarUIOffset(const LLVector3d& camera_pos_global)
-{
-	F32 ui_offset = 0.f;
-
-	F32 range = (F32)dist_vec(camera_pos_global, getFocusGlobal());
-	mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
-	return mUIOffset * range;
-}
-
-//-----------------------------------------------------------------------------
 // calcFocusPositionTargetGlobal()
 //-----------------------------------------------------------------------------
 LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 		LLVOAvatarSelf::onCustomizeStart();
 	}
 
+
+	// default focus point for customize avatar
+	LLVector3 focus_target;
+	if (isAgentAvatarValid())
+	{
+		focus_target = gAgentAvatarp->mHeadp->getWorldPosition();
+	}
+	else
+	{
+		focus_target = gAgent.getPositionAgent();
+	}
+
 	if (isAgentAvatarValid())
 	{
 		if(avatar_animate)
 		{	
-			// slamming the avatar's axis to the camera so that when the rotation
-			// completes it correctly points to the front of the avatar
 			// Remove any pitch or rotation from the avatar
-			LLVector3 at = LLViewerCamera::getInstance()->getAtAxis();
+			LLVector3 at = gAgent.getAtAxis();
 			at.mV[VZ] = 0.f;
 			at.normalize();
 			gAgent.resetAxes(at);
 
 			if (turn_motion)
 			{
-				mAnimationDuration = turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP;
+				setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
 
 			}
 			else
 			{
-				mAnimationDuration = gSavedSettings.getF32("ZoomTime");
+				setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
 			}
 		}
 
-		// this is what sets the avatar as the mFocusTargetGlobal
-		setFocusGlobal(LLVector3d::zero);
+		LLVector3 agent_at = gAgent.getAtAxis();
+		agent_at.mV[VZ] = 0.f;
+		agent_at.normalize();
+
+		LLVector3d camera_offset(agent_at * -1.0);
+		// push camera up and out from avatar
+		camera_offset.mdV[VZ] = 0.1f; 
+		camera_offset *= CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST;
+		LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
+		setCameraPosAndFocusGlobal(focus_target_global + camera_offset, focus_target_global, gAgent.getID());
 		
 		gAgentAvatarp->updateMeshTextures();
 	}
 // Focus point management
 //
 
+void LLAgentCamera::setAnimationDuration(F32 duration)
+{ 
+	if (mCameraAnimating)
+	{
+		// do not cut any existing camera animation short
+		F32 animation_left = llmax(0.f, mAnimationDuration - mAnimationTimer.getElapsedTimeF32());
+		mAnimationDuration = llmax(duration, animation_left);
+	}
+	else
+	{
+		mAnimationDuration = duration; 
+	}
+}
+
 //-----------------------------------------------------------------------------
 // startCameraAnimation()
 //-----------------------------------------------------------------------------
 {
 	mAnimationCameraStartGlobal = getCameraPositionGlobal();
 	mAnimationFocusStartGlobal = mFocusGlobal;
+	setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
 	mAnimationTimer.reset();
 	mCameraAnimating = TRUE;
-	mAnimationDuration = gSavedSettings.getF32("ZoomTime");
 }
 
 //-----------------------------------------------------------------------------
 	if (focus_delta_squared > ANIM_EPSILON_SQUARED)
 	{
 		startCameraAnimation();
-
-		if (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) 
-		{
-			// Compensate for the fact that the camera has already been offset to make room for LLFloaterCustomize.
-			mAnimationCameraStartGlobal -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal ));
-		}
 	}
 	
 	//LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) );

indra/newview/llagentcamera.h

 	F32				getCameraMinOffGround(); 		// Minimum height off ground for this mode, meters
 	void			setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; }
 	BOOL			calcCameraMinDistance(F32 &obj_min_distance);
-	F32				calcCustomizeAvatarUIOffset(const LLVector3d& camera_pos_global);
 	F32				getCurrentCameraBuildOffset() 	{ return (F32)mCameraFocusOffset.length(); }
 	void			clearCameraLag() { mCameraLag.clearVec(); }
 private:
 public:
 	void			setCameraAnimating(BOOL b)			{ mCameraAnimating = b; }
 	BOOL			getCameraAnimating()				{ return mCameraAnimating; }
-	void			setAnimationDuration(F32 seconds) 	{ mAnimationDuration = seconds; }
+	void			setAnimationDuration(F32 seconds);
 	void			startCameraAnimation();
 	void			stopCameraAnimation();
 private:
 	LLVector3		mFocusObjectOffset;
 	F32				mFocusDotRadius; 				// Meters
 	BOOL			mTrackFocusObject;
-	F32				mUIOffset;	
 	
 	//--------------------------------------------------------------------
 	// Lookat / Pointat

indra/newview/llagentwearables.cpp

 #include "llmd5.h"
 #include "llnotificationsutil.h"
 #include "lloutfitobserver.h"
-#include "llpaneloutfitsinventory.h"
 #include "llsidepanelappearance.h"
 #include "llsidetray.h"
 #include "lltexlayer.h"
 	gAgentAvatarp->onFirstTEMessageReceived();
 }
 
-
-class LLShowCreatedOutfit: public LLInventoryCallback
-{
-public:
-	LLShowCreatedOutfit(LLUUID& folder_id):
-		mFolderID(folder_id)
-	{
-	}
-
-	virtual ~LLShowCreatedOutfit()
-	{
-		LLSD key;
-		LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key);
-		LLPanelOutfitsInventory *outfit_panel =
-			dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
-		// TODO: add handling "My Outfits" tab.
-		if (outfit_panel && outfit_panel->isCOFPanelActive())
-		{
-			outfit_panel->getRootFolder()->clearSelection();
-			outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE);
-		}
-		LLAccordionCtrlTab* tab_outfits = outfit_panel ? outfit_panel->findChild<LLAccordionCtrlTab>("tab_outfits") : 0;
-		if (tab_outfits && !tab_outfits->getDisplayChildren())
-		{
-			tab_outfits->changeOpenClose(tab_outfits->getDisplayChildren());
-		}
-
-		LLAppearanceMgr::instance().updateIsDirty();
-		LLAppearanceMgr::instance().updatePanelOutfitName("");
-	}
-	
-	virtual void fire(const LLUUID&)
-	{
-	}
-	
-private:
-	LLUUID mFolderID;
-};
-
 void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
 {
 	LLUUID first_item_id = getWearableItemID((LLWearableType::EType)type, index);

indra/newview/llappearancemgr.cpp

 #include "llinventoryobserver.h"
 #include "llnotificationsutil.h"
 #include "lloutfitobserver.h"
-#include "llpaneloutfitsinventory.h"
+#include "lloutfitslist.h"
 #include "llselectmgr.h"
 #include "llsidepanelappearance.h"
 #include "llsidetray.h"
 	// That means subscribers will be notified that loading is done after first item in a batch is worn.
 	// (loading indicator disappears for example before all selected items are worn)
 	// Have not fix this issue for 2.1 because of stability reason. EXT-7777.
-	gAgentWearables.notifyLoadingStarted();
+
+	// Disabled for now because it is *not* acceptable to call updateAppearanceFromCOF() multiple times
+//	gAgentWearables.notifyLoadingStarted();
 
 	LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear);
 	if (!item_to_wear) return false;
 
 void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append)
 {
+	if(!category) return;
+
 	gAgentWearables.notifyLoadingStarted();
-	if(!category) return;
 
 	llinfos << "wearInventoryCategory( " << category->getName()
 			 << " )" << llendl;
 		{
 			LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key);
 		}
-		LLPanelOutfitsInventory *outfit_panel =
-			dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
-		if (outfit_panel)
+		LLOutfitsList *outfits_list =
+			dynamic_cast<LLOutfitsList*>(LLSideTray::getInstance()->getPanel("outfitslist_tab"));
+		if (outfits_list)
 		{
-			outfit_panel->getRootFolder()->clearSelection();
-			outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE);
-		}
-		
-		LLAccordionCtrlTab* tab_outfits = outfit_panel ? outfit_panel->findChild<LLAccordionCtrlTab>("tab_outfits") : 0;
-		if (tab_outfits && !tab_outfits->getDisplayChildren())
-		{
-			tab_outfits->changeOpenClose(tab_outfits->getDisplayChildren());
+			outfits_list->setSelectedOutfitByUUID(mFolderID);
 		}
 
 		LLAppearanceMgr::getInstance()->updateIsDirty();
 	   {
 		   // we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF.
 		   // it will trigger gAgentWariables.notifyLoadingFinished()
-		   LLAppearanceMgr::addCOFItemLink(item_id, true);  // Add COF link for item.
+		   // But it is not acceptable solution. See EXT-7777
+		   LLAppearanceMgr::addCOFItemLink(item_id, false);  // Add COF link for item.
 	   }
 	   else
 	   {
 		 ++it)
 	{
 		LLUUID item_id = *it;
-		addCOFItemLink(item_id, true);
+		addCOFItemLink(item_id, false);
 	}
 	mRegisteredAttachments.clear();
 }

indra/newview/llappearancemgr.h

 #define LL_LLAPPEARANCEMGR_H
 
 #include "llsingleton.h"
+
+#include "llagentwearables.h"
+#include "llcallbacklist.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 #include "llviewerinventory.h"
-#include "llcallbacklist.h"
 
 class LLWearable;
 class LLWearableHoldingPattern;
 					<< llendl;
 			//dec_busy_count();
 			gInventory.removeObserver(this);
+
+			// lets notify observers that loading is finished.
+			gAgentWearables.notifyLoadingFinished();
 			delete this;
 			return;
 		}

indra/newview/llinventorybridge.cpp

 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
 #include "llwearablelist.h"
-#include "llpaneloutfitsinventory.h"
 
 typedef std::pair<LLUUID, LLUUID> two_uuids_t;
 typedef std::list<two_uuids_t> two_uuids_list_t;
 {
 	const LLInventoryObject *obj = getInventoryObject();
 
-	bool is_sidepanel = isInOutfitsSidePanel();
-	if (is_sidepanel)
-	{
-		// Sidepanel includes restricted menu.
-		if (obj && obj->getIsLinkType() && !get_is_item_worn(mUUID))
-		{
-			items.push_back(std::string("Remove Link"));
-		}
-		return;
-	}
-
 	if (obj)
 	{
 		if (obj->getIsLinkType())
 	}
 }
 
-BOOL LLInvFVBridge::isInOutfitsSidePanel() const
-{
-	LLInventoryPanel *my_panel = dynamic_cast<LLInventoryPanel*>(mInventoryPanel.get());
-	LLPanelOutfitsInventory *outfit_panel =
-		dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
-	if (!outfit_panel)
-		return FALSE;
-	return outfit_panel->isTabPanel(my_panel);
-}
-
 BOOL LLInvFVBridge::canShare() const
 {
 	const LLInventoryModel* model = getInventoryModel();
 	const bool is_ensemble = (type == LLFolderType::FT_NONE ||
 							  LLFolderType::lookupIsEnsembleType(type));
 
-	// calling card related functionality for folders.
-
-	const bool is_sidepanel = isInOutfitsSidePanel();
-	if (is_sidepanel)
-	{
-		mItems.push_back("Rename");
-		addDeleteContextMenuOptions(mItems, disabled_items);
-	}
-
 	// Only enable calling-card related options for non-system folders.
-	if (!is_sidepanel && !is_system_folder)
+	if (!is_system_folder)
 	{
 		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
 		if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
 		checkFolderForContentsOfType(model, is_object) ||
 		checkFolderForContentsOfType(model, is_gesture) )
 	{
-		if (!is_sidepanel)
-		{
-			mItems.push_back(std::string("Folder Wearables Separator"));
-		}
+		mItems.push_back(std::string("Folder Wearables Separator"));
 
 		// Only enable add/replace outfit for non-system folders.
 		if (!is_system_folder)
 		{
 			disabled_items.push_back(std::string("Share"));
 		}
-		bool is_sidepanel = isInOutfitsSidePanel();
-
-		if (!is_sidepanel)
-		{
-			addOpenRightClickMenuOption(items);
-			items.push_back(std::string("Properties"));
-		}
 
 		getClipboardEntries(true, items, disabled_items, flags);
 
 		{
 			disabled_items.push_back(std::string("Share"));
 		}
-		bool is_sidepanel = isInOutfitsSidePanel();
-
-		if (!is_sidepanel)
-		{
-			items.push_back(std::string("Properties"));
-		}
+
+		items.push_back(std::string("Properties"));
 
 		getClipboardEntries(true, items, disabled_items, flags);
 
 		{
 			disabled_items.push_back(std::string("Share"));
 		}
-		bool is_sidepanel = isInOutfitsSidePanel();
 		
-		if (can_open && !is_sidepanel)
+		if (can_open)
 		{
 			addOpenRightClickMenuOption(items);
 		}
 
-		if (!is_sidepanel)
-		{
-			items.push_back(std::string("Properties"));
-		}
+		items.push_back(std::string("Properties"));
 
 		getClipboardEntries(true, items, disabled_items, flags);
 
-		if (!is_sidepanel)
-		{
-			items.push_back(std::string("Wearable Separator"));
-		}
+		items.push_back(std::string("Wearable Separator"));
 
 		items.push_back(std::string("Wearable Edit"));
 

indra/newview/llinventorybridge.h

 									   U32 flags = 0x00);
 	virtual ~LLInvFVBridge() {}
 
-	BOOL isInOutfitsSidePanel() const; // allow context menus to be customized for side panel
 	BOOL canShare() const;
 
 	//--------------------------------------------------------------------

indra/newview/llmanip.cpp

 	S32 vertical_offset = window_center_y - VERTICAL_OFFSET;
 
 
-	glPushMatrix();
+	gGL.pushMatrix();
 	{
 		LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
 		gViewerWindow->setup2DRender();
 		const LLVector2& display_scale = gViewerWindow->getDisplayScale();
-		glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
+		gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
 		gGL.color4f(0.f, 0.f, 0.f, 0.7f);
 
 		imagep->draw(
 			PAD * 2 + 10, 
 			LLColor4(0.f, 0.f, 0.f, 0.7f) );
 	}
-	glPopMatrix();
+	gGL.popMatrix();
 
 	gViewerWindow->setup3DRender();
 

indra/newview/llmorphview.cpp

 	mOldCameraNearClip( 0.f ),
 	mCameraPitch( 0.f ),
 	mCameraYaw( 0.f ),
-	mCameraDist( -1.f ),
 	mCameraDrivenByKeys( FALSE )
 {}
 
 {
 	mCameraPitch = 0.f;
 	mCameraYaw = 0.f;
-	mCameraDist = -1.f;
 
 	if (!isAgentAvatarValid() || gAgentAvatarp->isDead())
 	{

indra/newview/llmorphview.h

 	};
 	LLMorphView(const LLMorphView::Params&);
 	
-	void		initialize();
 	void		shutdown();
 
 	// inherited methods
 
 	void		setCameraOffset(const LLVector3d& camera_offset)	{mCameraOffset = camera_offset;}
 	void		setCameraTargetOffset(const LLVector3d& camera_target_offset) {mCameraTargetOffset = camera_target_offset;}
-	void		setCameraDistToDefault()					{ mCameraDist = -1.f; }
 
 	void		updateCamera();
 	void		setCameraDrivenByKeys( BOOL b );
 
 protected:
+	void		initialize();
+
 	LLJoint*	mCameraTargetJoint;
 	LLVector3d	mCameraOffset;
 	LLVector3d	mCameraTargetOffset;
 	F32			mCameraPitch;
 	F32			mCameraYaw;
 
-	// camera zoom
-	F32			mCameraDist;
-
 	BOOL		mCameraDrivenByKeys;
 };
 

indra/newview/lloutfitslist.cpp

 
 //////////////////////////////////////////////////////////////////////////
 
-class OutfitContextMenu : public LLListContextMenu
+class LLOutfitListGearMenu
+{
+public:
+	LLOutfitListGearMenu(LLOutfitsList* olist)
+	:	mOutfitList(olist),
+		mMenu(NULL)
+	{
+		llassert_always(mOutfitList);
+
+		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+		registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this));
+		registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this));
+		registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this));
+		registrar.add("Gear.Delete", boost::bind(&LLOutfitListGearMenu::onDelete, this));
+		registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
+
+		enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitsList::isActionEnabled, mOutfitList, _2));
+		enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));
+
+		mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
+			"menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+		llassert(mMenu);
+	}
+
+	void show(LLView* spawning_view)
+	{
+		if (!mMenu) return;
+
+		updateItemsVisibility();
+		mMenu->buildDrawLabels();
+		mMenu->updateParent(LLMenuGL::sMenuContainer);
+		S32 menu_x = 0;
+		S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight();
+		LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y);
+	}
+
+	void updateItemsVisibility()
+	{
+		if (!mMenu) return;
+
+		bool have_selection = getSelectedOutfitID().notNull();
+		mMenu->setItemVisible("sepatator1", have_selection);
+		mMenu->setItemVisible("sepatator2", have_selection);
+		mMenu->arrangeAndClear(); // update menu height
+	}
+
+private:
+	const LLUUID& getSelectedOutfitID()
+	{
+		return mOutfitList->getSelectedOutfitUUID();
+	}
+
+	LLViewerInventoryCategory* getSelectedOutfit()
+	{
+		const LLUUID& selected_outfit_id = getSelectedOutfitID();
+		if (selected_outfit_id.isNull())
+		{
+			return NULL;
+		}
+
+		LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id);
+		return cat;
+	}
+
+	void onWear()
+	{
+		LLViewerInventoryCategory* selected_outfit = getSelectedOutfit();
+		if (selected_outfit)
+		{
+			LLAppearanceMgr::instance().wearInventoryCategory(
+				selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
+		}
+	}
+
+	void onTakeOff()
+	{
+		const LLUUID& selected_outfit_id = getSelectedOutfitID();
+		if (selected_outfit_id.notNull())
+		{
+			LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
+		}
+	}
+
+	void onRename()
+	{
+		const LLUUID& selected_outfit_id = getSelectedOutfitID();
+		if (selected_outfit_id.notNull())
+		{
+			LLAppearanceMgr::instance().renameOutfit(selected_outfit_id);
+		}
+	}
+
+	void onDelete()
+	{
+		const LLUUID& selected_outfit_id = getSelectedOutfitID();
+		if (selected_outfit_id.notNull())
+		{
+			remove_category(&gInventory, selected_outfit_id);
+		}
+	}
+
+	void onCreate(const LLSD& data)
+	{
+		LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
+		if (type == LLWearableType::WT_NONE)
+		{
+			llwarns << "Invalid wearable type" << llendl;
+			return;
+		}
+
+		LLAgentWearables::createWearable(type, true);
+	}
+
+	bool onVisible(LLSD::String param)
+	{
+		const LLUUID& selected_outfit_id = getSelectedOutfitID();
+		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
+		{
+			return false;
+		}
+
+		// *TODO This condition leads to menu item behavior inconsistent with
+		// "Wear" button behavior and should be modified or removed.
+		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
+
+		if ("wear" == param)
+		{
+			return !is_worn;
+		}
+
+		return true;
+	}
+
+	LLOutfitsList*	mOutfitList;
+	LLMenuGL*		mMenu;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+class LLOutfitContextMenu : public LLListContextMenu
 {
 protected:
 	/* virtual */ LLContextMenu* createMenu()
 		registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id));
 		registrar.add("Outfit.Delete", boost::bind(deleteOutfit, selected_id));
 
-		enable_registrar.add("Outfit.OnEnable", boost::bind(&OutfitContextMenu::onEnable, this, _2));
-		enable_registrar.add("Outfit.OnVisible", boost::bind(&OutfitContextMenu::onVisible, this, _2));
+		enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2));
+		enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitContextMenu::onVisible, this, _2));
 
 		return createFromFile("menu_outfit_tab.xml");
 	}
 		{
 			return get_is_category_renameable(&gInventory, outfit_cat_id);
 		}
+		else if ("wear_replace" == param)
+		{
+			return !gAgentWearables.isCOFChangeInProgress();
+		}
 		else if ("wear_add" == param)
 		{
+			if (gAgentWearables.isCOFChangeInProgress()) return false;
 			return LLAppearanceMgr::getCanAddToCOF(outfit_cat_id);
 		}
 		else if ("take_off" == param)
 static LLRegisterPanelClassWrapper<LLOutfitsList> t_outfits_list("outfits_list");
 
 LLOutfitsList::LLOutfitsList()
-	:	LLPanel()
+	:	LLPanelAppearanceTab()
 	,	mAccordion(NULL)
 	,	mListCommands(NULL)
 	,	mIsInitialized(false)
 {
 	mCategoriesObserver = new LLInventoryCategoriesObserver();
 
-	mOutfitMenu = new OutfitContextMenu();
+	mGearMenu = new LLOutfitListGearMenu(this);
+	mOutfitMenu = new LLOutfitContextMenu();
 }
 
 LLOutfitsList::~LLOutfitsList()
 {
+	delete mGearMenu;
 	delete mOutfitMenu;
 
 	if (gInventory.containsObserver(mCategoriesObserver))
 		// Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875)
 		tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id));
 
+		// force showing list items that don't match current filter(EXT-7158)
+		list->setForceShowingUnmatchedItems(true);
+
 		// Setting list commit callback to monitor currently selected wearable item.
 		list->setCommitCallback(boost::bind(&LLOutfitsList::onSelectionChange, this, _1));
 
 
 		// If filter is currently applied we store the initial tab state and
 		// open it to show matched items if any.
-		if (!mFilterSubString.empty())
+		if (!sFilterSubString.empty())
 		{
 			tab->notifyChildren(LLSD().with("action","store_state"));
 			tab->setDisplayChildren(true);
 			// filter to the newly added list.
 			list->setForceRefresh(true);
 
-			list->setFilterSubString(mFilterSubString);
+			list->setFilterSubString(sFilterSubString);
 		}
 	}
 
 	}
 }
 
+void LLOutfitsList::removeSelected()
+{
+	if (mSelectedOutfitUUID.notNull())
+	{
+		remove_category(&gInventory, mSelectedOutfitUUID);
+	}
+}
+
+void LLOutfitsList::setSelectedOutfitByUUID(const LLUUID& outfit_uuid)
+{
+	for (outfits_map_t::iterator iter = mOutfitsMap.begin();
+			iter != mOutfitsMap.end();
+			++iter)
+	{
+		if (outfit_uuid == iter->first)
+		{
+			LLAccordionCtrlTab* tab = iter->second;
+			if (!tab) continue;
+
+			LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
+			if (!list) continue;
+
+			tab->setFocus(TRUE);
+			changeOutfitSelection(list, outfit_uuid);
+
+			tab->setDisplayChildren(true);
+		}
+	}
+}
+
+// virtual
 void LLOutfitsList::setFilterSubString(const std::string& string)
 {
 	applyFilter(string);
 
-	mFilterSubString = string;
+	sFilterSubString = string;
 }
 
-boost::signals2::connection LLOutfitsList::addSelectionChangeCallback(selection_change_callback_t cb)
+// virtual
+bool LLOutfitsList::isActionEnabled(const LLSD& userdata)
+{
+	if (mSelectedOutfitUUID.isNull()) return false;
+
+	const std::string command_name = userdata.asString();
+	if (command_name == "delete")
+	{
+		return !mItemSelected && LLAppearanceMgr::instance().getCanRemoveOutfit(mSelectedOutfitUUID);
+	}
+	if (command_name == "rename")
+	{
+		return get_is_category_renameable(&gInventory, mSelectedOutfitUUID);
+	}
+	if (command_name == "save_outfit")
+	{
+		bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();
+		bool outfit_dirty = LLAppearanceMgr::getInstance()->isOutfitDirty();
+		// allow save only if outfit isn't locked and is dirty
+		return !outfit_locked && outfit_dirty;
+	}
+	if (command_name == "wear")
+	{
+		return !gAgentWearables.isCOFChangeInProgress();
+	}
+	if (command_name == "take_off")
+	{
+		return LLAppearanceMgr::getInstance()->getBaseOutfitUUID() == mSelectedOutfitUUID;
+	}
+	return false;
+}
+
+// virtual
+void LLOutfitsList::showGearMenu(LLView* spawning_view)
+{
+	if (!mGearMenu) return;
+	mGearMenu->show(spawning_view);
+}
+
+boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb)
 {
 	return mSelectionChangeSignal.connect(cb);
 }
 
 void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl)
 {
-	if (!ctrl || mFilterSubString.empty())
+	if (!ctrl || sFilterSubString.empty())
 		return;
 
 	for (outfits_map_t::iterator
 		LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView());
 		if (list != ctrl) continue;
 
-		applyFilterToTab(iter->first, tab, mFilterSubString);
+		applyFilterToTab(iter->first, tab, sFilterSubString);
 	}
 }
 
 		LLAccordionCtrlTab* tab = iter->second;
 		if (!tab) continue;
 
-		bool more_restrictive = mFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, mFilterSubString.size()).compare(mFilterSubString);
+		bool more_restrictive = sFilterSubString.size() < new_filter_substring.size() && !new_filter_substring.substr(0, sFilterSubString.size()).compare(sFilterSubString);
 
 		// Restore tab visibility in case of less restrictive filter
 		// to compare it with updated string if it was previously hidden.
 			list->setFilterSubString(new_filter_substring);
 		}
 
-		if(mFilterSubString.empty() && !new_filter_substring.empty())
+		if(sFilterSubString.empty() && !new_filter_substring.empty())
 		{
 			//store accordion tab state when filter is not empty
 			tab->notifyChildren(LLSD().with("action","store_state"));
 			restoreOutfitSelection(tab, iter->first);
 		}
 	}
+
+	mAccordion->arrange();
 }
 
 void LLOutfitsList::applyFilterToTab(
 	{
 		// hide tab if its title doesn't pass filter
 		// and it has no visible items
-		tab->setVisible(list->size() > 0);
+		tab->setVisible(list->wasLasFilterSuccessfull());
 
 		// remove title highlighting because it might
 		// have been previously highlighted by less restrictive filter
 
 	uuid_vec_t selected_uuids;
 
-	// Collect seleted items from all selected lists.
+	// Collect selected items from all selected lists.
 	for (wearables_lists_map_t::iterator iter = mSelectedListsMap.begin();
 			iter != mSelectedListsMap.end();
 			++iter)

indra/newview/lloutfitslist.h

 
 // newview
 #include "llinventorymodel.h"
-#include "llinventoryobserver.h"
+#include "llpanelappearancetab.h"
 
 class LLAccordionCtrlTab;
+class LLInventoryCategoriesObserver;
+class LLOutfitListGearMenu;
 class LLWearableItemsList;
 class LLListContextMenu;
 
+
 /**
  * @class LLOutfitTabNameComparator
  *
  * which displays each outfit in an accordion tab with a flat list
  * of items inside it.
  *
- * Starts fetching nevessary inventory content on first openning.
+ * Starts fetching necessary inventory content on first opening.
  */
-class LLOutfitsList : public LLPanel
+class LLOutfitsList : public LLPanelAppearanceTab
 {
 public:
 	typedef boost::function<void (const LLUUID&)> selection_change_callback_t;
 
 	void performAction(std::string action);
 
-	void setFilterSubString(const std::string& string);
+	void removeSelected();
+
+	void setSelectedOutfitByUUID(const LLUUID& outfit_uuid);
+
+	/*virtual*/ void setFilterSubString(const std::string& string);
+
+	/*virtual*/ bool isActionEnabled(const LLSD& userdata);
+
+	/*virtual*/ void showGearMenu(LLView* spawning_view);
 
 	const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; }
 
-	boost::signals2::connection addSelectionChangeCallback(selection_change_callback_t cb);
+	boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb);
 
 	/**
 	 * Returns true if there is a selection inside currently selected outfit
 	LLUUID							mHighlightedOutfitUUID;
 	selection_change_signal_t		mSelectionChangeSignal;
 
-	std::string 					mFilterSubString;
-
 	typedef	std::map<LLUUID, LLAccordionCtrlTab*>		outfits_map_t;
 	typedef outfits_map_t::value_type					outfits_map_value_t;
 	outfits_map_t					mOutfitsMap;
 
-	LLListContextMenu*			mOutfitMenu;
+	LLOutfitListGearMenu*			mGearMenu;
+	LLListContextMenu*				mOutfitMenu;
 
 	bool							mIsInitialized;
 	/**

indra/newview/llpanelappearancetab.h

 /** 
- * @file llpanelplacestab.h
- * @brief Tabs interface for Side Bar "Places" panel
+ * @file llpanelappearancetab.h
+ * @brief Tabs interface for Side Bar "My Appearance" panel
  *
  * $LicenseInfo:firstyear=2009&license=viewergpl$
  * 
 
 #include "llpanel.h"
 
-#include "llpanelappearance.h"
-
 class LLPanelAppearanceTab : public LLPanel
 {
 public:
-	LLPanelAppearanceTab(LLPanelAppearance *parent) : 
-		LLPanel(),
-		mParent(parent)
-	{}
+	LLPanelAppearanceTab() : LLPanel() {}
 	virtual ~LLPanelAppearanceTab() {}
 
-	virtual void onSearchEdit(const std::string& string) = 0;
-	virtual void updateVerbs() = 0;		// Updates buttons at the bottom of Appearance panel
-	virtual void onWear() = 0;
-	virtual void onEdit() = 0;
-	virtual void onNew() = 0;
+	virtual void setFilterSubString(const std::string& string) = 0;
 
-	bool isTabVisible(); // Check if parent TabContainer is visible.
+	virtual bool isActionEnabled(const LLSD& userdata) = 0;
 
+	virtual void showGearMenu(LLView* spawning_view) = 0;
+
+	static const std::string& getFilterSubString() { return sFilterSubString; }
 
 protected:
-	LLPanelAppearance*		mParent;
+	static std::string		sFilterSubString;
 };
 
 #endif //LL_LLPANELAPPEARANCETAB_H

indra/newview/llpaneleditwearable.cpp

 	}
 
 	// Update the camera
-	gMorphView->setCameraDistToDefault();
 	gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) );
 	gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset );
 	gMorphView->setCameraOffset( subpart_entry->mCameraOffset );

indra/newview/llpaneloutfitedit.cpp

 	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL);
 	childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
 	childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
-	childSetCommitCallback("shop_btn", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
+	childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
+	childSetCommitCallback("shop_btn_2", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
 
 	mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list");
 	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this));

indra/newview/llpaneloutfitsinventory.cpp

 
 #include "llpaneloutfitsinventory.h"
 
-#include "llagent.h"
+#include "llnotificationsutil.h"
+#include "lltabcontainer.h"
+
+#include "llinventoryfunctions.h"
+#include "llinventorymodelbackgroundfetch.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
-
-#include "llbutton.h"
-#include "llfloaterreg.h"
-#include "llfloaterworldmap.h"
-#include "llfloaterinventory.h"
-#include "llfoldervieweventlistener.h"
-#include "llinventorybridge.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llinventorypanel.h"
-#include "lllandmark.h"
-#include "lllineeditor.h"
-#include "llmodaldialog.h"
-#include "llnotificationsutil.h"
 #include "lloutfitobserver.h"
 #include "lloutfitslist.h"
+#include "llpanelwearing.h"
 #include "llsaveoutfitcombobtn.h"
 #include "llsidepanelappearance.h"
 #include "llsidetray.h"
-#include "lltabcontainer.h"
 #include "llviewerfoldertype.h"
-#include "llviewerjointattachment.h"
-#include "llvoavatarself.h"
-
-// List Commands
-#include "lldndbutton.h"
-#include "llmenugl.h"
-#include "llviewermenu.h"
-
-#include "llviewercontrol.h"
 
 static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
 static const std::string COF_TAB_NAME = "cof_tab";
 
 static LLRegisterPanelClassWrapper<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
 
-class LLOutfitListGearMenu
-{
-public:
-	LLOutfitListGearMenu(LLOutfitsList* olist)
-	:	mOutfitList(olist),
-		mMenu(NULL)
-	{
-		llassert_always(mOutfitList);
-
-		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
-		registrar.add("Gear.Wear", boost::bind(&LLOutfitListGearMenu::onWear, this));
-		registrar.add("Gear.TakeOff", boost::bind(&LLOutfitListGearMenu::onTakeOff, this));
-		registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this));
-		registrar.add("Gear.Delete", boost::bind(&LLOutfitListGearMenu::onDelete, this));
-		registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
-
-		enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2));
-		enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));
-
-		mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
-			"menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-		llassert(mMenu);
-	}
-
-	LLMenuGL* getMenu() { return mMenu; }
-
-	void show(LLView* spawning_view)
-	{
-		if (!mMenu) return;
-
-		updateItemsVisibility();
-		mMenu->buildDrawLabels();
-		mMenu->updateParent(LLMenuGL::sMenuContainer);
-		S32 menu_x = 0;
-		S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight();
-		LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y);
-	}
-
-	void updateItemsVisibility()
-	{
-		if (!mMenu) return;
-
-		bool have_selection = getSelectedOutfitID().notNull();
-		mMenu->setItemVisible("sepatator1", have_selection);
-		mMenu->setItemVisible("sepatator2", have_selection);
-		mMenu->arrangeAndClear(); // update menu height
-	}
-
-private:
-	const LLUUID& getSelectedOutfitID()
-	{
-		return mOutfitList->getSelectedOutfitUUID();
-	}
-
-	LLViewerInventoryCategory* getSelectedOutfit()
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.isNull())
-		{
-			return NULL;
-		}
-
-		LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id);
-		return cat;
-	}
-
-	void onWear()
-	{
-		LLViewerInventoryCategory* selected_outfit = getSelectedOutfit();
-		if (selected_outfit)
-		{
-			LLAppearanceMgr::instance().wearInventoryCategory(
-				selected_outfit, /*copy=*/ FALSE, /*append=*/ FALSE);
-		}
-	}
-
-	void onTakeOff()
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.notNull())
-		{
-			LLAppearanceMgr::instance().takeOffOutfit(selected_outfit_id);
-		}
-	}
-
-	void onRename()
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.notNull())
-		{
-			LLAppearanceMgr::instance().renameOutfit(selected_outfit_id);
-		}
-	}
-
-	void onDelete()
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.notNull())
-		{
-			remove_category(&gInventory, selected_outfit_id);
-		}
-	}
-
-	void onCreate(const LLSD& data)
-	{
-		LLWearableType::EType type = LLWearableType::typeNameToType(data.asString());
-		if (type == LLWearableType::WT_NONE)
-		{
-			llwarns << "Invalid wearable type" << llendl;
-			return;
-		}
-
-		LLAgentWearables::createWearable(type, true);
-	}
-
-	bool onEnable(LLSD::String param)
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
-		{
-			return false;
-		}
-
-		if ("rename" == param)
-		{
-			return get_is_category_renameable(&gInventory, selected_outfit_id);
-		}
-		else if ("delete" == param)
-		{
-			return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id);
-		}
-		else if ("take_off" == param)
-		{
-			return LLAppearanceMgr::getCanRemoveFromCOF(selected_outfit_id);
-		}
-
-		return true;
-	}
-
-	bool onVisible(LLSD::String param)
-	{
-		const LLUUID& selected_outfit_id = getSelectedOutfitID();
-		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected
-		{
-			return false;
-		}
-
-		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;
-
-		if ("wear" == param)
-		{
-			return !is_worn;
-		}
-
-		return true;
-	}
-
-	LLOutfitsList*	mOutfitList;
-	LLMenuGL*		mMenu;
-};
-
 LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
 	mMyOutfitsPanel(NULL),
 	mCurrentOutfitPanel(NULL),
-	mGearMenu(NULL),
+	mActivePanel(NULL),
 	mInitialized(false)
 {
-	mSavedFolderState = new LLSaveFolderState();
-	mSavedFolderState->setApply(FALSE);
 	gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this));
 	gAgentWearables.addLoadingStartedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoading, this));
 
 
 LLPanelOutfitsInventory::~LLPanelOutfitsInventory()
 {
-	delete mGearMenu;
-	delete mSavedFolderState;
 }
 
 // virtual
 	// and update verbs.
 	onTabChange();
 	
-	// Auto open the first outfit newly created so new users can see sample outfit contents
+	// *TODO: Auto open the first outfit newly created so new users can see sample outfit contents
+	/*
 	static bool should_open_outfit = true;
 	if (should_open_outfit && gAgent.isFirstLogin())
 	{
 		}
 	}
 	should_open_outfit = false;
+	*/
 }
 
 void LLPanelOutfitsInventory::updateVerbs()
 // virtual
 void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
 {
+	if (!mActivePanel) return;
+
 	mFilterSubString = string;
 
-	// TODO: add handling "My Outfits" tab.
-	if (!isCOFPanelActive())
-	{
-		mMyOutfitsPanel->setFilterSubString(string);
-		return;
-	}
-
 	if (string == "")
 	{
-		getActivePanel()->setFilterSubString(LLStringUtil::null);
-
-		// re-open folders that were initially open
-		mSavedFolderState->setApply(TRUE);
-		getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
-		LLOpenFoldersWithSelection opener;
-		getRootFolder()->applyFunctorRecursively(opener);
-		getRootFolder()->scrollToShowSelection();
+		mActivePanel->setFilterSubString(LLStringUtil::null);
 	}
 
 	LLInventoryModelBackgroundFetch::instance().start();
 
-	if (getActivePanel()->getFilterSubString().empty() && string.empty())
+	if (mActivePanel->getFilterSubString().empty() && string.empty())
 	{
 		// current filter and new filter empty, do nothing
 		return;
 	}
 
-	// save current folder open state if no filter currently applied
-	if (getRootFolder()->getFilterSubString().empty())
-	{
-		mSavedFolderState->setApply(FALSE);
-		getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
-	}
-
 	// set new filter string
-	getActivePanel()->setFilterSubString(string);
+	mActivePanel->setFilterSubString(string);
 }
 
 void LLPanelOutfitsInventory::onWearButtonClick()
 {
-	// TODO: Remove if/else, add common interface
-	// for "My Outfits" and "Wearing" tabs.
-	if (!isCOFPanelActive())
-	{
-		mMyOutfitsPanel->performAction("replaceoutfit");
-	}
-	else
-	{
-		LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
-		if (listenerp)
-		{
-			listenerp->performAction(NULL, "replaceoutfit");
-		}
-	}
-}
-
-void LLPanelOutfitsInventory::onAdd()
-{
-	// TODO: Remove if/else, add common interface
-	// for "My Outfits" and "Wearing" tabs.
-	if (!isCOFPanelActive())
-	{
-		mMyOutfitsPanel->performAction("addtooutfit");
-	}
-	else
-	{
-		LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
-		if (listenerp)
-		{
-			listenerp->performAction(NULL, "addtooutfit");
-		}
-	}
-}
-
-void LLPanelOutfitsInventory::onRemove()
-{
-	LLFolderViewEventListener* listenerp = getCorrectListenerForAction();
-	if (listenerp)
-	{
-		listenerp->performAction(NULL, "removefromoutfit");
-	}
-}
-
-void LLPanelOutfitsInventory::onEdit()
-{
+	mMyOutfitsPanel->performAction("replaceoutfit");
 }
 
 bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD& response)
 	return false;
 }
 
-
-
 void LLPanelOutfitsInventory::onSave()
 {
 	std::string outfit_name;
 	}*/
 }
 
-void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
-{
-	updateVerbs();
-
-	// TODO: add handling "My Outfits" tab.
-	if (!isCOFPanelActive())
-		return;
-
-	if (getRootFolder()->needsAutoRename() && items.size())
-	{
-		getRootFolder()->startRenamingSelectedItem();
-		getRootFolder()->setNeedsAutoRename(FALSE);
-	}
-}
-
-LLFolderViewEventListener *LLPanelOutfitsInventory::getCorrectListenerForAction()
-{
-	// TODO: add handling "My Outfits" tab.
-	if (!isCOFPanelActive())
-		return NULL;
-
-	LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem();
-	if (!current_item)
-		return NULL;
-
-	LLFolderViewEventListener* listenerp = current_item->getListener();
-	if (getIsCorrectType(listenerp))
-	{
-		return listenerp;
-	}
-	return NULL;
-}
-
-bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *listenerp) const
-{
-	if (listenerp->getInventoryType() == LLInventoryType::IT_CATEGORY)
-	{
-		LLViewerInventoryCategory *cat = gInventory.getCategory(listenerp->getUUID());
-		if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
-		{
-			return true;
-		}
-	}
-	return false;
-}
-
-LLFolderView *LLPanelOutfitsInventory::getRootFolder()
-{
-	return getActivePanel()->getRootFolder();
-}
-
 //static
 LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance()
 {
 	mListCommands->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this));
 	mListCommands->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this));
 	mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this));
-
-	LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>("trash_btn");
-	trash_btn->setDragAndDropHandler(boost::bind(&LLPanelOutfitsInventory::handleDragAndDropToTrash, this
-				   ,       _4 // BOOL drop
-				   ,       _5 // EDragAndDropType cargo_type
-				   ,       _7 // EAcceptance* accept
-				   ));
-
-	mGearMenu = new LLOutfitListGearMenu(mMyOutfitsPanel);
 }
 
 void LLPanelOutfitsInventory::updateListCommands()
 {
 	bool trash_enabled = isActionEnabled("delete");
-	bool wear_enabled =  !gAgentWearables.isCOFChangeInProgress() && isActionEnabled("wear");
+	bool wear_enabled =  isActionEnabled("wear");
 	bool wear_visible = !isCOFPanelActive();
 	bool make_outfit_enabled = isActionEnabled("save_outfit");
 
 
 void LLPanelOutfitsInventory::showGearMenu()
 {
-	if (!mGearMenu) return;
+	if (!mActivePanel) return;
 
 	LLView* spawning_view = getChild<LLView>("options_gear_btn");
-	mGearMenu->show(spawning_view);
+	mActivePanel->showGearMenu(spawning_view);
 }
 
 void LLPanelOutfitsInventory::onTrashButtonClick()
 {
-	onClipboardAction("delete");
+	mMyOutfitsPanel->removeSelected();
+
+ 	updateListCommands();
+ 	updateVerbs();
 }
 
-void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)
+bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
 {
-	std::string command_name = userdata.asString();
-	if (isCOFPanelActive())
-	{
-		getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
-	}
-	else // "My Outfits" tab active
-	{
-		if (command_name == "delete")
-		{
-			const LLUUID& selected_outfit_id = mMyOutfitsPanel->getSelectedOutfitUUID();
-			if (selected_outfit_id.notNull())
-			{
-				remove_category(&gInventory, selected_outfit_id);
-			}
-		}
-		else
-		{
-			llwarns << "Unrecognized action" << llendl;
-		}
-	}
-	updateListCommands();
-	updateVerbs();
+	return mActivePanel && mActivePanel->isActionEnabled(userdata);
 }
-
-void LLPanelOutfitsInventory::onCustomAction(const LLSD& userdata)
-{
-	if (!isActionEnabled(userdata))
-		return;
-
-	const std::string command_name = userdata.asString();
-	if (command_name == "new")
-	{
-		onSave();
-	}
-	if (command_name == "edit")
-	{
-		onEdit();
-	}
-	if (command_name == "wear")
-	{
-		onWearButtonClick();
-	}
-	// Note: This option has been removed from the gear menu.
-	if (command_name == "add")
-	{
-		onAdd();
-	}
-	if (command_name == "remove")
-	{
-		onRemove();
-	}
-	if (command_name == "rename")
-	{
-		onClipboardAction("rename");
-	}
-	if (command_name == "remove_link")
-	{
-		onClipboardAction("delete");
-	}
-	if (command_name == "delete")
-	{
-		onClipboardAction("delete");
-	}
-	updateListCommands();
-	updateVerbs();
-}
-
-BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
-{
-	const std::string command_name = userdata.asString();
-	if (command_name == "delete" || command_name == "remove")
-	{
-		BOOL can_delete = FALSE;
-
-		if (isCOFPanelActive())
-		{
-			LLFolderView* root = getActivePanel()->getRootFolder();
-			if (root)
-			{
-				std::set<LLUUID> selection_set = root->getSelectionList();
-				can_delete = (selection_set.size() > 0);
-				for (std::set<LLUUID>::iterator iter = selection_set.begin();
-					 iter != selection_set.end();
-					 ++iter)
-				{
-					const LLUUID &item_id = (*iter);
-					LLFolderViewItem *item = root->getItemByID(item_id);
-					can_delete &= item->getListener()->isItemRemovable();
-				}
-			}
-		}
-		else // "My Outfits" tab active
-		{
-			const LLUUID& selected_outfit = mMyOutfitsPanel->getSelectedOutfitUUID();
-			// first condition prevents trash btn from enabling when items are selected inside outfit (EXT-7847)
-			can_delete = !mMyOutfitsPanel->hasItemSelected() && LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit);
-		}
-
-		return can_delete;
-	}
-	if (command_name == "remove_link")
-	{
-		BOOL can_delete = FALSE;
-		LLFolderView* root = getActivePanel()->getRootFolder();
-		if (root)
-		{
-			std::set<LLUUID> selection_set = root->getSelectionList();
-			can_delete = (selection_set.size() > 0);
-			for (std::set<LLUUID>::iterator iter = selection_set.begin();
-				 iter != selection_set.end();
-				 ++iter)
-			{
-				const LLUUID &item_id = (*iter);
-				LLViewerInventoryItem *item = gInventory.getItem(item_id);
-				if (!item || !item->getIsLinkType())
-					return FALSE;
-			}
-			return can_delete;
-		}
-		return FALSE;
-	}
-	if (command_name == "rename" ||
-		command_name == "delete_outfit")
-	{
-		return (getCorrectListenerForAction() != NULL) && hasItemsSelected();
-	}
-	
-	if (command_name == "wear")
-	{
-		if (isCOFPanelActive())
-		{
-			return FALSE;
-		}
-		return hasItemsSelected();
-	}
-	if (command_name == "save_outfit")
-	{
-		bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();
-		bool outfit_dirty =LLAppearanceMgr::getInstance()->isOutfitDirty();
-		// allow save only if outfit isn't locked and is dirty
-		return !outfit_locked && outfit_dirty;
-	}
-   
-	if (command_name == "edit" || 
-		command_name == "add"
-		)
-	{
-		return (getCorrectListenerForAction() != NULL);
-	}
-	return TRUE;
-}
-
-bool LLPanelOutfitsInventory::hasItemsSelected()
-{
-	bool has_items_selected = false;
-
-	if (isCOFPanelActive())
-	{
-		LLFolderView* root = getActivePanel()->getRootFolder();
-		if (root)
-		{
-			std::set<LLUUID> selection_set = root->getSelectionList();
-			has_items_selected = (selection_set.size() > 0);
-		}
-	}
-	else // My Outfits Tab is active
-	{
-		has_items_selected = mMyOutfitsPanel->getSelectedOutfitUUID().notNull();
-	}
-	return has_items_selected;
-}
-
-bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept)
-{