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 ®ion, 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