summaryrefslogtreecommitdiff
path: root/indra/newview/llfolderviewitem.cpp
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2010-09-24 11:23:07 -0700
committerMerov Linden <merov@lindenlab.com>2010-09-24 11:23:07 -0700
commitb85cf7b12562a3359e52147d26eb1051ce388559 (patch)
tree3f656bb586e7cd2a25763d8053365e106365a063 /indra/newview/llfolderviewitem.cpp
parent24473fc0d619beaafab029170a7aacde5855be1a (diff)
parentb34856d66dfa1a725cb85d813982709566b6db7a (diff)
Pull update from viewer-development
Diffstat (limited to 'indra/newview/llfolderviewitem.cpp')
-rw-r--r--indra/newview/llfolderviewitem.cpp142
1 files changed, 111 insertions, 31 deletions
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 04b690b903..3c36248c1f 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -489,27 +489,34 @@ void LLFolderViewItem::dirtyFilter()
// together.
BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
{
- if( selection == this )
+ if (selection == this && !mIsSelected)
{
- mIsSelected = TRUE;
- if(mListener)
+ selectItem();
+ if (mListener)
{
mListener->selectItem();
}
}
- else
+ else if (mIsSelected) // Deselect everything else.
{
- mIsSelected = FALSE;
+ deselectItem();
}
return mIsSelected;
}
BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
- if(selection == this && mIsSelected != selected)
+ if (selection == this && mIsSelected != selected)
{
- mIsSelected = selected;
- if(mListener)
+ if (mIsSelected)
+ {
+ deselectItem();
+ }
+ else
+ {
+ selectItem();
+ }
+ if (mListener)
{
mListener->selectItem();
}
@@ -518,6 +525,33 @@ BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selecte
return FALSE;
}
+void LLFolderViewItem::deselectItem(void)
+{
+ llassert(mIsSelected);
+
+ mIsSelected = FALSE;
+
+ // Update ancestors' count of selected descendents.
+ LLFolderViewFolder* parent_folder = getParentFolder();
+ if (parent_folder)
+ {
+ parent_folder->recursiveIncrementNumDescendantsSelected(-1);
+ }
+}
+
+void LLFolderViewItem::selectItem(void)
+{
+ llassert(!mIsSelected);
+
+ mIsSelected = TRUE;
+
+ // Update ancestors' count of selected descendents.
+ LLFolderViewFolder* parent_folder = getParentFolder();
+ if (parent_folder)
+ {
+ parent_folder->recursiveIncrementNumDescendantsSelected(1);
+ }
+}
BOOL LLFolderViewItem::isMovable()
{
@@ -1073,6 +1107,7 @@ void LLFolderViewItem::draw()
LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
LLFolderViewItem( p ), // 0 = no create time
+ mNumDescendantsSelected(0),
mIsOpen(FALSE),
mExpanderHighlighted(FALSE),
mCurHeight(0.f),
@@ -1458,16 +1493,34 @@ BOOL LLFolderViewFolder::hasFilteredDescendants()
return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
}
+void LLFolderViewFolder::recursiveIncrementNumDescendantsSelected(S32 increment)
+{
+ LLFolderViewFolder* parent_folder = this;
+ do
+ {
+ parent_folder->mNumDescendantsSelected += increment;
+
+ // Make sure we don't have negative values.
+ llassert(parent_folder->mNumDescendantsSelected >= 0);
+
+ parent_folder = parent_folder->getParentFolder();
+ }
+ while(parent_folder);
+}
+
// Passes selection information on to children and record selection
// information if necessary.
BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
- BOOL take_keyboard_focus)
+ BOOL take_keyboard_focus)
{
BOOL rv = FALSE;
- if( selection == this )
+ if (selection == this)
{
- mIsSelected = TRUE;
- if(mListener)
+ if (!isSelected())
+ {
+ selectItem();
+ }
+ if (mListener)
{
mListener->selectItem();
}
@@ -1475,7 +1528,10 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem
}
else
{
- mIsSelected = FALSE;
+ if (isSelected())
+ {
+ deselectItem();
+ }
rv = FALSE;
}
BOOL child_selected = FALSE;
@@ -1507,21 +1563,31 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem
return rv;
}
-// This method is used to change the selection of an item. If
-// selection is 'this', then note selection as true. Returns TRUE
-// if this or a child is now selected.
-BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection,
- BOOL selected)
+// This method is used to change the selection of an item.
+// Recursively traverse all children; if 'selection' is 'this' then change
+// the select status if necessary.
+// Returns TRUE if the selection state of this folder, or of a child, was changed.
+BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
{
BOOL rv = FALSE;
if(selection == this)
{
- mIsSelected = selected;
- if(mListener && selected)
+ if (isSelected() != selected)
+ {
+ rv = TRUE;
+ if (selected)
+ {
+ selectItem();
+ }
+ else
+ {
+ deselectItem();
+ }
+ }
+ if (mListener && selected)
{
mListener->selectItem();
}
- rv = TRUE;
}
for (folders_t::iterator iter = mFolders.begin();
@@ -1545,16 +1611,14 @@ BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection,
return rv;
}
-S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items)
+void LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& selected_items)
{
- S32 num_selected = 0;
-
// pass on to child folders first
for (folders_t::iterator iter = mFolders.begin();
iter != mFolders.end();)
{
folders_t::iterator fit = iter++;
- num_selected += (*fit)->extendSelection(selection, last_selected, selected_items);
+ (*fit)->extendSelection(selection, last_selected, selected_items);
}
// handle selection of our immediate children...
@@ -1647,7 +1711,6 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie
if (item->changeSelection(item, TRUE))
{
selected_items.put(item);
- num_selected++;
}
}
}
@@ -1657,11 +1720,8 @@ S32 LLFolderViewFolder::extendSelection(LLFolderViewItem* selection, LLFolderVie
if (selection->changeSelection(selection, TRUE))
{
selected_items.put(selection);
- num_selected++;
}
}
-
- return num_selected;
}
void LLFolderViewFolder::destroyView()
@@ -1711,6 +1771,10 @@ void LLFolderViewFolder::removeView(LLFolderViewItem* item)
return;
}
// deselect without traversing hierarchy
+ if (item->isSelected())
+ {
+ item->deselectItem();
+ }
getRoot()->removeFromSelectionList(item);
extractItem(item);
delete item;
@@ -1726,16 +1790,24 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
// This is an evil downcast. However, it's only doing
// pointer comparison to find if (which it should be ) the
// item is in the container, so it's pretty safe.
- LLFolderViewFolder* f = reinterpret_cast<LLFolderViewFolder*>(item);
+ LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
folders_t::iterator ft;
ft = std::find(mFolders.begin(), mFolders.end(), f);
- if(ft != mFolders.end())
+ if (ft != mFolders.end())
{
+ if ((*ft)->numSelected())
+ {
+ recursiveIncrementNumDescendantsSelected(-(*ft)->numSelected());
+ }
mFolders.erase(ft);
}
}
else
{
+ if ((*it)->isSelected())
+ {
+ recursiveIncrementNumDescendantsSelected(-1);
+ }
mItems.erase(it);
}
//item has been removed, need to update filter
@@ -1899,6 +1971,10 @@ 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 );
@@ -1912,6 +1988,10 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
{
mFolders.push_back(folder);
+ if (folder->numSelected())
+ {
+ recursiveIncrementNumDescendantsSelected(folder->numSelected());
+ }
folder->setOrigin(0, 0);
folder->reshape(getRect().getWidth(), 0);
folder->setVisible(FALSE);