summaryrefslogtreecommitdiff
path: root/indra/newview/llfolderview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfolderview.cpp')
-rw-r--r--indra/newview/llfolderview.cpp267
1 files changed, 173 insertions, 94 deletions
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 75c7467442..fd8c22b8e5 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -45,6 +45,7 @@
#include "llinventory.h"
#include "llcallbacklist.h"
+#include "llinventorybridge.h"
#include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.
#include "llinventoryview.h"// hacked in for the bonus context menu items.
#include "llkeyboard.h"
@@ -81,7 +82,7 @@ const S32 ICON_WIDTH = 16;
const S32 TEXT_PAD = 1;
const S32 ARROW_SIZE = 12;
const S32 RENAME_WIDTH_PAD = 4;
-const S32 RENAME_HEIGHT_PAD = 6;
+const S32 RENAME_HEIGHT_PAD = 2;
const S32 AUTO_OPEN_STACK_DEPTH = 16;
const S32 MIN_ITEM_WIDTH_VISIBLE = ICON_WIDTH + ICON_PAD + ARROW_SIZE + TEXT_PAD + /*first few characters*/ 40;
const S32 MINIMUM_RENAMER_WIDTH = 80;
@@ -135,8 +136,9 @@ void LLFolderViewItem::cleanupClass()
// Default constructor
LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p)
-: LLUICtrl(p),
+: LLView(p),
mLabelWidth(0),
+ mLabelWidthDirty(false),
mParentFolder( NULL ),
mIsSelected( FALSE ),
mIsCurSelection( FALSE ),
@@ -302,20 +304,15 @@ void LLFolderViewItem::refresh()
{
mSearchableLabel.assign(searchable_label);
dirtyFilter();
- // some part of label has changed, so overall width has potentially changed
+ // some part of label has changed, so overall width has potentially changed, and sort order too
if (mParentFolder)
{
+ mParentFolder->requestSort();
mParentFolder->requestArrange();
}
}
- S32 label_width = sFont->getWidth(mLabel);
- if( mLabelSuffix.size() )
- {
- label_width += sFont->getWidth( mLabelSuffix );
- }
-
- mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + label_width;
+ mLabelWidthDirty = true;
}
void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
@@ -392,6 +389,12 @@ BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* roo
S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
{
mIndentation = mParentFolder ? mParentFolder->getIndentation() + LEFT_INDENTATION : 0;
+ if (mLabelWidthDirty)
+ {
+ mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + sFont->getWidth(mSearchableLabel);
+ mLabelWidthDirty = false;
+ }
+
*width = llmax(*width, mLabelWidth + mIndentation);
*height = getItemHeight();
return *height;
@@ -569,14 +572,13 @@ void LLFolderViewItem::rename(const std::string& new_name)
{
if( !new_name.empty() )
{
- mLabel = new_name;
if( mListener )
{
mListener->renameItem(new_name);
if(mParentFolder)
{
- mParentFolder->resort(this);
+ mParentFolder->requestSort();
}
}
}
@@ -819,7 +821,7 @@ void LLFolderViewItem::draw()
// If we have keyboard focus, draw selection filled
BOOL show_context = getRoot()->getShowSelectionContext();
- BOOL filled = show_context || (gFocusMgr.getKeyboardFocus() == getRoot());
+ BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus());
// always render "current" item, only render other selected items if
// mShowSingleSelection is FALSE
@@ -999,10 +1001,9 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
mLastArrangeGeneration( -1 ),
mLastCalculatedWidth(0),
mCompletedFilterGeneration(-1),
- mMostFilteredDescendantGeneration(-1)
-{
- mType = std::string("(folder)");
-}
+ mMostFilteredDescendantGeneration(-1),
+ mNeedsSort(false)
+{}
// Destroys the object
LLFolderViewFolder::~LLFolderViewFolder( void )
@@ -1028,6 +1029,14 @@ BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* r
// makes sure that this view and it's children are the right size.
S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
{
+ // sort before laying out contents
+ if (mNeedsSort)
+ {
+ mFolders.sort(mSortFunction);
+ mItems.sort(mSortFunction);
+ mNeedsSort = false;
+ }
+
mHasVisibleChildren = hasFilteredDescendants(filter_generation);
LLInventoryFilter::EFolderShow show_folder_state = getRoot()->getShowFolderState();
@@ -1172,6 +1181,13 @@ BOOL LLFolderViewFolder::needsArrange()
return mLastArrangeGeneration < getRoot()->getArrangeGeneration();
}
+void LLFolderViewFolder::requestSort()
+{
+ mNeedsSort = true;
+ // whenever item order changes, we need to lay things out again
+ requestArrange();
+}
+
void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
{
mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
@@ -1708,14 +1724,6 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
removeChild(item);
}
-// This function is called by a child that needs to be resorted.
-// This is only called for renaming an object because it won't work for date
-void LLFolderViewFolder::resort(LLFolderViewItem* item)
-{
- mItems.sort(mSortFunction);
- mFolders.sort(mSortFunction);
-}
-
bool LLFolderViewFolder::isTrash() const
{
if (mAmTrash == LLFolderViewFolder::UNKNOWN)
@@ -1869,30 +1877,20 @@ BOOL LLFolderViewFolder::isRemovable()
// this is an internal method used for adding items to folders.
BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
{
-
- items_t::iterator it = std::lower_bound(
- mItems.begin(),
- mItems.end(),
- item,
- mSortFunction);
- mItems.insert(it,item);
+ mItems.push_back(item);
item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
item->setVisible(FALSE);
addChild( item );
item->dirtyFilter();
requestArrange();
+ requestSort();
return TRUE;
}
// this is an internal method used for adding items to folders.
BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
{
- folders_t::iterator it = std::lower_bound(
- mFolders.begin(),
- mFolders.end(),
- folder,
- mSortFunction);
- mFolders.insert(it,folder);
+ mFolders.push_back(folder);
folder->setOrigin(0, 0);
folder->reshape(getRect().getWidth(), 0);
folder->setVisible(FALSE);
@@ -1900,6 +1898,7 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
folder->dirtyFilter();
// rearrange all descendants too, as our indentation level might have changed
folder->requestArrange(TRUE);
+ requestSort();
return TRUE;
}
@@ -2522,7 +2521,9 @@ LLFolderView::LLFolderView(const Params& p)
mSignalSelectCallback(0),
mMinWidth(0),
mDragAndDropThisFrame(FALSE),
- mCallbackRegistrar(NULL)
+ mCallbackRegistrar(NULL),
+ mParentPanel(p.parent_panel)
+
{
LLRect rect = p.rect;
LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
@@ -2556,15 +2557,14 @@ LLFolderView::LLFolderView(const Params& p)
addChild(mRenamer);
// make the popup menu available
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", p.parent_panel);
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder);
if (!menu)
{
- menu = LLUICtrlFactory::createDummyWidget<LLMenuGL>("inventory_menu");
+ menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
}
menu->setBackgroundColor(gSavedSkinSettings.getColor("MenuPopupBgColor"));
mPopupMenuHandle = menu->getHandle();
- setTabStop(TRUE);
}
// Destroys the object
@@ -2578,7 +2578,6 @@ LLFolderView::~LLFolderView( void )
mScrollContainer = NULL;
mRenameItem = NULL;
mRenamer = NULL;
- gFocusMgr.releaseFocusIfNeeded( this );
if( gEditMenuHandler == this )
{
@@ -2668,6 +2667,7 @@ void LLFolderView::closeAllFolders()
{
// Close all the folders
setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
+ arrangeAll();
}
void LLFolderView::openFolder(const std::string& foldername)
@@ -2772,6 +2772,9 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
reshape( llmax(min_width, total_width), running_height );
}
+ // move item renamer text field to item's new position
+ updateRenamerPosition();
+
mTargetHeight = (F32)target_height;
return llround(mTargetHeight);
}
@@ -2805,6 +2808,8 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
}
width = llmax(mMinWidth, min_width);
LLView::reshape(width, height, called_from_parent);
+
+ mReshapeSignal(mSelectedItems, FALSE);
}
void LLFolderView::addToSelectionList(LLFolderViewItem* item)
@@ -2869,7 +2874,7 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
if( selection && take_keyboard_focus)
{
- setFocus(TRUE);
+ mParentPanel->setFocus(TRUE);
}
// clear selection down here because change of keyboard focus can potentially
@@ -2894,6 +2899,30 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
return rv;
}
+void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
+{
+ LLFolderViewItem* itemp = getItemByID(obj_id);
+ if(itemp && itemp->getListener())
+ {
+ itemp->getListener()->arrangeAndSet(itemp, TRUE, take_keyboard_focus);
+ mSelectThisID.setNull();
+ return;
+ }
+ else
+ {
+ // save the desired item to be selected later (if/when ready)
+ mSelectThisID = obj_id;
+ }
+}
+
+void LLFolderView::updateSelection()
+{
+ if (mSelectThisID.notNull())
+ {
+ setSelectionByID(mSelectThisID, false);
+ }
+}
+
BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
BOOL rv = FALSE;
@@ -3075,6 +3104,7 @@ void LLFolderView::clearSelection()
recursiveDeselect(FALSE);
mSelectedItems.clear();
}
+ mSelectThisID.setNull();
}
BOOL LLFolderView::getSelectionList(std::set<LLUUID> &selection)
@@ -3134,10 +3164,6 @@ void LLFolderView::draw()
{
closeAutoOpenedFolders();
}
- if(this == gFocusMgr.getKeyboardFocus() && !getVisible())
- {
- gFocusMgr.setKeyboardFocus( NULL );
- }
// while dragging, update selection rendering to reflect single/multi drag status
if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
@@ -3275,11 +3301,11 @@ void LLFolderView::removeSelectedItems( void )
// change selection on successful delete
if (new_selection)
{
- setSelectionFromRoot(new_selection, new_selection->isOpen(), gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
}
else
{
- setSelectionFromRoot(NULL, gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(NULL, mParentPanel->hasFocus());
}
}
}
@@ -3305,11 +3331,11 @@ void LLFolderView::removeSelectedItems( void )
}
if (new_selection)
{
- setSelectionFromRoot(new_selection, new_selection->isOpen(), gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
}
else
{
- setSelectionFromRoot(NULL, gFocusMgr.childHasKeyboardFocus(this));
+ setSelectionFromRoot(NULL, mParentPanel->hasFocus());
}
for(S32 i = 0; i < count; ++i)
@@ -3597,23 +3623,8 @@ void LLFolderView::startRenamingSelectedItem( void )
{
mRenameItem = item;
- S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD - 1 + item->getIndentation();
- S32 y = llfloor(item->getRect().getHeight()-sFont->getLineHeight()-2);
- item->localPointToScreen( x, y, &x, &y );
- screenPointToLocal( x, y, &x, &y );
- mRenamer->setOrigin( x, y );
-
- S32 scroller_height = 0;
- S32 scroller_width = gViewerWindow->getWindowWidth();
- BOOL dummy_bool;
- if (mScrollContainer)
- {
- mScrollContainer->calcVisibleSize( &scroller_width, &scroller_height, &dummy_bool, &dummy_bool);
- }
+ updateRenamerPosition();
- S32 width = llmax(llmin(item->getRect().getWidth() - x, scroller_width - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
- S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD);
- mRenamer->reshape( width, height, TRUE );
mRenamer->setText(item->getName());
mRenamer->selectAll();
@@ -3625,19 +3636,6 @@ void LLFolderView::startRenamingSelectedItem( void )
}
}
-void LLFolderView::setFocus(BOOL focus)
-{
- if (focus)
- {
- if(!hasFocus())
- {
- gEditMenuHandler = this;
- }
- }
-
- LLFolderViewFolder::setFocus(focus);
-}
-
BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
{
BOOL handled = FALSE;
@@ -3840,7 +3838,7 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
break;
}
- if (!handled && hasFocus())
+ if (!handled && mParentPanel->hasFocus())
{
if (key == KEY_BACKSPACE)
{
@@ -3929,20 +3927,11 @@ BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
mKeyboardSelection = FALSE;
mSearchString.clear();
- setFocus(TRUE);
+ mParentPanel->setFocus(TRUE);
return LLView::handleMouseDown( x, y, mask );
}
-void LLFolderView::onFocusLost( )
-{
- if( gEditMenuHandler == this )
- {
- gEditMenuHandler = NULL;
- }
- LLUICtrl::onFocusLost();
-}
-
BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
{
// get first selected item
@@ -4019,7 +4008,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
- setFocus(TRUE);
+ mParentPanel->setFocus(TRUE);
BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
S32 count = mSelectedItems.size();
@@ -4224,6 +4213,72 @@ LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
return NULL;
}
+bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
+{
+ std::string action = userdata.asString();
+
+ if ("rename" == action)
+ {
+ startRenamingSelectedItem();
+ return true;
+ }
+ if ("delete" == action)
+ {
+ removeSelectedItems();
+ return true;
+ }
+
+ if ("copy" == action)
+ {
+ LLInventoryClipboard::instance().reset();
+ }
+
+ std::set<LLUUID> selected_items;
+ getSelectionList(selected_items);
+
+ LLMultiPreview* multi_previewp = NULL;
+ LLMultiProperties* multi_propertiesp = NULL;
+
+ if (("task_open" == action || "open" == action) && selected_items.size() > 1)
+ {
+ multi_previewp = new LLMultiPreview();
+ gFloaterView->addChild(multi_previewp);
+
+ LLFloater::setFloaterHost(multi_previewp);
+
+ }
+ else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
+ {
+ multi_propertiesp = new LLMultiProperties();
+ gFloaterView->addChild(multi_propertiesp);
+
+ LLFloater::setFloaterHost(multi_propertiesp);
+ }
+
+ std::set<LLUUID>::iterator set_iter;
+
+ for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ {
+ LLFolderViewItem* folder_item = getItemByID(*set_iter);
+ if(!folder_item) continue;
+ LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+ if(!bridge) continue;
+
+ bridge->performAction(this, model, action);
+ }
+
+ LLFloater::setFloaterHost(NULL);
+ if (multi_previewp)
+ {
+ multi_previewp->openFloater(LLSD());
+ }
+ else if (multi_propertiesp)
+ {
+ multi_propertiesp->openFloater(LLSD());
+ }
+
+ return true;
+}
// Main idle routine
void LLFolderView::doIdle()
@@ -4307,7 +4362,6 @@ void LLFolderView::idle(void* user_data)
}
}
-
void LLFolderView::dumpSelectionInformation()
{
llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
@@ -4320,6 +4374,31 @@ void LLFolderView::dumpSelectionInformation()
llinfos << "****************************************" << llendl;
}
+void LLFolderView::updateRenamerPosition()
+{
+ if(mRenameItem)
+ {
+ S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD - 1 + mRenameItem->getIndentation();
+ S32 y = llfloor(mRenameItem->getRect().getHeight()-sFont->getLineHeight()-2);
+ mRenameItem->localPointToScreen( x, y, &x, &y );
+ screenPointToLocal( x, y, &x, &y );
+ mRenamer->setOrigin( x, y );
+
+ S32 scroller_height = 0;
+ S32 scroller_width = gViewerWindow->getWindowWidth();
+ BOOL dummy_bool;
+ if (mScrollContainer)
+ {
+ mScrollContainer->calcVisibleSize( &scroller_width, &scroller_height, &dummy_bool, &dummy_bool);
+ }
+
+ S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_width - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
+ S32 height = llfloor(sFont->getLineHeight() + RENAME_HEIGHT_PAD);
+ mRenamer->reshape( width, height, TRUE );
+ }
+}
+
+
///----------------------------------------------------------------------------
/// Local function definitions
///----------------------------------------------------------------------------