summaryrefslogtreecommitdiff
path: root/indra/llui/llfolderview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui/llfolderview.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llui/llfolderview.cpp165
1 files changed, 93 insertions, 72 deletions
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 8feaf654f0..4c05d001a0 100644..100755
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -53,7 +53,6 @@
/// Local function declarations, constants, enums, and typedefs
///----------------------------------------------------------------------------
-const S32 RENAME_WIDTH_PAD = 4;
const S32 RENAME_HEIGHT_PAD = 1;
const S32 AUTO_OPEN_STACK_DEPTH = 16;
@@ -167,13 +166,16 @@ LLFolderView::LLFolderView(const Params& p)
mMinWidth(0),
mDragAndDropThisFrame(FALSE),
mCallbackRegistrar(NULL),
- mParentPanel(p.parent_panel),
mUseEllipses(p.use_ellipses),
mDraggingOverItem(NULL),
mStatusTextBox(NULL),
mShowItemLinkOverlays(p.show_item_link_overlays),
- mViewModel(p.view_model)
+ mViewModel(p.view_model),
+ mGroupedItemModel(p.grouped_item_model)
{
+ claimMem(mViewModel);
+ LLPanel* panel = p.parent_panel;
+ mParentPanel = panel->getHandle();
mViewModel->setFolderView(this);
mRoot = this;
@@ -185,7 +187,7 @@ LLFolderView::LLFolderView(const Params& p)
mAutoOpenCandidate = NULL;
mAutoOpenTimer.stop();
mKeyboardSelection = FALSE;
- mIndentation = p.folder_indentation;
+ mIndentation = getParentFolder() ? getParentFolder()->getIndentation() + mLocalIndentation : 0;
//clear label
// go ahead and render root folder as usual
@@ -225,10 +227,11 @@ LLFolderView::LLFolderView(const Params& p)
mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
mStatusTextBox->setFollowsLeft();
mStatusTextBox->setFollowsTop();
- //addChild(mStatusTextBox);
+ addChild(mStatusTextBox);
// make the popup menu available
+ llassert(LLMenuGL::sMenuContainer != NULL);
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
if (!menu)
{
@@ -255,8 +258,6 @@ LLFolderView::~LLFolderView( void )
mRenamer = NULL;
mStatusTextBox = NULL;
- mAutoOpenItems.removeAllNodes();
-
if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
mAutoOpenItems.removeAllNodes();
@@ -264,6 +265,7 @@ LLFolderView::~LLFolderView( void )
mItems.clear();
mFolders.clear();
+ //mViewModel->setFolderView(NULL);
mViewModel = NULL;
}
@@ -305,27 +307,28 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
LLFolderViewFolder::arrange(&mMinWidth, &target_height);
LLRect scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
- reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
+ reshape( llmax(scroll_rect.getWidth(), mMinWidth), ll_round(mCurHeight) );
LLRect new_scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
{
- reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
+ reshape( llmax(scroll_rect.getWidth(), mMinWidth), ll_round(mCurHeight) );
}
// move item renamer text field to item's new position
updateRenamerPosition();
- return llround(mTargetHeight);
+ return ll_round(mTargetHeight);
}
-static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
+static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");
void LLFolderView::filter( LLFolderViewFilter& filter )
{
- LLFastTimer t2(FTM_FILTER);
- filter.setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+ LL_RECORD_BLOCK_TIME(FTM_FILTER);
+ filter.resetTime(llclamp(LLUI::sSettingGroups["config"]->getS32(mParentPanel.get()->getVisible() ? "FilterItemsMaxTimePerFrameVisible" : "FilterItemsMaxTimePerFrameUnvisible"), 1, 100));
+ // Note: we filter the model, not the view
getViewModelItem()->filter(filter);
}
@@ -338,7 +341,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
scroll_rect = mScrollContainer->getContentWindowRect();
}
width = llmax(mMinWidth, scroll_rect.getWidth());
- height = llmax(llround(mCurHeight), scroll_rect.getHeight());
+ height = llmax(ll_round(mCurHeight), scroll_rect.getHeight());
// Restrict width within scroll container's width
if (mUseEllipses && mScrollContainer)
@@ -417,7 +420,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
if( selection && take_keyboard_focus)
{
- mParentPanel->setFocus(TRUE);
+ mParentPanel.get()->setFocus(TRUE);
}
// clear selection down here because change of keyboard focus can potentially
@@ -482,10 +485,10 @@ BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
return rv;
}
-static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
+static LLTrace::BlockTimerStatHandle FTM_SANITIZE_SELECTION("Sanitize Selection");
void LLFolderView::sanitizeSelection()
{
- LLFastTimer _(FTM_SANITIZE_SELECTION);
+ LL_RECORD_BLOCK_TIME(FTM_SANITIZE_SELECTION);
// store off current item in case it is automatically deselected
// and we want to preserve context
LLFolderViewItem* original_selected_item = getCurSelectedItem();
@@ -627,6 +630,8 @@ bool LLFolderView::startDrag()
void LLFolderView::commitRename( const LLSD& data )
{
finishRenamingItem();
+ arrange( NULL, NULL );
+
}
void LLFolderView::draw()
@@ -661,7 +666,7 @@ void LLFolderView::draw()
// get preferable text height...
S32 pixel_height = mStatusTextBox->getTextPixelHeight();
- bool height_changed = local_rect.getHeight() != pixel_height;
+ bool height_changed = (local_rect.getHeight() < pixel_height);
if (height_changed)
{
// ... if it does not match current height, lets rearrange current view.
@@ -699,8 +704,9 @@ void LLFolderView::finishRenamingItem( void )
closeRenamer();
+ // This is moved to an inventory observer in llinventorybridge.cpp, to handle updating after operation completed in AISv3 (SH-4611).
// List is re-sorted alphabetically, so scroll to make sure the selected item is visible.
- scrollToShowSelection();
+ //scrollToShowSelection();
}
void LLFolderView::closeRenamer( void )
@@ -736,7 +742,7 @@ void LLFolderView::removeSelectedItems()
}
else
{
- llinfos << "Cannot delete " << item->getName() << llendl;
+ LL_INFOS() << "Cannot delete " << item->getName() << LL_ENDL;
return;
}
}
@@ -755,27 +761,28 @@ void LLFolderView::removeSelectedItems()
if (item_to_delete->remove())
{
// change selection on successful delete
- setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
}
}
arrangeAll();
}
else if (count > 1)
{
- LLDynamicArray<LLFolderViewModelItem*> listeners;
+ std::vector<LLFolderViewModelItem*> listeners;
LLFolderViewModelItem* listener;
- setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
+ listeners.reserve(count);
for(S32 i = 0; i < count; ++i)
{
listener = items[i]->getViewModelItem();
- if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItem*>::FAIL))
+ if(listener && (std::find(listeners.begin(), listeners.end(), listener) == listeners.end()))
{
- listeners.put(listener);
+ listeners.push_back(listener);
}
}
- listener = static_cast<LLFolderViewModelItem*>(listeners.get(0));
+ listener = static_cast<LLFolderViewModelItem*>(listeners.at(0));
if(listener)
{
listener->removeBatch(listeners);
@@ -945,7 +952,7 @@ void LLFolderView::cut()
}
// Update the selection
- setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
+ setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel.get()->hasFocus());
}
mSearchString.clear();
}
@@ -1055,12 +1062,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
LLMenuGL::sMenuContainer->hideMenus();
}
- LLView *item = NULL;
- if (getChildCount() > 0)
- {
- item = *(getChildList()->begin());
- }
-
switch( key )
{
case KEY_F2:
@@ -1129,18 +1130,18 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
if((mSelectedItems.size() > 0) && mScrollContainer)
{
LLFolderViewItem* last_selected = getCurSelectedItem();
+ BOOL shift_select = mask & MASK_SHIFT;
+ // don't shift select down to children of folders (they are implicitly selected through parent)
+ LLFolderViewItem* next = last_selected->getNextOpenNode(!shift_select);
- if (!mKeyboardSelection)
+ if (!mKeyboardSelection || (!shift_select && (!next || next == last_selected)))
{
setSelection(last_selected, FALSE, TRUE);
mKeyboardSelection = TRUE;
}
- LLFolderViewItem* next = NULL;
- if (mask & MASK_SHIFT)
+ if (shift_select)
{
- // don't shift select down to children of folders (they are implicitly selected through parent)
- next = last_selected->getNextOpenNode(FALSE);
if (next)
{
if (next->isSelected())
@@ -1157,7 +1158,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
}
else
{
- next = last_selected->getNextOpenNode();
if( next )
{
if (next == last_selected)
@@ -1193,18 +1193,18 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
if((mSelectedItems.size() > 0) && mScrollContainer)
{
LLFolderViewItem* last_selected = mSelectedItems.back();
+ BOOL shift_select = mask & MASK_SHIFT;
+ // don't shift select down to children of folders (they are implicitly selected through parent)
+ LLFolderViewItem* prev = last_selected->getPreviousOpenNode(!shift_select);
- if (!mKeyboardSelection)
+ if (!mKeyboardSelection || (!shift_select && prev == this))
{
setSelection(last_selected, FALSE, TRUE);
mKeyboardSelection = TRUE;
}
- LLFolderViewItem* prev = NULL;
- if (mask & MASK_SHIFT)
+ if (shift_select)
{
- // don't shift select down to children of folders (they are implicitly selected through parent)
- prev = last_selected->getPreviousOpenNode(FALSE);
if (prev)
{
if (prev->isSelected())
@@ -1221,7 +1221,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
}
else
{
- prev = last_selected->getPreviousOpenNode();
if( prev )
{
if (prev == this)
@@ -1288,12 +1287,12 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
if (uni_char > 0x7f)
{
- llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl;
+ LL_WARNS() << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << LL_ENDL;
return FALSE;
}
BOOL handled = FALSE;
- if (mParentPanel->hasFocus())
+ if (mParentPanel.get()->hasFocus())
{
// SL-51858: Key presses are not being passed to the Popup menu.
// A proper fix is non-trivial so instead just close the menu.
@@ -1327,7 +1326,7 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
mKeyboardSelection = FALSE;
mSearchString.clear();
- mParentPanel->setFocus(TRUE);
+ mParentPanel.get()->setFocus(TRUE);
LLEditMenuHandler::gEditMenuHandler = this;
@@ -1372,7 +1371,8 @@ BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &searc
}
}
- const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
+ std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
+ LLStringUtil::toUpper(current_item_label);
S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
if (!current_item_label.compare(0, search_string_length, upper_case_string))
{
@@ -1410,7 +1410,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
// all user operations move keyboard focus to inventory
// this way, we know when to stop auto-updating a search
- mParentPanel->setFocus(TRUE);
+ mParentPanel.get()->setFocus(TRUE);
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size();
@@ -1584,7 +1584,7 @@ BOOL LLFolderView::getShowSelectionContext()
return FALSE;
}
-void LLFolderView::setShowSingleSelection(BOOL show)
+void LLFolderView::setShowSingleSelection(bool show)
{
if (show != mShowSingleSelection)
{
@@ -1593,33 +1593,43 @@ void LLFolderView::setShowSingleSelection(BOOL show)
}
}
-static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
-static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
+static LLTrace::BlockTimerStatHandle FTM_AUTO_SELECT("Open and Select");
+static LLTrace::BlockTimerStatHandle FTM_INVENTORY("Inventory");
// Main idle routine
void LLFolderView::update()
{
// If this is associated with the user's inventory, don't do anything
// until that inventory is loaded up.
- LLFastTimer t2(FTM_INVENTORY);
+ LL_RECORD_BLOCK_TIME(FTM_INVENTORY);
+
+ // If there's no model, the view is in suspended state (being deleted) and shouldn't be updated
+ if (getFolderViewModel() == NULL)
+ {
+ return;
+ }
- if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
+ LLFolderViewFilter& filter_object = getFolderViewModel()->getFilter();
+
+ if (filter_object.isModified() && filter_object.isNotDefault() && mParentPanel.get()->getVisible())
{
mNeedsAutoSelect = TRUE;
}
- // filter to determine visibility before arranging
- filter(getFolderViewModel()->getFilter());
- // Clear the modified setting on the filter only if the filter count is non-zero after running the filter process
- // Note: if the filter count is zero, then the filter most likely halted before completing the entire set of items
- if (getFolderViewModel()->getFilter().isModified() && (getFolderViewModel()->getFilter().getFilterCount() > 0))
+
+ // Filter to determine visibility before arranging
+ filter(filter_object);
+
+ // Clear the modified setting on the filter only if the filter finished after running the filter process
+ // Note: if the filter count has timed out, that means the filter halted before completing the entire set of items
+ if (filter_object.isModified() && (!filter_object.isTimedOut()))
{
- getFolderViewModel()->getFilter().clearModified();
+ filter_object.clearModified();
}
// automatically show matching items, and select first one if we had a selection
if (mNeedsAutoSelect)
{
- LLFastTimer t3(FTM_AUTO_SELECT);
+ LL_RECORD_BLOCK_TIME(FTM_AUTO_SELECT);
// select new item only if a filtered item not currently selected
LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
@@ -1632,7 +1642,7 @@ void LLFolderView::update()
// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
// Used by LLPlacesFolderView.
- if (getFolderViewModel()->getFilter().showAllResults())
+ if (filter_object.showAllResults())
{
// these are named variables to get around gcc not binding non-const references to rvalues
// and functor application is inherently non-const to allow for stateful functors
@@ -1643,11 +1653,13 @@ void LLFolderView::update()
scrollToShowSelection();
}
- BOOL filter_finished = getViewModelItem()->passedFilter()
- && mViewModel->contentsReady();
+ BOOL filter_finished = mViewModel->contentsReady()
+ && (getViewModelItem()->passedFilter()
+ || ( getViewModelItem()->getLastFilterGeneration() >= filter_object.getFirstSuccessGeneration()
+ && !filter_object.isModified()));
if (filter_finished
- || gFocusMgr.childHasKeyboardFocus(mParentPanel)
- || gFocusMgr.childHasMouseCapture(mParentPanel))
+ || gFocusMgr.childHasKeyboardFocus(mParentPanel.get())
+ || gFocusMgr.childHasMouseCapture(mParentPanel.get()))
{
// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
mNeedsAutoSelect = FALSE;
@@ -1656,6 +1668,8 @@ void LLFolderView::update()
BOOL is_visible = isInVisibleChain();
//Puts folders/items in proper positions
+ // arrange() takes the model filter flag into account and call sort() if necessary (CHUI-849)
+ // It also handles the open/close folder animation
if ( is_visible )
{
sanitizeSelection();
@@ -1750,14 +1764,14 @@ void LLFolderView::update()
void LLFolderView::dumpSelectionInformation()
{
- llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
- llinfos << "****************************************" << llendl;
+ LL_INFOS() << "LLFolderView::dumpSelectionInformation()" << LL_NEWLINE
+ << "****************************************" << LL_ENDL;
selected_items_t::iterator item_it;
for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
{
- llinfos << " " << (*item_it)->getName() << llendl;
+ LL_INFOS() << " " << (*item_it)->getName() << LL_ENDL;
}
- llinfos << "****************************************" << llendl;
+ LL_INFOS() << "****************************************" << LL_ENDL;
}
void LLFolderView::updateRenamerPosition()
@@ -1797,7 +1811,6 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
}
// Successively filter out invalid options
-
U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0);
U32 flags = multi_select_flag | FIRST_SELECTED_ITEM;
for (selected_items_t::iterator item_itor = mSelectedItems.begin();
@@ -1809,6 +1822,14 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
flags = multi_select_flag;
}
+ // This adds a check for restrictions based on the entire
+ // selection set - for example, any one wearable may not push you
+ // over the limit, but all wearables together still might.
+ if (getFolderViewGroupedItemModel())
+ {
+ getFolderViewGroupedItemModel()->groupFilterContextMenu(mSelectedItems,*menu);
+ }
+
addNoOptions(menu);
}