1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 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. 14 * 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). 20 * 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. 25 * 26 ************************************************************************/ 27 28 #ifndef SC_CELL_HXX 29 #define SC_CELL_HXX 30 31 #include <stddef.h> 32 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" 44 45 #define USE_MEMPOOL 46 #define TEXTWIDTH_DIRTY 0xffff 47 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 51 52 class ScDocument; 53 class EditTextObject; 54 class ScMatrix; 55 class SvtBroadcaster; 56 class ScCodeArray; 57 class ScProgress; 58 class ScPostIt; 59 60 // ============================================================================ 61 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; 65 66 /** If set, cloned formula cells will start to listen to the document. */ 67 const int SC_CLONECELL_STARTLISTENING = 0x0001; 68 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; 72 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; 76 77 // ============================================================================ 78 79 class SC_DLLPUBLIC ScBaseCell 80 { 81 protected: 82 ~ScBaseCell(); // nicht virtuell -> darf nicht direkt aufgerufen werden 83 84 public: 85 explicit ScBaseCell( CellType eNewType ); 86 87 /** Base copy constructor. Does NOT clone cell note or broadcaster! */ 88 ScBaseCell( const ScBaseCell& rCell ); 89 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; 93 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; 97 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; 101 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(); 105 106 inline CellType GetCellType() const { return (CellType)eCellType; } 107 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; 111 112 // fuer Idle-Berechnung 113 inline sal_uInt16 GetTextWidth() const { return nTextWidth; } 114 inline void SetTextWidth( sal_uInt16 nNew ) { nTextWidth = nNew; } 115 116 inline sal_uInt8 GetScriptType() const { return nScriptType; } 117 inline void SetScriptType( sal_uInt8 nNew ) { nScriptType = nNew; } 118 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(); 131 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(); 142 143 // String- oder EditCell 144 static ScBaseCell* CreateTextCell( const String& rString, ScDocument* ); 145 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() ); 151 152 /** Error code if ScFormulaCell, else 0. */ 153 sal_uInt16 GetErrorCode() const; 154 /** ScFormulaCell with formula::svEmptyCell result, or ScNoteCell (may have been 155 created due to reference to empty cell). */ 156 sal_Bool HasEmptyData() const; 157 sal_Bool HasValueData() const; 158 sal_Bool HasStringData() const; 159 String GetStringData() const; // nur echte Strings 160 161 static sal_Bool CellEqual( const ScBaseCell* pCell1, const ScBaseCell* pCell2 ); 162 163 private: 164 ScBaseCell& operator=( const ScBaseCell& ); 165 166 private: 167 ScPostIt* mpNote; /// The cell note. Cell takes ownership! 168 SvtBroadcaster* mpBroadcaster; /// Broadcaster for changed values. Cell takes ownership! 169 170 protected: 171 sal_uInt16 nTextWidth; 172 sal_uInt8 eCellType; // enum CellType - sal_uInt8 spart Speicher 173 sal_uInt8 nScriptType; 174 }; 175 176 // ============================================================================ 177 178 class SC_DLLPUBLIC ScNoteCell : public ScBaseCell 179 { 180 public: 181 #ifdef USE_MEMPOOL 182 DECL_FIXEDMEMPOOL_NEWDEL( ScNoteCell ) 183 #endif 184 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 ); 189 190 #ifdef DBG_UTIL 191 ~ScNoteCell(); 192 #endif 193 194 private: 195 ScNoteCell( const ScNoteCell& ); 196 }; 197 198 // ============================================================================ 199 200 class SC_DLLPUBLIC ScValueCell : public ScBaseCell 201 { 202 public: 203 #ifdef USE_MEMPOOL 204 DECL_FIXEDMEMPOOL_NEWDEL( ScValueCell ) 205 #endif 206 ScValueCell(); 207 explicit ScValueCell( double fValue ); 208 209 #ifdef DBG_UTIL 210 ~ScValueCell(); 211 #endif 212 213 inline void SetValue( double fValue ) { mfValue = fValue; } 214 inline double GetValue() const { return mfValue; } 215 216 private: 217 double mfValue; 218 }; 219 220 // ============================================================================ 221 222 class SC_DLLPUBLIC ScStringCell : public ScBaseCell 223 { 224 public: 225 #ifdef USE_MEMPOOL 226 DECL_FIXEDMEMPOOL_NEWDEL( ScStringCell ) 227 #endif 228 229 ScStringCell(); 230 explicit ScStringCell( const String& rString ); 231 232 #ifdef DBG_UTIL 233 ~ScStringCell(); 234 #endif 235 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; } 239 240 private: 241 String maString; 242 }; 243 244 // ============================================================================ 245 246 class SC_DLLPUBLIC ScEditCell : public ScBaseCell 247 { 248 private: 249 EditTextObject* pData; 250 String* pString; // fuer schnelleren Zugriff von Formeln 251 ScDocument* pDoc; // fuer EditEngine Zugriff mit Pool 252 253 void SetTextObject( const EditTextObject* pObject, 254 const SfxItemPool* pFromPool ); 255 256 // not implemented 257 ScEditCell( const ScEditCell& ); 258 259 public: 260 261 #ifdef USE_MEMPOOL 262 DECL_FIXEDMEMPOOL_NEWDEL( ScEditCell ) 263 #endif 264 265 ~ScEditCell(); // wegen pData immer! 266 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* ); 272 273 void SetData( const EditTextObject* pObject, 274 const SfxItemPool* pFromPool /* = NULL */ ); 275 void GetData( const EditTextObject*& rpObject ) const; 276 void GetString( String& rString ) const; 277 278 const EditTextObject* GetData() const { return pData; } 279 }; 280 281 // ============================================================================ 282 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) 288 }; 289 290 class SC_DLLPUBLIC ScFormulaCell : public ScBaseCell, public SvtListener 291 { 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 sal_uLong nFormatIndex; // Number format set by calculation 302 short nFormatType; // Number format type set by calculation 303 sal_uInt16 nSeenInIteration; // Iteration cycle in which the cell was last encountered 304 sal_uInt8 cMatrixFlag; // One of ScMatrixMode 305 sal_Bool bDirty : 1; // Must be (re)calculated 306 sal_Bool bChanged : 1; // Whether something changed regarding display/representation 307 sal_Bool bRunning : 1; // Already interpreting right now 308 sal_Bool bCompile : 1; // Must be (re)compiled 309 sal_Bool bSubTotal : 1; // Cell is part of or contains a SubTotal 310 sal_Bool bIsIterCell : 1; // Cell is part of a circular reference 311 sal_Bool bInChangeTrack : 1; // Cell is in ChangeTrack 312 sal_Bool bTableOpDirty : 1; // Dirty flag for TableOp 313 sal_Bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference 314 315 enum ScInterpretTailParameter 316 { 317 SCITP_NORMAL, 318 SCITP_FROM_ITERATION, 319 SCITP_CLOSE_ITERATION_CIRCLE 320 }; 321 void InterpretTail( ScInterpretTailParameter ); 322 323 ScFormulaCell( const ScFormulaCell& ); 324 325 public: 326 327 #ifdef USE_MEMPOOL 328 DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell ) 329 #endif 330 331 ScAddress aPos; 332 333 ~ScFormulaCell(); 334 ScFormulaCell(); 335 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 sal_uInt8 = MM_NONE ); 340 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 sal_uInt8 cMatInd = MM_NONE ); 349 350 ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT ); 351 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; 356 357 void SetDirty(); 358 inline void SetDirtyVar() { bDirty = sal_True; } 359 // If setting entire document dirty after load, no broadcasts but still append to FormulaTree. 360 void SetDirtyAfterLoad(); 361 inline void ResetTableOpDirtyVar() { bTableOpDirty = sal_False; } 362 void SetTableOpDirty(); 363 sal_Bool IsDirtyOrInTableOpDirty() const; 364 sal_Bool GetDirty() const { return bDirty; } 365 sal_Bool NeedsListening() const { return bNeedListening; } 366 void SetNeedsListening( sal_Bool bVar ) { bNeedListening = bVar; } 367 void Compile(const String& rFormula, 368 sal_Bool bNoListening = sal_False, 369 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ); 370 void CompileTokenArray( sal_Bool bNoListening = sal_False ); 371 void CompileXML( ScProgress& rProgress ); // compile temporary string tokens 372 void CalcAfterLoad(); 373 bool MarkUsedExternalReferences(); 374 void Interpret(); 375 inline sal_Bool IsIterCell() const { return bIsIterCell; } 376 inline sal_uInt16 GetSeenInIteration() const { return nSeenInIteration; } 377 378 sal_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. 384 385 It is similar to HasOneReference(), but more general. 386 */ 387 bool HasRefListExpressibleAsOneReference(ScRange& rRange) const; 388 sal_Bool HasRelNameReference() const; 389 sal_Bool HasColRowName() const; 390 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 ); 396 397 void TransposeReference(); 398 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, 399 ScDocument* pUndoDoc ); 400 401 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY ); 402 403 void UpdateInsertTab(SCTAB nTable); 404 void UpdateInsertTabAbs(SCTAB nTable); 405 sal_Bool UpdateDeleteTab(SCTAB nTable, sal_Bool bIsMove = sal_False); 406 void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo); 407 void UpdateRenameTab(SCTAB nTable, const String& rName); 408 sal_Bool TestTabRefAbs(SCTAB nTable); 409 void UpdateCompile( sal_Bool bForceIfNameInUse = sal_False ); 410 sal_Bool IsRangeNameInUse(sal_uInt16 nIndex) const; 411 void FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const; 412 void ReplaceRangeNamesInUse( const ScRangeData::IndexMap& rMap ); 413 sal_Bool IsSubTotal() const { return bSubTotal; } 414 sal_Bool IsChanged() const { return bChanged; } 415 void ResetChanged() { bChanged = sal_False; } 416 sal_Bool IsEmpty(); // formula::svEmptyCell result 417 // display as empty string if formula::svEmptyCell result 418 sal_Bool IsEmptyDisplayedAsString(); 419 sal_Bool IsValue(); // also sal_True if formula::svEmptyCell 420 double GetValue(); 421 double GetValueAlways(); // ignore errors 422 void GetString( String& rString ); 423 const ScMatrix* GetMatrix(); 424 sal_Bool GetMatrixOrigin( ScAddress& rPos ) const; 425 void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows ); 426 sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos ); 427 sal_uInt16 GetErrCode(); // interpret first if necessary 428 sal_uInt16 GetRawError(); // don't interpret, just return code or result error 429 short GetFormatType() const { return nFormatType; } 430 sal_uLong GetFormatIndex() const { return nFormatIndex; } 431 void GetFormatInfo( short& nType, sal_uLong& nIndex ) const 432 { nType = nFormatType; nIndex = nFormatIndex; } 433 sal_uInt8 GetMatrixFlag() const { return cMatrixFlag; } 434 ScTokenArray* GetCode() const { return pCode; } 435 436 sal_Bool IsRunning() const { return bRunning; } 437 void SetRunning( sal_Bool bVal ) { bRunning = bVal; } 438 void CompileDBFormula(); 439 void CompileDBFormula( sal_Bool bCreateFormulaString ); 440 void CompileNameFormula( sal_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; } 450 451 virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint); 452 void SetCompile( sal_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; 456 457 // ob Zelle im ChangeTrack und nicht im echten Dokument ist 458 void SetInChangeTrack( sal_Bool bVal ) { bInChangeTrack = bVal; } 459 sal_Bool IsInChangeTrack() const { return bInChangeTrack; } 460 461 // Zu Typ und Format das entsprechende Standardformat. 462 // Bei Format "Standard" evtl. das in die Formelzelle 463 // uebernommene Format. 464 sal_uLong GetStandardFormat( SvNumberFormatter& rFormatter, sal_uLong nFormat ) const; 465 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( sal_uInt16 n ); 484 inline sal_Bool IsHyperLinkCell() const { return pCode && pCode->IsHyperLink(); } 485 EditTextObject* CreateURLObject() ; 486 void GetURLResult( String& rURL, String& rCellText ); 487 488 /** Determines whether or not the result string contains more than one paragraph */ 489 bool IsMultilineResult(); 490 }; 491 492 // Iterator fuer Referenzen in einer Formelzelle 493 class ScDetectiveRefIter 494 { 495 private: 496 ScTokenArray* pCode; 497 ScAddress aPos; 498 public: 499 ScDetectiveRefIter( ScFormulaCell* pCell ); 500 sal_Bool GetNextRef( ScRange& rRange ); 501 }; 502 503 // ============================================================================ 504 505 #endif 506 507