xref: /aoo42x/main/sc/inc/cell.hxx (revision cdf0e10c)
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