merged tag ooo/OOO330_m14
[LibreOffice.git] / sc / inc / cell.hxx
blobad9ed02a0415b4ae904bdebfde2a65dadc920d39
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #ifndef SC_CELL_HXX
29 #define SC_CELL_HXX
31 #include <stddef.h>
33 #include <set>
34 #include <tools/mempool.hxx>
35 #include <svl/listener.hxx>
36 #include "global.hxx"
37 #include "rangenam.hxx"
38 #include "formula/grammar.hxx"
39 #include "tokenarray.hxx"
40 #include "formularesult.hxx"
41 #include <rtl/ustrbuf.hxx>
42 #include <unotools/fontcvt.hxx>
43 #include "scdllapi.h"
45 #define USE_MEMPOOL
46 #define TEXTWIDTH_DIRTY 0xffff
48 // in addition to SCRIPTTYPE_... flags from scripttypeitem.hxx:
49 // set (in nScriptType) if type has not been determined yet
50 #define SC_SCRIPTTYPE_UNKNOWN 0x08
52 class ScDocument;
53 class EditTextObject;
54 class ScMatrix;
55 class SvtBroadcaster;
56 class ScCodeArray;
57 class ScProgress;
58 class ScPostIt;
60 // ============================================================================
62 /** Default cell clone flags: do not start listening, do not adjust 3D refs to
63 old position, clone note captions of cell notes. */
64 const int SC_CLONECELL_DEFAULT = 0x0000;
66 /** If set, cloned formula cells will start to listen to the document. */
67 const int SC_CLONECELL_STARTLISTENING = 0x0001;
69 /** If set, relative 3D references of cloned formula cells will be adjusted to
70 old position (used while swapping cells for sorting a cell range). */
71 const int SC_CLONECELL_ADJUST3DREL = 0x0002;
73 /** If set, the caption object of a cell note will not be cloned (used while
74 copying cells to undo document, where captions are handled in drawing undo). */
75 const int SC_CLONECELL_NOCAPTION = 0x0004;
77 // ============================================================================
79 class SC_DLLPUBLIC ScBaseCell
81 protected:
82 ~ScBaseCell(); // nicht virtuell -> darf nicht direkt aufgerufen werden
84 public:
85 explicit ScBaseCell( CellType eNewType );
87 /** Base copy constructor. Does NOT clone cell note or broadcaster! */
88 ScBaseCell( const ScBaseCell& rCell );
90 /** Returns a clone of this cell at the same position, cell note and
91 broadcaster will not be cloned. */
92 ScBaseCell* CloneWithoutNote( ScDocument& rDestDoc, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
94 /** Returns a clone of this cell for the passed document position, cell
95 note and broadcaster will not be cloned. */
96 ScBaseCell* CloneWithoutNote( ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
98 /** Returns a clone of this cell, clones cell note and caption object too
99 (unless SC_CLONECELL_NOCAPTION flag is set). Broadcaster will not be cloned. */
100 ScBaseCell* CloneWithNote( const ScAddress& rOwnPos, ScDocument& rDestDoc, const ScAddress& rDestPos, int nCloneFlags = SC_CLONECELL_DEFAULT ) const;
102 /** Due to the fact that ScBaseCell does not have a vtable, this function
103 deletes the cell by calling the appropriate d'tor of the derived class. */
104 void Delete();
106 inline CellType GetCellType() const { return (CellType)eCellType; }
108 /** Returns true, if the cell is empty (neither value nor formula nor cell note).
109 Returns false for formula cells returning nothing, use HasEmptyData() for that. */
110 bool IsBlank( bool bIgnoreNotes = false ) const;
112 // fuer Idle-Berechnung
113 inline USHORT GetTextWidth() const { return nTextWidth; }
114 inline void SetTextWidth( USHORT nNew ) { nTextWidth = nNew; }
116 inline BYTE GetScriptType() const { return nScriptType; }
117 inline void SetScriptType( BYTE nNew ) { nScriptType = nNew; }
119 /** Returns true, if the cell contains a note. */
120 inline bool HasNote() const { return mpNote != 0; }
121 /** Returns the pointer to a cell note object (read-only). */
122 inline const ScPostIt* GetNote() const { return mpNote; }
123 /** Returns the pointer to a cell note object. */
124 inline ScPostIt* GetNote() { return mpNote; }
125 /** Takes ownership of the passed cell note object. */
126 void TakeNote( ScPostIt* pNote );
127 /** Returns and forgets the own cell note object. Caller takes ownership! */
128 ScPostIt* ReleaseNote();
129 /** Deletes the own cell note object. */
130 void DeleteNote();
132 /** Returns true, if the cell contains a broadcaster. */
133 inline bool HasBroadcaster() const { return mpBroadcaster != 0; }
134 /** Returns the pointer to the cell broadcaster. */
135 inline SvtBroadcaster* GetBroadcaster() const { return mpBroadcaster; }
136 /** Takes ownership of the passed cell broadcaster. */
137 void TakeBroadcaster( SvtBroadcaster* pBroadcaster );
138 /** Returns and forgets the own cell broadcaster. Caller takes ownership! */
139 SvtBroadcaster* ReleaseBroadcaster();
140 /** Deletes the own cell broadcaster. */
141 void DeleteBroadcaster();
143 // String- oder EditCell
144 static ScBaseCell* CreateTextCell( const String& rString, ScDocument* );
146 // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
147 void StartListeningTo( ScDocument* pDoc );
148 void EndListeningTo( ScDocument* pDoc,
149 ScTokenArray* pArr = NULL,
150 ScAddress aPos = ScAddress() );
152 /** Error code if ScFormulaCell, else 0. */
153 USHORT GetErrorCode() const;
154 /** ScFormulaCell with formula::svEmptyCell result, or ScNoteCell (may have been
155 created due to reference to empty cell). */
156 BOOL HasEmptyData() const;
157 BOOL HasValueData() const;
158 BOOL HasStringData() const;
159 String GetStringData() const; // nur echte Strings
161 static BOOL CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 );
163 private:
164 ScBaseCell& operator=( const ScBaseCell& );
166 private:
167 ScPostIt* mpNote; /// The cell note. Cell takes ownership!
168 SvtBroadcaster* mpBroadcaster; /// Broadcaster for changed values. Cell takes ownership!
170 protected:
171 USHORT nTextWidth;
172 BYTE eCellType; // enum CellType - BYTE spart Speicher
173 BYTE nScriptType;
176 // ============================================================================
178 class SC_DLLPUBLIC ScNoteCell : public ScBaseCell
180 public:
181 #ifdef USE_MEMPOOL
182 DECL_FIXEDMEMPOOL_NEWDEL( ScNoteCell )
183 #endif
185 /** Cell takes ownership of the passed broadcaster. */
186 explicit ScNoteCell( SvtBroadcaster* pBC = 0 );
187 /** Cell takes ownership of the passed note and broadcaster. */
188 explicit ScNoteCell( ScPostIt* pNote, SvtBroadcaster* pBC = 0 );
190 #ifdef DBG_UTIL
191 ~ScNoteCell();
192 #endif
194 private:
195 ScNoteCell( const ScNoteCell& );
198 // ============================================================================
200 class SC_DLLPUBLIC ScValueCell : public ScBaseCell
202 public:
203 #ifdef USE_MEMPOOL
204 DECL_FIXEDMEMPOOL_NEWDEL( ScValueCell )
205 #endif
206 ScValueCell();
207 explicit ScValueCell( double fValue );
209 #ifdef DBG_UTIL
210 ~ScValueCell();
211 #endif
213 inline void SetValue( double fValue ) { mfValue = fValue; }
214 inline double GetValue() const { return mfValue; }
216 private:
217 double mfValue;
220 // ============================================================================
222 class SC_DLLPUBLIC ScStringCell : public ScBaseCell
224 public:
225 #ifdef USE_MEMPOOL
226 DECL_FIXEDMEMPOOL_NEWDEL( ScStringCell )
227 #endif
229 ScStringCell();
230 explicit ScStringCell( const String& rString );
232 #ifdef DBG_UTIL
233 ~ScStringCell();
234 #endif
236 inline void SetString( const String& rString ) { maString = rString; }
237 inline void GetString( String& rString ) const { rString = maString; }
238 inline const String& GetString() const { return maString; }
240 private:
241 String maString;
244 // ============================================================================
246 class SC_DLLPUBLIC ScEditCell : public ScBaseCell
248 private:
249 EditTextObject* pData;
250 String* pString; // fuer schnelleren Zugriff von Formeln
251 ScDocument* pDoc; // fuer EditEngine Zugriff mit Pool
253 void SetTextObject( const EditTextObject* pObject,
254 const SfxItemPool* pFromPool );
256 // not implemented
257 ScEditCell( const ScEditCell& );
259 public:
261 #ifdef USE_MEMPOOL
262 DECL_FIXEDMEMPOOL_NEWDEL( ScEditCell )
263 #endif
265 ~ScEditCell(); // wegen pData immer!
267 ScEditCell( const EditTextObject* pObject, ScDocument*,
268 const SfxItemPool* pFromPool /* = NULL */ );
269 ScEditCell( const ScEditCell& rCell, ScDocument& rDoc );
270 // fuer Zeilenumbrueche
271 ScEditCell( const String& rString, ScDocument* );
273 void SetData( const EditTextObject* pObject,
274 const SfxItemPool* pFromPool /* = NULL */ );
275 void GetData( const EditTextObject*& rpObject ) const;
276 void GetString( String& rString ) const;
278 const EditTextObject* GetData() const { return pData; }
281 // ============================================================================
283 enum ScMatrixMode {
284 MM_NONE = 0, // No matrix formula
285 MM_FORMULA = 1, // Upper left matrix formula cell
286 MM_REFERENCE = 2, // Remaining cells, via ocMatRef reference token
287 MM_FAKE = 3 // Interpret "as-if" matrix formula (legacy)
290 class SC_DLLPUBLIC ScFormulaCell : public ScBaseCell, public SvtListener
292 private:
293 ScFormulaResult aResult;
294 formula::FormulaGrammar::Grammar eTempGrammar; // used between string (creation) and (re)compilation
295 ScTokenArray* pCode; // The (new) token array
296 ScDocument* pDocument;
297 ScFormulaCell* pPrevious;
298 ScFormulaCell* pNext;
299 ScFormulaCell* pPreviousTrack;
300 ScFormulaCell* pNextTrack;
301 ULONG nFormatIndex; // Number format set by calculation
302 short nFormatType; // Number format type set by calculation
303 USHORT nSeenInIteration; // Iteration cycle in which the cell was last encountered
304 BYTE cMatrixFlag; // One of ScMatrixMode
305 BOOL bDirty : 1; // Must be (re)calculated
306 BOOL bChanged : 1; // Whether something changed regarding display/representation
307 BOOL bRunning : 1; // Already interpreting right now
308 BOOL bCompile : 1; // Must be (re)compiled
309 BOOL bSubTotal : 1; // Cell is part of or contains a SubTotal
310 BOOL bIsIterCell : 1; // Cell is part of a circular reference
311 BOOL bInChangeTrack : 1; // Cell is in ChangeTrack
312 BOOL bTableOpDirty : 1; // Dirty flag for TableOp
313 BOOL bNeedListening : 1; // Listeners need to be re-established after UpdateReference
315 enum ScInterpretTailParameter
317 SCITP_NORMAL,
318 SCITP_FROM_ITERATION,
319 SCITP_CLOSE_ITERATION_CIRCLE
321 void InterpretTail( ScInterpretTailParameter );
323 ScFormulaCell( const ScFormulaCell& );
325 public:
327 #ifdef USE_MEMPOOL
328 DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
329 #endif
331 ScAddress aPos;
333 ~ScFormulaCell();
334 ScFormulaCell();
336 /** Empty formula cell, or with a preconstructed token array. */
337 ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL,
338 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
339 BYTE = MM_NONE );
341 /** With formula string and grammar to compile with.
342 formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
343 also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
344 convention associated with rPos::nTab by default. */
345 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
346 const String& rFormula,
347 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
348 BYTE cMatInd = MM_NONE );
350 ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
352 void GetFormula( String& rFormula,
353 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
354 void GetFormula( rtl::OUStringBuffer& rBuffer,
355 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
357 void SetDirty();
358 inline void SetDirtyVar() { bDirty = TRUE; }
359 // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
360 void SetDirtyAfterLoad();
361 inline void ResetTableOpDirtyVar() { bTableOpDirty = FALSE; }
362 void SetTableOpDirty();
363 BOOL IsDirtyOrInTableOpDirty() const;
364 BOOL GetDirty() const { return bDirty; }
365 BOOL NeedsListening() const { return bNeedListening; }
366 void SetNeedsListening( BOOL bVar ) { bNeedListening = bVar; }
367 void Compile(const String& rFormula,
368 BOOL bNoListening = FALSE,
369 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT );
370 void CompileTokenArray( BOOL bNoListening = FALSE );
371 void CompileXML( ScProgress& rProgress ); // compile temporary string tokens
372 void CalcAfterLoad();
373 bool MarkUsedExternalReferences();
374 void Interpret();
375 inline BOOL IsIterCell() const { return bIsIterCell; }
376 inline USHORT GetSeenInIteration() const { return nSeenInIteration; }
378 BOOL HasOneReference( ScRange& r ) const;
379 /* Checks if the formula contains reference list that can be
380 expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
381 reference list is not required to be sorted (i.e. A3;A1;A2 is
382 still recognized as A1:A3), but no overlapping is allowed.
383 If one reference is recognized, the rRange is filled.
385 It is similar to HasOneReference(), but more general.
387 bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
388 BOOL HasRelNameReference() const;
389 BOOL HasColRowName() const;
391 void UpdateReference(UpdateRefMode eUpdateRefMode,
392 const ScRange& r,
393 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
394 ScDocument* pUndoDoc = NULL,
395 const ScAddress* pUndoCellPos = NULL );
397 void TransposeReference();
398 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
399 ScDocument* pUndoDoc );
401 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
403 void UpdateInsertTab(SCTAB nTable);
404 void UpdateInsertTabAbs(SCTAB nTable);
405 BOOL UpdateDeleteTab(SCTAB nTable, BOOL bIsMove = FALSE);
406 void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo);
407 void UpdateRenameTab(SCTAB nTable, const String& rName);
408 BOOL TestTabRefAbs(SCTAB nTable);
409 void UpdateCompile( BOOL bForceIfNameInUse = FALSE );
410 BOOL IsRangeNameInUse(USHORT nIndex) const;
411 void FindRangeNamesInUse(std::set<USHORT>& rIndexes) const;
412 void ReplaceRangeNamesInUse( const ScRangeData::IndexMap& rMap );
413 BOOL IsSubTotal() const { return bSubTotal; }
414 BOOL IsChanged() const { return bChanged; }
415 void ResetChanged() { bChanged = FALSE; }
416 BOOL IsEmpty(); // formula::svEmptyCell result
417 // display as empty string if formula::svEmptyCell result
418 BOOL IsEmptyDisplayedAsString();
419 BOOL IsValue(); // also TRUE if formula::svEmptyCell
420 double GetValue();
421 double GetValueAlways(); // ignore errors
422 void GetString( String& rString );
423 const ScMatrix* GetMatrix();
424 BOOL GetMatrixOrigin( ScAddress& rPos ) const;
425 void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
426 USHORT GetMatrixEdge( ScAddress& rOrgPos );
427 USHORT GetErrCode(); // interpret first if necessary
428 USHORT GetRawError(); // don't interpret, just return code or result error
429 short GetFormatType() const { return nFormatType; }
430 ULONG GetFormatIndex() const { return nFormatIndex; }
431 void GetFormatInfo( short& nType, ULONG& nIndex ) const
432 { nType = nFormatType; nIndex = nFormatIndex; }
433 BYTE GetMatrixFlag() const { return cMatrixFlag; }
434 ScTokenArray* GetCode() const { return pCode; }
436 BOOL IsRunning() const { return bRunning; }
437 void SetRunning( BOOL bVal ) { bRunning = bVal; }
438 void CompileDBFormula();
439 void CompileDBFormula( BOOL bCreateFormulaString );
440 void CompileNameFormula( BOOL bCreateFormulaString );
441 void CompileColRowNameFormula();
442 ScFormulaCell* GetPrevious() const { return pPrevious; }
443 ScFormulaCell* GetNext() const { return pNext; }
444 void SetPrevious( ScFormulaCell* pF ) { pPrevious = pF; }
445 void SetNext( ScFormulaCell* pF ) { pNext = pF; }
446 ScFormulaCell* GetPreviousTrack() const { return pPreviousTrack; }
447 ScFormulaCell* GetNextTrack() const { return pNextTrack; }
448 void SetPreviousTrack( ScFormulaCell* pF ) { pPreviousTrack = pF; }
449 void SetNextTrack( ScFormulaCell* pF ) { pNextTrack = pF; }
451 virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
452 void SetCompile( BOOL bVal ) { bCompile = bVal; }
453 ScDocument* GetDocument() const { return pDocument; }
454 void SetMatColsRows( SCCOL nCols, SCROW nRows );
455 void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
457 // ob Zelle im ChangeTrack und nicht im echten Dokument ist
458 void SetInChangeTrack( BOOL bVal ) { bInChangeTrack = bVal; }
459 BOOL IsInChangeTrack() const { return bInChangeTrack; }
461 // Zu Typ und Format das entsprechende Standardformat.
462 // Bei Format "Standard" evtl. das in die Formelzelle
463 // uebernommene Format.
464 ULONG GetStandardFormat( SvNumberFormatter& rFormatter, ULONG nFormat ) const;
466 // For import filters!
467 void AddRecalcMode( formula::ScRecalcMode );
468 /** For import only: set a double result. */
469 void SetHybridDouble( double n ) { aResult.SetHybridDouble( n); }
470 /** For import only: set a string result.
471 If for whatever reason you have to use both, SetHybridDouble() and
472 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
473 for performance reasons.*/
474 void SetHybridString( const String& r )
475 { aResult.SetHybridString( r); }
476 /** For import only: set a temporary formula string to be compiled later.
477 If for whatever reason you have to use both, SetHybridDouble() and
478 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
479 for performance reasons.*/
480 void SetHybridFormula( const String& r,
481 const formula::FormulaGrammar::Grammar eGrammar )
482 { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
483 void SetErrCode( USHORT n );
484 inline BOOL IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); }
485 EditTextObject* CreateURLObject() ;
486 void GetURLResult( String& rURL, String& rCellText );
488 /** Determines whether or not the result string contains more than one paragraph */
489 bool IsMultilineResult();
492 // Iterator fuer Referenzen in einer Formelzelle
493 class ScDetectiveRefIter
495 private:
496 ScTokenArray* pCode;
497 ScAddress aPos;
498 public:
499 ScDetectiveRefIter( ScFormulaCell* pCell );
500 BOOL GetNextRef( ScRange& rRange );
503 // ============================================================================
505 #endif