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

0001 /* This file is part of the KDE project
0002    Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org>
0003    Copyright 2006-2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0004    Copyright 2004 Tomas Mecir <mecirt@gmail.com>
0005    Copyright 1999-2002,2004 Laurent Montel <montel@kde.org>
0006    Copyright 2002,2004 Ariya Hidayat <ariya@kde.org>
0007    Copyright 2002-2003 Norbert Andres <nandres@web.de>
0008    Copyright 2003 Stefan Hetzl <shetzl@chello.at>
0009    Copyright 2001-2002 Philipp Mueller <philipp.mueller@gmx.de>
0010    Copyright 2002 Harri Porten <porten@kde.org>
0011    Copyright 2002 John Dailey <dailey@vt.edu>
0012    Copyright 1999-2001 David Faure <faure@kde.org>
0013    Copyright 2000-2001 Werner Trobin <trobin@kde.org>
0014    Copyright 2000 Simon Hausmann <hausmann@kde.org
0015    Copyright 1998-1999 Torben Weis <weis@kde.org>
0016    Copyright 1999 Michael Reiher <michael.reiher@gmx.de>
0017    Copyright 1999 Reginald Stadlbauer <reggie@kde.org>
0018 
0019    This library is free software; you can redistribute it and/or
0020    modify it under the terms of the GNU Library General Public
0021    License as published by the Free Software Foundation; either
0022    version 2 of the License, or (at your option) any later version.
0023 
0024    This library is distributed in the hope that it will be useful,
0025    but WITHOUT ANY WARRANTY; without even the implied warranty of
0026    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0027    Library General Public License for more details.
0028 
0029    You should have received a copy of the GNU Library General Public License
0030    along with this library; see the file COPYING.LIB.  If not, write to
0031    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0032    Boston, MA 02110-1301, USA.
0033 */
0034 
0035 #ifndef CALLIGRA_SHEETS_CELL
0036 #define CALLIGRA_SHEETS_CELL
0037 
0038 #include <QSharedDataPointer>
0039 #include <QSharedPointer>
0040 #include <QTextDocument>
0041 
0042 #include "Global.h"
0043 #include "Style.h"
0044 
0045 class QDomElement;
0046 class QDomDocument;
0047 class QRect;
0048 class QPoint;
0049 class QDate;
0050 
0051 class KLocale;
0052 
0053 namespace Calligra
0054 {
0055 namespace Sheets
0056 {
0057 class Conditions;
0058 class Database;
0059 class Doc;
0060 class Formula;
0061 class Sheet;
0062 class Validity;
0063 class Value;
0064 class CellTest;
0065 
0066 /**
0067  * An accessor to the actual cell data.
0068  * The Cell object acts as accessor to the actual data stored in the separate
0069  * storages in CellStorage. It provides methods to alter and retrieve this data
0070  * and methods related to loading and saving the contents.
0071  */
0072 class CALLIGRA_SHEETS_ODF_EXPORT Cell
0073 {
0074 public:
0075     /**
0076      * Constructor.
0077      * Creates the null cell.
0078      * \note Accessing the sheet(), column() or row() methods or any related method, that makes use
0079      * of the former, will fail.
0080      */
0081     Cell();
0082 
0083     /**
0084      * Constructor.
0085      * Creates a Cell for accessing the data in \p sheet at position \p col , \p row .
0086      */
0087     Cell(const Sheet* sheet, int column, int row);
0088 
0089     /**
0090      * Constructor.
0091      * Creates a Cell for accessing the data in \p sheet at position \p pos .
0092      */
0093     Cell(const Sheet* sheet, const QPoint& pos);
0094 
0095     /**
0096      * Copy constructor.
0097      */
0098     Cell(const Cell& other);
0099 
0100     /**
0101      * Destructor.
0102      */
0103     ~Cell();
0104 
0105     /**
0106      * \return the sheet this cell belongs to
0107      */
0108     Sheet* sheet() const;
0109 
0110     /**
0111      * Returns the locale setting of this cell.
0112      */
0113     KLocale* locale() const;
0114 
0115     /**
0116      * Returns true, if this is a default cell, i.e. if the cell has no value, formula, link and
0117      * does not merge any other cells, and has no custom style.
0118      */
0119     bool isDefault() const;
0120 
0121     /**
0122      * Returns true, if this is a cell with default content, i.e. if the cell has no value, formula, link and
0123      * does not merge any other cells. This is the same as isDefault, except that the style
0124      * is not taken into account here.
0125      */
0126     bool hasDefaultContent() const;
0127 
0128     /**
0129      * Returns true, if this cell has no content, i.e no value and no formula.
0130      */
0131     bool isEmpty() const;
0132 
0133     /**
0134      * Returns true if this cell is the null cell.
0135      */
0136     bool isNull() const;
0137 
0138     /**
0139      * Returns true if this cell holds a formula.
0140      */
0141     bool isFormula() const;
0142 
0143     /**
0144      * Returns the cell's column.
0145      */
0146     int column() const;
0147 
0148     /**
0149      * Returns the cell's row.
0150      */
0151     int row() const;
0152 
0153     /**
0154      * Returns the name of the cell. For example, the cell in first column and
0155      * first row is "A1".
0156      */
0157     QString name() const;
0158 
0159     /**
0160      * Returns the full name of the cell, i.e. including the worksheet name.
0161      * Example: "Sheet1!A1"
0162      */
0163     QString fullName() const;
0164 
0165     /**
0166      * Returns the column name of the cell.
0167      */
0168     QString columnName() const;
0169 
0170     /**
0171      * Given the cell position, this static function returns the name of the cell.
0172      * Example: name(5,4) will return "E4".
0173      */
0174     static QString name(int col, int row);
0175 
0176     /**
0177      * Given the sheet and cell position, this static function returns the full name
0178      * of the cell, i.e. with the name of the sheet.
0179      */
0180     static QString fullName(const Sheet *s, int col, int row);
0181 
0182     /**
0183      * Given the column number, this static function returns the corresponding
0184      * column name, i.e. the first column is "A", the second is "B", and so on.
0185      */
0186     static QString columnName(uint column);
0187 
0188     /**
0189      * \return the output text, e.g. the result of a formula
0190      */
0191     QString displayText(const Style& s = Style(), Value* v = 0, bool *showFormula = 0) const;
0192 
0193     /**
0194      * \return the comment associated with this cell
0195      */
0196     QString comment() const;
0197 
0198     void setComment(const QString& comment);
0199 
0200     /**
0201      * \return the conditions associated with this cell
0202      */
0203     Conditions conditions() const;
0204 
0205     void setConditions(const Conditions& conditions);
0206 
0207     /**
0208      * \return the database associated with this cell
0209      */
0210     Database database() const;
0211 
0212     /**
0213      * The cell's formula. Usable to analyze the formula's tokens.
0214      * \return pointer to the cell's formula object
0215      */
0216     Formula formula() const;
0217 
0218     /**
0219      * Sets \p formula as associated formula of this cell.
0220      */
0221     void setFormula(const Formula& formula);
0222 
0223     /**
0224      * Returns the link associated with cell. It is empty if this cell
0225      * contains no link.
0226      */
0227     QString link() const;
0228 
0229     /**
0230      * Sets a link for this cell. For example, setLink( "mailto:joe@somewhere.com" )
0231      * will open a new e-mail if this cell is clicked.
0232      * Possible choices for link are URL (web, ftp), e-mail address, local file,
0233      * or another cell.
0234      */
0235     void setLink(const QString& link);
0236 
0237     /**
0238      * \return the Style associated with this Cell
0239      */
0240     Style style() const;
0241 
0242     /**
0243      * The effective style takes conditional style attributes into account.
0244      * \return the effective Style associated with this Cell
0245      */
0246     Style effectiveStyle() const;
0247 
0248     void setStyle(const Style& style);
0249 
0250     /**
0251      * \return the validity checks associated with this cell
0252      */
0253     Validity validity() const;
0254 
0255     void setValidity(Validity validity);
0256 
0257     /**
0258      * Returns the value that this cell holds. It could be from the user
0259      * (i.e. when s/he enters a value) or a result of formula.
0260      */
0261     const Value value() const;
0262 
0263     /**
0264      * Sets the value for this cell.
0265      * It also clears all errors, if the value itself is not an error.
0266      * In addition to this, it calculates the outstring and sets the dirty
0267      * flags so that a redraw is forced.
0268      * \param value the new value
0269      *
0270      * \see setUserInput, parseUserInput
0271      */
0272     void setValue(const Value& value);
0273 
0274     /**
0275      * Returns the richtext that this cell holds.
0276      */
0277     QSharedPointer<QTextDocument> richText() const;
0278 
0279     /**
0280      * Sets the richtext for this cell.
0281      * If \p text is empty, richtext is removed.
0282      *
0283      * \param text the new richtext
0284      */
0285     void setRichText(QSharedPointer<QTextDocument> text);
0286 
0287     /**
0288      * Return the text the user entered. This could be a value (e.g. "14.03")
0289      * or a formula (e.g. "=SUM(A1:A10)")
0290      */
0291     QString userInput() const;
0292 
0293     /**
0294      * Sets the user input without parsing it.
0295      * If \p text is a formula, creates a formula object and sets \p text as
0296      * its expression. Otherwise, simply stores \p text as user input.
0297      *
0298      * \see parseUserInput, setValue
0299      */
0300     void setUserInput(const QString& text);
0301 
0302     /**
0303      * Sets the user input without parsing it, without clearing existing formulas
0304      * userinput or rich text. Used during loading of documents only!
0305      * If \p text is a formula, creates a formula object and sets \p text as
0306      * its expression. Otherwise, simply stores \p text as user input.
0307      *
0308      * \see parseUserInput, setValue
0309      */
0310     void setRawUserInput(const QString& text);
0311 
0312     /**
0313      * Sets the user input and parses it.
0314      * If \p text is a formula, creates a formula object and sets \p text as
0315      * its expression. Otherwise, parses \p text, creates an appropriate value,
0316      * including the proper type, validates the value and, if accepted, stores
0317      * \p text as the user input and the value as the cell's value.
0318      *
0319      * \see setUserInput, setValue
0320      */
0321     void parseUserInput(const QString& text);
0322 
0323     /**
0324      * \ingroup NativeFormat
0325      */
0326     bool load(const KoXmlElement& cell,
0327               int _xshift, int _yshift,
0328               Paste::Mode pm = Paste::Normal,
0329               Paste::Operation op = Paste::OverWrite,
0330               bool paste = false);
0331 
0332     /**
0333      * \ingroup NativeFormat
0334      * Save this cell.
0335      * @param doc document to save cell in
0336      * @param xOffset x offset
0337      * @param yOffset y offset
0338      * @param era set this to true if you want to encode relative references as absolutely (they will be switched
0339      *            back to relative references during decoding) - is used for cutting to clipboard
0340      *            Usually this is false, to only store the properties explicitly set.
0341      */
0342     QDomElement save(QDomDocument& doc, int xOffset = 0, int yOffset = 0, bool era = false);
0343 
0344     /**
0345      * \ingroup NativeFormat
0346      * Decodes a string into a time value.
0347      */
0348     QTime toTime(const KoXmlElement &element);
0349 
0350     /**
0351      * \ingroup NativeFormat
0352      * Decodes a string into a date value.
0353      */
0354     QDate toDate(const KoXmlElement &element);
0355 
0356     /**
0357      * Copies the format from \p cell .
0358      *
0359      * @see copyAll(Cell *cell)
0360      */
0361     void copyFormat(const Cell& cell);
0362 
0363     /**
0364      * Copies the content from \p cell .
0365      *
0366      * @see copyAll(Cell *cell)
0367      */
0368     void copyContent(const Cell& cell);
0369 
0370     /**
0371      * Copies the format and the content from \p cell .
0372      *
0373      * @see copyContent( const Cell& cell )
0374      * @see copyFormat( const Cell& cell )
0375      */
0376     void copyAll(const Cell& cell);
0377 
0378     /**
0379      * @return the width of this cell as double
0380      */
0381     double width() const;
0382 
0383     /**
0384      * @return the height of this cell as double
0385      */
0386     double height() const;
0387 
0388     /**
0389      * \return the position of this cell
0390      */
0391     QPoint cellPosition() const;
0392 
0393     /**
0394      * @return true if the cell should be printed in a print out.
0395      *         That's the case, if it has any content, border, backgroundcolor,
0396      *         or background brush.
0397      *
0398      * @see Sheet::print
0399      */
0400     bool needsPrinting() const;
0401 
0402     //
0403     //END
0404     //
0405     //////////////////////////////////////////////////////////////////////////
0406     //
0407     //BEGIN Merging
0408     //
0409 
0410     /**
0411      * If this cell is part of a merged cell, then the marker may
0412      * never reside on this cell.
0413      *
0414      * @return true if another cell has this one merged into itself.
0415      */
0416     bool isPartOfMerged() const;
0417 
0418     /**
0419      * \return the merging cell (might be this cell)
0420      */
0421     Cell masterCell() const;
0422 
0423     /**
0424      * Merge a number of cells, i.e. force the cell to occupy other
0425      * cells space.  If '_x' and '_y' are 0 then the merging is
0426      * disabled.
0427      *
0428      * @param _col is the column this cell is assumed to be in.
0429      * @param _row is the row this cell is assumed to be in.
0430      * @param _x tells to occupy _x additional cells in the horizontal
0431      * @param _y tells to occupy _y additional cells in the vertical
0432      *
0433      */
0434     void mergeCells(int _col, int _row, int _x, int _y);
0435 
0436     /**
0437      * @return true if the cell is forced to obscure other cells.
0438      */
0439     bool doesMergeCells() const;
0440 
0441     /**
0442      * @return the number of obscured cells in the horizontal direction as a
0443      *         result of cell merging (forced obscuring)
0444      */
0445     int mergedXCells() const;
0446 
0447     /**
0448      * @return the number of obscured cells in the vertical direction as a
0449      *         result of cell merging (forced obscuring)
0450      */
0451     int mergedYCells() const;
0452 
0453     //
0454     //END Merging
0455     //
0456     //////////////////////////////////////////////////////////////////////////
0457     //
0458     //BEGIN Matrix locking
0459     //
0460 
0461     bool isLocked() const;
0462     QRect lockedCells() const;
0463 
0464     //
0465     //END Matrix locking
0466     //
0467     //////////////////////////////////////////////////////////////////////////
0468     //
0469     //BEGIN Cut & paste
0470     //
0471 
0472     /**
0473      * Encodes the cell's formula into a text representation.
0474      *
0475      * \param fixedReferences encode relative references absolutely (this is used for copying
0476      *             a cell to make the paste operation create a formula that points
0477      *             to the original cells, not the cells at the same relative position)
0478      * \see decodeFormula()
0479      */
0480     QString encodeFormula(bool fixedReferences = false) const;
0481 
0482     /**
0483      * Decodes a text representation \p text into a formula expression.
0484      *
0485      * \see encodeFormula()
0486      */
0487     QString decodeFormula(const QString& text) const;
0488 
0489     /**
0490      * Merges the @p new_text with @p old_text during a paste operation.
0491      * If both texts represent doubles, then the operation is performed on both
0492      * values and the result is returned. If both texts represents a formula or
0493      * one a formula and the other a double value, then a formula is returned.
0494      * In all other cases @p new_text is returned.
0495      *
0496      * @return the merged text.
0497      */
0498     QString pasteOperation(const QString &new_text, const QString &old_text, Paste::Operation op);
0499 
0500     //
0501     //END Cut & paste
0502     //
0503     //////////////////////////////////////////////////////////////////////////
0504     //
0505     //BEGIN
0506     //
0507 
0508     /**
0509      * Parses the formula.
0510      * @return @c false on error.
0511      */
0512     bool makeFormula();
0513 
0514     //
0515     //END
0516     //
0517     //////////////////////////////////////////////////////////////////////////
0518     //
0519     //BEGIN Effective style attributes
0520     //
0521 
0522     /** returns horizontal alignment, depending on style and value type */
0523     int effectiveAlignX() const;
0524     /** returns true, if cell format is of date type or content is a date */
0525     bool isDate() const;
0526     /** returns true, if cell format is of time type or content is a time */
0527     bool isTime() const;
0528     /** returns true, if cell format is of text type */
0529     bool isText() const;
0530 
0531     //
0532     //END Effective style attributes
0533     //
0534     //////////////////////////////////////////////////////////////////////////
0535     //
0536     //BEGIN Operators
0537     //
0538 
0539     /**
0540      * Assignment.
0541      */
0542     Cell& operator=(const Cell& other);
0543 
0544     /**
0545      * Tests whether this cell's location is less than the \p other 's.
0546      * (QMap support)
0547      * \note Does not compare the cell attributes/data.
0548      */
0549     bool operator<(const Cell& other) const;
0550 
0551     /**
0552      * Tests for equality with \p other 's location only.
0553      * (QHash support)
0554      * \note Does not compare the cell attributes/data.
0555      */
0556     bool operator==(const Cell& other) const;
0557 
0558     /**
0559      * Is null.
0560      */
0561     bool operator!() const;
0562 
0563     //
0564     //END Operators
0565     //
0566     //////////////////////////////////////////////////////////////////////////
0567     //
0568     //BEGIN
0569     //
0570 
0571     /**
0572      * Tests for equality of all cell attributes/data to those in \p other .
0573      */
0574     bool compareData(const Cell& other) const;
0575 
0576 private:
0577     friend class CellTest;
0578 
0579     class Private;
0580     QSharedDataPointer<Private> d;
0581 
0582     /**
0583      * \ingroup NativeFormat
0584      */
0585     bool loadCellData(const KoXmlElement &text, Paste::Operation op, const QString &dataType = QString());
0586 
0587     /**
0588      * \ingroup NativeFormat
0589      */
0590     bool saveCellResult(QDomDocument& doc, QDomElement& result, QString str);
0591 };
0592 
0593 inline uint qHash(const Cell& cell)
0594 {
0595     return (static_cast<uint>(cell.column()) << 16) + static_cast<uint>(cell.row());
0596 }
0597 
0598 } // namespace Sheets
0599 } // namespace Calligra
0600 
0601 Q_DECLARE_TYPEINFO(Calligra::Sheets::Cell, Q_MOVABLE_TYPE);
0602 Q_DECLARE_METATYPE(Calligra::Sheets::Cell)
0603 
0604 /***************************************************************************
0605   QDebug support
0606 ****************************************************************************/
0607 
0608 inline QDebug operator<<(QDebug str, const Calligra::Sheets::Cell& cell)
0609 {
0610     return str << qPrintable(QString("%1%2").arg(Calligra::Sheets::Cell::columnName(cell.column())).arg(QString::number(cell.row())));
0611 }
0612 
0613 #endif  // CALLIGRA_SHEETS_CELL