Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / sc / inc / cell.hxx
blob0322db6e5b9fc5b04f23293dadd1a827bd902eb9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef SC_CELL_HXX
21 #define SC_CELL_HXX
23 #include <stddef.h>
25 #include <set>
26 #include <vector>
27 #include <boost/shared_ptr.hpp>
29 #include <tools/mempool.hxx>
30 #include <svl/listener.hxx>
31 #include "global.hxx"
32 #include "rangenam.hxx"
33 #include "formula/grammar.hxx"
34 #include "tokenarray.hxx"
35 #include "formularesult.hxx"
36 #include <rtl/ustrbuf.hxx>
37 #include <unotools/fontcvt.hxx>
38 #include "scdllapi.h"
40 #define USE_MEMPOOL
41 #define TEXTWIDTH_DIRTY 0xffff
43 // in addition to SCRIPTTYPE_... flags from scripttypeitem.hxx:
44 // set (in nScriptType) if type has not been determined yet
45 #define SC_SCRIPTTYPE_UNKNOWN 0x08
47 class ScDocument;
48 class EditTextObject;
49 class ScMatrix;
50 class SvtBroadcaster;
51 class ScProgress;
52 class ScPatternAttr;
54 // ============================================================================
56 /** Default cell clone flags: do not start listening, do not adjust 3D refs to
57 old position, clone note captions of cell notes. */
58 const int SC_CLONECELL_DEFAULT = 0x0000;
60 /** If set, cloned formula cells will start to listen to the document. */
61 const int SC_CLONECELL_STARTLISTENING = 0x0001;
63 /** If set, relative 3D references of cloned formula cells will be adjusted to
64 old position (used while swapping cells for sorting a cell range). */
65 const int SC_CLONECELL_ADJUST3DREL = 0x0002;
67 /** If set, the caption object of a cell note will not be cloned (used while
68 copying cells to undo document, where captions are handled in drawing undo). */
69 const int SC_CLONECELL_NOCAPTION = 0x0004;
71 /** If set, absolute refs will not transformed to external references */
72 const int SC_CLONECELL_NOMAKEABS_EXTERNAL = 0x0008;
73 // ============================================================================
75 class SC_DLLPUBLIC ScBaseCell
77 protected:
78 ~ScBaseCell(); // not virtual - not to be called directly.
80 public:
81 explicit ScBaseCell( CellType eNewType );
83 /** Base copy constructor. Does NOT clone cell note or broadcaster! */
84 ScBaseCell( const ScBaseCell& rCell );
86 /** Returns a clone of this cell at the same position,
87 broadcaster will not be cloned. */
88 ScBaseCell* Clone( ScDocument& rDestDoc, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
90 /** Returns a clone of this cell for the passed document position,
91 broadcaster will not be cloned. */
92 ScBaseCell* Clone( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
94 /** Due to the fact that ScBaseCell does not have a vtable, this function
95 deletes the cell by calling the appropriate d'tor of the derived class. */
96 void Delete();
98 inline CellType GetCellType() const { return (CellType)eCellType; }
100 /** Returns true, if the cell is empty (neither value nor formula nor cell note).
101 Returns false for formula cells returning nothing, use HasEmptyData() for that. */
102 bool IsBlank() const;
104 // for idle-calculations
105 inline sal_uInt16 GetTextWidth() const { return nTextWidth; }
106 inline void SetTextWidth( sal_uInt16 nNew ) { nTextWidth = nNew; }
108 inline sal_uInt8 GetScriptType() const { return nScriptType; }
109 inline void SetScriptType( sal_uInt8 nNew ) { nScriptType = nNew; }
111 /** Returns true, if the cell contains a broadcaster. */
112 inline bool HasBroadcaster() const { return mpBroadcaster != 0; }
113 /** Returns the pointer to the cell broadcaster. */
114 inline SvtBroadcaster* GetBroadcaster() const { return mpBroadcaster; }
115 /** Takes ownership of the passed cell broadcaster. */
116 void TakeBroadcaster( SvtBroadcaster* pBroadcaster );
117 /** Returns and forgets the own cell broadcaster. Caller takes ownership! */
118 SvtBroadcaster* ReleaseBroadcaster();
119 /** Deletes the own cell broadcaster. */
120 void DeleteBroadcaster();
122 // String- oder EditCell
123 static ScBaseCell* CreateTextCell( const rtl::OUString& rString, ScDocument* );
125 // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
126 void StartListeningTo( ScDocument* pDoc );
127 void EndListeningTo( ScDocument* pDoc,
128 ScTokenArray* pArr = NULL,
129 ScAddress aPos = ScAddress() );
131 /** Error code if ScFormulaCell, else 0. */
132 sal_uInt16 GetErrorCode() const;
133 /** ScFormulaCell with formula::svEmptyCell result, or ScNoteCell (may have been
134 created due to reference to empty cell). */
135 bool HasEmptyData() const;
136 bool HasValueData() const;
137 bool HasStringData() const;
138 rtl::OUString GetStringData() const; // only real strings
140 static bool CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 );
142 private:
143 ScBaseCell& operator=( const ScBaseCell& );
145 private:
146 SvtBroadcaster* mpBroadcaster; /// Broadcaster for changed values. Cell takes ownership!
148 protected:
149 sal_uInt16 nTextWidth;
150 sal_uInt8 eCellType; // enum CellType - sal_uInt8 spart Speicher
151 sal_uInt8 nScriptType;
154 // ============================================================================
156 class SC_DLLPUBLIC ScNoteCell : public ScBaseCell
158 public:
159 #ifdef USE_MEMPOOL
160 DECL_FIXEDMEMPOOL_NEWDEL( ScNoteCell )
161 #endif
163 /** Cell takes ownership of the passed broadcaster. */
164 explicit ScNoteCell( SvtBroadcaster* pBC = 0 );
166 #if OSL_DEBUG_LEVEL > 0
167 ~ScNoteCell();
168 #endif
170 private:
171 ScNoteCell( const ScNoteCell& );
174 class SC_DLLPUBLIC ScValueCell : public ScBaseCell
176 public:
177 #ifdef USE_MEMPOOL
178 DECL_FIXEDMEMPOOL_NEWDEL( ScValueCell )
179 #endif
181 explicit ScValueCell( double fValue );
183 #if OSL_DEBUG_LEVEL > 0
184 ~ScValueCell();
185 #endif
187 inline void SetValue( double fValue ) { mfValue = fValue; }
188 inline double GetValue() const { return mfValue; }
190 private:
191 double mfValue;
194 class SC_DLLPUBLIC ScStringCell : public ScBaseCell
196 public:
197 #ifdef USE_MEMPOOL
198 DECL_FIXEDMEMPOOL_NEWDEL( ScStringCell )
199 #endif
201 explicit ScStringCell(const rtl::OUString& rString);
203 #if OSL_DEBUG_LEVEL > 0
204 ~ScStringCell();
205 #endif
207 inline void SetString( const rtl::OUString& rString ) { maString = rString; }
208 inline const rtl::OUString& GetString() const { return maString; }
210 private:
211 rtl::OUString maString;
214 class SC_DLLPUBLIC ScEditCell : public ScBaseCell
216 private:
217 EditTextObject* pData;
218 mutable rtl::OUString* pString; // for faster access to formulas
219 ScDocument* pDoc; // for EditEngine access with Pool
221 void SetTextObject( const EditTextObject* pObject,
222 const SfxItemPool* pFromPool );
224 // not implemented
225 ScEditCell( const ScEditCell& );
227 public:
229 #ifdef USE_MEMPOOL
230 DECL_FIXEDMEMPOOL_NEWDEL( ScEditCell )
231 #endif
233 ~ScEditCell(); // always because of pData!
235 ScEditCell( const EditTextObject* pObject, ScDocument*,
236 const SfxItemPool* pFromPool /* = NULL */ );
237 ScEditCell(const ScEditCell& rCell, ScDocument& rDoc, const ScAddress& rDestPos);
238 // for line breaks
239 ScEditCell( const rtl::OUString& rString, ScDocument* );
241 void SetData( const EditTextObject* pObject,
242 const SfxItemPool* pFromPool /* = NULL */ );
243 void GetData( const EditTextObject*& rpObject ) const;
244 rtl::OUString GetString() const;
246 const EditTextObject* GetData() const { return pData; }
248 /** Removes character attribute based on new pattern attributes. */
249 void RemoveCharAttribs( const ScPatternAttr& rAttr );
251 /** Update field items if any. */
252 void UpdateFields(SCTAB nTab);
255 class ScEditDataArray
257 public:
258 class Item
260 public:
261 explicit Item(SCTAB nTab, SCCOL nCol, SCROW nRow,
262 EditTextObject* pOldData, EditTextObject* pNewData);
263 ~Item();
265 const EditTextObject* GetOldData() const;
266 const EditTextObject* GetNewData() const;
267 SCTAB GetTab() const;
268 SCCOL GetCol() const;
269 SCROW GetRow() const;
271 private:
272 Item(); // disabled
274 private:
275 ::boost::shared_ptr<EditTextObject> mpOldData;
276 ::boost::shared_ptr<EditTextObject> mpNewData;
277 SCTAB mnTab;
278 SCCOL mnCol;
279 SCROW mnRow;
283 ScEditDataArray();
284 ~ScEditDataArray();
286 void AddItem(SCTAB nTab, SCCOL nCol, SCROW nRow,
287 EditTextObject* pOldData, EditTextObject* pNewData);
289 const Item* First();
290 const Item* Next();
292 private:
293 ::std::vector<Item>::const_iterator maIter;
294 ::std::vector<Item> maArray;
297 enum ScMatrixMode {
298 MM_NONE = 0, // No matrix formula
299 MM_FORMULA = 1, // Upper left matrix formula cell
300 MM_REFERENCE = 2, // Remaining cells, via ocMatRef reference token
301 MM_FAKE = 3 // Interpret "as-if" matrix formula (legacy)
304 class SC_DLLPUBLIC ScFormulaCell : public ScBaseCell, public SvtListener
306 private:
307 ScFormulaResult aResult;
308 formula::FormulaGrammar::Grammar eTempGrammar; // used between string (creation) and (re)compilation
309 ScTokenArray* pCode; // The (new) token array
310 ScDocument* pDocument;
311 ScFormulaCell* pPrevious;
312 ScFormulaCell* pNext;
313 ScFormulaCell* pPreviousTrack;
314 ScFormulaCell* pNextTrack;
315 sal_uLong nFormatIndex; // Number format set by calculation
316 short nFormatType; // Number format type set by calculation
317 sal_uInt16 nSeenInIteration; // Iteration cycle in which the cell was last encountered
318 sal_uInt8 cMatrixFlag; // One of ScMatrixMode
319 bool bDirty : 1; // Must be (re)calculated
320 bool bChanged : 1; // Whether something changed regarding display/representation
321 bool bRunning : 1; // Already interpreting right now
322 bool bCompile : 1; // Must be (re)compiled
323 bool bSubTotal : 1; // Cell is part of or contains a SubTotal
324 bool bIsIterCell : 1; // Cell is part of a circular reference
325 bool bInChangeTrack : 1; // Cell is in ChangeTrack
326 bool bTableOpDirty : 1; // Dirty flag for TableOp
327 bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference
329 enum ScInterpretTailParameter
331 SCITP_NORMAL,
332 SCITP_FROM_ITERATION,
333 SCITP_CLOSE_ITERATION_CIRCLE
335 void InterpretTail( ScInterpretTailParameter );
337 ScFormulaCell( const ScFormulaCell& );
339 public:
341 #ifdef USE_MEMPOOL
342 DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
343 #endif
345 ScAddress aPos;
347 ~ScFormulaCell();
349 /** Empty formula cell, or with a preconstructed token array. */
350 ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL,
351 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
352 sal_uInt8 = MM_NONE );
354 /** With formula string and grammar to compile with.
355 formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
356 also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
357 convention associated with rPos::nTab by default. */
358 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
359 const rtl::OUString& rFormula,
360 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
361 sal_uInt8 cMatInd = MM_NONE );
363 ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
365 void GetFormula( rtl::OUString& rFormula,
366 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
367 void GetFormula( rtl::OUStringBuffer& rBuffer,
368 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
370 void SetDirty( bool bDirtyFlag=true );
371 void SetDirtyVar();
372 // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
373 void SetDirtyAfterLoad();
374 inline void ResetTableOpDirtyVar() { bTableOpDirty = false; }
375 void SetTableOpDirty();
376 bool IsDirtyOrInTableOpDirty() const;
377 bool GetDirty() const { return bDirty; }
378 void ResetDirty() { bDirty = false; }
379 bool NeedsListening() const { return bNeedListening; }
380 void SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
381 void Compile(const rtl::OUString& rFormula,
382 bool bNoListening = false,
383 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT );
384 void CompileTokenArray( bool bNoListening = false );
385 void CompileXML( ScProgress& rProgress ); // compile temporary string tokens
386 void CalcAfterLoad();
387 bool MarkUsedExternalReferences();
388 void Interpret();
389 inline bool IsIterCell() const { return bIsIterCell; }
390 inline sal_uInt16 GetSeenInIteration() const { return nSeenInIteration; }
392 bool HasOneReference( ScRange& r ) const;
393 /* Checks if the formula contains reference list that can be
394 expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
395 reference list is not required to be sorted (i.e. A3;A1;A2 is
396 still recognized as A1:A3), but no overlapping is allowed.
397 If one reference is recognized, the rRange is filled.
399 It is similar to HasOneReference(), but more general.
401 bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
402 bool HasRelNameReference() const;
403 bool HasColRowName() const;
405 bool UpdateReference(UpdateRefMode eUpdateRefMode,
406 const ScRange& r,
407 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
408 ScDocument* pUndoDoc = NULL,
409 const ScAddress* pUndoCellPos = NULL );
411 void TransposeReference();
412 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
413 ScDocument* pUndoDoc );
415 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
417 void UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets = 1);
418 void UpdateInsertTabAbs(SCTAB nTable);
419 bool UpdateDeleteTab(SCTAB nTable, bool bIsMove = false, SCTAB nSheets = 1);
420 void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo);
421 void UpdateRenameTab(SCTAB nTable, const rtl::OUString& rName);
422 bool TestTabRefAbs(SCTAB nTable);
423 void UpdateCompile( bool bForceIfNameInUse = false );
424 void FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const;
425 bool IsSubTotal() const { return bSubTotal; }
426 bool IsChanged() const;
427 void ResetChanged();
428 bool IsEmpty(); // formula::svEmptyCell result
429 // display as empty string if formula::svEmptyCell result
430 bool IsEmptyDisplayedAsString();
431 bool IsValue(); // also true if formula::svEmptyCell
432 bool IsHybridValueCell(); // for cells after import to deal with inherited number formats
433 double GetValue();
434 double GetValueAlways(); // ignore errors
435 rtl::OUString GetString();
436 const ScMatrix* GetMatrix();
437 bool GetMatrixOrigin( ScAddress& rPos ) const;
438 void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
439 sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos );
440 sal_uInt16 GetErrCode(); // interpret first if necessary
441 sal_uInt16 GetRawError(); // don't interpret, just return code or result error
442 short GetFormatType() const { return nFormatType; }
443 sal_uLong GetFormatIndex() const { return nFormatIndex; }
444 void GetFormatInfo( short& nType, sal_uLong& nIndex ) const
445 { nType = nFormatType; nIndex = nFormatIndex; }
446 sal_uInt8 GetMatrixFlag() const { return cMatrixFlag; }
447 ScTokenArray* GetCode() const { return pCode; }
449 bool IsRunning() const { return bRunning; }
450 void SetRunning( bool bVal ) { bRunning = bVal; }
451 void CompileDBFormula();
452 void CompileDBFormula( bool bCreateFormulaString );
453 void CompileNameFormula( bool bCreateFormulaString );
454 void CompileColRowNameFormula();
455 ScFormulaCell* GetPrevious() const { return pPrevious; }
456 ScFormulaCell* GetNext() const { return pNext; }
457 void SetPrevious( ScFormulaCell* pF ) { pPrevious = pF; }
458 void SetNext( ScFormulaCell* pF ) { pNext = pF; }
459 ScFormulaCell* GetPreviousTrack() const { return pPreviousTrack; }
460 ScFormulaCell* GetNextTrack() const { return pNextTrack; }
461 void SetPreviousTrack( ScFormulaCell* pF ) { pPreviousTrack = pF; }
462 void SetNextTrack( ScFormulaCell* pF ) { pNextTrack = pF; }
464 virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
465 void SetCompile( bool bVal ) { bCompile = bVal; }
466 ScDocument* GetDocument() const { return pDocument; }
467 void SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
468 void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
470 // cell belongs to ChangeTrack and not to the real document
471 void SetInChangeTrack( bool bVal ) { bInChangeTrack = bVal; }
472 bool IsInChangeTrack() const { return bInChangeTrack; }
474 // standard format for type and format
475 // for format "Standard" possibly the format used in the formula cell
476 sal_uLong GetStandardFormat( SvNumberFormatter& rFormatter, sal_uLong nFormat ) const;
478 // For import filters!
479 void AddRecalcMode( formula::ScRecalcMode );
480 /** For import only: set a double result. */
481 void SetHybridDouble( double n ) { aResult.SetHybridDouble( n); }
482 /** For import only: set a string result.
483 If for whatever reason you have to use both, SetHybridDouble() and
484 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
485 for performance reasons.*/
486 void SetHybridString( const rtl::OUString& r )
487 { aResult.SetHybridString( r); }
488 /** For import only: set a temporary formula string to be compiled later.
489 If for whatever reason you have to use both, SetHybridDouble() and
490 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
491 for performance reasons.*/
492 void SetHybridFormula( const rtl::OUString& r,
493 const formula::FormulaGrammar::Grammar eGrammar )
494 { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
497 * For import only: use for formula cells that return a number
498 * formatted as some kind of string
500 void SetHybridValueString( double nVal, const OUString& r )
501 { aResult.SetHybridValueString( nVal, r ); }
503 void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
505 aResult.SetMatrix(nCols, nRows, pMat, pUL);
508 /** For import only: set a double result.
509 Use this instead of SetHybridDouble() if there is no (temporary)
510 formula string because the formula is present as a token array, as it
511 is the case for binary Excel import.
513 void SetResultDouble( double n ) { aResult.SetDouble( n); }
515 void SetErrCode( sal_uInt16 n );
516 inline bool IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); }
517 EditTextObject* CreateURLObject() ;
518 void GetURLResult( rtl::OUString& rURL, rtl::OUString& rCellText );
520 /** Determines whether or not the result string contains more than one paragraph */
521 bool IsMultilineResult();
523 void MaybeInterpret();
526 // Iterator for references in a formula cell
527 class ScDetectiveRefIter
529 private:
530 ScTokenArray* pCode;
531 ScAddress aPos;
532 public:
533 ScDetectiveRefIter( ScFormulaCell* pCell );
534 bool GetNextRef( ScRange& rRange );
535 ScToken* GetNextRefToken();
538 #endif
540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */