///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System.Collections;
using JetBrains.DataStructures;
namespace JetBrains.JetListViewLibrary
{
///
/// A selection model implementation which allows selecting multiple items.
///
internal class MultipleSelectionModel: SelectionModel
{
private HashSet _selectedNodes;
private IEnumerable _selectedNodesEnumerable;
internal MultipleSelectionModel( JetListViewNodeCollection nodeCollection )
: base( nodeCollection )
{
_selectedNodes = new HashSet();
_selectedNodesEnumerable = new SelectedNodesEnumerable( this );
}
public override int Count
{
get { return _selectedNodes.Count; }
}
public override object SelectionLock
{
get { return _selectedNodes; }
}
internal override IEnumerable SelectedNodes
{
get { return _selectedNodesEnumerable; }
}
private static IEnumerator _emptyEnumerator = new ArrayList( 1 ).GetEnumerator();
public override IEnumerator GetEnumerator()
{
return ( _selectedNodes.Count == 0 ) ? _emptyEnumerator : new SelectedItemEnumerator( _selectedNodes.GetEnumerator() );
}
internal override void ClearSelection()
{
IViewNode[] clearedNodes;
lock( _selectedNodes )
{
clearedNodes = SelectionToArray();
_selectedNodes.Clear();
}
foreach( IViewNode node in clearedNodes )
{
OnSelectionStateChanged( node, false );
}
}
internal override void SelectNode( IViewNode node )
{
lock( _selectedNodes )
{
if ( _selectedNodes.Contains( node ) )
{
return;
}
_selectedNodes.Add( node );
}
OnSelectionStateChanged( node, true );
}
internal override bool UnselectNode( IViewNode node )
{
lock( _selectedNodes )
{
if ( !_selectedNodes.Contains( node ) )
{
return false;
}
_selectedNodes.Remove( node );
}
OnSelectionStateChanged( node, false );
return true;
}
internal override bool IsNodeSelected( IViewNode node )
{
lock( _selectedNodes )
{
return _selectedNodes.Contains( node );
}
}
internal override IViewNode[] SelectionToArray()
{
IViewNode[] selNodes;
lock( _selectedNodes )
{
selNodes = new IViewNode[ _selectedNodes.Count ];
int i=0;
foreach( HashSet.Entry entry in _selectedNodes )
{
selNodes [i++] = (IViewNode) entry.Key;
}
}
return selNodes;
}
private class SelectedNodesEnumerable: IEnumerable
{
private MultipleSelectionModel _selection;
public SelectedNodesEnumerable( MultipleSelectionModel selection )
{
_selection = selection;
}
public IEnumerator GetEnumerator()
{
return new SelectedNodeEnumerator( _selection._selectedNodes.GetEnumerator() );
}
}
private class SelectedNodeEnumerator: IEnumerator
{
private IEnumerator _baseEnumerator;
public SelectedNodeEnumerator( IEnumerator baseEnumerator )
{
_baseEnumerator = baseEnumerator;
}
public bool MoveNext()
{
return _baseEnumerator.MoveNext();
}
public void Reset()
{
_baseEnumerator.Reset();
}
public object Current
{
get
{
HashSet.Entry entry = (HashSet.Entry) _baseEnumerator.Current;
return entry.Key;
}
}
}
private class SelectedItemEnumerator: IEnumerator
{
private IEnumerator _baseEnumerator;
public SelectedItemEnumerator( IEnumerator baseEnumerator )
{
_baseEnumerator = baseEnumerator;
}
public bool MoveNext()
{
while( _baseEnumerator.MoveNext() )
{
HashSet.Entry entry = (HashSet.Entry) _baseEnumerator.Current;
if ( entry.Key is JetListViewNode )
{
return true;
}
}
return false;
}
public void Reset()
{
_baseEnumerator.Reset();
}
public object Current
{
get
{
HashSet.Entry entry = (HashSet.Entry) _baseEnumerator.Current;
JetListViewNode node = (JetListViewNode) entry.Key;
return node.Data;
}
}
}
}
}