1 | /* This file is part of the KDE project |
2 | Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org> |
3 | Copyright 2006-2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net> |
4 | Copyright 2004 Tomas Mecir <mecirt@gmail.com> |
5 | Copyright 1999-2002,2004 Laurent Montel <montel@kde.org> |
6 | Copyright 2002,2004 Ariya Hidayat <ariya@kde.org> |
7 | Copyright 2002-2003 Norbert Andres <nandres@web.de> |
8 | Copyright 2003 Stefan Hetzl <shetzl@chello.at> |
9 | Copyright 2001-2002 Philipp Mueller <philipp.mueller@gmx.de> |
10 | Copyright 2002 Harri Porten <porten@kde.org> |
11 | Copyright 2002 John Dailey <dailey@vt.edu> |
12 | Copyright 1999-2001 David Faure <faure@kde.org> |
13 | Copyright 2000-2001 Werner Trobin <trobin@kde.org> |
14 | Copyright 2000 Simon Hausmann <hausmann@kde.org |
15 | Copyright 1998-1999 Torben Weis <weis@kde.org> |
16 | Copyright 1999 Michael Reiher <michael.reiher@gmx.de> |
17 | Copyright 1999 Reginald Stadlbauer <reggie@kde.org> |
18 | |
19 | This library is free software; you can redistribute it and/or |
20 | modify it under the terms of the GNU Library General Public |
21 | License as published by the Free Software Foundation; either |
22 | version 2 of the License, or (at your option) any later version. |
23 | |
24 | This library is distributed in the hope that it will be useful, |
25 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
27 | Library General Public License for more details. |
28 | |
29 | You should have received a copy of the GNU Library General Public License |
30 | along with this library; see the file COPYING.LIB. If not, write to |
31 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
32 | Boston, MA 02110-1301, USA. |
33 | */ |
34 | |
35 | #ifndef CALLIGRA_SHEETS_CELL |
36 | #define CALLIGRA_SHEETS_CELL |
37 | |
38 | #include <QDate> |
39 | #include <QSharedDataPointer> |
40 | #include <QSharedPointer> |
41 | #include <QTextDocument> |
42 | |
43 | #include "Condition.h" |
44 | #include "Global.h" |
45 | #include "Format.h" |
46 | #include "OdfLoadingContext.h" |
47 | |
48 | #include "database/Database.h" |
49 | |
50 | class QDomElement; |
51 | class QDomDocument; |
52 | class QFont; |
53 | class QRect; |
54 | class QPoint; |
55 | |
56 | class KLocale; |
57 | class KoXmlWriter; |
58 | class KoGenStyles; |
59 | class KoGenStyle; |
60 | class KoOdfLoadingContext; |
61 | class KoShapeLoadingContext; |
62 | |
63 | namespace Calligra |
64 | { |
65 | namespace Sheets |
66 | { |
67 | class Doc; |
68 | class Formula; |
69 | class OdfLoadingContext; |
70 | class OdfSavingContext; |
71 | class Sheet; |
72 | class Validity; |
73 | class Value; |
74 | class CellTest; |
75 | |
76 | /** |
77 | * An accessor to the actual cell data. |
78 | * The Cell object acts as accessor to the actual data stored in the separate |
79 | * storages in CellStorage. It provides methods to alter and retrieve this data |
80 | * and methods related to loading and saving the contents. |
81 | */ |
82 | class CALLIGRA_SHEETS_ODF_EXPORT Cell |
83 | { |
84 | public: |
85 | /** |
86 | * Constructor. |
87 | * Creates the null cell. |
88 | * \note Accessing the sheet(), column() or row() methods or any related method, that makes use |
89 | * of the former, will fail. |
90 | */ |
91 | Cell(); |
92 | |
93 | /** |
94 | * Constructor. |
95 | * Creates a Cell for accessing the data in \p sheet at position \p col , \p row . |
96 | */ |
97 | Cell(const Sheet* sheet, int column, int row); |
98 | |
99 | /** |
100 | * Constructor. |
101 | * Creates a Cell for accessing the data in \p sheet at position \p pos . |
102 | */ |
103 | Cell(const Sheet* sheet, const QPoint& pos); |
104 | |
105 | /** |
106 | * Copy constructor. |
107 | */ |
108 | Cell(const Cell& other); |
109 | |
110 | /** |
111 | * Destructor. |
112 | */ |
113 | ~Cell(); |
114 | |
115 | /** |
116 | * \return the sheet this cell belongs to |
117 | */ |
118 | Sheet* sheet() const; |
119 | |
120 | /** |
121 | * Returns the locale setting of this cell. |
122 | */ |
123 | KLocale* locale() const; |
124 | |
125 | /** |
126 | * Returns true, if this is a default cell, i.e. if the cell has no value, formula, link and |
127 | * does not merge any other cells, and has no custom style. |
128 | */ |
129 | bool isDefault() const; |
130 | |
131 | /** |
132 | * Returns true, if this is a cell with default content, i.e. if the cell has no value, formula, link and |
133 | * does not merge any other cells. This is the same as isDefault, except that the style |
134 | * is not taken into account here. |
135 | */ |
136 | bool hasDefaultContent() const; |
137 | |
138 | /** |
139 | * Returns true, if this cell has no content, i.e no value and no formula. |
140 | */ |
141 | bool isEmpty() const; |
142 | |
143 | /** |
144 | * Returns true if this cell is the null cell. |
145 | */ |
146 | bool isNull() const; |
147 | |
148 | /** |
149 | * Returns true if this cell holds a formula. |
150 | */ |
151 | bool isFormula() const; |
152 | |
153 | /** |
154 | * Returns the cell's column. |
155 | */ |
156 | int column() const; |
157 | |
158 | /** |
159 | * Returns the cell's row. |
160 | */ |
161 | int row() const; |
162 | |
163 | /** |
164 | * Returns the name of the cell. For example, the cell in first column and |
165 | * first row is "A1". |
166 | */ |
167 | QString name() const; |
168 | |
169 | /** |
170 | * Returns the full name of the cell, i.e. including the worksheet name. |
171 | * Example: "Sheet1!A1" |
172 | */ |
173 | QString fullName() const; |
174 | |
175 | /** |
176 | * Returns the column name of the cell. |
177 | */ |
178 | QString columnName() const; |
179 | |
180 | /** |
181 | * Given the cell position, this static function returns the name of the cell. |
182 | * Example: name(5,4) will return "E4". |
183 | */ |
184 | static QString name(int col, int row); |
185 | |
186 | /** |
187 | * Given the sheet and cell position, this static function returns the full name |
188 | * of the cell, i.e. with the name of the sheet. |
189 | */ |
190 | static QString fullName(const Sheet *s, int col, int row); |
191 | |
192 | /** |
193 | * Given the column number, this static function returns the corresponding |
194 | * column name, i.e. the first column is "A", the second is "B", and so on. |
195 | */ |
196 | static QString columnName(uint column); |
197 | |
198 | /** |
199 | * \return the output text, e.g. the result of a formula |
200 | */ |
201 | QString displayText(const Style& s = Style(), Value* v = 0, bool *showFormula = 0) const; |
202 | |
203 | /** |
204 | * \return the comment associated with this cell |
205 | */ |
206 | QString () const; |
207 | |
208 | void (const QString& ); |
209 | |
210 | /** |
211 | * \return the conditions associated with this cell |
212 | */ |
213 | Conditions conditions() const; |
214 | |
215 | void setConditions(const Conditions& conditions); |
216 | |
217 | /** |
218 | * \return the database associated with this cell |
219 | */ |
220 | Database database() const; |
221 | |
222 | /** |
223 | * The cell's formula. Usable to analyze the formula's tokens. |
224 | * \return pointer to the cell's formula object |
225 | */ |
226 | Formula formula() const; |
227 | |
228 | /** |
229 | * Sets \p formula as associated formula of this cell. |
230 | */ |
231 | void setFormula(const Formula& formula); |
232 | |
233 | /** |
234 | * Returns the link associated with cell. It is empty if this cell |
235 | * contains no link. |
236 | */ |
237 | QString link() const; |
238 | |
239 | /** |
240 | * Sets a link for this cell. For example, setLink( "mailto:joe@somewhere.com" ) |
241 | * will open a new e-mail if this cell is clicked. |
242 | * Possible choices for link are URL (web, ftp), e-mail address, local file, |
243 | * or another cell. |
244 | */ |
245 | void setLink(const QString& link); |
246 | |
247 | /** |
248 | * \return the Style associated with this Cell |
249 | */ |
250 | Style style() const; |
251 | |
252 | /** |
253 | * The effective style takes conditional style attributes into account. |
254 | * \return the effective Style associated with this Cell |
255 | */ |
256 | Style effectiveStyle() const; |
257 | |
258 | void setStyle(const Style& style); |
259 | |
260 | /** |
261 | * \return the validity checks associated with this cell |
262 | */ |
263 | Validity validity() const; |
264 | |
265 | void setValidity(Validity validity); |
266 | |
267 | /** |
268 | * Returns the value that this cell holds. It could be from the user |
269 | * (i.e. when s/he enters a value) or a result of formula. |
270 | */ |
271 | const Value value() const; |
272 | |
273 | /** |
274 | * Sets the value for this cell. |
275 | * It also clears all errors, if the value itself is not an error. |
276 | * In addition to this, it calculates the outstring and sets the dirty |
277 | * flags so that a redraw is forced. |
278 | * \param value the new value |
279 | * |
280 | * \see setUserInput, parseUserInput |
281 | */ |
282 | void setValue(const Value& value); |
283 | |
284 | /** |
285 | * Returns the richtext that this cell holds. |
286 | */ |
287 | QSharedPointer<QTextDocument> richText() const; |
288 | |
289 | /** |
290 | * Sets the richtext for this cell. |
291 | * If \p text is empty, richtext is removed. |
292 | * |
293 | * \param text the new richtext |
294 | */ |
295 | void setRichText(QSharedPointer<QTextDocument> text); |
296 | |
297 | /** |
298 | * Return the text the user entered. This could be a value (e.g. "14.03") |
299 | * or a formula (e.g. "=SUM(A1:A10)") |
300 | */ |
301 | QString userInput() const; |
302 | |
303 | /** |
304 | * Sets the user input without parsing it. |
305 | * If \p text is a formula, creates a formula object and sets \p text as |
306 | * its expression. Otherwise, simply stores \p text as user input. |
307 | * |
308 | * \see parseUserInput, setValue |
309 | */ |
310 | void setUserInput(const QString& text); |
311 | |
312 | /** |
313 | * Sets the user input without parsing it, without clearing existing formulas |
314 | * userinput or rich text. Used during loading of documents only! |
315 | * If \p text is a formula, creates a formula object and sets \p text as |
316 | * its expression. Otherwise, simply stores \p text as user input. |
317 | * |
318 | * \see parseUserInput, setValue |
319 | */ |
320 | void setRawUserInput(const QString& text); |
321 | |
322 | /** |
323 | * Sets the user input and parses it. |
324 | * If \p text is a formula, creates a formula object and sets \p text as |
325 | * its expression. Otherwise, parses \p text, creates an appropriate value, |
326 | * including the proper type, validates the value and, if accepted, stores |
327 | * \p text as the user input and the value as the cell's value. |
328 | * |
329 | * \see setUserInput, setValue |
330 | */ |
331 | void parseUserInput(const QString& text); |
332 | |
333 | /** |
334 | * \ingroup NativeFormat |
335 | */ |
336 | bool load(const KoXmlElement& cell, |
337 | int _xshift, int _yshift, |
338 | Paste::Mode pm = Paste::Normal, |
339 | Paste::Operation op = Paste::OverWrite, |
340 | bool paste = false); |
341 | |
342 | /** |
343 | * \ingroup NativeFormat |
344 | * Save this cell. |
345 | * @param doc document to save cell in |
346 | * @param xOffset x offset |
347 | * @param yOffset y offset |
348 | * @param era set this to true if you want to encode relative references as absolutely (they will be switched |
349 | * back to relative references during decoding) - is used for cutting to clipboard |
350 | * Usually this is false, to only store the properties explicitly set. |
351 | */ |
352 | QDomElement save(QDomDocument& doc, int xOffset = 0, int yOffset = 0, bool era = false); |
353 | |
354 | /** |
355 | * \ingroup NativeFormat |
356 | * Decodes a string into a time value. |
357 | */ |
358 | QTime toTime(const KoXmlElement &element); |
359 | |
360 | /** |
361 | * \ingroup NativeFormat |
362 | * Decodes a string into a date value. |
363 | */ |
364 | QDate toDate(const KoXmlElement &element); |
365 | |
366 | /** |
367 | * \ingroup OpenDocument |
368 | * Loads a cell from an OASIS XML element. |
369 | * @param element An OASIS XML element |
370 | * @param tableContext The loading context assoiated with the XML element |
371 | */ |
372 | bool loadOdf(const KoXmlElement& element, OdfLoadingContext& tableContext, |
373 | const Styles& autoStyles, const QString& cellStyleName, |
374 | QList<ShapeLoadingData>& shapeData); |
375 | |
376 | /** |
377 | * \ingroup OpenDocument |
378 | */ |
379 | bool saveOdf(int row, int column, int &repeated, |
380 | OdfSavingContext& savingContext); |
381 | |
382 | /** |
383 | * Copies the format from \p cell . |
384 | * |
385 | * @see copyAll(Cell *cell) |
386 | */ |
387 | void copyFormat(const Cell& cell); |
388 | |
389 | /** |
390 | * Copies the content from \p cell . |
391 | * |
392 | * @see copyAll(Cell *cell) |
393 | */ |
394 | void copyContent(const Cell& cell); |
395 | |
396 | /** |
397 | * Copies the format and the content from \p cell . |
398 | * |
399 | * @see copyContent( const Cell& cell ) |
400 | * @see copyFormat( const Cell& cell ) |
401 | */ |
402 | void copyAll(const Cell& cell); |
403 | |
404 | /** |
405 | * @return the width of this cell as double |
406 | */ |
407 | double width() const; |
408 | |
409 | /** |
410 | * @return the height of this cell as double |
411 | */ |
412 | double height() const; |
413 | |
414 | /** |
415 | * \return the position of this cell |
416 | */ |
417 | QPoint cellPosition() const; |
418 | |
419 | /** |
420 | * @return true if the cell should be printed in a print out. |
421 | * That's the case, if it has any content, border, backgroundcolor, |
422 | * or background brush. |
423 | * |
424 | * @see Sheet::print |
425 | */ |
426 | bool needsPrinting() const; |
427 | |
428 | // |
429 | //END |
430 | // |
431 | ////////////////////////////////////////////////////////////////////////// |
432 | // |
433 | //BEGIN Merging |
434 | // |
435 | |
436 | /** |
437 | * If this cell is part of a merged cell, then the marker may |
438 | * never reside on this cell. |
439 | * |
440 | * @return true if another cell has this one merged into itself. |
441 | */ |
442 | bool isPartOfMerged() const; |
443 | |
444 | /** |
445 | * \return the merging cell (might be this cell) |
446 | */ |
447 | Cell masterCell() const; |
448 | |
449 | /** |
450 | * Merge a number of cells, i.e. force the cell to occupy other |
451 | * cells space. If '_x' and '_y' are 0 then the merging is |
452 | * disabled. |
453 | * |
454 | * @param _col is the column this cell is assumed to be in. |
455 | * @param _row is the row this cell is assumed to be in. |
456 | * @param _x tells to occupy _x additional cells in the horizontal |
457 | * @param _y tells to occupy _y additional cells in the vertical |
458 | * |
459 | */ |
460 | void mergeCells(int _col, int _row, int _x, int _y); |
461 | |
462 | /** |
463 | * @return true if the cell is forced to obscure other cells. |
464 | */ |
465 | bool doesMergeCells() const; |
466 | |
467 | /** |
468 | * @return the number of obscured cells in the horizontal direction as a |
469 | * result of cell merging (forced obscuring) |
470 | */ |
471 | int mergedXCells() const; |
472 | |
473 | /** |
474 | * @return the number of obscured cells in the vertical direction as a |
475 | * result of cell merging (forced obscuring) |
476 | */ |
477 | int mergedYCells() const; |
478 | |
479 | // |
480 | //END Merging |
481 | // |
482 | ////////////////////////////////////////////////////////////////////////// |
483 | // |
484 | //BEGIN Matrix locking |
485 | // |
486 | |
487 | bool isLocked() const; |
488 | QRect lockedCells() const; |
489 | |
490 | // |
491 | //END Matrix locking |
492 | // |
493 | ////////////////////////////////////////////////////////////////////////// |
494 | // |
495 | //BEGIN Cut & paste |
496 | // |
497 | |
498 | /** |
499 | * Encodes the cell's formula into a text representation. |
500 | * |
501 | * \param fixedReferences encode relative references absolutely (this is used for copying |
502 | * a cell to make the paste operation create a formula that points |
503 | * to the original cells, not the cells at the same relative position) |
504 | * \see decodeFormula() |
505 | */ |
506 | QString encodeFormula(bool fixedReferences = false) const; |
507 | |
508 | /** |
509 | * Decodes a text representation \p text into a formula expression. |
510 | * |
511 | * \see encodeFormula() |
512 | */ |
513 | QString decodeFormula(const QString& text) const; |
514 | |
515 | /** |
516 | * Merges the @p new_text with @p old_text during a paste operation. |
517 | * If both texts represent doubles, then the operation is performed on both |
518 | * values and the result is returned. If both texts represents a formula or |
519 | * one a formula and the other a double value, then a formula is returned. |
520 | * In all other cases @p new_text is returned. |
521 | * |
522 | * @return the merged text. |
523 | */ |
524 | QString pasteOperation(const QString &new_text, const QString &old_text, Paste::Operation op); |
525 | |
526 | // |
527 | //END Cut & paste |
528 | // |
529 | ////////////////////////////////////////////////////////////////////////// |
530 | // |
531 | //BEGIN |
532 | // |
533 | |
534 | /** |
535 | * Parses the formula. |
536 | * @return @c false on error. |
537 | */ |
538 | bool makeFormula(); |
539 | |
540 | // |
541 | //END |
542 | // |
543 | ////////////////////////////////////////////////////////////////////////// |
544 | // |
545 | //BEGIN Effective style attributes |
546 | // |
547 | |
548 | /** returns horizontal alignment, depending on style and value type */ |
549 | int effectiveAlignX() const; |
550 | /** returns true, if cell format is of date type or content is a date */ |
551 | bool isDate() const; |
552 | /** returns true, if cell format is of time type or content is a time */ |
553 | bool isTime() const; |
554 | /** returns true, if cell format is of text type */ |
555 | bool isText() const; |
556 | |
557 | // |
558 | //END Effective style attributes |
559 | // |
560 | ////////////////////////////////////////////////////////////////////////// |
561 | // |
562 | //BEGIN Operators |
563 | // |
564 | |
565 | /** |
566 | * Assignment. |
567 | */ |
568 | Cell& operator=(const Cell& other); |
569 | |
570 | /** |
571 | * Tests whether this cell's location is less than the \p other 's. |
572 | * (QMap support) |
573 | * \note Does not compare the cell attributes/data. |
574 | */ |
575 | bool operator<(const Cell& other) const; |
576 | |
577 | /** |
578 | * Tests for equality with \p other 's location only. |
579 | * (QHash support) |
580 | * \note Does not compare the cell attributes/data. |
581 | */ |
582 | bool operator==(const Cell& other) const; |
583 | |
584 | /** |
585 | * Is null. |
586 | */ |
587 | bool operator!() const; |
588 | |
589 | // |
590 | //END Operators |
591 | // |
592 | ////////////////////////////////////////////////////////////////////////// |
593 | // |
594 | //BEGIN |
595 | // |
596 | |
597 | /** |
598 | * Tests for equality of all cell attributes/data to those in \p other . |
599 | */ |
600 | bool compareData(const Cell& other) const; |
601 | |
602 | protected: |
603 | /** |
604 | * \ingroup OpenDocument |
605 | * Load the text paragraphs from an OASIS XML cell description. |
606 | * @param parent The DOM element representing the cell. |
607 | */ |
608 | void loadOdfCellText(const KoXmlElement& parent, OdfLoadingContext& tableContext, const Styles& autoStyles, const QString& cellStyleName); |
609 | |
610 | /** |
611 | * \ingroup OpenDocument |
612 | */ |
613 | void loadOdfObjects(const KoXmlElement& e, OdfLoadingContext& tableContext, QList<ShapeLoadingData>& shapeData); |
614 | |
615 | |
616 | /** |
617 | * \ingroup OpenDocument |
618 | */ |
619 | void saveOdfAnnotation(KoXmlWriter &xmlwriter); |
620 | public: |
621 | ShapeLoadingData loadOdfObject(const KoXmlElement& element, KoShapeLoadingContext& shapeContext); |
622 | private: |
623 | friend class CellTest; |
624 | |
625 | class Private; |
626 | QSharedDataPointer<Private> d; |
627 | |
628 | /** |
629 | * \ingroup NativeFormat |
630 | */ |
631 | bool loadCellData(const KoXmlElement &text, Paste::Operation op, const QString &dataType = QString()); |
632 | |
633 | /** |
634 | * \ingroup NativeFormat |
635 | */ |
636 | bool saveCellResult(QDomDocument& doc, QDomElement& result, QString str); |
637 | |
638 | /** |
639 | * \ingroup OpenDocument |
640 | */ |
641 | void saveOdfValue(KoXmlWriter &xmlWriter); |
642 | |
643 | /** |
644 | * \ingroup OpenDocument |
645 | * @return the OASIS style's name |
646 | */ |
647 | QString saveOdfCellStyle(KoGenStyle ¤tCellStyle, KoGenStyles &mainStyles); |
648 | }; |
649 | |
650 | inline uint qHash(const Cell& cell) |
651 | { |
652 | return (static_cast<uint>(cell.column()) << 16) + static_cast<uint>(cell.row()); |
653 | } |
654 | |
655 | } // namespace Sheets |
656 | } // namespace Calligra |
657 | |
658 | Q_DECLARE_TYPEINFO(Calligra::Sheets::Cell, Q_MOVABLE_TYPE); |
659 | |
660 | |
661 | /*************************************************************************** |
662 | kDebug support |
663 | ****************************************************************************/ |
664 | |
665 | inline QDebug operator<<(QDebug str, const Calligra::Sheets::Cell& cell) |
666 | { |
667 | return str << qPrintable(QString("%1%2" ).arg(Calligra::Sheets::Cell::columnName(cell.column())).arg(QString::number(cell.row()))); |
668 | } |
669 | |
670 | #endif // CALLIGRA_SHEETS_CELL |
671 | |