KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
9.5KB

  1. /* This file is part of the KDE project
  2. Copyright (C) 2000 Torben Weis <weis@kde.org>
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public License
  12. along with this library; see the file COPYING.LIB. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  14. * Boston, MA 02110-1301, USA.
  15. */
  16. #ifndef kspread_cluster_h
  17. #define kspread_cluster_h
  18. #include "kspread_value.h"
  19. #define KSPREAD_CLUSTER_LEVEL1 128
  20. #define KSPREAD_CLUSTER_LEVEL2 256
  21. #define KSPREAD_CLUSTER_MAX (128*256)
  22. class TQPoint;
  23. namespace KSpread
  24. {
  25. class Cell;
  26. class ColumnFormat;
  27. class RowFormat;
  28. /** Philipp
  29. This class defines a pointer map to all cells, which makes access to them more performant
  30. and additionally limits memory consumption.
  31. In detail: The class defines 2 cluster, where the second cluster (LEVEL2) is a matrix for
  32. single cells, while the first cluster (LEVEL1) is a matrix to handle the matrices of LEVEL2.
  33. On initialization, one LEVEL1 matrix is generated only.
  34. Each time, a cell stores something, this class checks if for the given column and row a
  35. matrix of LEVEL2 is already initialized and in case not generates it on the fly.
  36. This helps to reduce the memory usage to only consum one pointer matrix for LEVEL1 and all
  37. matrices of LEVEL2 that are necessary.
  38. LEVEL1 is defined as 128x128 matrix.
  39. LEVEL2 is defined as 256x256 matrices.
  40. Each direction then can have LEVEL1 * LEVEL2 = 128*256 = 2^15 different cells, which
  41. is in total (2^15)^2 cells.
  42. It can be changed easily to different sizes, but it should be more senseful to have a small LEVEL1,
  43. as in most cases only one/two entries in LEVEL1 will be used.
  44. There are 2 additional special classes to store pointers for column and row formats.
  45. Future enhancements:
  46. To reduce memory consumption, it should be possible to enhance the functionality by
  47. another LEVEL0, which then keeps the LEVEL1 size smaller.
  48. Maybe the LEVEL1 should only be generated when there is a need for more than 1 LEVEL2.
  49. LEVEL1 maybe reallocated.
  50. Another interesting possibility would be to differentiate between x size and y size. Currently both
  51. are equal in both matrizes, but normally it will be the regular case, that you have more need for
  52. a lot of rows than columns. Maybe something like LEVEL1=128/256 and LEVEL2=256/128 (x/y), still keeping
  53. 2^15 values/cells in each direction (benefit: you won't loose memory in empty columns).
  54. */
  55. class Cluster
  56. {
  57. public:
  58. Cluster();
  59. ~Cluster();
  60. Cell* lookup( int x, int y ) const;
  61. /**
  62. * Removes all cells from the sheet and frees memory that
  63. * was used for the clusters.
  64. */
  65. void clear();
  66. /**
  67. * Inserts a cell at the requested position. If there is already
  68. * a cell, then @ref #remove is called on it.
  69. */
  70. void insert( Cell* cell, int x, int y );
  71. /**
  72. * Removes the cell at the given position, if there is any.
  73. */
  74. void remove( int x, int y );
  75. void setAutoDelete( bool );
  76. bool autoDelete() const;
  77. Cell* firstCell() const;
  78. bool shiftRow( const TQPoint& marker );
  79. /**
  80. * Moves all cells in the column marker.x() beginning with
  81. * the one at marker.y() one position downwards.
  82. *
  83. * @return false if a cell would drop out of the sheet because of that.
  84. * In this case the shift is not performed.
  85. */
  86. bool shiftColumn( const TQPoint& marker );
  87. /**
  88. * Moves all cells in the column marker.x() beginning with
  89. * the one at marker.y() + 1 one position upwards.
  90. */
  91. void unshiftColumn( const TQPoint& marker );
  92. void unshiftRow( const TQPoint& marker );
  93. /**
  94. * Moves all columns beginning with @p col one position
  95. * to the right. If that does not work because a cell would
  96. * drop out of the sheet, then false is returned.
  97. *
  98. * @see #removeColumn
  99. */
  100. bool insertColumn( int col );
  101. bool insertRow( int row );
  102. /**
  103. * Removes all elements from the column and
  104. * move all columns right of @p col one position
  105. * to the left.
  106. *
  107. * @see #clearColumn
  108. */
  109. void removeColumn( int col );
  110. void removeRow( int row );
  111. /**
  112. * Removes all elements from the column.
  113. *
  114. */
  115. void clearColumn( int col );
  116. void clearRow( int row );
  117. /** Retrieve a range of values stored in a Value.
  118. The range is two-leveled with similar structure and reasoning as the
  119. storage of cells themselves.
  120. */
  121. Value valueRange (int col1, int row1, int col2, int row2) const;
  122. /**
  123. * Retrieve the first used cell in a given column. Can be used in conjunction
  124. * with getNextCellDown to loop through a column.
  125. *
  126. * @param col The column to get the first cell from
  127. *
  128. * @return Returns a pointer to the cell, or NULL if there are no used cells
  129. * in this column
  130. */
  131. Cell* getFirstCellColumn(int col) const;
  132. /**
  133. * Retrieve the last used cell in a given column. Can be used in conjunction
  134. * with getNextCellUp to loop through a column.
  135. *
  136. * @param col The column to get the cell from
  137. *
  138. * @return Returns a pointer to the cell, or NULL if there are no used cells
  139. * in this column
  140. */
  141. Cell* getLastCellColumn(int col) const;
  142. /**
  143. * Retrieve the first used cell in a given row. Can be used in conjunction
  144. * with getNextCellRight to loop through a row.
  145. *
  146. * @param row The row to get the first cell from
  147. *
  148. * @return Returns a pointer to the cell, or NULL if there are no used cells
  149. * in this row
  150. */
  151. Cell* getFirstCellRow(int row) const;
  152. /**
  153. * Retrieve the last used cell in a given row. Can be used in conjunction
  154. * with getNextCellLeft to loop through a row.
  155. *
  156. * @param row The row to get the last cell from
  157. *
  158. * @return Returns a pointer to the cell, or NULL if there are no used cells
  159. * in this row
  160. */
  161. Cell* getLastCellRow(int row) const;
  162. /**
  163. * Retrieves the next used cell above the given col/row pair. The given
  164. * col/row pair does not need to reference a used cell.
  165. *
  166. * @param col column to start looking through
  167. * @param row the row above which to start looking.
  168. *
  169. * @return Returns the next used cell above this one, or NULL if there are none
  170. */
  171. Cell* getNextCellUp(int col, int row) const;
  172. /**
  173. * Retrieves the next used cell below the given col/row pair. The given
  174. * col/row pair does not need to reference a used cell.
  175. *
  176. * @param col column to start looking through
  177. * @param row the row below which to start looking.
  178. *
  179. * @return Returns the next used cell below this one, or NULL if there are none
  180. */
  181. Cell* getNextCellDown(int col, int row) const;
  182. /**
  183. * Retrieves the next used cell to the right of the given col/row pair.
  184. * The given col/row pair does not need to reference a used cell.
  185. *
  186. * @param col the column after which should be searched
  187. * @param row the row to search through
  188. *
  189. * @return Returns the next used cell to the right of this one, or NULL if
  190. * there are none
  191. */
  192. Cell* getNextCellRight(int col, int row) const;
  193. /**
  194. * Retrieves the next used cell to the left of the given col/row pair.
  195. * The given col/row pair does not need to reference a used cell.
  196. *
  197. * @param col the column before which should be searched
  198. * @param row the row to search through
  199. *
  200. * @return Returns the next used cell to the left of this one, or NULL if
  201. * there are none
  202. */
  203. Cell* getNextCellLeft(int col, int row) const;
  204. private:
  205. /**
  206. * @param work is set to true if the method found some clusters
  207. * which belong to the shifted row.
  208. */
  209. bool shiftRow( const TQPoint& marker, bool& work );
  210. bool shiftColumn( const TQPoint& marker, bool& work );
  211. void unshiftColumn( const TQPoint& marker, bool& work );
  212. void unshiftRow( const TQPoint& marker, bool& work );
  213. /** helper method used by valueRange */
  214. Value makeArray (int col1, int row1, int col2, int row2) const;
  215. Cell*** m_cluster;
  216. Cell* m_first;
  217. bool m_autoDelete;
  218. int m_biggestX, m_biggestY;
  219. };
  220. class ColumnCluster
  221. {
  222. public:
  223. ColumnCluster();
  224. ~ColumnCluster();
  225. const ColumnFormat* lookup( int col ) const;
  226. ColumnFormat* lookup( int col );
  227. void clear();
  228. void insertElement( ColumnFormat*, int col );
  229. void removeElement( int col );
  230. bool insertColumn( int col );
  231. bool removeColumn( int col );
  232. void setAutoDelete( bool );
  233. bool autoDelete() const;
  234. ColumnFormat* first() const { return m_first; }
  235. ColumnFormat* next( int col ) const;
  236. private:
  237. ColumnFormat*** m_cluster;
  238. ColumnFormat* m_first;
  239. bool m_autoDelete;
  240. };
  241. class RowCluster
  242. {
  243. public:
  244. RowCluster();
  245. ~RowCluster();
  246. const RowFormat* lookup( int col ) const;
  247. RowFormat* lookup( int col );
  248. void clear();
  249. void insertElement( RowFormat*, int row );
  250. void removeElement( int row );
  251. bool insertRow( int row );
  252. bool removeRow( int row );
  253. void setAutoDelete( bool );
  254. bool autoDelete() const;
  255. RowFormat* first()const { return m_first; }
  256. private:
  257. RowFormat*** m_cluster;
  258. RowFormat* m_first;
  259. bool m_autoDelete;
  260. };
  261. } // namespace KSpread;
  262. #endif