Пример #1
0
        public bool Contains(SelectionCellRangeWithItems rangeWithItems)
        {
            if ((m_unsortedRanges.Count <= 0) || (SelectedCellsStorage.IsEmpty(rangeWithItems)))
            {
                return(false);
            }

            if (rangeWithItems.Length == 1)
            {
                return(this.IndexOfOverlap(rangeWithItems).Any());
            }

            var store = new SelectedCellsStorage(null);

            store.Add(rangeWithItems);

            foreach (var match in this.IndexOfOverlap(rangeWithItems))
            {
                store.Remove(m_unsortedRanges[match].Value);

                if (store.Count == 0)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        private void RemoveAt(int index, bool repairIndex)
        {
            var wrapper        = m_ranges[index];
            var rangeWithItems = wrapper.Value;

            Debug.Assert(wrapper.Index == index);

            if (!SelectedCellsStorage.IsEmpty(rangeWithItems))
            {
                var removed = m_map.Remove(SelectedCellsStorage.GetArea(rangeWithItems), wrapper);
                Debug.Assert(removed, "Failed to remove the selection range.");

                // Since there should be only a single instance of the wrapper within the collection, try an altenate strategy.
                if (!removed)
                {
                    var entry = m_map.FirstOrDefault(e => e.Item == wrapper);
                    if (entry.Item == wrapper)
                    {
                        removed = m_map.Remove(entry);
                    }

                    Debug.Assert(removed, "Failed to find the selection range.");
                }
            }

            m_ranges.RemoveAt(index);

            if (repairIndex)
            {
                this.RepairIndex(index);
            }
        }
Пример #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)));
        }
Пример #4
0
        public bool Remove(SelectionCellRangeWithItems rangeWithItems)
        {
            if (SelectedCellsStorage.IsEmpty(rangeWithItems))
            {
                return(true);
            }

            // It improves performance to leave early and prevent empty enumerators creation.
            if (m_ranges.Count <= 0)
            {
                return(false);
            }

            // The SelectionCellRange.IsEmpty should be mapped to the item range's SelectionRange.IsEmpty property.
            Debug.Assert(!rangeWithItems.ItemRange.IsEmpty);

            var matches       = this.IndexOfOverlap(rangeWithItems).OrderBy(index => index).ToList();
            var rangeToRemove = rangeWithItems.CellRange;

            for (int i = matches.Count - 1; i >= 0; i--)
            {
                var index = matches[i];
                var currentRangeWithItems = m_ranges[index].Value;
                var currentRange          = currentRangeWithItems.CellRange;
                var overlap = rangeToRemove.Intersect(currentRange);

                Debug.Assert(!overlap.IsEmpty);

                var newRanges = currentRange.Exclude(overlap);

                if (newRanges.Length == 0)
                {
                    this.RemoveAt(index, true);
                }
                else
                {
                    var currentRangeItems = currentRangeWithItems.ItemRangeWithItems;

                    this[index] = new SelectionCellRangeWithItems(newRanges[0].ItemRange, currentRangeItems.GetItems(newRanges[0].ItemRange), newRanges[0].ColumnRange);

                    if (newRanges.Length > 1)
                    {
                        for (int j = 1; j < newRanges.Length; j++)
                        {
                            this.Insert(index + j, new SelectionCellRangeWithItems(newRanges[j].ItemRange, currentRangeItems.GetItems(newRanges[j].ItemRange), newRanges[j].ColumnRange), false);
                        }

                        this.RepairIndex(index + 1);
                    }
                }
            }

            return(matches.Count > 0);
        }
Пример #5
0
            internal ItemComparer(SelectionCellRangeWithItemsWrapper target)
            {
                if (target == null)
                {
                    throw new ArgumentNullException("target");
                }

                if (SelectedCellsStorage.IsEmpty(target.Value))
                {
                    throw new ArgumentException("The selection range must not be empty.", "target");
                }

                m_target = target;
            }
Пример #6
0
        private void Insert(int index, SelectionCellRangeWithItems item, bool repairIndex)
        {
            var wrapper = new SelectionCellRangeWithItemsWrapper(item, index);

            m_ranges.Insert(index, wrapper);

            if (repairIndex)
            {
                this.RepairIndex(index + 1);
            }

            if (!SelectedCellsStorage.IsEmpty(item))
            {
                m_map.Add(SelectedCellsStorage.GetArea(item), wrapper);
            }
        }
Пример #7
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);
                }
            }
        }
Пример #8
0
        private void Insert(int index, SelectionCellRangeWithItems item, bool repairIndex)
        {
            var wrapper = new SelectionCellRangeWithItemsWrapper(item, index);

            m_unsortedRanges.Insert(index, wrapper);

            if (repairIndex)
            {
                this.RepairIndex(index + 1);
            }

            if (!SelectedCellsStorage.IsEmpty(item))
            {
                var insertionIndex = ~this.FindIndex(new ItemComparer(wrapper));
                Debug.Assert(insertionIndex >= 0);

                m_sortedRanges.Insert(insertionIndex, wrapper);
            }
        }
Пример #9
0
        private void RemoveAt(int index, bool repairIndex)
        {
            var wrapper = m_unsortedRanges[index];

            Debug.Assert(wrapper.Index == index);

            if (!SelectedCellsStorage.IsEmpty(wrapper.Value))
            {
                var removalIndex = this.FindIndex(new ItemComparer(wrapper));
                Debug.Assert(removalIndex >= 0);

                m_sortedRanges.RemoveAt(removalIndex);
            }

            m_unsortedRanges.RemoveAt(index);

            if (repairIndex)
            {
                this.RepairIndex(index);
            }
        }
Пример #10
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);
                }
            }
        }