Exemple #1
0
        private static RSTree2D <SelectionCellRangeWithItemsWrapper> .Area GetArea(SelectionCellRange range)
        {
            if (range.IsEmpty)
            {
                return(RSTree2D <SelectionCellRangeWithItemsWrapper> .Area.Empty);
            }

            var itemRange = range.ItemRange;
            var columnRange = range.ColumnRange;
            int rs, re, cs, ce;

            if (itemRange.StartIndex <= itemRange.EndIndex)
            {
                rs = itemRange.StartIndex;
                re = itemRange.EndIndex;
            }
            else
            {
                rs = itemRange.EndIndex;
                re = itemRange.StartIndex;
            }

            if (columnRange.StartIndex <= columnRange.EndIndex)
            {
                cs = columnRange.StartIndex;
                ce = columnRange.EndIndex;
            }
            else
            {
                cs = columnRange.EndIndex;
                ce = columnRange.StartIndex;
            }

            return(new RSTree2D <SelectionCellRangeWithItemsWrapper> .Area(rs, re - rs + 1, cs, ce - cs + 1));
        }
Exemple #2
0
 public IEnumerable <SelectionRange> GetIntersectedColumnRanges(SelectionCellRange range)
 {
     return((from match in this.IndexOfOverlap(range)
             let current = m_unsortedRanges[match].Value
                           let intersection = current.CellRange.Intersect(range)
                                              select intersection.ColumnRange).ToList());
 }
Exemple #3
0
        public bool Contains(SelectionCellRange range)
        {
            if ((m_unsortedRanges.Count <= 0) || (SelectedCellsStorage.IsEmpty(range)))
            {
                return(false);
            }

            return(this.Contains(new SelectionCellRangeWithItems(range.ItemRange, null, range.ColumnRange)));
        }
        public override bool Equals(object obj)
        {
            if (!(obj is SelectionCellRange))
            {
                return(false);
            }

            SelectionCellRange selectionRange = ( SelectionCellRange )obj;

            return((selectionRange.m_itemRange == m_itemRange) &&
                   (selectionRange.m_columnRange == m_columnRange));
        }
Exemple #5
0
        public IEnumerable <SelectionRange> GetIntersectedColumnRanges(SelectionCellRange range)
        {
            // It improves performance to leave early and prevent empty enumerators creation.
            if (m_ranges.Count <= 0)
            {
                return(Enumerable.Empty <SelectionRange>());
            }

            return((from match in this.IndexOfOverlap(range)
                    let current = m_ranges[match].Value
                                  let intersection = current.CellRange.Intersect(range)
                                                     select intersection.ColumnRange).ToList());
        }
Exemple #6
0
        public bool Contains(SelectionCellRangeWithItems cellRangeWithItemsToCompare)
        {
            int count = m_list.Count;
            SelectionCellRange cellRangeToCompare = cellRangeWithItemsToCompare.CellRange;

            int cellRangeLength = cellRangeToCompare.Length;

            // If there is more than one Cell in the range, ensure
            // the range is completely contained within this SelectedCellsStorage
            if (cellRangeLength > 1)
            {
                SelectedCellsStorage cellStorage = new SelectedCellsStorage(null, cellRangeLength);
                cellStorage.Add(cellRangeWithItemsToCompare);

                // The range is completely contained when the store
                // is empty after removing all ranges contained within
                // this SelectedCellsStorage
                for (int i = 0; i < count; i++)
                {
                    SelectionCellRangeWithItems cellRangeWithItems = m_list[i];

                    cellStorage.Remove(cellRangeWithItems);

                    if (cellStorage.Count == 0)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    SelectionCellRangeWithItems rangeWithItem     = m_list[i];
                    SelectionCellRange          rangeIntersection = rangeWithItem.CellRange.Intersect(cellRangeToCompare);

                    if (!rangeIntersection.IsEmpty)
                    {
                        if (cellRangeWithItemsToCompare.ItemRangeWithItems.IsItemsEqual(
                                rangeIntersection.ItemRange, rangeWithItem.ItemRangeWithItems))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public bool SelectJustThisCell(int itemIndex, object item, int columnIndex)
        {
            bool selectionDone = true;

            m_toDeferSelect.Clear();

            SelectionCellRangeWithItems rangeWithItemsToSelect =
                new SelectionCellRangeWithItems(itemIndex, item, columnIndex);

            SelectionCellRange cellRange = rangeWithItemsToSelect.CellRange;

            if (m_cellsToSelect.Contains(cellRange))
            {
                selectionDone = false;
            }

            m_cellsToSelect.Clear();
            SelectedCellsStorage selectedCellsInChange = m_owner.SelectedCellsStore;

            if (selectedCellsInChange.Contains(cellRange))
            {
                if (!m_cellsToUnselect.Contains(cellRange))
                {
                    selectionDone = false;
                }

                m_cellsToUnselect.Clear();

                foreach (SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange)
                {
                    m_cellsToUnselect.Add(selectedCellRangeWithItems);
                }

                m_cellsToUnselect.Remove(rangeWithItemsToSelect);
            }
            else
            {
                m_cellsToSelect.Add(rangeWithItemsToSelect);
                m_cellsToUnselect.Clear();

                foreach (SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange)
                {
                    m_cellsToUnselect.Add(selectedCellRangeWithItems);
                }
            }

            this.UnselectAllItems();
            return(selectionDone);
        }
Exemple #8
0
        public List <SelectionRange> GetIntersectedColumnRanges(SelectionCellRange cellRange)
        {
            List <SelectionRange> intersectionRanges = new List <SelectionRange>();
            int count = m_list.Count;

            for (int i = 0; i < count; i++)
            {
                SelectionCellRangeWithItems range = m_list[i];
                SelectionCellRange          cellRangeIntersection = range.CellRange.Intersect(cellRange);

                if (!cellRangeIntersection.IsEmpty)
                {
                    intersectionRanges.Add(cellRangeIntersection.ColumnRange);
                }
            }

            return(intersectionRanges);
        }
Exemple #9
0
        private IEnumerable <int> IndexOfOverlap(SelectionCellRange target)
        {
            if ((m_sortedRanges.Count <= 0) || SelectedCellsStorage.IsEmpty(target))
            {
                yield break;
            }

            var comparer = new ItemRangeComparer(target.ItemRange);

            var index = this.FindIndex(comparer);

            if (index < 0)
            {
                yield break;
            }

            while (index > 0)
            {
                if (comparer.Compare(m_sortedRanges[index - 1]) != 0)
                {
                    break;
                }

                index--;
            }

            for (int i = index; i < m_sortedRanges.Count; i++)
            {
                var wrapper = m_sortedRanges[i];
                if (comparer.Compare(wrapper) != 0)
                {
                    break;
                }

                var currentRangeWithItems = wrapper.Value;
                var overlap = target.Intersect(currentRangeWithItems.CellRange);

                if (!SelectedCellsStorage.IsEmpty(overlap))
                {
                    yield return(wrapper.Index);
                }
            }
        }
Exemple #10
0
        public bool Contains(int itemIndex, int columnIndex)
        {
            if ((itemIndex < 0) || (columnIndex < 0))
            {
                return(false);
            }

            SelectionCellRange cellRange = new SelectionCellRange(itemIndex, columnIndex);
            int count = m_list.Count;

            for (int i = 0; i < count; i++)
            {
                if (!m_list[i].CellRange.Intersect(cellRange).IsEmpty)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemple #11
0
        private IEnumerable <int> IndexOfOverlap(SelectionCellRange range)
        {
            // It improves performance to leave early.
            if (m_map.Count <= 0)
            {
                yield break;
            }

            foreach (var entry in m_map.GetEntriesWithin(SelectedCellsStorage.GetArea(range)))
            {
                var candidate = entry.Item;
                var target    = candidate.Value;
                var overlap   = range.Intersect(target.CellRange);

                Debug.Assert(!SelectedCellsStorage.IsEmpty(overlap));

                if (!SelectedCellsStorage.IsEmpty(overlap))
                {
                    yield return(candidate.Index);
                }
            }
        }
        private IEnumerable <SelectionCellRangeWithItems> GetUnselectedCellsFromRemove(ICollection <SelectionCellRangeWithItems> removedCellsRangeWithItems)
        {
            var store = m_owner.SelectedCellsStore;

            if ((store.Count <= 0) || (m_sourceChanges.Count <= 0))
            {
                return(Enumerable.Empty <SelectionCellRangeWithItems>());
            }

            var unselectedCellsFromRemove = new List <SelectionCellRangeWithItems>();

            for (int i = 0; i < m_sourceChanges.Count; i++)
            {
                var sourceChangeInfo = m_sourceChanges[i];
                if ((sourceChangeInfo.Action != NotifyCollectionChangedAction.Remove) || (sourceChangeInfo.StartIndex == -1))
                {
                    continue;
                }

                var startIndex       = sourceChangeInfo.StartIndex;
                var removedItemCount = sourceChangeInfo.Count;
                var range            = new SelectionCellRange(new SelectionRange(startIndex, startIndex + removedItemCount - 1), new SelectionRange(0, int.MaxValue - 1));

                if (removedCellsRangeWithItems != null)
                {
                    var removedItems = new object[removedItemCount];
                    sourceChangeInfo.Items.CopyTo(removedItems, 0);

                    removedCellsRangeWithItems.Add(new SelectionCellRangeWithItems(range.ItemRange, removedItems, range.ColumnRange));
                }

                foreach (var cellRangeWithItems in store.GetIntersectedCellRangesWithItems(range))
                {
                    unselectedCellsFromRemove.Add(cellRangeWithItems);
                }
            }

            return(unselectedCellsFromRemove);
        }
        public SelectionCellRange Intersect(SelectionCellRange range)
        {
            SelectionCellRange cellRangeIntersection = SelectionCellRange.Empty;

            SelectionRange itemRange             = range.ItemRange;
            SelectionRange itemRangeIntersection = m_itemRange.Intersect(itemRange);

            if (itemRangeIntersection.IsEmpty)
            {
                return(SelectionCellRange.Empty);
            }

            SelectionRange columnRange             = range.ColumnRange;
            SelectionRange columnRangeIntersection = m_columnRange.Intersect(columnRange);

            if (columnRangeIntersection.IsEmpty)
            {
                return(SelectionCellRange.Empty);
            }

            return(new SelectionCellRange(itemRangeIntersection, columnRangeIntersection));
        }
Exemple #14
0
        public bool Contains(SelectionCellRange cellRange)
        {
            int count = m_list.Count;

            int cellRangeLength = cellRange.Length;

            // Ensure every Cells are present in the SelectedCellsStorage
            if (cellRangeLength > 1)
            {
                SelectedCellsStorage cellStorage = new SelectedCellsStorage(null, cellRangeLength);
                cellStorage.Add(new SelectionCellRangeWithItems(cellRange.ItemRange,
                                                                null,
                                                                cellRange.ColumnRange));

                for (int i = 0; i < count; i++)
                {
                    cellStorage.Remove(m_list[i]);

                    if (cellStorage.Count == 0)
                    {
                        return(true);
                    }
                }
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    if (!m_list[i].CellRange.Intersect(cellRange).IsEmpty)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public                                    SelectionCellRange[] Exclude(SelectionCellRange cellRangeToExclude)
        {
            if (cellRangeToExclude.IsEmpty)
            {
                return new SelectionCellRange[] { this }
            }
            ;

            SelectionCellRange cellRangeIntersection = this.Intersect(cellRangeToExclude);

            if (cellRangeIntersection.IsEmpty)
            {
                return new SelectionCellRange[] { this }
            }
            ;

            SelectionRange[]     itemRanges   = m_itemRange.Exclude(cellRangeToExclude.ItemRange);
            SelectionRange[]     columnRanges = m_columnRange.Exclude(cellRangeToExclude.ColumnRange);
            SelectionCellRange[] cellRanges   = new SelectionCellRange[itemRanges.Length + columnRanges.Length];
            int index = 0;

            foreach (SelectionRange itemRange in itemRanges)
            {
                cellRanges[index] = new SelectionCellRange(itemRange, m_columnRange);

                index++;
            }

            foreach (SelectionRange columnRange in columnRanges)
            {
                cellRanges[index] = new SelectionCellRange(cellRangeIntersection.ItemRange, columnRange);
                index++;
            }

            Debug.Assert(index == cellRanges.Length);
            return(cellRanges);
        }
    public bool Contains( int itemIndex, int columnIndex )
    {
      if( ( itemIndex < 0 ) || ( columnIndex < 0 ) )
        return false;

      SelectionCellRange cellRange = new SelectionCellRange( itemIndex, columnIndex );
      int count = m_list.Count;

      for( int i = 0; i < count; i++ )
      {
        if( !m_list[ i ].CellRange.Intersect( cellRange ).IsEmpty )
          return true;
      }

      return false;
    }
    public bool UnselectCells( SelectionCellRangeWithItems cellRangeWithItems )
    {
      SelectionRange itemRange = cellRangeWithItems.ItemRange;
      SelectionRange columnRange = cellRangeWithItems.ColumnRange;
      SelectionCellRange cellRange = cellRangeWithItems.CellRange;

      if( itemRange.IsEmpty )
      {
        // We have no index we have to remove based on item
        bool selectionChanged = false;

        List<SelectionCellRangeWithItems> cellsRangeToRemove = new List<SelectionCellRangeWithItems>();
        List<object> itemsToUnselect = new List<object>( cellRangeWithItems.ItemRangeWithItems.Items );
        int count = itemsToUnselect.Count;

        for( int i = count - 1; i >= 0; i-- )
        {
          object itemToUnselect = itemsToUnselect[ i ];

          foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect )
          {
            SelectionRange columnIntersection = columnRange.Intersect( existingSelectionCellRangeWithItems.ColumnRange );

            if( columnIntersection.IsEmpty )
              continue;

            int index = Array.IndexOf( existingSelectionCellRangeWithItems.ItemRangeWithItems.Items, itemToUnselect );

            if( index > -1 )
            {
              cellsRangeToRemove.Add(
                new SelectionCellRangeWithItems(
                  new SelectionRange( existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset( index ) ),
                  new object[] { itemToUnselect },
                  columnIntersection ) );
            }
          }
        }

        // Remove the currently unselected item from the new range to select
        foreach( SelectionCellRangeWithItems cellRangeToRemove in cellsRangeToRemove )
        {
          selectionChanged |= m_cellsToSelect.Remove( cellRangeToRemove );
        }

        count = itemsToUnselect.Count;

        for( int i = 0; i < count; i++ )
        {
          object itemToUnselect = itemsToUnselect[ i ];

          foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_owner.SelectedCellsStore )
          {
            SelectionRange columnIntersection = columnRange.Intersect( existingSelectionCellRangeWithItems.ColumnRange );

            if( columnIntersection.IsEmpty )
              continue;

            int index = Array.IndexOf( existingSelectionCellRangeWithItems.ItemRangeWithItems.Items, itemToUnselect );

            if( index > -1 )
            {
              index = existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset( index );

              SelectionCellRange cellRangeTemp = new SelectionCellRange(
                new SelectionRange( existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset( index ) ),
                columnIntersection );

              if( !m_cellsToUnselect.Contains( cellRangeTemp ) )
              {
                selectionChanged = true;

                m_cellsToUnselect.Add( new SelectionCellRangeWithItems(
                  cellRangeTemp.ItemRange, new object[] { itemToUnselect }, cellRangeTemp.ColumnRange ) );
              }
            }
          }
        }

        return selectionChanged;
      }

      if( cellRangeWithItems.Length == 1 )
      {
        if( !m_cellsToSelect.Remove( cellRangeWithItems ) )
        {
          if( !m_owner.SelectedCellsStore.Contains( cellRange ) )
            return false;

          if( m_cellsToUnselect.Contains( cellRange ) )
            return false;

          m_cellsToUnselect.Add( cellRangeWithItems );
        }

        return true;
      }
      else
      {
        SelectedCellsStorage tempStorage = new SelectedCellsStorage( m_owner, 8 );
        tempStorage.Add( cellRangeWithItems );

        // Remove the currently selected item from the new range to select
        foreach( SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect )
        {
          tempStorage.Remove( existingSelectionCellRangeWithItems );
        }

        bool selectionChanged = m_cellsToSelect.Remove( cellRangeWithItems );

        if( tempStorage.Count > 0 )
        {
          selectionChanged = true;

          foreach( SelectionCellRangeWithItems cellRangeWithItemsToAdd in tempStorage )
          {
            Debug.Assert( !m_cellsToUnselect.Contains( cellRangeWithItemsToAdd.CellRange ) );
            m_cellsToUnselect.Add( cellRangeWithItemsToAdd );
          }
        }

        return selectionChanged;
      }
    }
Exemple #18
0
        public bool Remove(SelectionCellRangeWithItems cellRangeWithItemsToRemove)
        {
            if (cellRangeWithItemsToRemove.CellRange.IsEmpty)
            {
                return(true);
            }

            bool removed = false;
            SelectionCellRange cellRangeToRemove = cellRangeWithItemsToRemove.CellRange;

            object[] itemsToRemove            = cellRangeWithItemsToRemove.ItemRangeWithItems.Items;
            int      itemsToRemoveCount       = (itemsToRemove == null) ? 0 : itemsToRemove.Length;
            int      itemOffsetToRemove       = 0;
            bool     itemRangeToRemoveIsEmpty = cellRangeToRemove.ItemRange.IsEmpty;

            do
            {
                for (int i = m_list.Count - 1; i >= 0; i--)
                {
                    SelectionCellRangeWithItems cellRangeWithItems = m_list[i];
                    SelectionRange          itemRange          = cellRangeWithItems.ItemRange;
                    SelectionCellRange      cellRange          = cellRangeWithItems.CellRange;
                    SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems;
                    SelectionCellRange      cellRangeIntersection;
                    object[] oldRangeItems = itemRangeWithItems.Items;

                    if (itemRangeToRemoveIsEmpty)
                    {
                        int itemOffset = Array.IndexOf(oldRangeItems, itemsToRemove[itemOffsetToRemove]);

                        if (itemOffset == -1)
                        {
                            continue;
                        }

                        int itemIndex = itemRange.GetIndexFromItemOffset(itemOffset);

                        cellRangeIntersection = new SelectionCellRange(
                            new SelectionRange(itemIndex, itemIndex),
                            cellRangeWithItems.ColumnRange.Intersect(cellRangeToRemove.ColumnRange));
                    }
                    else
                    {
                        cellRangeIntersection = cellRange.Intersect(cellRangeToRemove);

                        if (cellRangeIntersection.IsEmpty)
                        {
                            continue;
                        }

                        if (!itemRangeWithItems.IsItemsEqual(
                                cellRangeIntersection.ItemRange, cellRangeWithItemsToRemove.ItemRangeWithItems))
                        {
                            continue;
                        }
                    }

                    removed       = true;
                    m_cellsCount -= cellRangeIntersection.Length;
                    SelectionCellRange[] newCellRanges = cellRange.Exclude(cellRangeIntersection);

                    if (newCellRanges.Length == 0)
                    {
                        m_list.RemoveAt(i);
                    }
                    else
                    {
                        SelectionCellRange newCellRange = newCellRanges[0];

                        m_list[i] = new SelectionCellRangeWithItems(
                            newCellRange.ItemRange, itemRangeWithItems.GetItems(newCellRange.ItemRange), newCellRange.ColumnRange);

                        for (int j = 1; j < newCellRanges.Length; j++)
                        {
                            newCellRange = newCellRanges[j];

                            m_list.Insert(i + j, new SelectionCellRangeWithItems(
                                              newCellRange.ItemRange, itemRangeWithItems.GetItems(newCellRange.ItemRange), newCellRange.ColumnRange));
                        }
                    }
                }

                itemOffsetToRemove++;
            } while((itemRangeToRemoveIsEmpty) && (itemOffsetToRemove < itemsToRemoveCount));

            return(removed);
        }
    public void UpdateSelectionAfterSourceDataItemReplaced( NotifyCollectionChangedEventArgs e )
    {
      Debug.Assert( e.OldItems.Count == e.NewItems.Count );
      Debug.Assert( e.OldStartingIndex == e.NewStartingIndex );

      SelectedItemsStorage selectedItemsStorage = m_owner.SelectedItemsStore;
      SelectedCellsStorage selectedCellsStorage = m_owner.SelectedCellsStore;
      int oldItemIndex = e.OldStartingIndex;
      IList oldItems = e.OldItems;
      IList newItems = e.NewItems;
      int replacedItemCount = oldItems.Count;
      int cellRangeCount = selectedCellsStorage.Count;

      if( oldItemIndex != -1 )
      {
        int itemIndex = oldItemIndex;

        for( int i = 0; i < replacedItemCount; i++ )
        {
          object newItem = newItems[ i ];

          if( selectedItemsStorage.Contains( itemIndex ) )
          {
            this.UnselectItems( new SelectionRangeWithItems( itemIndex, oldItems[ i ] ) );
            this.SelectItems( new SelectionRangeWithItems( itemIndex, newItem ) );
          }

          SelectionCellRange replacedCellRange = new SelectionCellRange(
            new SelectionRange( itemIndex ), new SelectionRange( 0, int.MaxValue - 1 ) );

          for( int j = 0; j < cellRangeCount; j++ )
          {
            SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[ j ];
            SelectionCellRange cellRange = cellRangeWithItems.CellRange;

            if( !cellRange.Intersect( replacedCellRange ).IsEmpty )
            {
              object[] items = cellRangeWithItems.ItemRangeWithItems.Items;

              if( items != null )
              {
                items[ cellRange.ItemRange.GetOffsetFromItemIndex( itemIndex ) ] = newItem;
              }
            }
          }

          itemIndex++;
        }
      }
      else
      {
        CollectionView sourceItems = m_owner.Items;

        for( int i = 0; i < replacedItemCount; i++ )
        {
          object newItem = newItems[ i ];
          int itemIndex = sourceItems.IndexOf( newItem );

          if( itemIndex == -1 )
            continue;

          if( selectedItemsStorage.Contains( itemIndex ) )
          {
            this.UnselectItems( new SelectionRangeWithItems( itemIndex, oldItems[ i ] ) );
            this.SelectItems( new SelectionRangeWithItems( itemIndex, newItem ) );
          }

          SelectionCellRange replacedCellRange = new SelectionCellRange(
            new SelectionRange( itemIndex ), new SelectionRange( 0, int.MaxValue - 1 ) );

          for( int j = 0; j < cellRangeCount; j++ )
          {
            SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[ j ];
            SelectionCellRange cellRange = cellRangeWithItems.CellRange;

            if( !cellRange.Intersect( replacedCellRange ).IsEmpty )
            {
              object[] items = cellRangeWithItems.ItemRangeWithItems.Items;

              if( items != null )
              {
                items[ cellRange.ItemRange.GetOffsetFromItemIndex( itemIndex ) ] = newItem;
              }
            }
          }
        }
      }
    }
Exemple #20
0
 public IEnumerable <SelectionCellRangeWithItems> GetIntersectedCellRangesWithItems(SelectionCellRange range)
 {
     return((from match in this.IndexOfOverlap(range)
             let current = m_unsortedRanges[match].Value
                           let intersection = current.CellRange.Intersect(range)
                                              select new SelectionCellRangeWithItems(
                 intersection.ItemRange,
                 current.ItemRangeWithItems.GetItems(intersection.ItemRange),
                 intersection.ColumnRange)).ToList());
 }
Exemple #21
0
 private static bool IsEmpty(SelectionCellRange range)
 {
     return((range.ItemRange.IsEmpty) ||
            (range.ColumnRange.IsEmpty));
 }
    public List<SelectionCellRangeWithItems> GetIntersectedCellRangesWithItems( SelectionCellRange cellRange )
    {
      List<SelectionCellRangeWithItems> intersectionCellRanges = new List<SelectionCellRangeWithItems>();
      int count = m_list.Count;

      for( int i = 0; i < count; i++ )
      {
        SelectionCellRangeWithItems range = m_list[ i ];
        SelectionCellRange cellRangeIntersection = range.CellRange.Intersect( cellRange );

        if( !cellRangeIntersection.IsEmpty )
        {
          intersectionCellRanges.Add(
            new SelectionCellRangeWithItems(
              cellRangeIntersection.ItemRange,
              range.ItemRangeWithItems.GetItems( cellRangeIntersection.ItemRange ),
              cellRangeIntersection.ColumnRange ) );
        }
      }

      return intersectionCellRanges;
    }
    public SelectionCellRange[] Exclude( SelectionCellRange cellRangeToExclude )
    {
      if( cellRangeToExclude.IsEmpty )
        return new SelectionCellRange[] { this };

      SelectionCellRange cellRangeIntersection = this.Intersect( cellRangeToExclude );

      if( cellRangeIntersection.IsEmpty )
        return new SelectionCellRange[] { this };

      SelectionRange[] itemRanges = m_itemRange.Exclude( cellRangeToExclude.ItemRange );
      SelectionRange[] columnRanges = m_columnRange.Exclude( cellRangeToExclude.ColumnRange );
      SelectionCellRange[] cellRanges = new SelectionCellRange[ itemRanges.Length + columnRanges.Length ];
      int index = 0;

      foreach( SelectionRange itemRange in itemRanges )
      {
        cellRanges[ index ] = new SelectionCellRange( itemRange, m_columnRange );
        index++;
      }

      foreach( SelectionRange columnRange in columnRanges )
      {
        cellRanges[ index ] = new SelectionCellRange( cellRangeIntersection.ItemRange, columnRange );
        index++;
      }

      Debug.Assert( index == cellRanges.Length );
      return cellRanges;
    }
        public bool SelectItemCells(
            int itemIndex,
            object item,
            HashedLinkedList <ColumnBase> columnsByVisiblePosition,
            bool preserveSelection)
        {
            bool selectionDone = true;
            int  columnsCount  = columnsByVisiblePosition.Count;

            m_toDeferSelect.Clear();

            SelectionCellRangeWithItems rangeWithItemsToSelect =
                new SelectionCellRangeWithItems(
                    new SelectionRange(itemIndex),
                    new object[] { item },
                    new SelectionRange(0, columnsCount - 1));

            SelectionCellRange cellRange = rangeWithItemsToSelect.CellRange;

            m_cellsToSelect.Clear();
            SelectedCellsStorage selectedCellsInChange = m_owner.SelectedCellsStore;

            // Remove all currently selected Cells from the new selectionRange
            // to avoid duplicate SelectionCellRange
            SelectedCellsStorage tempStorage = new SelectedCellsStorage(null);

            tempStorage.Add(rangeWithItemsToSelect);

            for (int i = 0; i < selectedCellsInChange.Count; i++)
            {
                tempStorage.Remove(selectedCellsInChange[i]);
            }

            foreach (ColumnBase column in columnsByVisiblePosition)
            {
                if (!column.Visible)
                {
                    tempStorage.Remove(new SelectionCellRangeWithItems(itemIndex, item, column.VisiblePosition));
                }
            }

            int tempStorageCount = tempStorage.Count;

            // All Cells are already selected
            if (tempStorageCount == 0)
            {
                if (!m_cellsToUnselect.Contains(cellRange))
                {
                    selectionDone = false;
                }

                m_cellsToUnselect.Clear();

                if (!preserveSelection)
                {
                    foreach (SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange)
                    {
                        m_cellsToUnselect.Add(selectedCellRangeWithItems);
                    }
                }

                m_cellsToUnselect.Remove(rangeWithItemsToSelect);
            }
            else
            {
                // Add each range to selection
                for (int i = 0; i < tempStorageCount; i++)
                {
                    m_cellsToSelect.Add(tempStorage[i]);
                }

                m_cellsToUnselect.Clear();

                if (!preserveSelection)
                {
                    foreach (SelectionCellRangeWithItems selectedCellRangeWithItems in selectedCellsInChange)
                    {
                        tempStorage = new SelectedCellsStorage(null);
                        tempStorage.Add(selectedCellRangeWithItems);
                        tempStorage.Remove(rangeWithItemsToSelect);
                        tempStorageCount = tempStorage.Count;

                        for (int i = 0; i < tempStorageCount; i++)
                        {
                            m_cellsToUnselect.Add(tempStorage[i]);
                        }
                    }
                }
            }

            if (!preserveSelection)
            {
                this.UnselectAllItems();
            }

            return(selectionDone);
        }
        public bool UnselectCells(SelectionCellRangeWithItems cellRangeWithItems)
        {
            SelectionRange     itemRange   = cellRangeWithItems.ItemRange;
            SelectionRange     columnRange = cellRangeWithItems.ColumnRange;
            SelectionCellRange cellRange   = cellRangeWithItems.CellRange;

            if (itemRange.IsEmpty)
            {
                // We have no index we have to remove based on item
                bool selectionChanged = false;

                List <SelectionCellRangeWithItems> cellsRangeToRemove = new List <SelectionCellRangeWithItems>();
                List <object> itemsToUnselect = new List <object>(cellRangeWithItems.ItemRangeWithItems.Items);
                int           count           = itemsToUnselect.Count;

                for (int i = count - 1; i >= 0; i--)
                {
                    object itemToUnselect = itemsToUnselect[i];

                    foreach (SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect)
                    {
                        SelectionRange columnIntersection = columnRange.Intersect(existingSelectionCellRangeWithItems.ColumnRange);

                        if (columnIntersection.IsEmpty)
                        {
                            continue;
                        }

                        int index = Array.IndexOf(existingSelectionCellRangeWithItems.ItemRangeWithItems.Items, itemToUnselect);

                        if (index > -1)
                        {
                            cellsRangeToRemove.Add(
                                new SelectionCellRangeWithItems(
                                    new SelectionRange(existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset(index)),
                                    new object[] { itemToUnselect },
                                    columnIntersection));
                        }
                    }
                }

                // Remove the currently unselected item from the new range to select
                foreach (SelectionCellRangeWithItems cellRangeToRemove in cellsRangeToRemove)
                {
                    selectionChanged |= m_cellsToSelect.Remove(cellRangeToRemove);
                }

                count = itemsToUnselect.Count;

                for (int i = 0; i < count; i++)
                {
                    object itemToUnselect = itemsToUnselect[i];

                    foreach (SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_owner.SelectedCellsStore)
                    {
                        SelectionRange columnIntersection = columnRange.Intersect(existingSelectionCellRangeWithItems.ColumnRange);

                        if (columnIntersection.IsEmpty)
                        {
                            continue;
                        }

                        int index = Array.IndexOf(existingSelectionCellRangeWithItems.ItemRangeWithItems.Items, itemToUnselect);

                        if (index > -1)
                        {
                            index = existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset(index);

                            SelectionCellRange cellRangeTemp = new SelectionCellRange(
                                new SelectionRange(existingSelectionCellRangeWithItems.ItemRange.GetIndexFromItemOffset(index)),
                                columnIntersection);

                            if (!m_cellsToUnselect.Contains(cellRangeTemp))
                            {
                                selectionChanged = true;

                                m_cellsToUnselect.Add(new SelectionCellRangeWithItems(
                                                          cellRangeTemp.ItemRange, new object[] { itemToUnselect }, cellRangeTemp.ColumnRange));
                            }
                        }
                    }
                }

                return(selectionChanged);
            }

            if (cellRangeWithItems.Length == 1)
            {
                if (!m_cellsToSelect.Remove(cellRangeWithItems))
                {
                    if (!m_owner.SelectedCellsStore.Contains(cellRange))
                    {
                        return(false);
                    }

                    if (m_cellsToUnselect.Contains(cellRange))
                    {
                        return(false);
                    }

                    m_cellsToUnselect.Add(cellRangeWithItems);
                }

                return(true);
            }
            else
            {
                SelectedCellsStorage tempStorage = new SelectedCellsStorage(m_owner);
                tempStorage.Add(cellRangeWithItems);

                // Remove the currently selected item from the new range to select
                foreach (SelectionCellRangeWithItems existingSelectionCellRangeWithItems in m_cellsToSelect)
                {
                    tempStorage.Remove(existingSelectionCellRangeWithItems);
                }

                bool selectionChanged = m_cellsToSelect.Remove(cellRangeWithItems);

                if (tempStorage.Count > 0)
                {
                    selectionChanged = true;

                    foreach (SelectionCellRangeWithItems cellRangeWithItemsToAdd in tempStorage)
                    {
                        Debug.Assert(!m_cellsToUnselect.Contains(cellRangeWithItemsToAdd.CellRange));
                        m_cellsToUnselect.Add(cellRangeWithItemsToAdd);
                    }
                }

                return(selectionChanged);
            }
        }
    public bool Contains( SelectionCellRange cellRange )
    {
      int count = m_list.Count;

      int cellRangeLength = cellRange.Length;

      // Ensure every Cells are present in the SelectedCellsStorage
      if( cellRangeLength > 1 )
      {
        SelectedCellsStorage cellStorage = new SelectedCellsStorage( null, cellRangeLength );
        cellStorage.Add( new SelectionCellRangeWithItems( cellRange.ItemRange,
          null,
          cellRange.ColumnRange ) );

        for( int i = 0; i < count; i++ )
        {
          cellStorage.Remove( m_list[ i ] );

          if( cellStorage.Count == 0 )
            return true;
        }
      }
      else
      {
        for( int i = 0; i < count; i++ )
        {
          if( !m_list[ i ].CellRange.Intersect( cellRange ).IsEmpty )
            return true;
        }
      }

      return false;
    }
    public bool Remove( SelectionCellRangeWithItems cellRangeWithItemsToRemove )
    {
      if( cellRangeWithItemsToRemove.CellRange.IsEmpty )
        return true;

      bool removed = false;
      SelectionCellRange cellRangeToRemove = cellRangeWithItemsToRemove.CellRange;
      object[] itemsToRemove = cellRangeWithItemsToRemove.ItemRangeWithItems.Items;
      int itemsToRemoveCount = ( itemsToRemove == null ) ? 0 : itemsToRemove.Length;
      int itemOffsetToRemove = 0;
      bool itemRangeToRemoveIsEmpty = cellRangeToRemove.ItemRange.IsEmpty;

      do
      {
        for( int i = m_list.Count - 1; i >= 0; i-- )
        {
          SelectionCellRangeWithItems cellRangeWithItems = m_list[ i ];
          SelectionRange itemRange = cellRangeWithItems.ItemRange;
          SelectionCellRange cellRange = cellRangeWithItems.CellRange;
          SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems;
          SelectionCellRange cellRangeIntersection;
          object[] oldRangeItems = itemRangeWithItems.Items;

          if( itemRangeToRemoveIsEmpty )
          {
            int itemOffset = Array.IndexOf( oldRangeItems, itemsToRemove[ itemOffsetToRemove ] );

            if( itemOffset == -1 )
              continue;

            int itemIndex = itemRange.GetIndexFromItemOffset( itemOffset );

            cellRangeIntersection = new SelectionCellRange(
              new SelectionRange( itemIndex, itemIndex ),
              cellRangeWithItems.ColumnRange.Intersect( cellRangeToRemove.ColumnRange ) );
          }
          else
          {
            cellRangeIntersection = cellRange.Intersect( cellRangeToRemove );

            if( cellRangeIntersection.IsEmpty )
              continue;

            if( !itemRangeWithItems.IsItemsEqual(
              cellRangeIntersection.ItemRange, cellRangeWithItemsToRemove.ItemRangeWithItems ) )
            {
              continue;
            }
          }

          removed = true;
          m_cellsCount -= cellRangeIntersection.Length;
          SelectionCellRange[] newCellRanges = cellRange.Exclude( cellRangeIntersection );

          if( newCellRanges.Length == 0 )
          {
            m_list.RemoveAt( i );
          }
          else
          {
            SelectionCellRange newCellRange = newCellRanges[ 0 ];

            m_list[ i ] = new SelectionCellRangeWithItems(
              newCellRange.ItemRange, itemRangeWithItems.GetItems( newCellRange.ItemRange ), newCellRange.ColumnRange );

            for( int j = 1; j < newCellRanges.Length; j++ )
            {
              newCellRange = newCellRanges[ j ];

              m_list.Insert( i + j, new SelectionCellRangeWithItems(
                newCellRange.ItemRange, itemRangeWithItems.GetItems( newCellRange.ItemRange ), newCellRange.ColumnRange ) );
            }
          }
        }

        itemOffsetToRemove++;
      } while( ( itemRangeToRemoveIsEmpty ) && ( itemOffsetToRemove < itemsToRemoveCount ) );

      return removed;
    }
        public void UpdateSelectionAfterSourceDataItemReplaced(NotifyCollectionChangedEventArgs e)
        {
            Debug.Assert(e.OldItems.Count == e.NewItems.Count);
            Debug.Assert(e.OldStartingIndex == e.NewStartingIndex);

            SelectedItemsStorage selectedItemsStorage = m_owner.SelectedItemsStore;
            SelectedCellsStorage selectedCellsStorage = m_owner.SelectedCellsStore;
            int   oldItemIndex      = e.OldStartingIndex;
            IList oldItems          = e.OldItems;
            IList newItems          = e.NewItems;
            int   replacedItemCount = oldItems.Count;
            int   cellRangeCount    = selectedCellsStorage.Count;

            if (oldItemIndex >= 0)
            {
                int itemIndex = oldItemIndex;

                for (int i = 0; i < replacedItemCount; i++)
                {
                    object newItem = newItems[i];

                    if (selectedItemsStorage.Contains(itemIndex))
                    {
                        this.UnselectItems(new SelectionRangeWithItems(itemIndex, oldItems[i]));
                        this.SelectItems(new SelectionRangeWithItems(itemIndex, newItem));
                    }

                    SelectionCellRange replacedCellRange = new SelectionCellRange(
                        new SelectionRange(itemIndex), new SelectionRange(0, int.MaxValue - 1));

                    for (int j = 0; j < cellRangeCount; j++)
                    {
                        SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[j];
                        SelectionCellRange          cellRange          = cellRangeWithItems.CellRange;

                        if (!cellRange.Intersect(replacedCellRange).IsEmpty)
                        {
                            object[] items = cellRangeWithItems.ItemRangeWithItems.Items;

                            if (items != null)
                            {
                                items[cellRange.ItemRange.GetOffsetFromItemIndex(itemIndex)] = newItem;
                            }
                        }
                    }

                    itemIndex++;
                }
            }
            else
            {
                CollectionView sourceItems = m_owner.Items;

                for (int i = 0; i < replacedItemCount; i++)
                {
                    object newItem   = newItems[i];
                    int    itemIndex = sourceItems.IndexOf(newItem);

                    if (itemIndex < 0)
                    {
                        continue;
                    }

                    if (selectedItemsStorage.Contains(itemIndex))
                    {
                        this.UnselectItems(new SelectionRangeWithItems(itemIndex, oldItems[i]));
                        this.SelectItems(new SelectionRangeWithItems(itemIndex, newItem));
                    }

                    SelectionCellRange replacedCellRange = new SelectionCellRange(
                        new SelectionRange(itemIndex), new SelectionRange(0, int.MaxValue - 1));

                    for (int j = 0; j < cellRangeCount; j++)
                    {
                        SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[j];
                        SelectionCellRange          cellRange          = cellRangeWithItems.CellRange;

                        if (!cellRange.Intersect(replacedCellRange).IsEmpty)
                        {
                            object[] items = cellRangeWithItems.ItemRangeWithItems.Items;

                            if (items != null)
                            {
                                items[cellRange.ItemRange.GetOffsetFromItemIndex(itemIndex)] = newItem;
                            }
                        }
                    }
                }
            }
        }
    public SelectionCellRange Intersect( SelectionCellRange range )
    {
      SelectionCellRange cellRangeIntersection = SelectionCellRange.Empty;

      SelectionRange itemRange = range.ItemRange;
      SelectionRange itemRangeIntersection = m_itemRange.Intersect( itemRange );

      if( itemRangeIntersection.IsEmpty )
        return SelectionCellRange.Empty;

      SelectionRange columnRange = range.ColumnRange;
      SelectionRange columnRangeIntersection = m_columnRange.Intersect( columnRange );

      if( columnRangeIntersection.IsEmpty )
        return SelectionCellRange.Empty;

      return new SelectionCellRange( itemRangeIntersection, columnRangeIntersection );
    }