File indexing completed on 2024-04-28 16:21:20

0001 /* This file is part of the KDE project
0002    Copyright 2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef CALLIGRA_SHEETS_CELL_STORAGE
0021 #define CALLIGRA_SHEETS_CELL_STORAGE
0022 
0023 #include <QPair>
0024 #include <QRect>
0025 #include <QTextDocument>
0026 
0027 #include "Cell.h"
0028 #include "calligra_sheets_limits.h"
0029 #include "PointStorage.h"
0030 
0031 #include "database/Database.h"
0032 
0033 class KUndo2Command;
0034 
0035 namespace Calligra
0036 {
0037 namespace Sheets
0038 {
0039 class Binding;
0040 class BindingStorage;
0041 class Cell;
0042 class CommentStorage;
0043 class Conditions;
0044 class ConditionsStorage;
0045 class Formula;
0046 class FormulaStorage;
0047 class FusionStorage;
0048 class LinkStorage;
0049 class Region;
0050 class RichTextStorage;
0051 class Sheet;
0052 class StyleStorage;
0053 class UserInputStorage;
0054 class Validity;
0055 class ValidityStorage;
0056 class Value;
0057 class ValueStorage;
0058 
0059 /**
0060  * \ingroup Storage
0061  * The cell storage.
0062  * A wrapper around a couple of storages, which hold the cell data.
0063  * Provides methods to iterate over the non-empty cells.
0064  * Emits Damages on changes.
0065  * Capable of recording the old data for undoing.
0066  *
0067  * \author Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0068  *
0069  * \note If you fill the storage, do it row-wise. That's more performant.
0070  */
0071 class CALLIGRA_SHEETS_ODF_EXPORT CellStorage : public QObject
0072 {
0073     Q_OBJECT
0074 public:
0075     enum Visiting {
0076         Values          = 0x01,
0077         Formulas        = 0x02,
0078         Comments        = 0x04,
0079         Links           = 0x08,
0080         Styles          = 0x10,
0081         ConditionStyles = 0x20,
0082         Validities      = 0x40,
0083         VisitContent    = 0x03, ///< just visit the cell contents: values, formulas
0084         VisitAll        = 0xFF  ///< visit all: cell contents, styles, comments, ...
0085     };
0086 
0087     /**
0088      * Constructor.
0089      * Creates an empty storage for \p sheet.
0090      */
0091     explicit CellStorage(Sheet *sheet);
0092 
0093     /**
0094      * Copy constructor.
0095      * \note Take care: does not perform a deep copy!
0096      */
0097     CellStorage(const CellStorage& other);
0098 
0099     /**
0100      * Copy constructor.
0101      * Creates a CellStorage for \p sheet and copies the data from \p other.
0102      */
0103     CellStorage(const CellStorage& other, Sheet* sheet);
0104 
0105     /**
0106      * Destructor.
0107      */
0108     ~CellStorage() override;
0109 
0110     /**
0111      * \return the sheet this CellStorage is for.
0112      */
0113     Sheet* sheet() const;
0114 
0115     /**
0116      * Removes all data at \p col , \p row .
0117      */
0118     void take(int col, int row);
0119 
0120     /**
0121      * \return the binding associated with the Cell at \p column , \p row .
0122      */
0123     Binding binding(int column, int row) const;
0124     void setBinding(const Region& region, const Binding& binding);
0125     void removeBinding(const Region& region, const Binding& binding);
0126 
0127     /**
0128      * \return the comment associated with the Cell at \p column , \p row .
0129      */
0130     QString comment(int column, int row) const;
0131     void setComment(const Region& region, const QString& comment);
0132 
0133     /**
0134      * \return the conditional formattings associated with the Cell at \p column , \p row .
0135      */
0136     Conditions conditions(int column, int row) const;
0137     void setConditions(const Region& region, Conditions conditions);
0138 
0139     /**
0140      * \return the database associated with the Cell at \p column , \p row .
0141      */
0142     Database database(int column, int row) const;
0143     QList< QPair<QRectF, Database> > databases(const Region& region) const;
0144     void setDatabase(const Region& region, const Database& database);
0145 
0146     /**
0147      * \return the formula associated with the Cell at \p column , \p row .
0148      */
0149     Formula formula(int column, int row) const;
0150     void setFormula(int column, int row, const Formula& formula);
0151 
0152     /**
0153      * \return the hyperlink associated with the Cell at \p column , \p row .
0154      */
0155     QString link(int column, int row) const;
0156     void setLink(int column, int row, const QString& link);
0157 
0158     /**
0159      * \return the named area's name associated with the Cell at \p column , \p row .
0160      */
0161     QString namedArea(int column, int row) const;
0162     QList< QPair<QRectF, QString> > namedAreas(const Region& region) const;
0163     void setNamedArea(const Region& region, const QString& namedArea);
0164     void emitInsertNamedArea(const Region &region, const QString &namedArea);
0165     void removeNamedArea(const Region& region, const QString& namedArea);
0166 
0167     /**
0168      * \return the Style associated with the Cell at \p column , \p row .
0169      */
0170     Style style(int column, int row) const;
0171 
0172     /**
0173      * \return the Style associated with \p rect.
0174      */
0175     Style style(const QRect& rect) const;
0176     void setStyle(const Region& region, const Style& style);
0177     void insertSubStyle(const QRect& rect, const SharedSubStyle& subStyle);
0178 
0179     /**
0180      * \return the user input associated with the Cell at \p column , \p row .
0181      */
0182     QString userInput(int column, int row) const;
0183     void setUserInput(int column, int row, const QString& input);
0184 
0185     /**
0186      * \return the validity checks associated with the Cell at \p column , \p row .
0187      */
0188     Validity validity(int column, int row) const;
0189     void setValidity(const Region& region, Validity validity);
0190 
0191     /**
0192      * \return the value associated with the Cell at \p column , \p row .
0193      */
0194     Value value(int column, int row) const;
0195 
0196     /**
0197      * Creates a value array containing the values in \p region.
0198      */
0199     Value valueRegion(const Region& region) const;
0200     void setValue(int column, int row, const Value& value);
0201 
0202     QSharedPointer<QTextDocument> richText(int column, int row) const;
0203     void setRichText(int column, int row, QSharedPointer<QTextDocument> text);
0204 
0205     /**
0206      */
0207     bool doesMergeCells(int column, int row) const;
0208     bool isPartOfMerged(int column, int row) const;
0209 
0210     /**
0211      * Merge the cell at \p column, \p row with the \p numXCells adjacent cells in horizontal
0212      * direction and with the \p numYCells adjacent cells in vertical direction. I.e. the
0213      * resulting cell spans \p numXCells + 1 columns and \p numYCells + 1 rows. Passing \c 0
0214      * as \p numXCells and \p numYCells unmerges the cell at \p column, \p row.
0215      *
0216      * \param column the master cell's column
0217      * \param row the master cell's row
0218      * \param numXCells number of horizontal cells to be merged in
0219      * \param numYCells number of vertical cells to be merged in
0220      *
0221      */
0222     void mergeCells(int column, int row, int numXCells, int numYCells);
0223     Cell masterCell(int column, int row) const;
0224     int mergedXCells(int column, int row) const;
0225     int mergedYCells(int column, int row) const;
0226     QList<Cell> masterCells(const Region& region) const;
0227 
0228     /**
0229      * \return \c true, if the cell's value is a matrix and obscures other cells
0230      */
0231     bool locksCells(int column, int row) const;
0232     bool isLocked(int column, int row) const;
0233     bool hasLockedCells(const Region& region) const;
0234     void lockCells(const QRect& rect);
0235     void unlockCells(int column, int row);
0236     QRect lockedCells(int column, int row) const;
0237 
0238     /**
0239      * Insert \p number columns at \p position .
0240      * \return the data, that became out of range (shifted over the end)
0241      */
0242     void insertColumns(int position, int number = 1);
0243 
0244     /**
0245      * Removes \p number columns at \p position .
0246      * \return the removed data
0247      */
0248     void removeColumns(int position, int number = 1);
0249 
0250     /**
0251      * Insert \p number rows at \p position .
0252      * \return the data, that became out of range (shifted over the end)
0253      */
0254     void insertRows(int position, int number = 1);
0255 
0256     /**
0257      * Removes \p number rows at \p position .
0258      * \return the removed data
0259      */
0260     void removeRows(int position, int number = 1);
0261 
0262     /**
0263      * Shifts the data right of \p rect to the left by the width of \p rect .
0264      * The data formerly contained in \p rect becomes overridden.
0265      */
0266     void removeShiftLeft(const QRect& rect);
0267 
0268     /**
0269      * Shifts the data in and right of \p rect to the right by the width of \p rect .
0270      */
0271     void insertShiftRight(const QRect& rect);
0272 
0273     /**
0274      * Shifts the data below \p rect to the top by the height of \p rect .
0275      * The data formerly contained in \p rect becomes overridden.
0276      */
0277     void removeShiftUp(const QRect& rect);
0278 
0279     /**
0280      * Shifts the data in and below \p rect to the bottom by the height of \p rect .
0281      */
0282     void insertShiftDown(const QRect& rect);
0283 
0284     /**
0285      * Retrieve the first used data in \p col .
0286      * Can be used in conjunction with nextInColumn() to loop through a column.
0287      * \return the first used data in \p col or the default data, if the column is empty.
0288      */
0289     Cell firstInColumn(int col, Visiting visiting = VisitAll) const;
0290 
0291     /**
0292      * Retrieve the first used data in \p row .
0293      * Can be used in conjunction with nextInRow() to loop through a row.
0294      * \return the first used data in \p row or the default data, if the row is empty.
0295      */
0296     Cell firstInRow(int row, Visiting visiting = VisitAll) const;
0297 
0298     /**
0299      * Retrieve the last used data in \p col .
0300      * Can be used in conjunction with prevInColumn() to loop through a column.
0301      * \return the last used data in \p col or the default data, if the column is empty.
0302      */
0303     Cell lastInColumn(int col, Visiting visiting = VisitAll) const;
0304 
0305     /**
0306      * Retrieve the last used data in \p row .
0307      * Can be used in conjunction with prevInRow() to loop through a row.
0308      * \return the last used data in \p row or the default data, if the row is empty.
0309      */
0310     Cell lastInRow(int row, Visiting visiting = VisitAll) const;
0311 
0312     /**
0313      * Retrieve the next used data in \p col after \p row .
0314      * Can be used in conjunction with firstInColumn() to loop through a column.
0315      * \return the next used data in \p col or the default data, there is no further data.
0316      */
0317     Cell nextInColumn(int col, int row, Visiting visiting = VisitAll) const;
0318 
0319     /**
0320      * Retrieve the next used data in \p row after \p col .
0321      * Can be used in conjunction with firstInRow() to loop through a row.
0322      * \return the next used data in \p row or the default data, if there is no further data.
0323      */
0324     Cell nextInRow(int col, int row, Visiting visiting = VisitAll) const;
0325 
0326     /**
0327      * Retrieve the previous used data in \p col after \p row .
0328      * Can be used in conjunction with lastInColumn() to loop through a column.
0329      * \return the previous used data in \p col or the default data, there is no further data.
0330      */
0331     Cell prevInColumn(int col, int row, Visiting visiting = VisitAll) const;
0332 
0333     /**
0334      * Retrieve the previous used data in \p row after \p col .
0335      * Can be used in conjunction with lastInRow() to loop through a row.
0336      * \return the previous used data in \p row or the default data, if there is no further data.
0337      */
0338     Cell prevInRow(int col, int row, Visiting visiting = VisitAll) const;
0339 
0340     /**
0341      * The maximum occupied column, i.e. the horizontal storage dimension.
0342      * \return the maximum column
0343      */
0344     int columns(bool includeStyles = true) const;
0345 
0346     /**
0347      * The maximum occupied row, i.e. the vertical storage dimension.
0348      * \return the maximum row
0349      */
0350     int rows(bool includeStyles = true) const;
0351 
0352     /**
0353      * The number of rows that are consecutive to, and identical to \p row. This includes the row
0354      * itself.
0355      */
0356     int rowRepeat(int row) const;
0357 
0358     /**
0359      * The first row in the block of consecutive identical rows \p row is in.
0360      */
0361     int firstIdenticalRow(int row) const;
0362 
0363     /**
0364      * Set how often the specified row is repeated. \p row is the index of the first row in a block,
0365      * \p count is the number of times it is repeated (including the first one). This method is used
0366      * during loading.
0367      */
0368     void setRowsRepeated(int row, int count);
0369 
0370     /**
0371      * Creates a substorage consisting of the values in \p region.
0372      * \return a subset of the storage stripped down to the values in \p region
0373      */
0374     CellStorage subStorage(const Region& region) const;
0375 
0376     const BindingStorage* bindingStorage() const;
0377     const CommentStorage* commentStorage() const;
0378     const ConditionsStorage* conditionsStorage() const;
0379     const FormulaStorage* formulaStorage() const;
0380     const FusionStorage* fusionStorage() const;
0381     const LinkStorage* linkStorage() const;
0382     const StyleStorage* styleStorage() const;
0383     const UserInputStorage* userInputStorage() const;
0384     const ValidityStorage* validityStorage() const;
0385     const ValueStorage* valueStorage() const;
0386 
0387     void loadConditions(const QList<QPair<QRegion, Conditions> >& conditions);
0388     void loadStyles(const QList<QPair<QRegion, Style> >& styles);
0389 
0390     void invalidateStyleCache();
0391 
0392     /**
0393      * Starts the undo recording.
0394      * While recording the undo data of each storage operation is saved in
0395      * an undo command, that can be retrieved when the recording is stopped.
0396      * \see stopUndoRecording
0397      */
0398     void startUndoRecording();
0399 
0400     /**
0401      * Stops the undo recording.
0402      * An undo command has to be passed as \p parent command and
0403      * for each sub-storage an undo-capable command is attached to \p parent.
0404      * \see startUndoRecording
0405      */
0406     void stopUndoRecording(KUndo2Command *parent);
0407 
0408 Q_SIGNALS:
0409     void insertNamedArea(const Region&, const QString&);
0410     void namedAreaRemoved(const QString&);
0411 
0412 private:
0413     // do not allow assignment
0414     CellStorage& operator=(const CellStorage&);
0415 
0416     class Private;
0417     Private * const d;
0418 };
0419 
0420 class UserInputStorage : public PointStorage<QString>
0421 {
0422 public:
0423     UserInputStorage& operator=(const PointStorage<QString>& o) {
0424         PointStorage<QString>::operator=(o);
0425         return *this;
0426     }
0427 };
0428 
0429 class LinkStorage : public PointStorage<QString>
0430 {
0431 public:
0432     LinkStorage& operator=(const PointStorage<QString>& o) {
0433         PointStorage<QString>::operator=(o);
0434         return *this;
0435     }
0436 };
0437 
0438 class RichTextStorage : public PointStorage<QSharedPointer<QTextDocument> >
0439 {
0440 public:
0441     RichTextStorage& operator=(const PointStorage<QSharedPointer<QTextDocument> >& o) {
0442         PointStorage<QSharedPointer<QTextDocument> >::operator=(o);
0443         return *this;
0444     }
0445 };
0446 
0447 } // namespace Sheets
0448 } // namespace Calligra
0449 
0450 #endif // CALLIGRA_SHEETS_CELL_STORAGE