summaryrefslogtreecommitdiff
path: root/indra/newview/llpanellandmarks.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llpanellandmarks.cpp')
-rw-r--r--indra/newview/llpanellandmarks.cpp204
1 files changed, 125 insertions, 79 deletions
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index e24fa14e1e..32c9faa688 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -66,13 +66,15 @@ static const std::string TRASH_BUTTON_NAME = "trash_btn";
// helper functions
static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string);
+static void save_folder_state_if_no_filter(LLInventorySubTreePanel* inventory_list);
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLLandmarksPanelObserver
-//
-// Bridge to support knowing when the inventory has changed to update
-// landmarks accordions visibility.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+/**
+ * Bridge to support knowing when the inventory has changed to update folder (open/close) state
+ * for landmarks panels.
+ *
+ * Due to Inventory data are loaded in background we need to save folder state each time
+ * next level is loaded. See EXT-3094.
+ */
class LLLandmarksPanelObserver : public LLInventoryObserver
{
public:
@@ -86,7 +88,7 @@ private:
void LLLandmarksPanelObserver::changed(U32 mask)
{
- mLP->updateFilteredAccordions();
+ mLP->saveFolderStateIfNoFilter();
}
LLLandmarksPanel::LLLandmarksPanel()
@@ -99,7 +101,6 @@ LLLandmarksPanel::LLLandmarksPanel()
, mListCommands(NULL)
, mGearFolderMenu(NULL)
, mGearLandmarkMenu(NULL)
- , mDirtyFilter(false)
{
mInventoryObserver = new LLLandmarksPanelObserver(this);
gInventory.addObserver(mInventoryObserver);
@@ -110,7 +111,9 @@ LLLandmarksPanel::LLLandmarksPanel()
LLLandmarksPanel::~LLLandmarksPanel()
{
if (gInventory.containsObserver(mInventoryObserver))
+ {
gInventory.removeObserver(mInventoryObserver);
+ }
}
BOOL LLLandmarksPanel::postBuild()
@@ -137,39 +140,38 @@ BOOL LLLandmarksPanel::postBuild()
// virtual
void LLLandmarksPanel::onSearchEdit(const std::string& string)
{
- static std::string prev_string("");
-
- if (prev_string == string) return;
-
// show all folders in Landmarks Accordion for empty filter
- mLandmarksInventoryPanel->setShowFolderState(string.empty() ?
- LLInventoryFilter::SHOW_ALL_FOLDERS :
- LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS
- );
-
- filter_list(mFavoritesInventoryPanel, string);
- filter_list(mLandmarksInventoryPanel, string);
- filter_list(mMyInventoryPanel, string);
- filter_list(mLibraryInventoryPanel, string);
-
- prev_string = string;
- mDirtyFilter = true;
+ if (mLandmarksInventoryPanel->getFilter())
+ {
+ mLandmarksInventoryPanel->setShowFolderState(string.empty() ?
+ LLInventoryFilter::SHOW_ALL_FOLDERS :
+ LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS
+ );
+ }
// 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);
+ tab->setVisible(TRUE);
// expand accordion to see matched items in each one. See EXT-2014.
- tab->changeOpenClose(false);
+ if (string != "")
+ {
+ tab->changeOpenClose(false);
+ }
- // refresh all accordions to display their contents in case of less restrictive filter
LLInventorySubTreePanel* inventory_list = dynamic_cast<LLInventorySubTreePanel*>(tab->getAccordionView());
if (NULL == inventory_list) continue;
- LLFolderView* fv = inventory_list->getRootFolder();
- fv->refresh();
+
+ if (inventory_list->getFilter())
+ {
+ filter_list(inventory_list, string);
+ }
}
+
+ if (sFilterSubString != string)
+ sFilterSubString = string;
}
// virtual
@@ -255,29 +257,12 @@ void LLLandmarksPanel::onSelectorButtonClicked()
}
}
-void LLLandmarksPanel::updateFilteredAccordions()
+void LLLandmarksPanel::saveFolderStateIfNoFilter()
{
- LLInventoryPanel* inventory_list = NULL;
- LLAccordionCtrlTab* accordion_tab = NULL;
- for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
- {
- accordion_tab = *iter;
- inventory_list = dynamic_cast<LLInventorySubTreePanel*> (accordion_tab->getAccordionView());
- if (NULL == inventory_list) continue;
- LLFolderView* fv = inventory_list->getRootFolder();
-
- bool has_descendants = fv->hasFilteredDescendants();
-
- accordion_tab->setVisible(has_descendants);
- }
-
- // we have to arrange accordion tabs for cases when filter string is less restrictive but
- // all items are still filtered.
- static LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
- accordion->arrange();
-
- // now filter state is applied to accordion tabs
- mDirtyFilter = false;
+ save_folder_state_if_no_filter(mFavoritesInventoryPanel);
+ save_folder_state_if_no_filter(mLandmarksInventoryPanel);
+ save_folder_state_if_no_filter(mMyInventoryPanel);
+ save_folder_state_if_no_filter(mLibraryInventoryPanel);
}
//////////////////////////////////////////////////////////////////////////
@@ -381,7 +366,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()
mFavoritesInventoryPanel = getChild<LLInventorySubTreePanel>("favorites_list");
initLandmarksPanel(mFavoritesInventoryPanel);
-
+ mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems");
initAccordion("tab_favorites", mFavoritesInventoryPanel);
}
@@ -391,7 +376,12 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
initLandmarksPanel(mLandmarksInventoryPanel);
- mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+ // Check if mLandmarksInventoryPanel is properly initialized and has a Filter created.
+ // In case of a dummy widget getFilter() will return NULL.
+ if (mLandmarksInventoryPanel->getFilter())
+ {
+ mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+ }
// subscribe to have auto-rename functionality while creating New Folder
mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
@@ -419,6 +409,11 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list)
{
+ // In case of a dummy widget further we have no Folder View widget and no Filter,
+ // so further initialization leads to crash.
+ if (!inventory_list->getFilter())
+ return;
+
inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
@@ -432,14 +427,13 @@ void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_lis
root_folder->setupMenuHandle(LLInventoryType::IT_LANDMARK, mGearLandmarkMenu->getHandle());
}
- // save initial folder state to avoid incorrect work while switching between Landmarks & Teleport History tabs
- // See EXT-1609.
- inventory_list->saveFolderState();
+ root_folder->setParentLandmarksPanel(this);
}
void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list)
{
LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);
+
mAccordionTabs.push_back(accordion_tab);
accordion_tab->setDropDownStateChangedCallback(
boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list));
@@ -457,6 +451,19 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLInvento
mCurrentSelectedList = NULL;
updateVerbs();
}
+
+ // Start background fetch, mostly for My Inventory and Library
+ if (expanded)
+ {
+ const LLUUID &cat_id = inventory_list->getStartFolderID();
+ // Just because the category itself has been fetched, doesn't mean its child folders have.
+ /*
+ if (!gInventory.isCategoryComplete(cat_id))
+ */
+ {
+ gInventory.startBackgroundFetch(cat_id);
+ }
+ }
}
void LLLandmarksPanel::deselectOtherThan(const LLInventorySubTreePanel* inventory_list)
@@ -580,11 +587,11 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
if(landmark)
{
LLSideTray::getInstance()->showPanel("panel_places",
- LLSD().insert("type", "landmark").insert("id",landmark->getUUID()));
+ LLSD().with("type", "landmark").with("id",landmark->getUUID()));
}
else
{
- LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark"));
+ LLSideTray::getInstance()->showPanel("panel_places", LLSD().with("type", "create_landmark"));
}
}
else if ("category" == command_name)
@@ -730,13 +737,14 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
{
return canSelectedBeModified(command_name);
}
- else if ( "sort_by_date" == command_name)
- {
- return mSortByDate;
- }
else if("create_pick" == command_name)
{
- return !LLAgentPicksInfo::getInstance()->isPickLimitReached();
+ std::set<LLUUID> selection;
+ if ( mCurrentSelectedList && mCurrentSelectedList->getRootFolder()->getSelectionList(selection) )
+ {
+ return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() );
+ }
+ return false;
}
else
{
@@ -770,6 +778,46 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)
}
}
+void LLLandmarksPanel::updateFilteredAccordions()
+{
+ LLInventoryPanel* inventory_list = NULL;
+ LLAccordionCtrlTab* accordion_tab = NULL;
+ bool needs_arrange = false;
+
+ for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
+ {
+ accordion_tab = *iter;
+
+ accordion_tab->setVisible(TRUE);
+
+ inventory_list = dynamic_cast<LLInventorySubTreePanel*> (accordion_tab->getAccordionView());
+ if (NULL == inventory_list) continue;
+
+ // This doesn't seem to work correctly. Disabling for now. -Seraph
+ // Enabled to show/hide accordions with/without landmarks. See EXT-2346. (Seth PE)
+ LLFolderView* fv = inventory_list->getRootFolder();
+
+ // arrange folder view contents to draw its descendants if it has any
+ fv->arrangeFromRoot();
+
+ bool has_descendants = fv->hasFilteredDescendants();
+ if (!has_descendants)
+ needs_arrange = true;
+
+ accordion_tab->setVisible(has_descendants);
+
+ //accordion_tab->setVisible(TRUE);
+ }
+
+ // we have to arrange accordion tabs for cases when filter string is less restrictive but
+ // all items are still filtered.
+ if (needs_arrange)
+ {
+ static LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
+ accordion->arrange();
+ }
+}
+
/*
Processes such actions: cut/rename/delete/paste actions
@@ -882,12 +930,7 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg
void LLLandmarksPanel::doIdle(void* landmarks_panel)
{
LLLandmarksPanel* panel = (LLLandmarksPanel* ) landmarks_panel;
-
- if (panel->mDirtyFilter)
- {
- panel->updateFilteredAccordions();
- }
-
+ panel->updateFilteredAccordions();
}
void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark)
@@ -987,29 +1030,32 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
//////////////////////////////////////////////////////////////////////////
static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string)
{
+ // Open the immediate children of the root folder, since those
+ // are invisible in the UI and thus must always be open.
+ inventory_list->getRootFolder()->openTopLevelFolders();
+
if (string == "")
{
inventory_list->setFilterSubString(LLStringUtil::null);
-
- // re-open folders that were initially open
- inventory_list->restoreFolderState();
}
- gInventory.startBackgroundFetch();
-
if (inventory_list->getFilterSubString().empty() && string.empty())
{
// current filter and new filter empty, do nothing
return;
}
+ // Set new filter string
+ inventory_list->setFilterSubString(string);
+
+}
+
+static void save_folder_state_if_no_filter(LLInventorySubTreePanel* inventory_list)
+{
// save current folder open state if no filter currently applied
- if (inventory_list->getRootFolder()->getFilterSubString().empty())
+ if (inventory_list->getRootFolder() && inventory_list->getRootFolder()->getFilterSubString().empty())
{
- inventory_list->saveFolderState();
+ // inventory_list->saveFolderState(); // *TODO: commented out to fix build
}
-
- // set new filter string
- inventory_list->setFilterSubString(string);
}
// EOF