File: CellStorage.h

package info (click to toggle)
calligra 1%3A3.2.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 260,432 kB
  • sloc: cpp: 650,911; xml: 27,662; python: 6,044; perl: 2,724; yacc: 1,817; ansic: 1,325; sh: 1,277; lex: 1,107; ruby: 1,010; javascript: 495; makefile: 24
file content (450 lines) | stat: -rw-r--r-- 14,916 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
/* This file is part of the KDE project
   Copyright 2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef CALLIGRA_SHEETS_CELL_STORAGE
#define CALLIGRA_SHEETS_CELL_STORAGE

#include <QPair>
#include <QRect>
#include <QTextDocument>

#include "Cell.h"
#include "calligra_sheets_limits.h"
#include "PointStorage.h"

#include "database/Database.h"

class KUndo2Command;

namespace Calligra
{
namespace Sheets
{
class Binding;
class BindingStorage;
class Cell;
class CommentStorage;
class Conditions;
class ConditionsStorage;
class Formula;
class FormulaStorage;
class FusionStorage;
class LinkStorage;
class Region;
class RichTextStorage;
class Sheet;
class StyleStorage;
class UserInputStorage;
class Validity;
class ValidityStorage;
class Value;
class ValueStorage;

/**
 * \ingroup Storage
 * The cell storage.
 * A wrapper around a couple of storages, which hold the cell data.
 * Provides methods to iterate over the non-empty cells.
 * Emits Damages on changes.
 * Capable of recording the old data for undoing.
 *
 * \author Stefan Nikolaus <stefan.nikolaus@kdemail.net>
 *
 * \note If you fill the storage, do it row-wise. That's more performant.
 */
class CALLIGRA_SHEETS_ODF_EXPORT CellStorage : public QObject
{
    Q_OBJECT
public:
    enum Visiting {
        Values          = 0x01,
        Formulas        = 0x02,
        Comments        = 0x04,
        Links           = 0x08,
        Styles          = 0x10,
        ConditionStyles = 0x20,
        Validities      = 0x40,
        VisitContent    = 0x03, ///< just visit the cell contents: values, formulas
        VisitAll        = 0xFF  ///< visit all: cell contents, styles, comments, ...
    };

    /**
     * Constructor.
     * Creates an empty storage for \p sheet.
     */
    explicit CellStorage(Sheet *sheet);

    /**
     * Copy constructor.
     * \note Take care: does not perform a deep copy!
     */
    CellStorage(const CellStorage& other);

    /**
     * Copy constructor.
     * Creates a CellStorage for \p sheet and copies the data from \p other.
     */
    CellStorage(const CellStorage& other, Sheet* sheet);

    /**
     * Destructor.
     */
    ~CellStorage() override;

    /**
     * \return the sheet this CellStorage is for.
     */
    Sheet* sheet() const;

    /**
     * Removes all data at \p col , \p row .
     */
    void take(int col, int row);

    /**
     * \return the binding associated with the Cell at \p column , \p row .
     */
    Binding binding(int column, int row) const;
    void setBinding(const Region& region, const Binding& binding);
    void removeBinding(const Region& region, const Binding& binding);

    /**
     * \return the comment associated with the Cell at \p column , \p row .
     */
    QString comment(int column, int row) const;
    void setComment(const Region& region, const QString& comment);

    /**
     * \return the conditional formattings associated with the Cell at \p column , \p row .
     */
    Conditions conditions(int column, int row) const;
    void setConditions(const Region& region, Conditions conditions);

    /**
     * \return the database associated with the Cell at \p column , \p row .
     */
    Database database(int column, int row) const;
    QList< QPair<QRectF, Database> > databases(const Region& region) const;
    void setDatabase(const Region& region, const Database& database);

    /**
     * \return the formula associated with the Cell at \p column , \p row .
     */
    Formula formula(int column, int row) const;
    void setFormula(int column, int row, const Formula& formula);

    /**
     * \return the hyperlink associated with the Cell at \p column , \p row .
     */
    QString link(int column, int row) const;
    void setLink(int column, int row, const QString& link);

    /**
     * \return the named area's name associated with the Cell at \p column , \p row .
     */
    QString namedArea(int column, int row) const;
    QList< QPair<QRectF, QString> > namedAreas(const Region& region) const;
    void setNamedArea(const Region& region, const QString& namedArea);
    void emitInsertNamedArea(const Region &region, const QString &namedArea);
    void removeNamedArea(const Region& region, const QString& namedArea);

    /**
     * \return the Style associated with the Cell at \p column , \p row .
     */
    Style style(int column, int row) const;

    /**
     * \return the Style associated with \p rect.
     */
    Style style(const QRect& rect) const;
    void setStyle(const Region& region, const Style& style);
    void insertSubStyle(const QRect& rect, const SharedSubStyle& subStyle);

    /**
     * \return the user input associated with the Cell at \p column , \p row .
     */
    QString userInput(int column, int row) const;
    void setUserInput(int column, int row, const QString& input);

    /**
     * \return the validity checks associated with the Cell at \p column , \p row .
     */
    Validity validity(int column, int row) const;
    void setValidity(const Region& region, Validity validity);

    /**
     * \return the value associated with the Cell at \p column , \p row .
     */
    Value value(int column, int row) const;

    /**
     * Creates a value array containing the values in \p region.
     */
    Value valueRegion(const Region& region) const;
    void setValue(int column, int row, const Value& value);

    QSharedPointer<QTextDocument> richText(int column, int row) const;
    void setRichText(int column, int row, QSharedPointer<QTextDocument> text);

    /**
     */
    bool doesMergeCells(int column, int row) const;
    bool isPartOfMerged(int column, int row) const;

    /**
     * Merge the cell at \p column, \p row with the \p numXCells adjacent cells in horizontal
     * direction and with the \p numYCells adjacent cells in vertical direction. I.e. the
     * resulting cell spans \p numXCells + 1 columns and \p numYCells + 1 rows. Passing \c 0
     * as \p numXCells and \p numYCells unmerges the cell at \p column, \p row.
     *
     * \param column the master cell's column
     * \param row the master cell's row
     * \param numXCells number of horizontal cells to be merged in
     * \param numYCells number of vertical cells to be merged in
     *
     */
    void mergeCells(int column, int row, int numXCells, int numYCells);
    Cell masterCell(int column, int row) const;
    int mergedXCells(int column, int row) const;
    int mergedYCells(int column, int row) const;
    QList<Cell> masterCells(const Region& region) const;

    /**
     * \return \c true, if the cell's value is a matrix and obscures other cells
     */
    bool locksCells(int column, int row) const;
    bool isLocked(int column, int row) const;
    bool hasLockedCells(const Region& region) const;
    void lockCells(const QRect& rect);
    void unlockCells(int column, int row);
    QRect lockedCells(int column, int row) const;

    /**
     * Insert \p number columns at \p position .
     * \return the data, that became out of range (shifted over the end)
     */
    void insertColumns(int position, int number = 1);

    /**
     * Removes \p number columns at \p position .
     * \return the removed data
     */
    void removeColumns(int position, int number = 1);

    /**
     * Insert \p number rows at \p position .
     * \return the data, that became out of range (shifted over the end)
     */
    void insertRows(int position, int number = 1);

    /**
     * Removes \p number rows at \p position .
     * \return the removed data
     */
    void removeRows(int position, int number = 1);

    /**
     * Shifts the data right of \p rect to the left by the width of \p rect .
     * The data formerly contained in \p rect becomes overridden.
     */
    void removeShiftLeft(const QRect& rect);

    /**
     * Shifts the data in and right of \p rect to the right by the width of \p rect .
     */
    void insertShiftRight(const QRect& rect);

    /**
     * Shifts the data below \p rect to the top by the height of \p rect .
     * The data formerly contained in \p rect becomes overridden.
     */
    void removeShiftUp(const QRect& rect);

    /**
     * Shifts the data in and below \p rect to the bottom by the height of \p rect .
     */
    void insertShiftDown(const QRect& rect);

    /**
     * Retrieve the first used data in \p col .
     * Can be used in conjunction with nextInColumn() to loop through a column.
     * \return the first used data in \p col or the default data, if the column is empty.
     */
    Cell firstInColumn(int col, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the first used data in \p row .
     * Can be used in conjunction with nextInRow() to loop through a row.
     * \return the first used data in \p row or the default data, if the row is empty.
     */
    Cell firstInRow(int row, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the last used data in \p col .
     * Can be used in conjunction with prevInColumn() to loop through a column.
     * \return the last used data in \p col or the default data, if the column is empty.
     */
    Cell lastInColumn(int col, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the last used data in \p row .
     * Can be used in conjunction with prevInRow() to loop through a row.
     * \return the last used data in \p row or the default data, if the row is empty.
     */
    Cell lastInRow(int row, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the next used data in \p col after \p row .
     * Can be used in conjunction with firstInColumn() to loop through a column.
     * \return the next used data in \p col or the default data, there is no further data.
     */
    Cell nextInColumn(int col, int row, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the next used data in \p row after \p col .
     * Can be used in conjunction with firstInRow() to loop through a row.
     * \return the next used data in \p row or the default data, if there is no further data.
     */
    Cell nextInRow(int col, int row, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the previous used data in \p col after \p row .
     * Can be used in conjunction with lastInColumn() to loop through a column.
     * \return the previous used data in \p col or the default data, there is no further data.
     */
    Cell prevInColumn(int col, int row, Visiting visiting = VisitAll) const;

    /**
     * Retrieve the previous used data in \p row after \p col .
     * Can be used in conjunction with lastInRow() to loop through a row.
     * \return the previous used data in \p row or the default data, if there is no further data.
     */
    Cell prevInRow(int col, int row, Visiting visiting = VisitAll) const;

    /**
     * The maximum occupied column, i.e. the horizontal storage dimension.
     * \return the maximum column
     */
    int columns(bool includeStyles = true) const;

    /**
     * The maximum occupied row, i.e. the vertical storage dimension.
     * \return the maximum row
     */
    int rows(bool includeStyles = true) const;

    /**
     * The number of rows that are consecutive to, and identical to \p row. This includes the row
     * itself.
     */
    int rowRepeat(int row) const;

    /**
     * The first row in the block of consecutive identical rows \p row is in.
     */
    int firstIdenticalRow(int row) const;

    /**
     * Set how often the specified row is repeated. \p row is the index of the first row in a block,
     * \p count is the number of times it is repeated (including the first one). This method is used
     * during loading.
     */
    void setRowsRepeated(int row, int count);

    /**
     * Creates a substorage consisting of the values in \p region.
     * \return a subset of the storage stripped down to the values in \p region
     */
    CellStorage subStorage(const Region& region) const;

    const BindingStorage* bindingStorage() const;
    const CommentStorage* commentStorage() const;
    const ConditionsStorage* conditionsStorage() const;
    const FormulaStorage* formulaStorage() const;
    const FusionStorage* fusionStorage() const;
    const LinkStorage* linkStorage() const;
    const StyleStorage* styleStorage() const;
    const UserInputStorage* userInputStorage() const;
    const ValidityStorage* validityStorage() const;
    const ValueStorage* valueStorage() const;

    void loadConditions(const QList<QPair<QRegion, Conditions> >& conditions);
    void loadStyles(const QList<QPair<QRegion, Style> >& styles);

    void invalidateStyleCache();

    /**
     * Starts the undo recording.
     * While recording the undo data of each storage operation is saved in
     * an undo command, that can be retrieved when the recording is stopped.
     * \see stopUndoRecording
     */
    void startUndoRecording();

    /**
     * Stops the undo recording.
     * An undo command has to be passed as \p parent command and
     * for each sub-storage an undo-capable command is attached to \p parent.
     * \see startUndoRecording
     */
    void stopUndoRecording(KUndo2Command *parent);

Q_SIGNALS:
    void insertNamedArea(const Region&, const QString&);
    void namedAreaRemoved(const QString&);

private:
    // do not allow assignment
    CellStorage& operator=(const CellStorage&);

    class Private;
    Private * const d;
};

class UserInputStorage : public PointStorage<QString>
{
public:
    UserInputStorage& operator=(const PointStorage<QString>& o) {
        PointStorage<QString>::operator=(o);
        return *this;
    }
};

class LinkStorage : public PointStorage<QString>
{
public:
    LinkStorage& operator=(const PointStorage<QString>& o) {
        PointStorage<QString>::operator=(o);
        return *this;
    }
};

class RichTextStorage : public PointStorage<QSharedPointer<QTextDocument> >
{
public:
    RichTextStorage& operator=(const PointStorage<QSharedPointer<QTextDocument> >& o) {
        PointStorage<QSharedPointer<QTextDocument> >::operator=(o);
        return *this;
    }
};

} // namespace Sheets
} // namespace Calligra

#endif // CALLIGRA_SHEETS_CELL_STORAGE