Bump version to 4.3-4
[LibreOffice.git] / sc / inc / formulacell.hxx
blob70072e5664188dbe9e2a573ed3e3096d1d524c47
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 INCLUDED_SC_INC_FORMULACELL_HXX
21 #define INCLUDED_SC_INC_FORMULACELL_HXX
23 #include <set>
25 #include <boost/noncopyable.hpp>
27 #include <formula/tokenarray.hxx>
28 #include <osl/conditn.hxx>
29 #include <osl/mutex.hxx>
30 #include <rtl/ref.hxx>
31 #include <svl/listener.hxx>
33 #include "types.hxx"
35 #include "formularesult.hxx"
37 #define ENABLE_THREADED_OPENCL_KERNEL_COMPILATION 0
39 namespace sc {
41 class CLBuildKernelThread;
42 class CompiledFormula;
43 class StartListeningContext;
44 class EndListeningContext;
45 struct RefUpdateContext;
46 struct RefUpdateInsertTabContext;
47 struct RefUpdateDeleteTabContext;
48 struct RefUpdateMoveTabContext;
49 class CompileFormulaContext;
53 class ScFormulaCell;
54 class ScProgress;
55 class ScTokenArray;
56 struct ScSimilarFormulaDelta;
58 struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable
60 mutable size_t mnRefCount;
62 ScTokenArray* mpCode;
63 sc::CompiledFormula* mpCompiledFormula;
64 ScFormulaCell *mpTopCell;
65 SCROW mnLength; // How many of these do we have ?
66 short mnFormatType;
67 bool mbInvariant:1;
68 bool mbSubTotal:1;
70 sal_uInt8 meCalcState;
71 sal_uInt8 meKernelState;
73 ScFormulaCellGroup();
74 ~ScFormulaCellGroup();
76 void scheduleCompilation();
78 void setCode( const ScTokenArray& rCode );
79 void setCode( ScTokenArray* pCode );
80 void compileCode(
81 ScDocument& rDoc, const ScAddress& rPos, formula::FormulaGrammar::Grammar eGram );
82 void compileOpenCLKernel();
84 #if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
85 static int snCount;
86 static rtl::Reference<sc::CLBuildKernelThread> sxCompilationThread;
87 #endif
90 inline void intrusive_ptr_add_ref(const ScFormulaCellGroup *p)
92 p->mnRefCount++;
95 inline void intrusive_ptr_release(const ScFormulaCellGroup *p)
97 if( --p->mnRefCount == 0 )
98 delete p;
101 enum ScMatrixMode {
102 MM_NONE = 0, // No matrix formula
103 MM_FORMULA = 1, // Upper left matrix formula cell
104 MM_REFERENCE = 2, // Remaining cells, via ocMatRef reference token
105 MM_FAKE = 3 // Interpret "as-if" matrix formula (legacy)
108 class SC_DLLPUBLIC ScFormulaCell : public SvtListener
110 private:
111 ScFormulaCellGroupRef mxGroup; // re-factoring hack - group of formulae we're part of.
112 ScFormulaResult aResult;
113 formula::FormulaGrammar::Grammar eTempGrammar; // used between string (creation) and (re)compilation
114 ScTokenArray* pCode; // The (new) token array
115 ScDocument* pDocument;
116 ScFormulaCell* pPrevious;
117 ScFormulaCell* pNext;
118 ScFormulaCell* pPreviousTrack;
119 ScFormulaCell* pNextTrack;
120 sal_uInt16 nSeenInIteration; // Iteration cycle in which the cell was last encountered
121 sal_uInt8 cMatrixFlag; // One of ScMatrixMode
122 short nFormatType;
123 bool bDirty : 1; // Must be (re)calculated
124 bool bChanged : 1; // Whether something changed regarding display/representation
125 bool bRunning : 1; // Already interpreting right now
126 bool bCompile : 1; // Must be (re)compiled
127 bool bSubTotal : 1; // Cell is part of or contains a SubTotal
128 bool bIsIterCell : 1; // Cell is part of a circular reference
129 bool bInChangeTrack : 1; // Cell is in ChangeTrack
130 bool bTableOpDirty : 1; // Dirty flag for TableOp
131 bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference
132 bool mbNeedsNumberFormat : 1; // set the calculated number format as hard number format
133 bool mbPostponedDirty : 1; // if cell needs to be set dirty later
135 enum ScInterpretTailParameter
137 SCITP_NORMAL,
138 SCITP_FROM_ITERATION,
139 SCITP_CLOSE_ITERATION_CIRCLE
141 void InterpretTail( ScInterpretTailParameter );
144 * Update reference in response to cell copy-n-paste.
146 bool UpdateReferenceOnCopy(
147 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
149 ScFormulaCell( const ScFormulaCell& );
150 public:
152 enum CompareState { NotEqual = 0, EqualInvariant, EqualRelativeRef };
154 #ifdef USE_MEMPOOL
155 DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
156 #endif
158 ScAddress aPos;
160 virtual ~ScFormulaCell();
162 ScFormulaCell* Clone() const;
163 ScFormulaCell* Clone( const ScAddress& rPos, int nCloneFlags ) const;
165 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos );
168 * Transfer the ownership of the passed token array instance to the
169 * formula cell being constructed. The caller <i>must not</i> pass a NULL
170 * token array pointer.
172 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, ScTokenArray* pArray,
173 const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
174 sal_uInt8 cMatInd = MM_NONE );
176 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScTokenArray& rArray,
177 const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
178 sal_uInt8 cMatInd = MM_NONE );
180 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScFormulaCellGroupRef& xGroup,
181 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
182 sal_uInt8 = MM_NONE );
184 /** With formula string and grammar to compile with.
185 formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
186 also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefor uses the address
187 convention associated with rPos::nTab by default. */
188 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
189 const OUString& rFormula,
190 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
191 sal_uInt8 cMatInd = MM_NONE );
193 ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
195 size_t GetHash() const;
197 ScFormulaVectorState GetVectorState() const;
199 void GetFormula( OUString& rFormula,
200 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
201 void GetFormula( OUStringBuffer& rBuffer,
202 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
204 OUString GetFormula( sc::CompileFormulaContext& rCxt ) const;
206 void SetDirty( bool bDirtyFlag=true );
207 void SetDirtyVar();
208 // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
209 void SetDirtyAfterLoad();
210 void ResetTableOpDirtyVar();
211 void SetTableOpDirty();
212 bool IsDirtyOrInTableOpDirty() const;
213 bool GetDirty() const;
214 void ResetDirty();
215 bool NeedsListening() const;
216 void SetNeedsListening( bool bVar );
217 void SetNeedsDirty( bool bVar );
218 void SetNeedNumberFormat( bool bVal );
219 bool NeedsNumberFormat() const;
220 short GetFormatType() const;
221 void Compile(const OUString& rFormula,
222 bool bNoListening = false,
223 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT );
224 void Compile(
225 sc::CompileFormulaContext& rCxt, const OUString& rFormula, bool bNoListening = false );
227 void CompileTokenArray( bool bNoListening = false );
228 void CompileTokenArray( sc::CompileFormulaContext& rCxt, bool bNoListening = false );
229 void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); // compile temporary string tokens
230 void CalcAfterLoad( sc::CompileFormulaContext& rCxt );
231 bool MarkUsedExternalReferences();
232 void Interpret();
233 bool IsIterCell() const;
234 sal_uInt16 GetSeenInIteration() const;
236 bool HasOneReference( ScRange& r ) const;
237 /* Checks if the formula contains reference list that can be
238 expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
239 reference list is not required to be sorted (i.e. A3;A1;A2 is
240 still recognized as A1:A3), but no overlapping is allowed.
241 If one reference is recognized, the rRange is filled.
243 It is similar to HasOneReference(), but more general.
245 bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
246 bool HasRelNameReference() const;
248 bool UpdateReference(
249 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc = NULL, const ScAddress* pUndoCellPos = NULL );
252 * Shift the position of formula cell as part of reference update.
254 * @return true if the position has shifted, false otherwise.
256 bool UpdatePosOnShift( const sc::RefUpdateContext& rCxt );
259 * Update reference in response to cell insertion or deletion.
261 bool UpdateReferenceOnShift(
262 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
265 * Update reference in response to cell move.
267 bool UpdateReferenceOnMove(
268 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
270 void TransposeReference();
271 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
272 ScDocument* pUndoDoc );
274 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
276 void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt );
277 void UpdateInsertTabAbs(SCTAB nTable);
278 bool UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt );
279 void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo );
280 void UpdateRenameTab(SCTAB nTable, const OUString& rName);
281 bool TestTabRefAbs(SCTAB nTable);
282 void UpdateCompile( bool bForceIfNameInUse = false );
283 void FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const;
284 bool IsSubTotal() const;
285 bool IsChanged() const;
286 void SetChanged(bool b);
287 bool IsEmpty(); // formula::svEmptyCell result
288 // display as empty string if formula::svEmptyCell result
289 bool IsEmptyDisplayedAsString();
290 bool IsValue(); // also true if formula::svEmptyCell
291 bool IsValueNoError();
292 bool IsHybridValueCell(); // for cells after import to deal with inherited number formats
293 double GetValue();
294 svl::SharedString GetString();
295 const ScMatrix* GetMatrix();
296 bool GetMatrixOrigin( ScAddress& rPos ) const;
297 void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
298 sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos ) const;
299 sal_uInt16 GetErrCode(); // interpret first if necessary
300 sal_uInt16 GetRawError(); // don't interpret, just return code or result error
301 bool GetErrorOrValue( sal_uInt16& rErr, double& rVal );
302 sc::FormulaResultValue GetResult();
303 sal_uInt8 GetMatrixFlag() const;
304 ScTokenArray* GetCode();
305 const ScTokenArray* GetCode() const;
307 void SetCode( ScTokenArray* pNew );
309 bool IsRunning() const;
310 void SetRunning( bool bVal );
311 void CompileDBFormula( sc::CompileFormulaContext& rCxt );
312 void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
313 ScFormulaCell* GetPrevious() const;
314 ScFormulaCell* GetNext() const;
315 void SetPrevious( ScFormulaCell* pF );
316 void SetNext( ScFormulaCell* pF );
317 ScFormulaCell* GetPreviousTrack() const;
318 ScFormulaCell* GetNextTrack() const;
319 void SetPreviousTrack( ScFormulaCell* pF );
320 void SetNextTrack( ScFormulaCell* pF );
322 virtual void Notify( const SfxHint& rHint ) SAL_OVERRIDE;
323 virtual void Query( SvtListener::QueryBase& rQuery ) const SAL_OVERRIDE;
325 void SetCompile( bool bVal );
326 ScDocument* GetDocument() const;
327 void SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
328 void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
330 // cell belongs to ChangeTrack and not to the real document
331 void SetInChangeTrack( bool bVal );
332 bool IsInChangeTrack() const;
334 // For import filters!
335 void AddRecalcMode( formula::ScRecalcMode );
336 /** For import only: set a double result. */
337 void SetHybridDouble( double n );
338 /** For import only: set a string result.
339 If for whatever reason you have to use both, SetHybridDouble() and
340 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
341 for performance reasons.*/
342 void SetHybridString( const svl::SharedString& r );
343 /** For import only: set a temporary formula string to be compiled later.
344 If for whatever reason you have to use both, SetHybridDouble() and
345 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
346 for performance reasons.*/
347 void SetHybridFormula(
348 const OUString& r, const formula::FormulaGrammar::Grammar eGrammar );
350 OUString GetHybridFormula() const;
352 void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL );
354 /** For import only: set a double result.
355 Use this instead of SetHybridDouble() if there is no (temporary)
356 formula string because the formula is present as a token array, as it
357 is the case for binary Excel import.
359 void SetResultDouble( double n );
361 void SetResultToken( const formula::FormulaToken* pToken );
363 svl::SharedString GetResultString() const;
365 void SetErrCode( sal_uInt16 n );
366 bool IsHyperLinkCell() const;
367 EditTextObject* CreateURLObject();
368 void GetURLResult( OUString& rURL, OUString& rCellText );
370 /** Determines whether or not the result string contains more than one paragraph */
371 bool IsMultilineResult();
373 void MaybeInterpret();
376 * Turn a non-grouped cell into the top of a grouped cell.
378 ScFormulaCellGroupRef CreateCellGroup( SCROW nLen, bool bInvariant );
379 ScFormulaCellGroupRef GetCellGroup();
380 void SetCellGroup( const ScFormulaCellGroupRef &xRef );
382 CompareState CompareByTokenArray( ScFormulaCell& rOther ) const;
384 bool InterpretFormulaGroup();
385 bool InterpretInvariantFormulaGroup();
387 // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
388 void StartListeningTo( ScDocument* pDoc );
389 void StartListeningTo( sc::StartListeningContext& rCxt );
390 void EndListeningTo(
391 ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
392 void EndListeningTo( sc::EndListeningContext& rCxt );
394 bool IsShared() const;
395 bool IsSharedTop() const;
396 SCROW GetSharedTopRow() const;
397 SCROW GetSharedLength() const;
398 ScTokenArray* GetSharedCode();
399 const ScTokenArray* GetSharedCode() const;
401 void SyncSharedCode();
403 bool IsPostponedDirty() const;
406 #endif
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */