1 | /* This file is part of the KDE project |
2 | Copyright 2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #ifndef CALLIGRA_SHEETS_CELL_STORAGE |
21 | #define CALLIGRA_SHEETS_CELL_STORAGE |
22 | |
23 | #include <QPair> |
24 | #include <QRect> |
25 | #include <QTextDocument> |
26 | |
27 | #include "Cell.h" |
28 | #include "calligra_sheets_limits.h" |
29 | #include "PointStorage.h" |
30 | |
31 | #include "database/Database.h" |
32 | |
33 | class KoXmlWriter; |
34 | |
35 | class KUndo2Command; |
36 | |
37 | namespace Calligra |
38 | { |
39 | namespace Sheets |
40 | { |
41 | class Binding; |
42 | class BindingStorage; |
43 | class Cell; |
44 | class ; |
45 | class Conditions; |
46 | class ConditionsStorage; |
47 | class Formula; |
48 | class FormulaStorage; |
49 | class FusionStorage; |
50 | class LinkStorage; |
51 | class Region; |
52 | class RichTextStorage; |
53 | class Sheet; |
54 | class StyleStorage; |
55 | class UserInputStorage; |
56 | class Validity; |
57 | class ValidityStorage; |
58 | class Value; |
59 | class ValueStorage; |
60 | |
61 | /** |
62 | * \ingroup Storage |
63 | * The cell storage. |
64 | * A wrapper around a couple of storages, which hold the cell data. |
65 | * Provides methods to iterate over the non-empty cells. |
66 | * Emits Damages on changes. |
67 | * Capable of recording the old data for undoing. |
68 | * |
69 | * \author Stefan Nikolaus <stefan.nikolaus@kdemail.net> |
70 | * |
71 | * \note If you fill the storage, do it row-wise. That's more performant. |
72 | */ |
73 | class CALLIGRA_SHEETS_ODF_EXPORT CellStorage : public QObject |
74 | { |
75 | Q_OBJECT |
76 | public: |
77 | enum Visiting { |
78 | Values = 0x01, |
79 | Formulas = 0x02, |
80 | = 0x04, |
81 | Links = 0x08, |
82 | Styles = 0x10, |
83 | ConditionStyles = 0x20, |
84 | Validities = 0x40, |
85 | VisitContent = 0x03, ///< just visit the cell contents: values, formulas |
86 | VisitAll = 0xFF ///< visit all: cell contents, styles, comments, ... |
87 | }; |
88 | |
89 | /** |
90 | * Constructor. |
91 | * Creates an empty storage for \p sheet. |
92 | */ |
93 | explicit CellStorage(Sheet *sheet); |
94 | |
95 | /** |
96 | * Copy constructor. |
97 | * \note Take care: does not perform a deep copy! |
98 | */ |
99 | CellStorage(const CellStorage& other); |
100 | |
101 | /** |
102 | * Copy constructor. |
103 | * Creates a CellStorage for \p sheet and copies the data from \p other. |
104 | */ |
105 | CellStorage(const CellStorage& other, Sheet* sheet); |
106 | |
107 | /** |
108 | * Destructor. |
109 | */ |
110 | ~CellStorage(); |
111 | |
112 | /** |
113 | * \return the sheet this CellStorage is for. |
114 | */ |
115 | Sheet* sheet() const; |
116 | |
117 | /** |
118 | * Removes all data at \p col , \p row . |
119 | */ |
120 | void take(int col, int row); |
121 | |
122 | /** |
123 | * \return the binding associated with the Cell at \p column , \p row . |
124 | */ |
125 | Binding binding(int column, int row) const; |
126 | void setBinding(const Region& region, const Binding& binding); |
127 | void removeBinding(const Region& region, const Binding& binding); |
128 | |
129 | /** |
130 | * \return the comment associated with the Cell at \p column , \p row . |
131 | */ |
132 | QString (int column, int row) const; |
133 | void (const Region& region, const QString& ); |
134 | |
135 | /** |
136 | * \return the conditional formattings associated with the Cell at \p column , \p row . |
137 | */ |
138 | Conditions conditions(int column, int row) const; |
139 | void setConditions(const Region& region, Conditions conditions); |
140 | |
141 | /** |
142 | * \return the database associated with the Cell at \p column , \p row . |
143 | */ |
144 | Database database(int column, int row) const; |
145 | QList< QPair<QRectF, Database> > databases(const Region& region) const; |
146 | void setDatabase(const Region& region, const Database& database); |
147 | |
148 | /** |
149 | * \return the formula associated with the Cell at \p column , \p row . |
150 | */ |
151 | Formula formula(int column, int row) const; |
152 | void setFormula(int column, int row, const Formula& formula); |
153 | |
154 | /** |
155 | * \return the hyperlink associated with the Cell at \p column , \p row . |
156 | */ |
157 | QString link(int column, int row) const; |
158 | void setLink(int column, int row, const QString& link); |
159 | |
160 | /** |
161 | * \return the named area's name associated with the Cell at \p column , \p row . |
162 | */ |
163 | QString namedArea(int column, int row) const; |
164 | QList< QPair<QRectF, QString> > namedAreas(const Region& region) const; |
165 | void setNamedArea(const Region& region, const QString& namedArea); |
166 | void emitInsertNamedArea(const Region ®ion, const QString &namedArea); |
167 | void removeNamedArea(const Region& region, const QString& namedArea); |
168 | |
169 | /** |
170 | * \return the Style associated with the Cell at \p column , \p row . |
171 | */ |
172 | Style style(int column, int row) const; |
173 | |
174 | /** |
175 | * \return the Style associated with \p rect. |
176 | */ |
177 | Style style(const QRect& rect) const; |
178 | void setStyle(const Region& region, const Style& style); |
179 | void insertSubStyle(const QRect& rect, const SharedSubStyle& subStyle); |
180 | |
181 | /** |
182 | * \return the user input associated with the Cell at \p column , \p row . |
183 | */ |
184 | QString userInput(int column, int row) const; |
185 | void setUserInput(int column, int row, const QString& input); |
186 | |
187 | /** |
188 | * \return the validity checks associated with the Cell at \p column , \p row . |
189 | */ |
190 | Validity validity(int column, int row) const; |
191 | void setValidity(const Region& region, Validity validity); |
192 | |
193 | /** |
194 | * \return the value associated with the Cell at \p column , \p row . |
195 | */ |
196 | Value value(int column, int row) const; |
197 | |
198 | /** |
199 | * Creates a value array containing the values in \p region. |
200 | */ |
201 | Value valueRegion(const Region& region) const; |
202 | void setValue(int column, int row, const Value& value); |
203 | |
204 | QSharedPointer<QTextDocument> richText(int column, int row) const; |
205 | void setRichText(int column, int row, QSharedPointer<QTextDocument> text); |
206 | |
207 | /** |
208 | */ |
209 | bool doesMergeCells(int column, int row) const; |
210 | bool isPartOfMerged(int column, int row) const; |
211 | |
212 | /** |
213 | * Merge the cell at \p column, \p row with the \p numXCells adjacent cells in horizontal |
214 | * direction and with the \p numYCells adjacent cells in vertical direction. I.e. the |
215 | * resulting cell spans \p numXCells + 1 columns and \p numYCells + 1 rows. Passing \c 0 |
216 | * as \p numXCells and \p numYCells unmerges the cell at \p column, \p row. |
217 | * |
218 | * \param column the master cell's column |
219 | * \param row the master cell's row |
220 | * \param numXCells number of horizontal cells to be merged in |
221 | * \param numYCells number of vertical cells to be merged in |
222 | * |
223 | */ |
224 | void mergeCells(int column, int row, int numXCells, int numYCells); |
225 | Cell masterCell(int column, int row) const; |
226 | int mergedXCells(int column, int row) const; |
227 | int mergedYCells(int column, int row) const; |
228 | QList<Cell> masterCells(const Region& region) const; |
229 | |
230 | /** |
231 | * \return \c true, if the cell's value is a matrix and obscures other cells |
232 | */ |
233 | bool locksCells(int column, int row) const; |
234 | bool isLocked(int column, int row) const; |
235 | bool hasLockedCells(const Region& region) const; |
236 | void lockCells(const QRect& rect); |
237 | void unlockCells(int column, int row); |
238 | QRect lockedCells(int column, int row) const; |
239 | |
240 | /** |
241 | * Insert \p number columns at \p position . |
242 | * \return the data, that became out of range (shifted over the end) |
243 | */ |
244 | void insertColumns(int position, int number = 1); |
245 | |
246 | /** |
247 | * Removes \p number columns at \p position . |
248 | * \return the removed data |
249 | */ |
250 | void removeColumns(int position, int number = 1); |
251 | |
252 | /** |
253 | * Insert \p number rows at \p position . |
254 | * \return the data, that became out of range (shifted over the end) |
255 | */ |
256 | void insertRows(int position, int number = 1); |
257 | |
258 | /** |
259 | * Removes \p number rows at \p position . |
260 | * \return the removed data |
261 | */ |
262 | void removeRows(int position, int number = 1); |
263 | |
264 | /** |
265 | * Shifts the data right of \p rect to the left by the width of \p rect . |
266 | * The data formerly contained in \p rect becomes overridden. |
267 | */ |
268 | void removeShiftLeft(const QRect& rect); |
269 | |
270 | /** |
271 | * Shifts the data in and right of \p rect to the right by the width of \p rect . |
272 | */ |
273 | void insertShiftRight(const QRect& rect); |
274 | |
275 | /** |
276 | * Shifts the data below \p rect to the top by the height of \p rect . |
277 | * The data formerly contained in \p rect becomes overridden. |
278 | */ |
279 | void removeShiftUp(const QRect& rect); |
280 | |
281 | /** |
282 | * Shifts the data in and below \p rect to the bottom by the height of \p rect . |
283 | */ |
284 | void insertShiftDown(const QRect& rect); |
285 | |
286 | /** |
287 | * Retrieve the first used data in \p col . |
288 | * Can be used in conjunction with nextInColumn() to loop through a column. |
289 | * \return the first used data in \p col or the default data, if the column is empty. |
290 | */ |
291 | Cell firstInColumn(int col, Visiting visiting = VisitAll) const; |
292 | |
293 | /** |
294 | * Retrieve the first used data in \p row . |
295 | * Can be used in conjunction with nextInRow() to loop through a row. |
296 | * \return the first used data in \p row or the default data, if the row is empty. |
297 | */ |
298 | Cell firstInRow(int row, Visiting visiting = VisitAll) const; |
299 | |
300 | /** |
301 | * Retrieve the last used data in \p col . |
302 | * Can be used in conjunction with prevInColumn() to loop through a column. |
303 | * \return the last used data in \p col or the default data, if the column is empty. |
304 | */ |
305 | Cell lastInColumn(int col, Visiting visiting = VisitAll) const; |
306 | |
307 | /** |
308 | * Retrieve the last used data in \p row . |
309 | * Can be used in conjunction with prevInRow() to loop through a row. |
310 | * \return the last used data in \p row or the default data, if the row is empty. |
311 | */ |
312 | Cell lastInRow(int row, Visiting visiting = VisitAll) const; |
313 | |
314 | /** |
315 | * Retrieve the next used data in \p col after \p row . |
316 | * Can be used in conjunction with firstInColumn() to loop through a column. |
317 | * \return the next used data in \p col or the default data, there is no further data. |
318 | */ |
319 | Cell nextInColumn(int col, int row, Visiting visiting = VisitAll) const; |
320 | |
321 | /** |
322 | * Retrieve the next used data in \p row after \p col . |
323 | * Can be used in conjunction with firstInRow() to loop through a row. |
324 | * \return the next used data in \p row or the default data, if there is no further data. |
325 | */ |
326 | Cell nextInRow(int col, int row, Visiting visiting = VisitAll) const; |
327 | |
328 | /** |
329 | * Retrieve the previous used data in \p col after \p row . |
330 | * Can be used in conjunction with lastInColumn() to loop through a column. |
331 | * \return the previous used data in \p col or the default data, there is no further data. |
332 | */ |
333 | Cell prevInColumn(int col, int row, Visiting visiting = VisitAll) const; |
334 | |
335 | /** |
336 | * Retrieve the previous used data in \p row after \p col . |
337 | * Can be used in conjunction with lastInRow() to loop through a row. |
338 | * \return the previous used data in \p row or the default data, if there is no further data. |
339 | */ |
340 | Cell prevInRow(int col, int row, Visiting visiting = VisitAll) const; |
341 | |
342 | /** |
343 | * The maximum occupied column, i.e. the horizontal storage dimension. |
344 | * \return the maximum column |
345 | */ |
346 | int columns(bool includeStyles = true) const; |
347 | |
348 | /** |
349 | * The maximum occupied row, i.e. the vertical storage dimension. |
350 | * \return the maximum row |
351 | */ |
352 | int rows(bool includeStyles = true) const; |
353 | |
354 | /** |
355 | * The number of rows that are consecutive to, and identical to \p row. This includes the row |
356 | * itself. |
357 | */ |
358 | int rowRepeat(int row) const; |
359 | |
360 | /** |
361 | * The first row in the block of consecutive identical rows \p row is in. |
362 | */ |
363 | int firstIdenticalRow(int row) const; |
364 | |
365 | /** |
366 | * Set how often the specified row is repeated. \p row is the index of the first row in a block, |
367 | * \p count is the number of times it is repeated (including the first one). This method is used |
368 | * during loading. |
369 | */ |
370 | void setRowsRepeated(int row, int count); |
371 | |
372 | /** |
373 | * Creates a substorage consisting of the values in \p region. |
374 | * \return a subset of the storage stripped down to the values in \p region |
375 | */ |
376 | CellStorage subStorage(const Region& region) const; |
377 | |
378 | const BindingStorage* bindingStorage() const; |
379 | const CommentStorage* () const; |
380 | const ConditionsStorage* conditionsStorage() const; |
381 | const FormulaStorage* formulaStorage() const; |
382 | const FusionStorage* fusionStorage() const; |
383 | const LinkStorage* linkStorage() const; |
384 | const StyleStorage* styleStorage() const; |
385 | const UserInputStorage* userInputStorage() const; |
386 | const ValidityStorage* validityStorage() const; |
387 | const ValueStorage* valueStorage() const; |
388 | |
389 | void loadConditions(const QList<QPair<QRegion, Conditions> >& conditions); |
390 | void loadStyles(const QList<QPair<QRegion, Style> >& styles); |
391 | |
392 | void invalidateStyleCache(); |
393 | |
394 | /** |
395 | * Starts the undo recording. |
396 | * While recording the undo data of each storage operation is saved in |
397 | * an undo command, that can be retrieved when the recording is stopped. |
398 | * \see stopUndoRecording |
399 | */ |
400 | void startUndoRecording(); |
401 | |
402 | /** |
403 | * Stops the undo recording. |
404 | * An undo command has to be passed as \p parent command and |
405 | * for each sub-storage an undo-capable command is attached to \p parent. |
406 | * \see startUndoRecording |
407 | */ |
408 | void stopUndoRecording(KUndo2Command *parent); |
409 | |
410 | Q_SIGNALS: |
411 | void insertNamedArea(const Region&, const QString&); |
412 | void namedAreaRemoved(const QString&); |
413 | |
414 | private: |
415 | // do not allow assignment |
416 | CellStorage& operator=(const CellStorage&); |
417 | |
418 | class Private; |
419 | Private * const d; |
420 | }; |
421 | |
422 | class UserInputStorage : public PointStorage<QString> |
423 | { |
424 | public: |
425 | UserInputStorage& operator=(const PointStorage<QString>& o) { |
426 | PointStorage<QString>::operator=(o); |
427 | return *this; |
428 | } |
429 | }; |
430 | |
431 | class LinkStorage : public PointStorage<QString> |
432 | { |
433 | public: |
434 | LinkStorage& operator=(const PointStorage<QString>& o) { |
435 | PointStorage<QString>::operator=(o); |
436 | return *this; |
437 | } |
438 | }; |
439 | |
440 | class RichTextStorage : public PointStorage<QSharedPointer<QTextDocument> > |
441 | { |
442 | public: |
443 | RichTextStorage& operator=(const PointStorage<QSharedPointer<QTextDocument> >& o) { |
444 | PointStorage<QSharedPointer<QTextDocument> >::operator=(o); |
445 | return *this; |
446 | } |
447 | }; |
448 | |
449 | } // namespace Sheets |
450 | } // namespace Calligra |
451 | |
452 | #endif // CALLIGRA_SHEETS_CELL_STORAGE |
453 | |