Fixed normal bug EXT-2346 "My Landmarks accordion panels shouldn't be displayed if there are no landmarks in respective folders".

- Added updating accordions contents in idle routine.
- Removed inventory observer.

--HG--
branch : product-engine
meow-7.2.2
Sergei Litovchuk 2009-12-01 20:25:01 +02:00
parent 857bc15a39
commit 56504054d8
7 changed files with 90 additions and 111 deletions

View File

@ -67,28 +67,6 @@ static const std::string TRASH_BUTTON_NAME = "trash_btn";
// helper functions
static void filter_list(LLInventorySubTreePanel* inventory_list, const std::string& string);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLLandmarksPanelObserver
//
// Bridge to support knowing when the inventory has changed to update
// landmarks accordions visibility.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLLandmarksPanelObserver : public LLInventoryObserver
{
public:
LLLandmarksPanelObserver(LLLandmarksPanel* lp) : mLP(lp) {}
virtual ~LLLandmarksPanelObserver() {}
/*virtual*/ void changed(U32 mask);
private:
LLLandmarksPanel* mLP;
};
void LLLandmarksPanelObserver::changed(U32 mask)
{
mLP->updateFilteredAccordions();
}
LLLandmarksPanel::LLLandmarksPanel()
: LLPanelPlacesTab()
, mFavoritesInventoryPanel(NULL)
@ -99,18 +77,12 @@ LLLandmarksPanel::LLLandmarksPanel()
, mListCommands(NULL)
, mGearFolderMenu(NULL)
, mGearLandmarkMenu(NULL)
, mDirtyFilter(false)
{
mInventoryObserver = new LLLandmarksPanelObserver(this);
gInventory.addObserver(mInventoryObserver);
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_landmarks.xml");
}
LLLandmarksPanel::~LLLandmarksPanel()
{
if (gInventory.containsObserver(mInventoryObserver))
gInventory.removeObserver(mInventoryObserver);
}
BOOL LLLandmarksPanel::postBuild()
@ -137,39 +109,34 @@ 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);
if (tab && !tab->getVisible())
tab->setVisible(TRUE);
// expand accordion to see matched items in each one. See EXT-2014.
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,31 +222,6 @@ void LLLandmarksPanel::onSelectorButtonClicked()
}
}
void LLLandmarksPanel::updateFilteredAccordions()
{
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;
}
//////////////////////////////////////////////////////////////////////////
// PROTECTED METHODS
//////////////////////////////////////////////////////////////////////////
@ -391,7 +333,8 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
initLandmarksPanel(mLandmarksInventoryPanel);
mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
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 +362,9 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_list)
{
if (!inventory_list->getFilter())
return;
inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
@ -440,6 +386,9 @@ void LLLandmarksPanel::initLandmarksPanel(LLInventorySubTreePanel* inventory_lis
void LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLInventorySubTreePanel* inventory_list)
{
LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);
if (!accordion_tab)
return;
mAccordionTabs.push_back(accordion_tab);
accordion_tab->setDropDownStateChangedCallback(
boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list));
@ -771,6 +720,42 @@ 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;
if (accordion_tab && !accordion_tab->getVisible())
accordion_tab->setVisible(TRUE);
inventory_list = dynamic_cast<LLInventorySubTreePanel*> (accordion_tab->getAccordionView());
if (NULL == inventory_list) continue;
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);
}
// 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
@ -883,12 +868,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)

View File

@ -46,7 +46,6 @@ class LLAccordionCtrlTab;
class LLFolderViewItem;
class LLMenuGL;
class LLInventoryPanel;
class LLInventoryObserver;
class LLInventorySubTreePanel;
class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
@ -64,13 +63,6 @@ public:
void onSelectionChange(LLInventorySubTreePanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onSelectorButtonClicked();
/**
* Updates accordions according to filtered items in lists.
*
* It hides accordion for empty lists
*/
void updateFilteredAccordions();
protected:
/**
* @return true - if current selected panel is not null and selected item is a landmark
@ -110,6 +102,13 @@ private:
bool isActionEnabled(const LLSD& command_name) const;
void onCustomAction(const LLSD& command_name);
/**
* Updates accordions according to filtered items in lists.
*
* It hides accordion for empty lists
*/
void updateFilteredAccordions();
/**
* Determines if selected item can be modified via context/gear menu.
*
@ -148,11 +147,9 @@ private:
LLMenuGL* mGearFolderMenu;
LLMenuGL* mMenuAdd;
LLInventorySubTreePanel* mCurrentSelectedList;
LLInventoryObserver* mInventoryObserver;
LLPanel* mListCommands;
bool mSortByDate;
bool mDirtyFilter;
typedef std::vector<LLAccordionCtrlTab*> accordion_tabs_t;
accordion_tabs_t mAccordionTabs;

View File

@ -118,7 +118,6 @@ static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
LLPanelPlaces::LLPanelPlaces()
: LLPanel(),
mFilterSubString(LLStringUtil::null),
mActivePanel(NULL),
mFilterEditor(NULL),
mPlaceProfile(NULL),
@ -385,16 +384,16 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark)
void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_filter)
{
if (force_filter || mFilterSubString != search_string)
if (force_filter || LLPanelPlacesTab::sFilterSubString != search_string)
{
mFilterSubString = search_string;
std::string string = search_string;
// Searches are case-insensitive
LLStringUtil::toUpper(mFilterSubString);
LLStringUtil::trimHead(mFilterSubString);
LLStringUtil::toUpper(string);
LLStringUtil::trimHead(string);
if (mActivePanel)
mActivePanel->onSearchEdit(mFilterSubString);
mActivePanel->onSearchEdit(string);
}
}
@ -404,7 +403,7 @@ void LLPanelPlaces::onTabSelected()
if (!mActivePanel)
return;
onFilterEdit(mFilterSubString, true);
onFilterEdit(LLPanelPlacesTab::sFilterSubString, true);
mActivePanel->updateVerbs();
}
@ -815,7 +814,7 @@ void LLPanelPlaces::changedInventory(U32 mask)
// Filter applied to show all items.
if (mActivePanel)
mActivePanel->onSearchEdit(mFilterSubString);
mActivePanel->onSearchEdit(LLPanelPlacesTab::sFilterSubString);
// we don't need to monitor inventory changes anymore,
// so remove the observer

View File

@ -120,10 +120,6 @@ private:
// be available (hence zero)
LLVector3d mPosGlobal;
// Search string for filtering landmarks and teleport
// history locations
std::string mFilterSubString;
// Information type currently shown in Place Information panel
std::string mPlaceInfoType;

View File

@ -33,14 +33,17 @@
#include "llpanelplacestab.h"
#include "llwindow.h"
#include "llbutton.h"
#include "llnotificationsutil.h"
#include "llbutton.h"
#include "llwindow.h"
#include "llpanelplaces.h"
#include "llslurl.h"
#include "llworldmap.h"
std::string LLPanelPlacesTab::sFilterSubString = LLStringUtil::null;
bool LLPanelPlacesTab::isTabVisible()
{
LLUICtrl* parent = getParentUICtrl();

View File

@ -34,7 +34,7 @@
#include "llpanel.h"
#include "llpanelplaces.h"
class LLPanelPlaces;
class LLPanelPlacesTab : public LLPanel
{
@ -55,6 +55,11 @@ public:
const std::string& url,
const LLUUID& snapshot_id,
bool teleport);
public:
// Search string for filtering landmarks and teleport history locations
static std::string sFilterSubString;
protected:
LLButton* mTeleportBtn;
LLButton* mShowOnMapBtn;

View File

@ -220,7 +220,6 @@ void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard()
LLTeleportHistoryPanel::LLTeleportHistoryPanel()
: LLPanelPlacesTab(),
mFilterSubString(LLStringUtil::null),
mDirty(true),
mCurrentItem(0),
mTeleportHistory(NULL),
@ -317,9 +316,9 @@ void LLTeleportHistoryPanel::draw()
// virtual
void LLTeleportHistoryPanel::onSearchEdit(const std::string& string)
{
if (mFilterSubString != string)
if (sFilterSubString != string)
{
mFilterSubString = string;
sFilterSubString = string;
showTeleportHistory();
}
}
@ -482,8 +481,8 @@ void LLTeleportHistoryPanel::refresh()
std::string landmark_title = items[mCurrentItem].mTitle;
LLStringUtil::toUpper(landmark_title);
std::string::size_type match_offset = mFilterSubString.size() ? landmark_title.find(mFilterSubString) : std::string::npos;
bool passed = mFilterSubString.size() == 0 || match_offset != std::string::npos;
std::string::size_type match_offset = sFilterSubString.size() ? landmark_title.find(sFilterSubString) : std::string::npos;
bool passed = sFilterSubString.size() == 0 || match_offset != std::string::npos;
if (!passed)
{