summaryrefslogtreecommitdiff
path: root/indra/newview/llfolderviewitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfolderviewitem.cpp')
-rw-r--r--indra/newview/llfolderviewitem.cpp226
1 files changed, 175 insertions, 51 deletions
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 3c36248c1f..622dcfe8dd 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -30,8 +30,10 @@
// viewer includes
#include "llfolderview.h" // Items depend extensively on LLFolderViews
#include "llfoldervieweventlistener.h"
+#include "llviewerfoldertype.h"
#include "llinventorybridge.h" // for LLItemBridge in LLInventorySort::operator()
#include "llinventoryfilter.h"
+#include "llinventoryfunctions.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llpanel.h"
#include "llviewercontrol.h" // gSavedSettings
@@ -99,10 +101,7 @@ LLFolderViewItem::Params::Params()
item_height("item_height"),
item_top_pad("item_top_pad"),
creation_date()
-{
- mouse_opaque(true);
- follows.flags(FOLLOWS_LEFT|FOLLOWS_TOP|FOLLOWS_RIGHT);
-}
+{}
// Default constructor
LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
@@ -130,10 +129,15 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
mIconOpen(p.icon_open),
mIconOverlay(p.icon_overlay),
mListener(p.listener),
- mHidden(false),
- mShowLoadStatus(false)
+ mShowLoadStatus(false),
+ mIsMouseOverTitle(false)
+{
+}
+
+BOOL LLFolderViewItem::postBuild()
{
refresh();
+ return TRUE;
}
// Destroys the object
@@ -195,7 +199,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)
@@ -278,9 +282,9 @@ void LLFolderViewItem::refreshFromListener()
setToolTip(mLabel);
setIcon(mListener->getIcon());
time_t creation_date = mListener->getCreationDate();
- if (mCreationDate != creation_date)
+ if ((creation_date > 0) && (mCreationDate != creation_date))
{
- mCreationDate = mListener->getCreationDate();
+ setCreationDate(creation_date);
dirtyFilter();
}
if (mRoot->useLabelSuffix())
@@ -351,7 +355,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);
@@ -442,23 +449,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();
}
@@ -718,6 +722,8 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
{
+ mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
if( hasMouseCapture() && isMovable() )
{
S32 screen_x;
@@ -824,6 +830,11 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
return TRUE;
}
+void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ mIsMouseOverTitle = false;
+}
+
BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
EDragAndDropType cargo_type,
void* cargo_data,
@@ -834,7 +845,7 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
BOOL handled = FALSE;
if(mListener)
{
- accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data);
+ accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
handled = accepted;
if (accepted)
{
@@ -863,11 +874,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);
@@ -878,6 +884,7 @@ void LLFolderViewItem::draw()
static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+ static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
const S32 TOP_PAD = default_params.item_top_pad;
@@ -891,8 +898,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;
@@ -959,6 +966,14 @@ void LLFolderViewItem::draw()
}
}
}
+ else if (mIsMouseOverTitle)
+ {
+ gl_rect_2d(FOCUS_LEFT,
+ focus_top,
+ getRect().getWidth() - 2,
+ focus_bottom,
+ sMouseOverColor, FALSE);
+ }
//--------------------------------------------------------------------------------//
// Draw DragNDrop highlight
@@ -1054,8 +1069,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,
@@ -1119,7 +1137,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mLastCalculatedWidth(0),
mCompletedFilterGeneration(-1),
mMostFilteredDescendantGeneration(-1),
- mNeedsSort(false)
+ mNeedsSort(false),
+ mPassedFolderFilter(FALSE)
{
}
@@ -1131,6 +1150,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)
{
@@ -1157,8 +1187,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 );
@@ -1190,8 +1218,10 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
}
else
{
- folderp->setVisible(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( folderp->getListener()
+ && (folderp->getFiltered(filter_generation)
+ || (folderp->getFilteredFolder(filter_generation)
+ && folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
}
if (folderp->getVisible())
@@ -1311,7 +1341,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);
}
@@ -1336,21 +1368,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())
@@ -1377,7 +1407,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());
}
@@ -1403,6 +1436,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
{
mMostFilteredDescendantGeneration = filter_generation;
+ requestArrange();
}
// just skip it, it has already been filtered
continue;
@@ -1415,6 +1449,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))
{
mMostFilteredDescendantGeneration = filter_generation;
+ requestArrange();
if (getRoot()->needsAutoSelect() && autoopen_folders)
{
folder->setOpenArrangeRecursively(TRUE);
@@ -1436,6 +1471,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
if (item->getFiltered())
{
mMostFilteredDescendantGeneration = filter_generation;
+ requestArrange();
}
continue;
}
@@ -1454,6 +1490,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
if (item->getFiltered(filter.getMinRequiredGeneration()))
{
mMostFilteredDescendantGeneration = filter_generation;
+ requestArrange();
}
}
@@ -1467,6 +1504,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
@@ -1488,6 +1550,23 @@ void LLFolderViewFolder::dirtyFilter()
LLFolderViewItem::dirtyFilter();
}
+BOOL LLFolderViewFolder::getFiltered()
+{
+ return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration())
+ && LLFolderViewItem::getFiltered();
+}
+
+BOOL LLFolderViewFolder::getFiltered(S32 filter_generation)
+{
+ return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation);
+}
+
+BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
+{
+ return mMostFilteredDescendantGeneration >= filter_generation;
+}
+
+
BOOL LLFolderViewFolder::hasFilteredDescendants()
{
return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
@@ -1743,7 +1822,7 @@ void LLFolderViewFolder::destroyView()
folderp->destroyView(); // removes entry from mFolders
}
- deleteAllChildren();
+ //deleteAllChildren();
if (mParentFolder)
{
@@ -1835,7 +1914,7 @@ void LLFolderViewFolder::sortBy(U32 order)
return;
}
- // Propegate this change to sub folders
+ // Propagate this change to sub folders
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
@@ -1843,8 +1922,12 @@ void LLFolderViewFolder::sortBy(U32 order)
(*fit)->sortBy(order);
}
- mFolders.sort(mSortFunction);
- mItems.sort(mSortFunction);
+ // Don't sort the topmost folders (My Inventory and Library)
+ if (mListener->getUUID().notNull())
+ {
+ mFolders.sort(mSortFunction);
+ mItems.sort(mSortFunction);
+ }
if (order & LLInventoryFilter::SO_DATE)
{
@@ -1971,16 +2054,42 @@ BOOL LLFolderViewFolder::isRemovable()
BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
{
mItems.push_back(item);
+
if (item->isSelected())
{
recursiveIncrementNumDescendantsSelected(1);
}
+
item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
item->setVisible(FALSE);
- addChild( item );
+
+ addChild(item);
+
item->dirtyFilter();
+
+ // Update the folder creation date if the child is newer than our current date
+ setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
+
+ // Handle sorting
requestArrange();
requestSort();
+
+ // Traverse parent folders and update creation date and resort, if necessary
+ LLFolderViewFolder* parentp = getParentFolder();
+ while (parentp)
+ {
+ // Update the folder creation date if the child is newer than our current date
+ parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
+
+ if (parentp->mSortFunction.isByDate())
+ {
+ // parent folder doesn't have a time stamp yet, so get it from us
+ parentp->requestSort();
+ }
+
+ parentp = parentp->getParentFolder();
+ }
+
return TRUE;
}
@@ -2000,6 +2109,13 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
// rearrange all descendants too, as our indentation level might have changed
folder->requestArrange(TRUE);
requestSort();
+ LLFolderViewFolder* parentp = getParentFolder();
+ while (parentp && !parentp->mSortFunction.isByDate())
+ {
+ // parent folder doesn't have a time stamp yet, so get it from us
+ parentp->requestSort();
+ parentp = parentp->getParentFolder();
+ }
return TRUE;
}
@@ -2059,7 +2175,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);
}
@@ -2077,7 +2195,7 @@ BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
EAcceptance* accept,
std::string& tooltip_msg)
{
- BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data);
+ BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
if (accepted)
{
mDragAndDropTarget = TRUE;
@@ -2169,7 +2287,7 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
if (!handled)
{
- BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data);
+ BOOL accepted = mListener && mListener->dragOrDrop(mask, drop,cargo_type,cargo_data, tooltip_msg);
if (accepted)
{
@@ -2214,6 +2332,8 @@ BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
{
+ mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
BOOL handled = LLView::handleHover(x, y, mask);
if (!handled)
@@ -2301,13 +2421,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 )
{
@@ -2573,7 +2696,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)
{