bump product version to 4.1.6.2
[LibreOffice.git] / sc / inc / formulacell.hxx
blobfd4af058f41da104a7327c8c484a7e1b94ba526d
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_FORMULACELL_HXX
21 #define SC_FORMULACELL_HXX
23 #include "cell.hxx"
24 #include "formularesult.hxx"
26 #include "formula/tokenarray.hxx"
27 #include "svl/listener.hxx"
29 #include <set>
31 namespace sc {
33 class StartListeningContext;
34 class EndListeningContext;
38 class ScTokenArray;
39 struct ScSimilarFormulaDelta;
41 struct SC_DLLPUBLIC ScFormulaCellGroup
43 sal_Int32 mnRefCount;
44 SCROW mnStart; // Start offset of that cell
45 SCROW mnLength; // How many of these do we have ?
46 bool mbInvariant;
48 ScFormulaCellGroup();
49 ~ScFormulaCellGroup();
51 inline void intrusive_ptr_add_ref(ScFormulaCellGroup *p)
53 p->mnRefCount++;
55 inline void intrusive_ptr_release(ScFormulaCellGroup *p)
57 if( --p->mnRefCount == 0 )
58 delete p;
61 enum ScMatrixMode {
62 MM_NONE = 0, // No matrix formula
63 MM_FORMULA = 1, // Upper left matrix formula cell
64 MM_REFERENCE = 2, // Remaining cells, via ocMatRef reference token
65 MM_FAKE = 3 // Interpret "as-if" matrix formula (legacy)
68 class SC_DLLPUBLIC ScFormulaCell : public ScBaseCell, public SvtListener
70 private:
71 ScFormulaResult aResult;
72 formula::FormulaGrammar::Grammar eTempGrammar; // used between string (creation) and (re)compilation
73 ScTokenArray* pCode; // The (new) token array
74 ScDocument* pDocument;
75 ScFormulaCell* pPrevious;
76 ScFormulaCell* pNext;
77 ScFormulaCell* pPreviousTrack;
78 ScFormulaCell* pNextTrack;
79 ScFormulaCellGroupRef xGroup; // re-factoring hack - group of formulae we're part of.
80 sal_uInt16 nSeenInIteration; // Iteration cycle in which the cell was last encountered
81 sal_uInt8 cMatrixFlag; // One of ScMatrixMode
82 short nFormatType;
83 bool bDirty : 1; // Must be (re)calculated
84 bool bChanged : 1; // Whether something changed regarding display/representation
85 bool bRunning : 1; // Already interpreting right now
86 bool bCompile : 1; // Must be (re)compiled
87 bool bSubTotal : 1; // Cell is part of or contains a SubTotal
88 bool bIsIterCell : 1; // Cell is part of a circular reference
89 bool bInChangeTrack : 1; // Cell is in ChangeTrack
90 bool bTableOpDirty : 1; // Dirty flag for TableOp
91 bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference
92 bool mbNeedsNumberFormat : 1; // set the calculated number format as hard number format
93 bool mbPostponedDirty : 1; // if cell needs to be set dirty later
95 enum ScInterpretTailParameter
97 SCITP_NORMAL,
98 SCITP_FROM_ITERATION,
99 SCITP_CLOSE_ITERATION_CIRCLE
101 void InterpretTail( ScInterpretTailParameter );
103 ScFormulaCell( const ScFormulaCell& );
104 public:
106 enum CompareState { NotEqual = 0, EqualInvariant, EqualRelativeRef };
108 #ifdef USE_MEMPOOL
109 DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
110 #endif
112 ScAddress aPos;
114 ~ScFormulaCell();
116 using ScBaseCell::Clone;
118 ScFormulaCell* Clone() const;
120 /** Empty formula cell, or with a preconstructed token array. */
121 ScFormulaCell( ScDocument*, const ScAddress&, const ScTokenArray* = NULL,
122 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
123 sal_uInt8 = MM_NONE );
125 /** With formula string and grammar to compile with.
126 formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
127 also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
128 convention associated with rPos::nTab by default. */
129 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
130 const OUString& rFormula,
131 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
132 sal_uInt8 cMatInd = MM_NONE );
134 ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
136 size_t GetHash() const;
138 ScFormulaVectorState GetVectorState() const;
140 void GetFormula( OUString& rFormula,
141 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
142 void GetFormula( OUStringBuffer& rBuffer,
143 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
145 void SetDirty( bool bDirtyFlag=true );
146 void SetDirtyVar();
147 // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
148 void SetDirtyAfterLoad();
149 inline void ResetTableOpDirtyVar() { bTableOpDirty = false; }
150 void SetTableOpDirty();
151 bool IsDirtyOrInTableOpDirty() const;
152 bool GetDirty() const { return bDirty; }
153 void ResetDirty() { bDirty = bTableOpDirty = mbPostponedDirty = false; }
154 bool NeedsListening() const { return bNeedListening; }
155 void SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
156 void SetNeedNumberFormat( bool bVal ) { mbNeedsNumberFormat = bVal; }
157 short GetFormatType() const { return nFormatType; }
158 void Compile(const OUString& rFormula,
159 bool bNoListening = false,
160 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT );
161 void CompileTokenArray( bool bNoListening = false );
162 void CompileXML( ScProgress& rProgress ); // compile temporary string tokens
163 void CalcAfterLoad();
164 bool MarkUsedExternalReferences();
165 void Interpret();
166 inline bool IsIterCell() const { return bIsIterCell; }
167 inline sal_uInt16 GetSeenInIteration() const { return nSeenInIteration; }
169 bool HasOneReference( ScRange& r ) const;
170 /* Checks if the formula contains reference list that can be
171 expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
172 reference list is not required to be sorted (i.e. A3;A1;A2 is
173 still recognized as A1:A3), but no overlapping is allowed.
174 If one reference is recognized, the rRange is filled.
176 It is similar to HasOneReference(), but more general.
178 bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
179 bool HasRelNameReference() const;
180 bool HasColRowName() const;
182 bool UpdateReference(UpdateRefMode eUpdateRefMode,
183 const ScRange& r,
184 SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
185 ScDocument* pUndoDoc = NULL,
186 const ScAddress* pUndoCellPos = NULL );
188 void TransposeReference();
189 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
190 ScDocument* pUndoDoc );
192 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
194 void UpdateInsertTab(SCTAB nTable, SCTAB nNewSheets = 1);
195 void UpdateInsertTabAbs(SCTAB nTable);
196 bool UpdateDeleteTab(SCTAB nTable, bool bIsMove = false, SCTAB nSheets = 1);
197 void UpdateMoveTab(SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo);
198 void UpdateRenameTab(SCTAB nTable, const OUString& rName);
199 bool TestTabRefAbs(SCTAB nTable);
200 void UpdateCompile( bool bForceIfNameInUse = false );
201 void FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const;
202 bool IsSubTotal() const { return bSubTotal; }
203 bool IsChanged() const;
204 void SetChanged(bool b);
205 bool IsEmpty(); // formula::svEmptyCell result
206 // display as empty string if formula::svEmptyCell result
207 bool IsEmptyDisplayedAsString();
208 bool IsValue(); // also true if formula::svEmptyCell
209 bool IsHybridValueCell(); // for cells after import to deal with inherited number formats
210 double GetValue();
211 double GetValueAlways(); // ignore errors
212 OUString GetString();
213 const ScMatrix* GetMatrix();
214 bool GetMatrixOrigin( ScAddress& rPos ) const;
215 void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
216 sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos );
217 sal_uInt16 GetErrCode(); // interpret first if necessary
218 sal_uInt16 GetRawError(); // don't interpret, just return code or result error
219 sal_uInt8 GetMatrixFlag() const { return cMatrixFlag; }
220 ScTokenArray* GetCode() const { return pCode; }
222 bool IsRunning() const { return bRunning; }
223 void SetRunning( bool bVal ) { bRunning = bVal; }
224 void CompileDBFormula();
225 void CompileDBFormula( bool bCreateFormulaString );
226 void CompileNameFormula( bool bCreateFormulaString );
227 void CompileColRowNameFormula();
228 ScFormulaCell* GetPrevious() const { return pPrevious; }
229 ScFormulaCell* GetNext() const { return pNext; }
230 void SetPrevious( ScFormulaCell* pF ) { pPrevious = pF; }
231 void SetNext( ScFormulaCell* pF ) { pNext = pF; }
232 ScFormulaCell* GetPreviousTrack() const { return pPreviousTrack; }
233 ScFormulaCell* GetNextTrack() const { return pNextTrack; }
234 void SetPreviousTrack( ScFormulaCell* pF ) { pPreviousTrack = pF; }
235 void SetNextTrack( ScFormulaCell* pF ) { pNextTrack = pF; }
237 virtual void Notify( SvtBroadcaster& rBC, const SfxHint& rHint);
238 void SetCompile( bool bVal ) { bCompile = bVal; }
239 ScDocument* GetDocument() const { return pDocument; }
240 void SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
241 void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
243 // cell belongs to ChangeTrack and not to the real document
244 void SetInChangeTrack( bool bVal ) { bInChangeTrack = bVal; }
245 bool IsInChangeTrack() const { return bInChangeTrack; }
247 // For import filters!
248 void AddRecalcMode( formula::ScRecalcMode );
249 /** For import only: set a double result. */
250 void SetHybridDouble( double n ) { aResult.SetHybridDouble( n); }
251 /** For import only: set a string result.
252 If for whatever reason you have to use both, SetHybridDouble() and
253 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
254 for performance reasons.*/
255 void SetHybridString( const OUString& r )
256 { aResult.SetHybridString( r); }
257 /** For import only: set a temporary formula string to be compiled later.
258 If for whatever reason you have to use both, SetHybridDouble() and
259 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
260 for performance reasons.*/
261 void SetHybridFormula( const OUString& r,
262 const formula::FormulaGrammar::Grammar eGrammar )
263 { aResult.SetHybridFormula( r); eTempGrammar = eGrammar; }
265 void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL )
267 aResult.SetMatrix(nCols, nRows, pMat, pUL);
270 /** For import only: set a double result.
271 Use this instead of SetHybridDouble() if there is no (temporary)
272 formula string because the formula is present as a token array, as it
273 is the case for binary Excel import.
275 void SetResultDouble( double n ) { aResult.SetDouble( n); }
277 void SetResultToken( const formula::FormulaToken* pToken );
279 double GetResultDouble() const { return aResult.GetDouble(); }
281 void SetErrCode( sal_uInt16 n );
282 bool IsHyperLinkCell() const;
283 EditTextObject* CreateURLObject();
284 void GetURLResult( OUString& rURL, OUString& rCellText );
286 /** Determines whether or not the result string contains more than one paragraph */
287 bool IsMultilineResult();
289 void MaybeInterpret();
291 // Temporary formula cell grouping API
292 ScFormulaCellGroupRef GetCellGroup()
293 { return xGroup; }
294 void SetCellGroup( const ScFormulaCellGroupRef &xRef )
295 { xGroup = xRef; }
297 CompareState CompareByTokenArray( ScFormulaCell *pOther ) const;
299 bool InterpretFormulaGroup();
300 bool InterpretInvariantFormulaGroup();
302 // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
303 void StartListeningTo( ScDocument* pDoc );
304 void StartListeningTo( sc::StartListeningContext& rCxt );
305 void EndListeningTo(
306 ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
307 void EndListeningTo( sc::EndListeningContext& rCxt );
309 bool IsPostponedDirty() const { return mbPostponedDirty; }
312 #endif
314 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */