From cdd71c5e64782b33aaf5f8caac8ef61eaa78f607 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 16 Mar 2021 19:29:23 +0200
Subject: [PATCH] SL-14938 Remove Library and Inventory from Places floater

---
 indra/newview/llpanellandmarks.cpp            | 464 +++---------------
 indra/newview/llpanellandmarks.h              |  57 +--
 indra/newview/llpanelplaces.cpp               |  22 +-
 .../xui/en/menu_places_gear_folder.xml        |   3 +
 .../xui/en/menu_places_gear_sorting.xml       |   3 +
 .../skins/default/xui/en/panel_favorites.xml  |  22 +
 .../skins/default/xui/en/panel_landmarks.xml  |  99 +---
 .../skins/default/xui/en/panel_places.xml     |   7 +-
 .../newview/skins/default/xui/en/strings.xml  |   4 +-
 9 files changed, 153 insertions(+), 528 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/panel_favorites.xml

diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 9d0c8b015ae..1a10654a718 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -36,7 +36,6 @@
 #include "llregionhandle.h"
 
 #include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
 #include "llagent.h"
 #include "llagentpicksinfo.h"
 #include "llagentui.h"
@@ -60,8 +59,6 @@
 // Not yet implemented; need to remove buildPanel() from constructor when we switch
 //static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks");
 
-static const std::string TAB_FAVORITES = "tab_favorites";
-
 // helper functions
 static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string);
 static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list);
@@ -145,69 +142,37 @@ void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
 	}
 }
 
-/**
- * Bridge to support knowing when the inventory has changed to update Landmarks tab
- * ShowFolderState filter setting to show all folders when the filter string is empty and
- * empty folder message when Landmarks inventory category has no children.
- * Ensures that "Landmarks" folder in the Library is open on strart up.
- */
-class LLLandmarksPanelObserver : public LLInventoryObserver
-{
-public:
-	LLLandmarksPanelObserver(LLLandmarksPanel* lp)
-	:	mLP(lp),
-	 	mIsLibraryLandmarksOpen(false)
-	{}
-	virtual ~LLLandmarksPanelObserver() {}
-	/*virtual*/ void changed(U32 mask);
-
-private:
-	LLLandmarksPanel* mLP;
-	bool mIsLibraryLandmarksOpen;
-};
-
-void LLLandmarksPanelObserver::changed(U32 mask)
+LLLandmarksPanel::LLLandmarksPanel()
+	:	LLPanelPlacesTab()
+	,	mLandmarksInventoryPanel(NULL)
+	,	mCurrentSelectedList(NULL)
+	,	mGearFolderMenu(NULL)
+	,	mGearLandmarkMenu(NULL)
+	,	mSortingMenu(NULL)
+	,	mAddMenu(NULL)
+	,	isLandmarksPanel(true)
 {
-	mLP->updateShowFolderState();
-
-	LLPlacesInventoryPanel* library = mLP->getLibraryInventoryPanel();
-	if (!mIsLibraryLandmarksOpen && library)
-	{
-		// Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827.
-		const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
-		if (landmarks_cat.notNull())
-		{
-			LLOpenFolderByID opener(landmarks_cat);
-			library->getRootFolder()->applyFunctorRecursively(opener);
-			mIsLibraryLandmarksOpen = opener.isFolderOpen();
-		}
-	}
+	buildFromFile("panel_landmarks.xml");
 }
 
-LLLandmarksPanel::LLLandmarksPanel()
+LLLandmarksPanel::LLLandmarksPanel(bool is_landmark_panel)
 	:	LLPanelPlacesTab()
-	,	mFavoritesInventoryPanel(NULL)
 	,	mLandmarksInventoryPanel(NULL)
-	,	mMyInventoryPanel(NULL)
-	,	mLibraryInventoryPanel(NULL)
 	,	mCurrentSelectedList(NULL)
 	,	mGearFolderMenu(NULL)
 	,	mGearLandmarkMenu(NULL)
 	,	mSortingMenu(NULL)
 	,	mAddMenu(NULL)
+	,	isLandmarksPanel(is_landmark_panel)
 {
-	mInventoryObserver = new LLLandmarksPanelObserver(this);
-	gInventory.addObserver(mInventoryObserver);
-
-	buildFromFile( "panel_landmarks.xml");
+	if (is_landmark_panel)
+	{
+		buildFromFile("panel_landmarks.xml");
+	}
 }
 
 LLLandmarksPanel::~LLLandmarksPanel()
 {
-	if (gInventory.containsObserver(mInventoryObserver))
-	{
-		gInventory.removeObserver(mInventoryObserver);
-	}
 }
 
 BOOL LLLandmarksPanel::postBuild()
@@ -217,17 +182,7 @@ BOOL LLLandmarksPanel::postBuild()
 
 	// mast be called before any other initXXX methods to init Gear menu
 	initListCommandsHandlers();
-
-	initFavoritesInventoryPanel();
 	initLandmarksInventoryPanel();
-	initMyInventoryPanel();
-	initLibraryInventoryPanel();
-
-	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
-	if (accordion)
-	{
-		accordion->setSkipScrollToChild(true);
-	}
 
 	return TRUE;
 }
@@ -235,30 +190,10 @@ BOOL LLLandmarksPanel::postBuild()
 // virtual
 void LLLandmarksPanel::onSearchEdit(const std::string& string)
 {
-	// give FolderView a chance to be refreshed. So, made all accordions visible
-	for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-	{
-		LLAccordionCtrlTab* tab = *iter;
-		tab->setVisible(TRUE);
-
-		// expand accordion to see matched items in each one. See EXT-2014.
-		if (string != "")
-		{
-			tab->changeOpenClose(false);
-		}
-
-		LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView());
-		if (NULL == inventory_list) continue;
-
-		filter_list(inventory_list, string);
-	}
+	filter_list(mCurrentSelectedList, string);
 
 	if (sFilterSubString != string)
 		sFilterSubString = string;
-
-	// show all folders in Landmarks Accordion for empty filter
-	// only if Landmarks inventory folder is not empty
-	updateShowFolderState();
 }
 
 // virtual
@@ -349,76 +284,21 @@ LLToggleableMenu* LLLandmarksPanel::getCreateMenu()
     return mAddMenu;
 }
 
-// virtual
 void LLLandmarksPanel::updateVerbs()
 {
-	if (!isTabVisible()) 
-		return;
-}
-
-void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
-{
-	if (user_action && (items.size() > 0))
-	{
-		deselectOtherThan(inventory_list);
-		mCurrentSelectedList = inventory_list;
-	}
-	updateVerbs();
-}
-
-void LLLandmarksPanel::onSelectorButtonClicked()
-{
-	// TODO: mantipov: update getting of selected item
-	// TODO: bind to "i" button
-	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
-	if (!cur_item) return;
-
-	LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
-	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
-	{
-		LLSD key;
-		key["type"] = "landmark";
-		key["id"] = listenerp->getUUID();
-
-		LLFloaterSidePanelContainer::showPanel("places", key);
-	}
-}
-
-void LLLandmarksPanel::updateShowFolderState()
-{
-	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty();
-	if (show_all_folders)
-	{
-		show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
-	}
-
-	mLandmarksInventoryPanel->setShowFolderState(show_all_folders ?
-		LLInventoryFilter::SHOW_ALL_FOLDERS :
-		LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS
-		);
 }
 
 void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus)
 {
-	if (selectItemInAccordionTab(mFavoritesInventoryPanel, TAB_FAVORITES, obj_id, take_keyboard_focus))
-	{
-		return;
-	}
-
-	if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus))
-	{
+	if (!mCurrentSelectedList)
 		return;
-	}
-
-	if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus))
-	{
-		return;
-	}
 
-	if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus))
-	{
+	LLFolderView* root = mCurrentSelectedList->getRootFolder();
+	LLFolderViewItem* item = mCurrentSelectedList->getItemByID(obj_id);
+	if (!item)
 		return;
-	}
+	root->setSelection(item, FALSE, take_keyboard_focus);
+	root->scrollToShowSelection();
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -437,18 +317,6 @@ bool LLLandmarksPanel::isFolderSelected() const
 	return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY);
 }
 
-bool LLLandmarksPanel::isReceivedFolderSelected() const
-{
-	// Received Folder can be only in Landmarks accordion
-	if (mCurrentSelectedList != mLandmarksInventoryPanel) return false;
-
-	// *TODO: it should be filled with logic when EXT-976 is done.
-
-	LL_WARNS() << "Not implemented yet until EXT-976 is done." << LL_ENDL;
-
-	return false;
-}
-
 void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
 {
 	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
@@ -478,36 +346,6 @@ LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem()
 }
 
 
-LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
-															 const std::string& tab_name,
-															 const LLUUID& obj_id,
-															 BOOL take_keyboard_focus) const
-{
-	if (!inventory_list)
-		return NULL;
-
-	LLFolderView* root = inventory_list->getRootFolder();
-
-	LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
-	if (!item)
-		return NULL;
-
-	LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name);
-	if (!tab->isExpanded())
-	{
-		tab->changeOpenClose(false);
-	}
-
-	root->setSelection(item, FALSE, take_keyboard_focus);
-
-	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
-	LLRect screen_rc;
-	localRectToScreen(item->getRect(), &screen_rc);
-	accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue()));
-
-	return item;
-}
-
 void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
 {
 	if(!panel) return; 
@@ -525,8 +363,6 @@ void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
 
 void LLLandmarksPanel::resetSelection()
 {
-	getChild<LLAccordionCtrlTab>(TAB_FAVORITES)->setDisplayChildren(true);
-	getChild<LLAccordionCtrlTab>(TAB_FAVORITES)->showAndFocusHeader();
 }
 
 // virtual
@@ -572,16 +408,6 @@ void LLLandmarksPanel::setErrorStatus(S32 status, const std::string& reason)
 // PRIVATE METHODS
 //////////////////////////////////////////////////////////////////////////
 
-void LLLandmarksPanel::initFavoritesInventoryPanel()
-{
-	mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list");
-
-	initLandmarksPanel(mFavoritesInventoryPanel);
-	mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
-
-	initAccordion(TAB_FAVORITES, mFavoritesInventoryPanel, true);
-}
-
 void LLLandmarksPanel::initLandmarksInventoryPanel()
 {
 	mLandmarksInventoryPanel = getChild<LLPlacesInventoryPanel>("landmarks_list");
@@ -593,40 +419,13 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
 	// subscribe to have auto-rename functionality while creating New Folder
 	mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
 
-	mMyLandmarksAccordionTab = initAccordion("tab_landmarks", mLandmarksInventoryPanel, true);
-}
-
-void LLLandmarksPanel::initMyInventoryPanel()
-{
-	mMyInventoryPanel= getChild<LLPlacesInventoryPanel>("my_inventory_list");
-
-	initLandmarksPanel(mMyInventoryPanel);
-
-	initAccordion("tab_inventory", mMyInventoryPanel, false);
-}
-
-void LLLandmarksPanel::initLibraryInventoryPanel()
-{
-	mLibraryInventoryPanel = getChild<LLPlacesInventoryPanel>("library_list");
-
-	initLandmarksPanel(mLibraryInventoryPanel);
-
-	// We want to fetch only "Landmarks" category from the library.
-	const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
-	if (landmarks_cat.notNull())
-	{
-		LLInventoryModelBackgroundFetch::instance().start(landmarks_cat);
-	}
-
-	// Expanding "Library" tab for new users who have no landmarks in "My Inventory".
-	initAccordion("tab_library", mLibraryInventoryPanel, true);
+	mCurrentSelectedList = mLandmarksInventoryPanel;
 }
 
 void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
 {
 	inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");
 	inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
-	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
 
 	inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
 	bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate");
@@ -644,71 +443,6 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list
 	inventory_list->saveFolderState();
 }
 
-LLAccordionCtrlTab* LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list,	bool expand_tab)
-{
-	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);
-
-	mAccordionTabs.push_back(accordion_tab);
-	accordion_tab->setDropDownStateChangedCallback(
-		boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list));
-	accordion_tab->setDisplayChildren(expand_tab);
-	return accordion_tab;
-}
-
-void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list)
-{
-	bool expanded = param.asBoolean();
-
-	if(!expanded && (mCurrentSelectedList == inventory_list))
-	{
-		inventory_list->getRootFolder()->clearSelection();
-
-		mCurrentSelectedList = NULL;
-		updateVerbs();
-	}
-
-	// Start background fetch, mostly for My Inventory and Library
-	if (expanded)
-	{
-		const LLUUID &cat_id = inventory_list->getRootFolderID();
-		// Just because the category itself has been fetched, doesn't mean its child folders have.
-		/*
-		  if (!gInventory.isCategoryComplete(cat_id))
-		*/
-		{
-			LLInventoryModelBackgroundFetch::instance().start(cat_id);
-		}
-
-		// Apply filter substring because it might have been changed
-		// while accordion was closed. See EXT-3714.
-		filter_list(inventory_list, sFilterSubString);
-	}
-}
-
-void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory_list)
-{
-	if (inventory_list != mFavoritesInventoryPanel)
-	{
-		mFavoritesInventoryPanel->clearSelection();
-		mFavoritesInventoryPanel->getRootFolder()->clearSelection();
-	}
-
-	if (inventory_list != mLandmarksInventoryPanel)
-	{
-		mLandmarksInventoryPanel->clearSelection();
-		mLandmarksInventoryPanel->getRootFolder()->clearSelection();
-	}
-	if (inventory_list != mMyInventoryPanel)
-	{
-		mMyInventoryPanel->clearSelection();
-		mMyInventoryPanel->getRootFolder()->clearSelection();
-	}
-	if (inventory_list != mLibraryInventoryPanel)
-	{
-		mLibraryInventoryPanel->clearSelection();
-		mLibraryInventoryPanel->getRootFolder()->clearSelection();
-	}
-}
 
 // List Commands Handlers
 void LLLandmarksPanel::initListCommandsHandlers()
@@ -730,6 +464,7 @@ void LLLandmarksPanel::initListCommandsHandlers()
 	// show menus even if all items are disabled
 	mGearLandmarkMenu->setAlwaysShowMenu(TRUE);
 	mGearFolderMenu->setAlwaysShowMenu(TRUE);
+	mAddMenu->setAlwaysShowMenu(TRUE);
 }
 
 void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu)
@@ -797,11 +532,6 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 			//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
 			menu_create_inventory_item(mLandmarksInventoryPanel, NULL,  LLSD("category"), 
 				gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
-
-			if (mMyLandmarksAccordionTab)
-			{
-				mMyLandmarksAccordionTab->changeOpenClose(false);
-			}
 		}
 	}
     else if ("category_root" == command_name)
@@ -809,11 +539,6 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
         //in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
         menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"),
             gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
-
-        if (mMyLandmarksAccordionTab)
-        {
-            mMyLandmarksAccordionTab->changeOpenClose(false);
-        }
     }
 }
 
@@ -848,27 +573,11 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
 
 	if ("expand_all" == command_name)
 	{
-		expand_all_folders(mFavoritesInventoryPanel->getRootFolder());
-		expand_all_folders(mLandmarksInventoryPanel->getRootFolder());
-		expand_all_folders(mMyInventoryPanel->getRootFolder());
-		expand_all_folders(mLibraryInventoryPanel->getRootFolder());
-
-		for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-		{
-			(*iter)->changeOpenClose(false);
-		}
+		expand_all_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("collapse_all" == command_name)
 	{
-		collapse_all_folders(mFavoritesInventoryPanel->getRootFolder());
-		collapse_all_folders(mLandmarksInventoryPanel->getRootFolder());
-		collapse_all_folders(mMyInventoryPanel->getRootFolder());
-		collapse_all_folders(mLibraryInventoryPanel->getRootFolder());
-
-		for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-		{
-			(*iter)->changeOpenClose(true);
-		}
+		collapse_all_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("sort_by_date" == command_name)
 	{
@@ -876,8 +585,6 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
 		sorting_order=!sorting_order;
 		gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order);
 		updateSortOrder(mLandmarksInventoryPanel, sorting_order);
-		updateSortOrder(mMyInventoryPanel, sorting_order);
-		updateSortOrder(mLibraryInventoryPanel, sorting_order);
 	}
 	else
 	{
@@ -911,49 +618,17 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 	if ("collapse_all" == command_name)
 	{
-		bool disable_collapse_all =	!has_expanded_folders(mFavoritesInventoryPanel->getRootFolder())
-									&& !has_expanded_folders(mLandmarksInventoryPanel->getRootFolder())
-									&& !has_expanded_folders(mMyInventoryPanel->getRootFolder())
-									&& !has_expanded_folders(mLibraryInventoryPanel->getRootFolder());
-		if (disable_collapse_all)
-		{
-			for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-			{
-				if ((*iter)->isExpanded())
-				{
-					disable_collapse_all = false;
-					break;
-				}
-			}
-		}
-
-		return !disable_collapse_all;
+		return has_expanded_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("expand_all" == command_name)
 	{
-		bool disable_expand_all = !has_collapsed_folders(mFavoritesInventoryPanel->getRootFolder())
-								  && !has_collapsed_folders(mLandmarksInventoryPanel->getRootFolder())
-								  && !has_collapsed_folders(mMyInventoryPanel->getRootFolder())
-								  && !has_collapsed_folders(mLibraryInventoryPanel->getRootFolder());
-		if (disable_expand_all)
-		{
-			for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-			{
-				if (!(*iter)->isExpanded())
-				{
-					disable_expand_all = false;
-					break;
-				}
-			}
-		}
-
-		return !disable_expand_all;
+		return has_collapsed_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("sort_by_date"	== command_name)
 	{
-		// disable "sort_by_date" for Favorites accordion because
+		// disable "sort_by_date" for Favorites tab because
 		// it has its own items order. EXT-1758
-		if (mCurrentSelectedList == mFavoritesInventoryPanel)
+		if (!isLandmarksPanel)
 		{
 			return false;
 		}
@@ -970,6 +645,11 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();
 
+		if (selected_uuids.empty())
+		{
+			return false;
+		}
+		
 		// Allow to execute the command only if it can be applied to all selected items.
 		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
 		{
@@ -1020,25 +700,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 		return true;
 	}
-    if ("category_root" == command_name)
+    if ("category_root" == command_name || "category" == command_name)
     {
-        // Landmarks Accordion
-        return true;
-    }
-	else if("category" == command_name)
-	{
-		// we can add folder only in Landmarks Accordion
-		if (mCurrentSelectedList == mLandmarksInventoryPanel)
-		{
-			// ... but except Received folder
-			return !isReceivedFolderSelected();
-		}
-		if (mCurrentSelectedList == mLibraryInventoryPanel)
-		{
-			return false;
-		}
-		//"Add a folder" is enabled by default (case when My Landmarks is empty)
-		return true;
+		// we can add folder only in Landmarks tab
+		return isLandmarksPanel;
 	}
 	else if("create_pick" == command_name)
 	{
@@ -1059,10 +724,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
         {
             return false;
         }
-        if (mCurrentSelectedList == mLibraryInventoryPanel)
-        {
-            return false;
-        }
+
         LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
         if (!view_model || view_model->getInventoryType() != LLInventoryType::IT_CATEGORY)
         {
@@ -1203,29 +865,17 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 
 	if (!item) return false;
 
-	// nothing can be modified in Library
-	if (mLibraryInventoryPanel == mCurrentSelectedList) return false;
-
 	bool can_be_modified = false;
 
 	// landmarks can be modified in any other accordion...
 	if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		can_be_modified = true;
-
-		// we can modify landmarks anywhere except paste to My Inventory
-		if ("paste" == command_name)
-		{
-			can_be_modified = (mCurrentSelectedList != mMyInventoryPanel);
-		}
 	}
 	else
 	{
 		// ...folders only in the Landmarks accordion...
-		can_be_modified = mLandmarksInventoryPanel == mCurrentSelectedList;
-
-		// ...except "Received" folder
-		can_be_modified &= !isReceivedFolderSelected();
+		can_be_modified = isLandmarksPanel;
 	}
 
 	// then ask LLFolderView permissions
@@ -1325,7 +975,6 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg
 		break;
 	}
 
-	updateVerbs();
 	return true;
 }
 
@@ -1470,10 +1119,6 @@ static void collapse_all_folders(LLFolderView* root_folder)
 		return;
 
 	root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
-
-	// The top level folder is invisible, it must be open to
-	// display its sub-folders.
-	root_folder->openTopLevelFolders();
 	root_folder->arrangeAll();
 }
 
@@ -1540,4 +1185,31 @@ void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled)
 		}
 	}
 }
+
+LLFavoritesPanel::LLFavoritesPanel()
+	:	LLLandmarksPanel(false)
+{
+	buildFromFile("panel_favorites.xml");
+}
+
+BOOL LLFavoritesPanel::postBuild()
+{
+	if (!gInventory.isInventoryUsable())
+		return FALSE;
+
+	// mast be called before any other initXXX methods to init Gear menu
+	LLLandmarksPanel::initListCommandsHandlers();
+
+	initFavoritesInventoryPanel();
+
+	return TRUE;
+}
+
+void LLFavoritesPanel::initFavoritesInventoryPanel()
+{
+	mCurrentSelectedList = getChild<LLPlacesInventoryPanel>("favorites_list");
+
+	LLLandmarksPanel::initLandmarksPanel(mCurrentSelectedList);
+	mCurrentSelectedList->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
+}
 // EOF
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 95256f4bb49..d7408269b5d 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -50,6 +50,7 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 {
 public:
 	LLLandmarksPanel();
+	LLLandmarksPanel(bool is_landmark_panel);
 	virtual ~LLLandmarksPanel();
 
 	BOOL postBuild() override;
@@ -70,26 +71,16 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
      */
     bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override;
 
-	void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
-	void onSelectorButtonClicked();
 	void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list)
 	{
 		mCurrentSelectedList = inventory_list;
 	}
 
-	/**
-	 * 	Update filter ShowFolderState setting to show empty folder message
-	 *  if Landmarks inventory folder is empty.
-	 */
-	void updateShowFolderState();
-
 	/**
 	 * Selects item with "obj_id" in one of accordion tabs.
 	 */
 	void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus);
 
-	LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; }
-
 	void updateMenuVisibility(LLUICtrl* menu);
 
 	void doCreatePick(LLLandmark* landmark, const LLUUID &item_id );
@@ -102,40 +93,26 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 	 */
 	bool isLandmarkSelected() const;
 	bool isFolderSelected() const;
-	bool isReceivedFolderSelected() const;
 	void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
 	LLFolderViewItem* getCurSelectedItem() const;
 	LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
 
-	/**
-	 * Selects item with "obj_id" in "inventory_list" and scrolls accordion
-	 * scrollbar to show the item.
-	 * Returns pointer to the item if it is found in "inventory_list", otherwise NULL.
-	 */
-	LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
-											   const std::string& tab_name,
-											   const LLUUID& obj_id,
-											   BOOL take_keyboard_focus) const;
-
 	void updateSortOrder(LLInventoryPanel* panel, bool byDate);
 
 	//LLRemoteParcelInfoObserver interface
 	void processParcelInfo(const LLParcelData& parcel_data) override;
 	void setParcelID(const LLUUID& parcel_id) override;
 	void setErrorStatus(S32 status, const std::string& reason) override;
+
+	// List Commands Handlers
+	void initListCommandsHandlers();
+	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
+
+	LLPlacesInventoryPanel*		mCurrentSelectedList;
 	
 private:
-	void initFavoritesInventoryPanel();
 	void initLandmarksInventoryPanel();
-	void initMyInventoryPanel();
-	void initLibraryInventoryPanel();
-	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
-	LLAccordionCtrlTab* initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab);
-	void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list);
-	void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list);
 
-	// List Commands Handlers
-	void initListCommandsHandlers();
 	void onTrashButtonClick() const;
 	void onAddAction(const LLSD& command_name) const;
 	void onClipboardAction(const LLSD& command_name) const;
@@ -170,23 +147,25 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 							 const LLParcelData& parcel_data);
 
 private:
-	LLPlacesInventoryPanel*		mFavoritesInventoryPanel;
 	LLPlacesInventoryPanel*		mLandmarksInventoryPanel;
-	LLPlacesInventoryPanel*		mMyInventoryPanel;
-	LLPlacesInventoryPanel*		mLibraryInventoryPanel;
 	LLToggleableMenu*			mGearLandmarkMenu;
 	LLToggleableMenu*			mGearFolderMenu;
 	LLToggleableMenu*			mSortingMenu;
 	LLToggleableMenu*			mAddMenu;
-	LLPlacesInventoryPanel*		mCurrentSelectedList;
-	LLInventoryObserver*		mInventoryObserver;
+
+	bool						isLandmarksPanel;
 	
-	typedef	std::vector<LLAccordionCtrlTab*> accordion_tabs_t;
-	accordion_tabs_t			mAccordionTabs;
+    LLUUID                      mCreatePickItemId; // item we requested a pick for
+};
 
-	LLAccordionCtrlTab*			mMyLandmarksAccordionTab;
 
-    LLUUID                      mCreatePickItemId; // item we requested a pick for
+class LLFavoritesPanel : public LLLandmarksPanel
+{
+public:
+	LLFavoritesPanel();
+
+	BOOL postBuild() override;
+	void initFavoritesInventoryPanel();
 };
 
 #endif //LL_LLPANELLANDMARKS_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 11ae980941d..7928896d966 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -1119,8 +1119,16 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 		}
 		else
 		{
-			LLLandmarksPanel* landmarks_panel =
-					dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
+			std::string tab_panel_name("Landmarks");
+			if (mItem.notNull())
+			{
+				if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)))
+				{
+					tab_panel_name = "Favorites";
+				}
+			}
+			
+			LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName(tab_panel_name));
 			if (landmarks_panel)
 			{
 				// If a landmark info is being closed we open the landmarks tab
@@ -1201,6 +1209,16 @@ void LLPanelPlaces::createTabs()
 	if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated))
 		return;
 
+	LLFavoritesPanel* favorites_panel = new LLFavoritesPanel();
+	if (favorites_panel)
+	{
+		mTabContainer->addTabPanel(
+			LLTabContainer::TabPanelParams().
+			panel(favorites_panel).
+			label(getString("favorites_tab_title")).
+			insert_at(LLTabContainer::END));
+	}
+
 	LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel();
 	if (landmarks_panel)
 	{
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
index df1139c98fa..e9ada52a8f6 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
@@ -27,6 +27,9 @@
         <on_enable
          function="Places.LandmarksGear.Enable"
          parameter="category" />
+        <on_visible
+         function="Places.LandmarksGear.Enable"
+         parameter="category" />
     </menu_item_call>
     <menu_item_call
      label="Restore Item"
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
index 6548fadfa56..4193a72e2e3 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
@@ -39,5 +39,8 @@
         <on_click
          function="Places.LandmarksGear.Folding.Action"
          parameter="sort_by_date" />
+        <on_enable
+         function="Places.LandmarksGear.Enable"
+         parameter="sort_by_date" />
     </menu_item_check>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_favorites.xml b/indra/newview/skins/default/xui/en/panel_favorites.xml
new file mode 100644
index 00000000000..1e8ea34ad28
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_favorites.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+   name="Favorites"
+   layout="topleft" 
+   left="0"
+   border="false"
+   background_visible="true"
+   bg_alpha_color="DkGray"
+   follows="all">
+    <places_inventory_panel
+      allow_multi_select="true"
+      border="false"
+      top="1"
+      left="3"
+      bottom="0"
+      follows="all"
+      right="-3"
+      mouse_opaque="true"
+      name="favorites_list"
+      folder_view.use_ellipses="true"
+      start_folder.name="Favorites"/>        
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index af2115156ef..10b925ec93e 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -1,98 +1,23 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
    name="Landmarks"
-   top="0"
-   height="400"
    layout="topleft" 
    left="0"
-   width="313"
    help_topic="panel_landmarks"
    border="false"
    background_visible="true"
    bg_alpha_color="DkGray"
    follows="all">
-    <accordion
-     background_visible="true"
-     bg_alpha_color="DkGray2"
-     bg_opaque_color="DkGray2"
-     follows="all"
-     height="398"
-     layout="topleft"
-     left="3"
-     name="landmarks_accordion"
-     top="0"
-     width="307">
-        <accordion_tab
-         layout="topleft"
-         name="tab_favorites"
-         title="Favorites bar">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="favorites_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="Favorites"
-             width="307"/>
-        </accordion_tab>
-        <accordion_tab
-         layout="topleft"
-         name="tab_landmarks"
-         title="My Landmarks">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="landmarks_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="Landmarks"
-             width="307"/>
-        </accordion_tab>
-        <accordion_tab
-         layout="topleft"
-         name="tab_inventory"
-         title="My Inventory">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="my_inventory_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="My Inventory"
-             width="307"/>
-          </accordion_tab>
-          <accordion_tab
-           layout="topleft"
-           name="tab_library"
-           title="Library">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="library_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="LIBRARY"
-             width="313"/>
-        </accordion_tab>
-    </accordion>
+    <places_inventory_panel
+      allow_multi_select="true"
+      border="false"
+      top="1"
+      follows="all"
+      left="3"
+      bottom="0"
+      right="-3"
+      mouse_opaque="true"
+      name="landmarks_list"
+      folder_view.use_ellipses="true"
+      start_folder.name="Landmarks"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index eed56209b70..dd4cf7ab4e7 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -13,10 +13,13 @@ background_visible="true"
  width="333">
   <string
    name="landmarks_tab_title"
-   value="MY LANDMARKS" />
+   value="LANDMARKS" />
   <string
    name="teleport_history_tab_title"
-   value="PLACES VISITED" />
+   value="VISITED" />
+  <string
+   name="favorites_tab_title"
+   value="FAVORITES" />
   <layout_stack
     animate="false"
     border_size="0"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 20ef10f1724..d9d0b659cc0 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2298,8 +2298,8 @@ For AI Character: Get the closest navigable point to the point provided.
 	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
 	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
 	<string name="InventoryFavoritItemsNotSelected">Click "Use as Favorites folder" on a folder of your choice. You can choose a different folder at any time. System folders and folders inside them cannot be used for Favorites.</string>
-	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
-	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
+	<string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string>
+	<string name="FavoritesNoMatchingItems">To add a place to your favorites bar, click the star to the right of the location name.</string>
 	<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>
 	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
 	<string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string>
-- 
GitLab