Automated merge with ssh://hg.lindenlab.com/leyla/viewer-experience-dd

master
Richard Linden 2011-06-23 10:57:41 -07:00
commit 715cb3cc0c
16 changed files with 305 additions and 314 deletions

View File

@ -167,13 +167,22 @@ void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
///----------------------------------------------------------------------------
/// Class LLFolderView
///----------------------------------------------------------------------------
LLFolderView::Params::Params()
: task_id("task_id"),
title("title"),
use_label_suffix("use_label_suffix"),
allow_multiselect("allow_multiselect", true),
use_ellipses("use_ellipses", false)
{
}
// Default constructor
LLFolderView::LLFolderView(const Params& p)
: LLFolderViewFolder(p),
mScrollContainer( NULL ),
mPopupMenuHandle(),
mAllowMultiSelect(TRUE),
mAllowMultiSelect(p.allow_multiselect),
mShowFolderHierarchy(FALSE),
mSourceID(p.task_id),
mRenameItem( NULL ),
@ -194,10 +203,12 @@ LLFolderView::LLFolderView(const Params& p)
mDragAndDropThisFrame(FALSE),
mCallbackRegistrar(NULL),
mParentPanel(p.parent_panel),
mUseEllipses(false),
mUseEllipses(p.use_ellipses),
mDraggingOverItem(NULL),
mStatusTextBox(NULL)
{
mRoot = this;
LLRect rect = p.rect;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
setRect( rect );
@ -424,11 +435,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
}
// Need to call arrange regardless of visibility, since children's visibility
// might need to be changed too (e.g. even though a folder is invisible, its
// children also need to be set invisible for state-tracking purposes, e.g.
// llfolderviewitem::filter).
// if (folderp->getVisible())
if (folderp->getVisible())
{
S32 child_height = 0;
S32 child_width = 0;
@ -764,7 +771,7 @@ void LLFolderView::sanitizeSelection()
}
// Don't allow invisible items (such as root folders) to be selected.
if (item->getHidden())
if (item == getRoot())
{
items_to_remove.push_back(item);
}
@ -787,7 +794,7 @@ void LLFolderView::sanitizeSelection()
parent_folder;
parent_folder = parent_folder->getParentFolder())
{
if (parent_folder->potentiallyVisible() && !parent_folder->getHidden())
if (parent_folder->potentiallyVisible())
{
// give initial selection to first ancestor folder that potentially passes the filter
if (!new_selection)
@ -806,7 +813,13 @@ void LLFolderView::sanitizeSelection()
}
else
{
new_selection = NULL;
// nothing selected to start with, so pick "My Inventory" as best guess
new_selection = getItemByID(gInventory.getRootFolderID());
// ... except if it's hidden from the UI.
if (new_selection && new_selection->getHidden())
{
new_selection = NULL;
}
}
if (new_selection)
@ -956,7 +969,9 @@ void LLFolderView::draw()
}
LLFolderViewFolder::draw();
// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,
// and arrow for the root folder
LLView::draw();
mDragAndDropThisFrame = FALSE;
}
@ -1636,12 +1651,8 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
LLFolderViewItem* parent_folder = last_selected->getParentFolder();
if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
{
// Don't change selectin to hidden folder. See EXT-5328.
if (!parent_folder->getHidden())
{
setSelection(parent_folder, FALSE, TRUE);
}
}
else
{
last_selected->setOpen( FALSE );
@ -2025,7 +2036,7 @@ void LLFolderView::removeItemID(const LLUUID& id)
LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
{
if (id.isNull())
if (id == getListener()->getUUID())
{
return this;
}
@ -2042,7 +2053,7 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
{
if (id.isNull())
if (id == getListener()->getUUID())
{
return this;
}
@ -2490,11 +2501,6 @@ BOOL LLFolderView::isFilterModified()
return mFilter->isNotDefault();
}
BOOL LLFolderView::getAllowMultiSelect()
{
return mAllowMultiSelect;
}
void delete_selected_item(void* user_data)
{
if(user_data)

View File

@ -89,7 +89,11 @@ public:
Mandatory<LLPanel*> parent_panel;
Optional<LLUUID> task_id;
Optional<std::string> title;
Optional<bool> use_label_suffix;
Optional<bool> use_label_suffix,
allow_multiselect,
use_ellipses;
Params();
};
LLFolderView(const Params&);
virtual ~LLFolderView( void );
@ -102,7 +106,6 @@ public:
// and resort the items if necessary.
void setSortOrder(U32 order);
void setFilterPermMask(PermissionMask filter_perm_mask);
void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }
typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
@ -117,7 +120,6 @@ public:
//LLInventoryFilter::EFolderShow getShowFolderState();
U32 getSortOrder() const;
BOOL isFilterModified();
BOOL getAllowMultiSelect();
// Close all folders in the view
void closeAllFolders();
@ -238,7 +240,6 @@ public:
void setShowSingleSelection(BOOL show);
BOOL getShowSingleSelection() { return mShowSingleSelection; }
F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
void setUseEllipses(bool use_ellipses) { mUseEllipses = use_ellipses; }
bool getUseEllipses() { return mUseEllipses; }
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);

View File

@ -131,10 +131,14 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mIconOpen(p.icon_open),
mIconOverlay(p.icon_overlay),
mListener(p.listener),
mHidden(false),
mShowLoadStatus(false)
{
}
BOOL LLFolderViewItem::postBuild()
{
refresh();
return TRUE;
}
// Destroys the object
@ -196,7 +200,7 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
// Skip over items that are invisible or are hidden from the UI.
while(itemp && (!itemp->getVisible() || itemp->getHidden()))
while(itemp && !itemp->getVisible())
{
LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
if (itemp == next_itemp)
@ -352,7 +356,10 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
BOOL take_keyboard_focus)
{
LLFolderView* root = getRoot();
if (getParentFolder())
{
getParentFolder()->requestArrange();
}
if(set_selection)
{
setSelectionFromRoot(this, TRUE, take_keyboard_focus);
@ -443,23 +450,20 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
S32 LLFolderViewItem::getItemHeight()
{
if (getHidden()) return 0;
return mItemHeight;
}
void LLFolderViewItem::filter( LLInventoryFilter& filter)
{
const BOOL previous_passed_filter = mPassedFilter;
const BOOL passed_filter = mListener && filter.check(this);
const BOOL passed_filter = filter.check(this);
// If our visibility will change as a result of this filter, then
// we need to be rearranged in our parent folder
if (mParentFolder)
{
if (getVisible() != passed_filter)
mParentFolder->requestArrange();
if (passed_filter != previous_passed_filter)
if (getVisible() != passed_filter
|| previous_passed_filter != passed_filter )
mParentFolder->requestArrange();
}
@ -864,11 +868,6 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
void LLFolderViewItem::draw()
{
if (getHidden())
{
return;
}
static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
@ -892,8 +891,8 @@ void LLFolderViewItem::draw()
// Draw open folder arrow
//
const bool up_to_date = mListener && mListener->isUpToDate();
const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) || // we fetched our children and some of them have passed the filter...
(!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
if (possibly_has_children)
{
LLUIImage* arrow_image = default_params.folder_arrow_image;
@ -1055,8 +1054,11 @@ void LLFolderViewItem::draw()
{
root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
}
if ((mIsLoading && mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime")) ||
(LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && root_is_loading && (mShowLoadStatus || mHidden)))
if ((mIsLoading
&& mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
|| (LLInventoryModelBackgroundFetch::instance().backgroundFetchActive()
&& root_is_loading
&& mShowLoadStatus))
{
std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
@ -1120,7 +1122,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mLastCalculatedWidth(0),
mCompletedFilterGeneration(-1),
mMostFilteredDescendantGeneration(-1),
mNeedsSort(false)
mNeedsSort(false),
mPassedFolderFilter(FALSE)
{
}
@ -1132,6 +1135,17 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
}
void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
{
mPassedFolderFilter = filtered;
mLastFilterGeneration = filter_generation;
}
bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
{
return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
}
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
{
@ -1158,8 +1172,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
mHasVisibleChildren = hasFilteredDescendants(filter_generation);
LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getFilter()->getShowFolderState();
// calculate height as a single item (without any children), and reshapes rectangle to match
LLFolderViewItem::arrange( width, height, filter_generation );
@ -1193,9 +1205,9 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
{
bool is_hidden = folderp->getListener() && LLViewerFolderType::lookupIsHiddenType(folderp->getListener()->getPreferredType());
folderp->setVisible( !is_hidden &&
(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
folderp->setVisible( !is_hidden
&& (show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS
|| (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
}
if (folderp->getVisible())
@ -1315,7 +1327,9 @@ void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recur
mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
mCompletedFilterGeneration = generation;
// only aggregate up if we are a lower (older) value
if (recurse_up && mParentFolder && generation < mParentFolder->getCompletedFilterGeneration())
if (recurse_up
&& mParentFolder
&& generation < mParentFolder->getCompletedFilterGeneration())
{
mParentFolder->setCompletedFilterGeneration(generation, TRUE);
}
@ -1340,21 +1354,19 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
// filter folder itself
if (getLastFilterGeneration() < filter_generation)
{
if (getLastFilterGeneration() >= must_pass_generation && // folder has been compared to a valid precursor filter
!mPassedFilter) // and did not pass the filter
if (getLastFilterGeneration() >= must_pass_generation // folder has been compared to a valid precursor filter
&& !mPassedFilter) // and did not pass the filter
{
// go ahead and flag this folder as done
mLastFilterGeneration = filter_generation;
}
else
else // filter self only on first pass through
{
// filter self only on first pass through
// filter against folder rules
filterFolder(filter);
// and then item rules
LLFolderViewItem::filter( filter );
}
if (mHidden)
{
setOpen();
}
}
if (getRoot()->getDebugFilters())
@ -1381,7 +1393,10 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
}
// when applying a filter, matching folders get their contents downloaded first
if (filter.isNotDefault() && getFiltered(filter.getMinRequiredGeneration()) && (mListener && !gInventory.isCategoryComplete(mListener->getUUID())))
if (filter.isNotDefault()
&& getFiltered(filter.getMinRequiredGeneration())
&& (mListener
&& !gInventory.isCategoryComplete(mListener->getUUID())))
{
LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
}
@ -1471,6 +1486,31 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
}
}
void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
{
const BOOL previous_passed_filter = mPassedFolderFilter;
const BOOL passed_filter = filter.checkFolder(this);
// If our visibility will change as a result of this filter, then
// we need to be rearranged in our parent folder
if (mParentFolder)
{
if (getVisible() != passed_filter
|| previous_passed_filter != passed_filter )
{
mParentFolder->requestArrange();
}
}
setFilteredFolder(passed_filter, filter.getCurrentGeneration());
filter.decrementFilterCount();
if (getRoot()->getDebugFilters())
{
mStatusText = llformat("%d", mLastFilterGeneration);
}
}
void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
{
// if this folder is now filtered, but wasn't before
@ -2077,7 +2117,9 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN); /* Flawfinder: ignore */
}
}
if (mParentFolder && (recurse == RECURSE_UP || recurse == RECURSE_UP_DOWN))
if (mParentFolder
&& (recurse == RECURSE_UP
|| recurse == RECURSE_UP_DOWN))
{
mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
}
@ -2319,13 +2361,16 @@ void LLFolderViewFolder::draw()
bool possibly_has_children = false;
bool up_to_date = mListener && mListener->isUpToDate();
if(!up_to_date && mListener && mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
if(!up_to_date
&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
{
possibly_has_children = true;
}
BOOL loading = ( mIsOpen && possibly_has_children && !up_to_date );
BOOL loading = (mIsOpen
&& possibly_has_children
&& !up_to_date );
if ( loading && !mIsLoading )
{
@ -2606,7 +2651,8 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
{
// ignore sort order for landmarks in the Favorites folder.
// they should be always sorted as in Favorites bar. See EXT-719
if (a->getSortGroup() == SG_ITEM && b->getSortGroup() == SG_ITEM
if (a->getSortGroup() == SG_ITEM
&& b->getSortGroup() == SG_ITEM
&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
{

View File

@ -157,7 +157,6 @@ protected:
BOOL mDragAndDropTarget;
BOOL mIsLoading;
LLTimer mTimeSinceRequestStart;
bool mHidden;
bool mShowLoadStatus;
// helper function to change the selection from the root.
@ -174,6 +173,8 @@ protected:
static LLFontGL* getLabelFontForStyle(U8 style);
public:
BOOL postBuild();
// This function clears the currently selected item, and records
// the specified selected item appropriately for display and use
// in the UI. If open is TRUE, then folders are opened up along
@ -202,11 +203,6 @@ public:
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
virtual S32 getItemHeight();
// Hide the folder from the UI, such as if you want to hide the root
// folder in an inventory panel.
void setHidden(bool hidden) { mHidden = hidden; }
bool getHidden() const { return mHidden; }
// applies filters to control visibility of inventory items
virtual void filter( LLInventoryFilter& filter);
@ -278,7 +274,7 @@ public:
// Used for sorting, like getLabel() above.
virtual time_t getCreationDate() const { return mCreationDate; }
LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
@ -393,6 +389,8 @@ protected:
S32 mCompletedFilterGeneration;
S32 mMostFilteredDescendantGeneration;
bool mNeedsSort;
bool mPassedFolderFilter;
public:
typedef enum e_recurse_type
{
@ -434,6 +432,11 @@ public:
virtual void setFiltered(BOOL filtered, S32 filter_generation);
virtual void dirtyFilter();
// folder-specific filtering (filter status propagates top down instead of bottom up)
void filterFolder(LLInventoryFilter& filter);
void setFilteredFolder(bool filtered, S32 filter_generation);
bool getFilteredFolder(S32 filter_generation);
// Passes selection information on to children and record
// selection information if necessary.
// Returns TRUE if this object (or a child) ends up being selected.

View File

@ -107,6 +107,31 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
return passed;
}
bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
{
// we're showing all folders, overriding filter
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
{
return true;
}
const LLFolderViewEventListener* listener = folder->getListener();
const LLUUID folder_id = listener->getUUID();
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
if (!cat)
return false;
if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
return false;
}
return true;
}
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
{
const LLFolderViewEventListener* listener = item->getListener();
@ -137,30 +162,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
}
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_CATEGORY
// Pass if this item is a category of the filter type, or
// if its parent is a category of the filter type.
if (filterTypes & FILTERTYPE_CATEGORY)
{
// Can only filter categories for items in your inventory
// (e.g. versus in-world object contents).
if (!object) return FALSE;
LLUUID cat_id = object_id;
if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
{
cat_id = object->getParentUUID();
}
const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (!cat)
return FALSE;
if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_UUID
// Pass if this item is the target UUID or if it links to the target UUID
@ -172,7 +173,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
// FILTERTYPE_DATE
// Pass if this item is within the date range.
@ -293,15 +293,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()
return ret;
}
void LLInventoryFilter::setFilterObjectTypes(U64 types)
void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
{
if (mFilterOps.mFilterObjectTypes != types)
if (current_types != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterObjectTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterObjectTypes & types);
BOOL fewer_bits_set = (current_types & ~types);
BOOL more_bits_set = (~current_types & types);
mFilterOps.mFilterObjectTypes = types;
current_types = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
@ -318,62 +318,23 @@ void LLInventoryFilter::setFilterObjectTypes(U64 types)
setModified(FILTER_MORE_RESTRICTIVE);
}
}
}
void LLInventoryFilter::setFilterObjectTypes(U64 types)
{
updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
}
void LLInventoryFilter::setFilterCategoryTypes(U64 types)
{
if (mFilterOps.mFilterCategoryTypes != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterCategoryTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterCategoryTypes & types);
mFilterOps.mFilterCategoryTypes = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
// so we need to filter from scratch
setModified(FILTER_RESTART);
}
else if (more_bits_set)
{
// target is only one of all requested types so more type bits == less restrictive
setModified(FILTER_LESS_RESTRICTIVE);
}
else if (fewer_bits_set)
{
setModified(FILTER_MORE_RESTRICTIVE);
}
}
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
}
void LLInventoryFilter::setFilterWearableTypes(U64 types)
{
if (mFilterOps.mFilterWearableTypes != types)
{
// keep current items only if no type bits getting turned off
BOOL fewer_bits_set = (mFilterOps.mFilterWearableTypes & ~types);
BOOL more_bits_set = (~mFilterOps.mFilterWearableTypes & types);
mFilterOps.mFilterWearableTypes = types;
if (more_bits_set && fewer_bits_set)
{
// neither less or more restrive, both simultaneously
// so we need to filter from scratch
setModified(FILTER_RESTART);
}
else if (more_bits_set)
{
// target is only one of all requested types so more type bits == less restrictive
setModified(FILTER_LESS_RESTRICTIVE);
}
else if (fewer_bits_set)
{
setModified(FILTER_MORE_RESTRICTIVE);
}
}
updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
}
@ -898,11 +859,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
}
}
U32 LLInventoryFilter::getFilterObjectTypes() const
U64 LLInventoryFilter::getFilterObjectTypes() const
{
return mFilterOps.mFilterObjectTypes;
}
U64 LLInventoryFilter::getFilterCategoryTypes() const
{
return mFilterOps.mFilterCategoryTypes;
}
BOOL LLInventoryFilter::hasFilterString() const
{
return mFilterSubString.size() > 0;

View File

@ -31,6 +31,7 @@
#include "llpermissionsflags.h"
class LLFolderViewItem;
class LLFolderViewFolder;
class LLInventoryFilter
{
@ -81,11 +82,13 @@ public:
// + Parameters
// +-------------------------------------------------------------------+
void setFilterObjectTypes(U64 types);
U32 getFilterObjectTypes() const;
U64 getFilterObjectTypes() const;
U64 getFilterCategoryTypes() const;
BOOL isFilterObjectTypesWith(LLInventoryType::EType t) const;
void setFilterCategoryTypes(U64 types);
void setFilterUUID(const LLUUID &object_id);
void setFilterWearableTypes(U64 types);
void updateFilterTypes(U64 types, U64& current_types);
void setFilterSubString(const std::string& string);
const std::string& getFilterSubString(BOOL trim = FALSE) const;
@ -110,6 +113,7 @@ public:
// + Execution And Results
// +-------------------------------------------------------------------+
BOOL check(const LLFolderViewItem* item);
bool checkFolder(const LLFolderViewFolder* folder);
BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;

View File

@ -131,8 +131,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mAllowMultiSelect(p.allow_multi_select),
mShowItemLinkOverlays(p.show_item_link_overlays),
mViewsInitialized(false),
mStartFolderString(p.start_folder),
mBuildDefaultHierarchy(true),
mInvFVBridgeBuilder(NULL)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@ -146,20 +144,27 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars));
if (mStartFolderString != "")
{
mBuildDefaultHierarchy = false;
}
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
// Determine the root folder in case specified, and
// build the views starting with that folder.
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
LLUUID root_id;
// Create root folder
if ("LIBRARY" == params.start_folder())
{
root_id = gInventory.getLibraryRootFolderID();
}
else
{
root_id = (preferred_type != LLFolderType::FT_NONE)
? gInventory.findCategoryUUIDForType(preferred_type, false, false)
: LLUUID::null;
}
LLRect folder_rect(0,
0,
getRect().getWidth(),
@ -170,11 +175,26 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
p.rect = folder_rect;
p.parent_panel = this;
p.tool_tip = p.name;
p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
NULL,
root_id);
p.use_label_suffix = params.use_label_suffix;
p.allow_multiselect = mAllowMultiSelect;
mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
}
void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
buildFolderView(params);
mCommitCallbackRegistrar.popScope();
mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
@ -201,7 +221,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
// Build view of inventory if we need default full hierarchy and inventory ready,
// otherwise wait for idle callback.
if (mBuildDefaultHierarchy && mInventory->isInventoryUsable() && !mViewsInitialized)
if (mInventory->isInventoryUsable() && !mViewsInitialized)
{
initializeViews();
}
@ -259,6 +279,15 @@ LLInventoryFilter* LLInventoryPanel::getFilter()
return NULL;
}
const LLInventoryFilter* LLInventoryPanel::getFilter() const
{
if (mFolderRoot)
{
return mFolderRoot->getFilter();
}
return NULL;
}
void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
{
if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
@ -483,23 +512,16 @@ void LLInventoryPanel::onIdle(void *userdata)
}
}
const LLUUID& LLInventoryPanel::getRootFolderID() const
{
return mFolderRoot->getListener()->getUUID();
}
void LLInventoryPanel::initializeViews()
{
if (!gInventory.isInventoryUsable()) return;
// Determine the root folder in case specified, and
// build the views starting with that folder.
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(mStartFolderString);
if ("LIBRARY" == mStartFolderString)
{
mStartFolderID = gInventory.getLibraryRootFolderID();
}
else
{
mStartFolderID = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type, false, false) : LLUUID::null);
}
rebuildViewsFor(mStartFolderID);
rebuildViewsFor(getRootFolderID());
mViewsInitialized = true;
@ -528,7 +550,7 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
{
// Destroy the old view for this ID so we can rebuild it.
LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
if (old_view && id.notNull())
if (old_view && old_view != mFolderRoot)
{
old_view->destroyView();
}
@ -538,28 +560,27 @@ void LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
void LLInventoryPanel::buildNewViews(const LLUUID& id)
{
LLMemType mt(LLMemType::MTYPE_INVENTORY_BUILD_NEW_VIEWS);
LLFolderViewItem* itemp = NULL;
LLInventoryObject* objectp = gInventory.getObject(id);
if (objectp)
{
const LLUUID &parent_id = objectp->getParentUUID();
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
if (id == mStartFolderID)
LLInventoryObject const* objectp = gInventory.getObject(id);
LLUUID root_id = mFolderRoot->getListener()->getUUID();
LLFolderViewFolder* parent_folder = NULL;
if (id == root_id)
{
parent_folder = mFolderRoot;
}
else if ((mStartFolderID != LLUUID::null) && (!gInventory.isObjectDescendentOf(id, mStartFolderID)))
else if (objectp)
{
// This item exists outside the inventory's hierarchy, so don't add it.
return;
}
LLFolderViewItem* itemp = NULL;
const LLUUID &parent_id = objectp->getParentUUID();
parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
if (parent_folder)
{
if (objectp->getType() <= LLAssetType::AT_NONE ||
objectp->getType() >= LLAssetType::AT_COUNT)
{
llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< llendl;
return;
}
@ -589,21 +610,9 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(params);
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
itemp = folderp;
// Hide the root folder, so we can show the contents of a folder flat
// but still have the parent folder present for listener-related operations.
if (id == mStartFolderID)
{
folderp->setHidden(TRUE);
}
const LLViewerInventoryCategory *cat = dynamic_cast<LLViewerInventoryCategory *>(objectp);
if (cat && getIsHiddenFolderType(cat->getPreferredType()))
{
folderp->setHidden(TRUE);
}
}
}
else
else
{
// Build new view for item.
LLInventoryItem* item = (LLInventoryItem*)objectp;
@ -637,19 +646,15 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
if (itemp)
{
itemp->addToFolder(parent_folder, mFolderRoot);
// Don't add children of hidden folders unless this is the panel's root folder.
if (itemp->getHidden() && (id != mStartFolderID))
{
return;
}
}
}
// If this is a folder, add the children of the folder and recursively add any
// child folders.
if ((id == mStartFolderID) ||
(objectp && objectp->getType() == LLAssetType::AT_CATEGORY))
if (id.isNull()
|| (objectp
&& objectp->getType() == LLAssetType::AT_CATEGORY))
{
LLViewerInventoryCategory::cat_array_t* categories;
LLViewerInventoryItem::item_array_t* items;
@ -666,7 +671,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
}
}
if(items)
if(items && parent_folder)
{
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
item_iter != items->end();
@ -683,18 +688,13 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
// bit of a hack to make sure the inventory is open.
void LLInventoryPanel::openStartFolderOrMyInventory()
{
if (mStartFolderString != "")
{
mFolderRoot->openFolder(mStartFolderString);
}
else
{
// Find My Inventory folder and open it up by name
for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
{
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild && fchild->getListener() &&
(fchild->getListener()->getUUID() == gInventory.getRootFolderID()))
if (fchild
&& fchild->getListener()
&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
{
const std::string& child_name = child->getName();
mFolderRoot->openFolder(child_name);
@ -702,7 +702,6 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
}
}
}
}
void LLInventoryPanel::onItemsCompletion()
{
@ -1062,15 +1061,12 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
{
if (!getIsHiddenFolderType(folder_type))
{
mHiddenFolderTypes.push_back(folder_type);
}
getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
}
BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
{
return (std::find(mHiddenFolderTypes.begin(), mHiddenFolderTypes.end(), folder_type) != mHiddenFolderTypes.end());
return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
}

View File

@ -128,6 +128,7 @@ public:
void setSelectCallback(const LLFolderView::signal_t::slot_type& cb);
void clearSelection();
LLInventoryFilter* getFilter();
const LLInventoryFilter* getFilter() const;
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); }
void setFilterPermMask(PermissionMask filter_perm_mask);
@ -142,7 +143,6 @@ public:
void setShowFolderState(LLInventoryFilter::EFolderShow show);
LLInventoryFilter::EFolderShow getShowFolderState();
void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }
// This method is called when something has changed about the inventory.
void modelChanged(U32 mask);
LLFolderView* getRootFolder() { return mFolderRoot; }
@ -209,23 +209,18 @@ private:
//--------------------------------------------------------------------
public:
void addHideFolderType(LLFolderType::EType folder_type);
protected:
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
private:
std::vector<LLFolderType::EType> mHiddenFolderTypes;
//--------------------------------------------------------------------
// Initialization routines for building up the UI ("views")
//--------------------------------------------------------------------
public:
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
const LLUUID& getStartFolderID() const { return mStartFolderID; }
const std::string& getStartFolderString() { return mStartFolderString; }
const LLUUID& getRootFolderID() const;
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();
void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
virtual void buildNewViews(const LLUUID& id);
void rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
virtual void buildFolderView(const LLInventoryPanel::Params& params);
virtual void buildNewViews(const LLUUID& id);
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
private:
BOOL mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
BOOL mViewsInitialized; // Views have been generated

View File

@ -71,7 +71,7 @@ void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &ch
void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
{
updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
updateButtons(new_state);
}
void LLPanelChatControlPanel::updateCallButton()
@ -96,12 +96,15 @@ void LLPanelChatControlPanel::updateCallButton()
getChildView("call_btn")->setEnabled(enable_connect);
}
void LLPanelChatControlPanel::updateButtons(bool is_call_started)
void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)
{
bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
getChildView("end_call_btn_panel")->setVisible( is_call_started);
getChildView("volume_ctrl_panel")->setVisible( is_call_started);
getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));
getChildView("call_btn_panel")->setVisible( ! is_call_started);
getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED);
updateCallButton();
}
@ -136,7 +139,7 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));
//call (either p2p, group or ad-hoc) can be already in started state
updateButtons(voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
updateButtons(voice_channel->getState());
}
}

View File

@ -54,7 +54,7 @@ public:
virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
void updateButtons(bool is_call_started);
void updateButtons(LLVoiceChannel::EState state);
// Enables/disables call button depending on voice availability
void updateCallButton();

View File

@ -645,7 +645,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI
// Start background fetch, mostly for My Inventory and Library
if (expanded)
{
const LLUUID &cat_id = inventory_list->getStartFolderID();
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))
@ -1414,7 +1414,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)
{
LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getStartFolderID());
LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());
if (category)
{
return category->getDescendentCount() > 0;

View File

@ -35,6 +35,7 @@
#include "llinventoryfunctions.h"
#include "llpanellandmarks.h"
#include "llplacesinventorybridge.h"
#include "llviewerfoldertype.h"
static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_inventory_panel");
@ -56,72 +57,44 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
delete mSavedFolderState;
}
BOOL LLPlacesInventoryPanel::postBuild()
void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
{
LLInventoryPanel::postBuild();
// Determine the root folder in case specified, and
// build the views starting with that folder.
const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
// clear Contents();
LLUUID root_id;
if ("LIBRARY" == params.start_folder())
{
mFolderRoot->destroyView();
mFolderRoot->getParent()->removeChild(mFolderRoot);
mFolderRoot->die();
if( mScroller )
{
removeChild( mScroller );
mScroller->die();
mScroller = NULL;
}
mFolderRoot = NULL;
root_id = gInventory.getLibraryRootFolderID();
}
else
{
root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
}
mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
// create root folder
{
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLPlacesFolderView::Params p;
p.name = getName();
p.title = getLabel();
p.rect = folder_rect;
p.parent_panel = this;
mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
}
mCommitCallbackRegistrar.popScope();
mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
// scroller
{
LLRect scroller_view_rect = getRect();
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
LLScrollContainer::Params p;
p.name("Inventory Scroller");
p.rect(scroller_view_rect);
p.follows.flags(FOLLOWS_ALL);
p.reserve_scroll_corner(true);
p.tab_stop(true);
mScroller = LLUICtrlFactory::create<LLScrollContainer>(p);
}
addChild(mScroller);
mScroller->addChild(mFolderRoot);
mFolderRoot->setScrollContainer(mScroller);
mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
// cut subitems
mFolderRoot->setUseEllipses(true);
return TRUE;
LLRect folder_rect(0,
0,
getRect().getWidth(),
0);
LLPlacesFolderView::Params p;
p.name = getName();
p.title = getLabel();
p.rect = folder_rect;
p.listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
LLAssetType::AT_CATEGORY,
LLInventoryType::IT_CATEGORY,
this,
NULL,
root_id);
p.parent_panel = this;
p.allow_multiselect = mAllowMultiSelect;
p.use_ellipses = true; // truncate inventory item text so remove horizontal scroller
mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
}
// save current folder open state
void LLPlacesInventoryPanel::saveFolderState()
{

View File

@ -46,7 +46,7 @@ public:
LLPlacesInventoryPanel(const Params& p);
~LLPlacesInventoryPanel();
/*virtual*/ BOOL postBuild();
/*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);
void saveFolderState();
void restoreFolderState();

View File

@ -420,7 +420,6 @@ BOOL LLFloaterTexturePicker::postBuild()
mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mInventoryPanel->setAllowMultiSelect(FALSE);
// Disable auto selecting first filtered item because it takes away
// selection from the item set by LLTextureCtrl owning this floater.

View File

@ -937,7 +937,6 @@ protected:
//one global instance to bind them
LLOpenTaskOffer* gNewInventoryObserver=NULL;
class LLNewInventoryHintObserver : public LLInventoryAddedObserver
{
protected:
@ -947,6 +946,8 @@ protected:
}
};
LLNewInventoryHintObserver* gNewInventoryHintObserver=NULL;
void start_new_inventory_observer()
{
if (!gNewInventoryObserver) //task offer observer
@ -963,7 +964,12 @@ void start_new_inventory_observer()
gInventory.addObserver(gInventoryMoveObserver);
}
gInventory.addObserver(new LLNewInventoryHintObserver());
if (!gNewInventoryHintObserver)
{
// Observer is deleted by gInventory
gNewInventoryHintObserver = new LLNewInventoryHintObserver();
gInventory.addObserver(gNewInventoryHintObserver);
}
}
class LLDiscardAgentOffer : public LLInventoryFetchItemsObserver

View File

@ -153,13 +153,6 @@
name="volume_ctrl_panel"
visible="false"
user_resize="false">
<text
follows="left|top|right"
left="5"
top="14"
height="23"
name="volume_ctrl_text"
width="140">Volume Control:</text>
<slider
follows="top|left"
height="23"
@ -169,8 +162,8 @@
min_val="0.05"
name="volume_slider"
show_text="false"
tool_tip="Voice volume"
top_pad="-5"
tool_tip="Call Volume"
top_pad="32"
value="0.5"
width="125" />
<button