Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Breadcrumbs/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/3.1.3/EPPlus-3.1.3/RangeCollection.cs @ 11571

Last change on this file since 11571 was 9580, checked in by sforsten, 12 years ago

#1730:

  • added SymbolicDataAnalysisExpressionExcelFormatter
  • changed modifiers in SymbolicExpressionTreeChart of methods SaveImageAsBitmap and SaveImageAsEmf to public
  • added menu item ExportSymbolicSolutionToExcelMenuItem to export a symbolic solution to an excel file
  • added EPPlus-3.1.3 to ExtLibs
File size: 10.6 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 * ******************************************************************************
29 * Jan Källman        Added                   2010-02-04
30 * Jan Källman        License changed GPL-->LGPL  2011-12-27
31 *******************************************************************************/
32using System;
33using System.Collections.Generic;
34using System.Text;
35using System.Collections;
36using OfficeOpenXml.Drawing.Vml;
37namespace OfficeOpenXml
38{
39    /// <summary>
40    /// This is the store for all Rows, Columns and Cells.
41    /// It is a Dictionary implementation that allows you to change the Key (the RowID, ColumnID or CellID )
42    /// </summary>
43    internal class RangeCollection : IEnumerator<IRangeID>, IEnumerable
44    {
45        private class IndexItem
46        {
47            internal IndexItem(ulong cellId)
48            {
49                RangeID = cellId;
50            }
51            internal IndexItem(ulong cellId, int listPointer)
52          {
53                RangeID = cellId;
54                ListPointer=listPointer;
55          }
56            internal ulong RangeID;
57            internal int ListPointer;
58        }
59        /// <summary>
60        /// Compares an IndexItem
61        /// </summary>
62        internal class Compare : IComparer<IndexItem>
63        {
64            #region IComparer<IndexItem> Members
65            int IComparer<IndexItem>.Compare(IndexItem x, IndexItem y)
66            {
67                return x.RangeID < y.RangeID ? -1 : x.RangeID > y.RangeID ? 1 : 0;
68            }
69
70            #endregion
71        }
72        IndexItem[] _cellIndex;
73        List<IRangeID> _cells;
74        Compare _comparer;
75        /// <summary>
76        /// Creates a new collection
77        /// </summary>
78        /// <param name="cells">The Cells. This list must be sorted</param>
79        internal RangeCollection(List<IRangeID> cells)
80        {   
81            _cells = cells;
82            _comparer = new Compare();
83            InitSize(_cells);
84            for (int i = 0; i < _cells.Count; i++)
85            {
86                _cellIndex[i] = new IndexItem(cells[i].RangeID, i);
87            }
88        }
89        ~RangeCollection()
90        {
91            _cellIndex = null;
92            _cells = null;
93        }
94        /// <summary>
95        /// Return the item with the RangeID
96        /// </summary>
97        /// <param name="RangeID"></param>
98        /// <returns></returns>
99        internal IRangeID this[ulong RangeID]
100        {
101            get
102            {
103                return _cells[_cellIndex[IndexOf(RangeID)].ListPointer];
104            }
105        }
106        /// <summary>
107        /// Return specified index from the sorted list
108        /// </summary>
109        /// <param name="Index"></param>
110        /// <returns></returns>
111        internal IRangeID this[int Index]
112        {
113            get
114            {
115                return _cells[_cellIndex[Index].ListPointer];
116            }
117        }
118        internal int Count
119        {
120            get
121            {
122                return _cells.Count;
123            }
124        }
125        internal void Add(IRangeID cell)
126        {
127            var ix = IndexOf(cell.RangeID);
128            if (ix >= 0)
129            {
130                throw (new Exception("Item already exists"));
131            }
132            Insert(~ix, cell);
133        }
134        internal void Delete(ulong key)
135        {
136            var ix = IndexOf(key);
137            if (ix < 0)
138            {
139                throw (new Exception("Key does not exists"));
140            }
141            int listPointer = _cellIndex[ix].ListPointer;
142            Array.Copy(_cellIndex, ix + 1, _cellIndex, ix, _cells.Count - ix - 1);
143            _cells.RemoveAt(listPointer);
144
145            //Item is removed subtract one from all items with greater ListPointer
146            for (int i = 0; i < _cells.Count; i++)
147            {
148                if (_cellIndex[i].ListPointer >= listPointer)
149                {
150                    _cellIndex[i].ListPointer--;
151                }
152
153            }
154        }
155        internal int IndexOf(ulong key)
156        {
157            return Array.BinarySearch<IndexItem>(_cellIndex, 0, _cells.Count, new IndexItem(key), _comparer);
158        }
159        internal bool ContainsKey(ulong key)
160        {
161            return IndexOf(key) < 0 ? false : true;
162        }
163        int _size { get; set; }
164        #region "RangeID manipulation methods"
165        /// <summary>
166        /// Insert a number of rows in the collecion but dont update the cell only the index
167        /// </summary>
168        /// <param name="rowID"></param>
169        /// <param name="rows"></param>
170        /// <returns>Index of first rangeItem</returns>
171        internal int InsertRowsUpdateIndex(ulong rowID, int rows)
172        {
173            int index = IndexOf(rowID);
174            if (index < 0) index = ~index; //No match found invert to get start cell
175            ulong rowAdd = (((ulong)rows) << 29);
176            for (int i = index; i < _cells.Count; i++)
177            {
178                _cellIndex[i].RangeID += rowAdd;
179            }
180            return index;
181        }
182        /// <summary>
183        /// Insert a number of rows in the collecion
184        /// </summary>
185        /// <param name="rowID"></param>
186        /// <param name="rows"></param>
187        /// <returns>Index of first rangeItem</returns>
188        internal int InsertRows(ulong rowID, int rows)
189        {
190            int index = IndexOf(rowID);
191            if (index < 0) index = ~index; //No match found invert to get start cell
192            ulong rowAdd=(((ulong)rows) << 29);
193            for (int i = index; i < _cells.Count; i++)
194            {
195                _cellIndex[i].RangeID += rowAdd;
196                _cells[_cellIndex[i].ListPointer].RangeID += rowAdd;
197            }
198            return index;
199        }
200        /// <summary>
201        /// Delete rows from the collecion
202        /// </summary>
203        /// <param name="rowID"></param>
204        /// <param name="rows"></param>
205        /// <param name="updateCells">Update range id's on cells</param>
206        internal int DeleteRows(ulong rowID, int rows, bool updateCells)
207        {
208            ulong rowAdd = (((ulong)rows) << 29);
209            var index = IndexOf(rowID);
210            if (index < 0) index = ~index; //No match found invert to get start cell
211
212            if (index >= _cells.Count || _cellIndex[index] == null) return -1;   //No row above this row
213            while (index < _cells.Count && _cellIndex[index].RangeID < rowID + rowAdd)
214            {
215                Delete(_cellIndex[index].RangeID);
216            }
217
218            int updIndex = IndexOf(rowID + rowAdd);
219            if (updIndex < 0) updIndex = ~updIndex; //No match found invert to get start cell
220
221            for (int i = updIndex; i < _cells.Count; i++)
222            {
223                _cellIndex[i].RangeID -= rowAdd;                        //Change the index
224                if (updateCells) _cells[_cellIndex[i].ListPointer].RangeID -= rowAdd;    //Change the cell/row or column object
225            }
226            return index;
227        }
228        internal void InsertColumn(ulong ColumnID, int columns)
229        {
230            throw (new Exception("Working on it..."));
231        }
232        internal void DeleteColumn(ulong ColumnID,int columns)
233        {
234            throw (new Exception("Working on it..."));
235        }
236        #endregion
237        #region "Private Methods"
238        /// <summary>
239        /// Init the size starting from 128 items. Double the size until the list fits.
240        /// </summary>
241        /// <param name="_cells"></param>
242        private void InitSize(List<IRangeID> _cells)
243        {
244            _size = 128;
245            while (_cells.Count > _size) _size <<= 1;
246            _cellIndex = new IndexItem[_size];
247        }
248        /// <summary>
249        /// Check the size and double the size if out of bound
250        /// </summary>
251        private void CheckSize()
252        {
253            if (_cells.Count >= _size)
254            {
255                _size <<= 1;
256                Array.Resize(ref _cellIndex, _size);
257            }
258        }
259        private void Insert(int ix, IRangeID cell)
260        {
261            CheckSize();
262            Array.Copy(_cellIndex, ix, _cellIndex, ix + 1, _cells.Count - ix);
263            _cellIndex[ix] = new IndexItem(cell.RangeID, _cells.Count);
264            _cells.Add(cell);
265        }
266        #endregion
267
268        #region IEnumerator<IRangeID> Members
269
270        IRangeID IEnumerator<IRangeID>.Current
271        {
272            get { throw new NotImplementedException(); }
273        }
274
275        #endregion
276
277        #region IDisposable for the enumerator Members
278
279        void IDisposable.Dispose()
280        {
281            _ix = -1;
282        }
283
284        #endregion
285
286        #region IEnumerator Members
287        int _ix = -1;
288        object IEnumerator.Current
289        {
290            get
291            {
292                return _cells[_cellIndex[_ix].ListPointer];
293            }
294        }
295
296        bool IEnumerator.MoveNext()
297        {
298           _ix++;
299           return _ix < _cells.Count;
300        }
301
302        void IEnumerator.Reset()
303        {
304            _ix = -1;
305        }
306
307        #endregion
308
309        #region IEnumerable Members
310
311        IEnumerator IEnumerable.GetEnumerator()
312        {
313            return this;
314        }
315
316        #endregion
317    }
318}
Note: See TracBrowser for help on using the repository browser.