update emoji autocorrect entries from po-files
[LibreOffice.git] / sc / inc / formulacell.hxx
blob66f4c9b03cc589e1a4fc98656097636d8aea3308
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;
50 class FormulaGroupAreaListener;
54 class ScFormulaCell;
55 class ScProgress;
56 class ScTokenArray;
58 struct SC_DLLPUBLIC ScFormulaCellGroup : boost::noncopyable
60 private:
61 struct Impl;
62 Impl* mpImpl;
64 public:
66 mutable size_t mnRefCount;
68 ScTokenArray* mpCode;
69 sc::CompiledFormula* mpCompiledFormula;
70 ScFormulaCell *mpTopCell;
71 SCROW mnLength; // How many of these do we have ?
72 short mnFormatType;
73 bool mbInvariant:1;
74 bool mbSubTotal:1;
76 sal_uInt8 meCalcState;
77 sal_uInt8 meKernelState;
79 ScFormulaCellGroup();
80 ~ScFormulaCellGroup();
81 #if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
82 void scheduleCompilation();
83 #endif
85 void setCode( const ScTokenArray& rCode );
86 void setCode( ScTokenArray* pCode );
87 void compileCode(
88 ScDocument& rDoc, const ScAddress& rPos, formula::FormulaGrammar::Grammar eGram );
89 void compileOpenCLKernel();
91 sc::FormulaGroupAreaListener* getAreaListener(
92 ScFormulaCell** ppTopCell, const ScRange& rRange, bool bStartFixed, bool bEndFixed );
94 void endAllGroupListening( ScDocument& rDoc );
96 #if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
97 static int snCount;
98 static rtl::Reference<sc::CLBuildKernelThread> sxCompilationThread;
99 #endif
102 inline void intrusive_ptr_add_ref(const ScFormulaCellGroup *p)
104 p->mnRefCount++;
107 inline void intrusive_ptr_release(const ScFormulaCellGroup *p)
109 if( --p->mnRefCount == 0 )
110 delete p;
113 enum ScMatrixMode {
114 MM_NONE = 0, // No matrix formula
115 MM_FORMULA = 1, // Upper left matrix formula cell
116 MM_REFERENCE = 2, // Remaining cells, via ocMatRef reference token
117 MM_FAKE = 3 // Interpret "as-if" matrix formula (legacy)
120 class SC_DLLPUBLIC ScFormulaCell : public SvtListener
122 private:
123 ScFormulaCellGroupRef mxGroup; // re-factoring hack - group of formulae we're part of.
124 ScFormulaResult aResult;
125 formula::FormulaGrammar::Grammar eTempGrammar; // used between string (creation) and (re)compilation
126 ScTokenArray* pCode; // The (new) token array
127 ScDocument* pDocument;
128 ScFormulaCell* pPrevious;
129 ScFormulaCell* pNext;
130 ScFormulaCell* pPreviousTrack;
131 ScFormulaCell* pNextTrack;
132 sal_uInt16 nSeenInIteration; // Iteration cycle in which the cell was last encountered
133 short nFormatType;
134 sal_uInt8 cMatrixFlag : 2; // One of ScMatrixMode
135 bool bDirty : 1; // Must be (re)calculated
136 bool bChanged : 1; // Whether something changed regarding display/representation
137 bool bRunning : 1; // Already interpreting right now
138 bool bCompile : 1; // Must be (re)compiled
139 bool bSubTotal : 1; // Cell is part of or contains a SubTotal
140 bool bIsIterCell : 1; // Cell is part of a circular reference
141 bool bInChangeTrack : 1; // Cell is in ChangeTrack
142 bool bTableOpDirty : 1; // Dirty flag for TableOp
143 bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference
144 bool mbNeedsNumberFormat : 1; // set the calculated number format as hard number format
145 bool mbPostponedDirty : 1; // if cell needs to be set dirty later
146 bool mbIsExtRef : 1; // has references in ScExternalRefManager; never cleared after set
148 enum ScInterpretTailParameter
150 SCITP_NORMAL,
151 SCITP_FROM_ITERATION,
152 SCITP_CLOSE_ITERATION_CIRCLE
154 void InterpretTail( ScInterpretTailParameter );
157 * Update reference in response to cell copy-n-paste.
159 bool UpdateReferenceOnCopy(
160 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
162 ScFormulaCell( const ScFormulaCell& ) SAL_DELETED_FUNCTION;
163 public:
165 enum CompareState { NotEqual = 0, EqualInvariant, EqualRelativeRef };
167 #ifdef USE_MEMPOOL
168 DECL_FIXEDMEMPOOL_NEWDEL( ScFormulaCell )
169 #endif
171 ScAddress aPos;
173 virtual ~ScFormulaCell();
175 ScFormulaCell* Clone() const;
176 ScFormulaCell* Clone( const ScAddress& rPos, int nCloneFlags ) const;
178 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos );
181 * Transfer the ownership of the passed token array instance to the
182 * formula cell being constructed. The caller <i>must not</i> pass a NULL
183 * token array pointer.
185 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, ScTokenArray* pArray,
186 const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
187 sal_uInt8 cMatInd = MM_NONE );
189 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScTokenArray& rArray,
190 const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT,
191 sal_uInt8 cMatInd = MM_NONE );
193 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos, const ScFormulaCellGroupRef& xGroup,
194 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
195 sal_uInt8 = MM_NONE );
197 /** With formula string and grammar to compile with.
198 formula::FormulaGrammar::GRAM_DEFAULT effectively isformula::FormulaGrammar::GRAM_NATIVE_UI that
199 also includes formula::FormulaGrammar::CONV_UNSPECIFIED, therefore uses the address
200 convention associated with rPos::nTab by default. */
201 ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
202 const OUString& rFormula,
203 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT,
204 sal_uInt8 cMatInd = MM_NONE );
206 ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, const ScAddress& rPos, int nCloneFlags = SC_CLONECELL_DEFAULT );
208 size_t GetHash() const;
210 ScFormulaVectorState GetVectorState() const;
212 void GetFormula( OUString& rFormula,
213 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
214 void GetFormula( OUStringBuffer& rBuffer,
215 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
217 OUString GetFormula( sc::CompileFormulaContext& rCxt ) const;
219 void SetDirty( bool bDirtyFlag=true );
220 void SetDirtyVar();
221 // If setting entire document dirty after load, no broadcasts but still append to FormulaTree.
222 void SetDirtyAfterLoad();
223 void ResetTableOpDirtyVar();
224 void SetTableOpDirty();
225 bool IsDirtyOrInTableOpDirty() const;
226 bool GetDirty() const { return bDirty; }
227 void ResetDirty();
228 bool NeedsListening() const { return bNeedListening; }
229 void SetNeedsListening( bool bVar );
230 void SetNeedsDirty( bool bVar );
231 void SetNeedNumberFormat( bool bVal );
232 bool NeedsNumberFormat() const { return mbNeedsNumberFormat;}
233 short GetFormatType() const { return nFormatType; }
234 void Compile(const OUString& rFormula,
235 bool bNoListening = false,
236 const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT );
237 void Compile(
238 sc::CompileFormulaContext& rCxt, const OUString& rFormula, bool bNoListening = false );
240 void CompileTokenArray( bool bNoListening = false );
241 void CompileTokenArray( sc::CompileFormulaContext& rCxt, bool bNoListening = false );
242 void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); // compile temporary string tokens
243 void CalcAfterLoad( sc::CompileFormulaContext& rCxt, bool bStartListening );
244 bool MarkUsedExternalReferences();
245 void Interpret();
246 bool IsIterCell() const { return bIsIterCell; }
247 sal_uInt16 GetSeenInIteration() const { return nSeenInIteration; }
249 bool HasOneReference( ScRange& r ) const;
250 /* Checks if the formula contains reference list that can be
251 expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
252 reference list is not required to be sorted (i.e. A3;A1;A2 is
253 still recognized as A1:A3), but no overlapping is allowed.
254 If one reference is recognized, the rRange is filled.
256 It is similar to HasOneReference(), but more general.
258 bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
259 bool HasRelNameReference() const;
261 bool UpdateReference(
262 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc = NULL, const ScAddress* pUndoCellPos = NULL );
265 * Shift the position of formula cell as part of reference update.
267 * @return true if the position has shifted, false otherwise.
269 bool UpdatePosOnShift( const sc::RefUpdateContext& rCxt );
272 * Update reference in response to cell insertion or deletion.
274 bool UpdateReferenceOnShift(
275 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
278 * Update reference in response to cell move.
280 bool UpdateReferenceOnMove(
281 const sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, const ScAddress* pUndoCellPos );
283 void TransposeReference();
284 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
285 ScDocument* pUndoDoc );
287 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
289 void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt );
290 void UpdateInsertTabAbs(SCTAB nTable);
291 bool UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt );
292 void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nTabNo );
293 void UpdateRenameTab(SCTAB nTable, const OUString& rName);
294 bool TestTabRefAbs(SCTAB nTable);
295 void UpdateCompile( bool bForceIfNameInUse = false );
296 void FindRangeNamesInUse(std::set<sal_uInt16>& rIndexes) const;
297 bool IsSubTotal() const { return bSubTotal;}
298 bool IsChanged() const { return bChanged;}
299 void SetChanged(bool b);
300 bool IsEmpty(); // formula::svEmptyCell result
301 // display as empty string if formula::svEmptyCell result
302 bool IsEmptyDisplayedAsString();
303 bool IsValue(); // also true if formula::svEmptyCell
304 bool IsValueNoError();
305 bool IsValueNoError() const;
306 bool IsHybridValueCell(); // for cells after import to deal with inherited number formats
307 double GetValue();
308 svl::SharedString GetString();
309 const ScMatrix* GetMatrix();
310 bool GetMatrixOrigin( ScAddress& rPos ) const;
311 void GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows );
312 sal_uInt16 GetMatrixEdge( ScAddress& rOrgPos ) const;
313 sal_uInt16 GetErrCode(); // interpret first if necessary
314 sal_uInt16 GetRawError(); // don't interpret, just return code or result error
315 bool GetErrorOrValue( sal_uInt16& rErr, double& rVal );
316 sc::FormulaResultValue GetResult();
317 sc::FormulaResultValue GetResult() const;
318 sal_uInt8 GetMatrixFlag() const { return cMatrixFlag;}
319 ScTokenArray* GetCode() { return pCode;}
320 const ScTokenArray* GetCode() const { return pCode;}
322 void SetCode( ScTokenArray* pNew );
324 bool IsRunning() const { return bRunning;}
325 void SetRunning( bool bVal );
326 void CompileDBFormula( sc::CompileFormulaContext& rCxt );
327 void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt );
328 ScFormulaCell* GetPrevious() const { return pPrevious; }
329 ScFormulaCell* GetNext() const { return pNext; }
330 void SetPrevious( ScFormulaCell* pF );
331 void SetNext( ScFormulaCell* pF );
332 ScFormulaCell* GetPreviousTrack() const { return pPreviousTrack; }
333 ScFormulaCell* GetNextTrack() const { return pNextTrack; }
334 void SetPreviousTrack( ScFormulaCell* pF );
335 void SetNextTrack( ScFormulaCell* pF );
337 virtual void Notify( const SfxHint& rHint ) SAL_OVERRIDE;
338 virtual void Query( SvtListener::QueryBase& rQuery ) const SAL_OVERRIDE;
340 void SetCompile( bool bVal );
341 ScDocument* GetDocument() const { return pDocument;}
342 void SetMatColsRows( SCCOL nCols, SCROW nRows, bool bDirtyFlag=true );
343 void GetMatColsRows( SCCOL& nCols, SCROW& nRows ) const;
345 // cell belongs to ChangeTrack and not to the real document
346 void SetInChangeTrack( bool bVal );
347 bool IsInChangeTrack() const { return bInChangeTrack;}
349 // For import filters!
350 void AddRecalcMode( ScRecalcMode );
351 /** For import only: set a double result. */
352 void SetHybridDouble( double n );
353 /** For import only: set a string result.
354 If for whatever reason you have to use both, SetHybridDouble() and
355 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
356 for performance reasons.*/
357 void SetHybridString( const svl::SharedString& r );
358 /** For import only: set a temporary formula string to be compiled later.
359 If for whatever reason you have to use both, SetHybridDouble() and
360 SetHybridString() or SetHybridFormula(), use SetHybridDouble() first
361 for performance reasons.*/
362 void SetHybridFormula(
363 const OUString& r, const formula::FormulaGrammar::Grammar eGrammar );
365 OUString GetHybridFormula() const;
367 void SetResultMatrix( SCCOL nCols, SCROW nRows, const ScConstMatrixRef& pMat, formula::FormulaToken* pUL );
369 /** For import only: set a double result.
370 Use this instead of SetHybridDouble() if there is no (temporary)
371 formula string because the formula is present as a token array, as it
372 is the case for binary Excel import.
374 void SetResultDouble( double n );
376 void SetResultToken( const formula::FormulaToken* pToken );
378 svl::SharedString GetResultString() const;
380 /* Sets the shared code array to error state in addition to the cell result */
381 void SetErrCode( sal_uInt16 n );
383 /* Sets just the result to error */
384 void SetResultError( sal_uInt16 n );
386 bool IsHyperLinkCell() const;
387 EditTextObject* CreateURLObject();
388 void GetURLResult( OUString& rURL, OUString& rCellText );
390 /** Determines whether or not the result string contains more than one paragraph */
391 bool IsMultilineResult();
393 bool NeedsInterpret() const;
395 void MaybeInterpret();
398 * Turn a non-grouped cell into the top of a grouped cell.
400 ScFormulaCellGroupRef CreateCellGroup( SCROW nLen, bool bInvariant );
401 ScFormulaCellGroupRef GetCellGroup() const { return mxGroup;}
402 void SetCellGroup( const ScFormulaCellGroupRef &xRef );
404 CompareState CompareByTokenArray( ScFormulaCell& rOther ) const;
406 bool InterpretFormulaGroup();
407 bool InterpretInvariantFormulaGroup();
409 // nOnlyNames may be one or more of SC_LISTENING_NAMES_*
410 void StartListeningTo( ScDocument* pDoc );
411 void StartListeningTo( sc::StartListeningContext& rCxt );
412 void EndListeningTo(
413 ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
414 void EndListeningTo( sc::EndListeningContext& rCxt );
416 bool IsShared() const;
417 bool IsSharedTop() const;
418 SCROW GetSharedTopRow() const;
419 SCROW GetSharedLength() const;
421 // An estimate of the number of cells referenced by the formula
422 sal_Int32 GetWeight() const;
424 ScTokenArray* GetSharedCode();
425 const ScTokenArray* GetSharedCode() const;
427 void SyncSharedCode();
429 bool IsPostponedDirty() const { return mbPostponedDirty;}
431 void SetIsExtRef() { mbIsExtRef = true; }
434 #endif
436 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */