/src/libreoffice/sc/inc/tokenarray.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <formula/token.hxx> |
23 | | #include <rtl/ref.hxx> |
24 | | #include "document.hxx" |
25 | | #include "scdllapi.h" |
26 | | #include "types.hxx" |
27 | | #include "calcmacros.hxx" |
28 | | #include "address.hxx" |
29 | | #include "global.hxx" |
30 | | #include <formula/tokenarray.hxx> |
31 | | |
32 | | namespace sc { |
33 | | |
34 | | struct RefUpdateContext; |
35 | | struct RefUpdateInsertTabContext; |
36 | | struct RefUpdateDeleteTabContext; |
37 | | struct RefUpdateMoveTabContext; |
38 | | struct RefUpdateResult; |
39 | | struct TokenStringContext; |
40 | | class ColRowReorderMapType; |
41 | | |
42 | | /** If the target tab was inserted, or an existing tab was used. */ |
43 | | enum class TargetTabState |
44 | | { |
45 | | Existing, |
46 | | Inserted, |
47 | | }; |
48 | | |
49 | | } |
50 | | |
51 | | struct ScRawToken; |
52 | | struct ScSingleRefData; |
53 | | struct ScComplexRefData; |
54 | | |
55 | | class SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI ScTokenArray final : public formula::FormulaTokenArray |
56 | | { |
57 | | friend class ScCompiler; |
58 | | |
59 | | bool ImplGetReference( ScRange& rRange, const ScAddress& rPos, bool bValidOnly ) const; |
60 | | |
61 | | // hold a reference to the limits because sometimes our lifetime exceeds the lifetime of the associated ScDocument |
62 | | rtl::Reference<ScSheetLimits> mxSheetLimits; |
63 | | size_t mnHashValue; |
64 | | ScFormulaVectorState meVectorState : 4; // Only 4 bits |
65 | | bool mbOpenCLEnabled : 1; |
66 | | bool mbThreadingEnabled : 1; |
67 | | |
68 | | void CheckForThreading( const formula::FormulaToken& r ); |
69 | | |
70 | | public: |
71 | | SC_DLLPUBLIC ScTokenArray(const ScDocument& rDoc); |
72 | | ScTokenArray(ScSheetLimits&); |
73 | | /** Assignment with incrementing references of FormulaToken entries |
74 | | (not copied!) */ |
75 | 1.29M | ScTokenArray( const ScTokenArray& ) = default; |
76 | 1.21M | ScTokenArray( ScTokenArray&& ) = default; |
77 | | SC_DLLPUBLIC virtual ~ScTokenArray() override; |
78 | | |
79 | | bool EqualTokens( const ScTokenArray* pArr2 ) const; |
80 | | |
81 | | SC_DLLPUBLIC virtual void Clear() override; |
82 | | SC_DLLPUBLIC std::unique_ptr<ScTokenArray> Clone() const; /// True copy! |
83 | | SC_DLLPUBLIC ScTokenArray CloneValue() const; /// True copy! |
84 | | |
85 | | SC_DLLPUBLIC void GenHash(); |
86 | 31.7M | size_t GetHash() const { return mnHashValue;} |
87 | | |
88 | 93.8k | ScFormulaVectorState GetVectorState() const { return meVectorState;} |
89 | | void ResetVectorState(); |
90 | | bool IsFormulaVectorDisabled() const; |
91 | | |
92 | | /** |
93 | | * If the array contains at least one relative row reference or named |
94 | | * expression, it's variant. Otherwise invariant. |
95 | | */ |
96 | | bool IsInvariant() const; |
97 | | |
98 | | /// Exactly and only one range (valid or deleted) |
99 | | SC_DLLPUBLIC bool IsReference( ScRange& rRange, const ScAddress& rPos ) const; |
100 | | /// Exactly and only one valid range (no #REF!s) |
101 | | SC_DLLPUBLIC bool IsValidReference( ScRange& rRange, const ScAddress& rPos ) const; |
102 | | |
103 | | /** Determines the extent of direct adjacent |
104 | | references. Only use with real functions, e.g. |
105 | | GetOuterFuncOpCode() == ocSum ! */ |
106 | | bool GetAdjacentExtendOfOuterFuncRefs( |
107 | | SCCOLROW& nExtend, |
108 | | const ScAddress& rPos, ScDirection ); |
109 | | |
110 | | formula::FormulaToken* AddRawToken( const ScRawToken& ); |
111 | | SC_DLLPUBLIC virtual bool AddFormulaToken( |
112 | | const css::sheet::FormulaToken& rToken, |
113 | | svl::SharedStringPool& rSPool, |
114 | | formula::ExternalReferenceHelper* _pRef) override; |
115 | | SC_DLLPUBLIC virtual void CheckToken( const formula::FormulaToken& r ) override; |
116 | | SC_DLLPUBLIC virtual formula::FormulaToken* AddOpCode( OpCode eCode ) override; |
117 | | /** ScSingleRefToken with ocPush. */ |
118 | | SC_DLLPUBLIC formula::FormulaToken* AddSingleReference( const ScSingleRefData& rRef ); |
119 | | /** ScSingleRefOpToken with ocMatRef. */ |
120 | | formula::FormulaToken* AddMatrixSingleReference( const ScSingleRefData& rRef ); |
121 | | SC_DLLPUBLIC formula::FormulaToken* AddDoubleReference( const ScComplexRefData& rRef ); |
122 | | SC_DLLPUBLIC void AddRangeName( sal_uInt16 n, sal_Int16 nSheet ); |
123 | | formula::FormulaToken* AddDBRange( sal_uInt16 n ); |
124 | | SC_DLLPUBLIC formula::FormulaToken* AddTableRef( sal_uInt16 n ); |
125 | | SC_DLLPUBLIC formula::FormulaToken* AddExternalName( sal_uInt16 nFileId, const svl::SharedString& rName ); |
126 | | SC_DLLPUBLIC void AddExternalSingleReference( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScSingleRefData& rRef ); |
127 | | SC_DLLPUBLIC formula::FormulaToken* AddExternalDoubleReference( sal_uInt16 nFileId, const svl::SharedString& rTabName, const ScComplexRefData& rRef ); |
128 | | SC_DLLPUBLIC formula::FormulaToken* AddMatrix( const ScMatrixRef& p ); |
129 | | /** ScSingleRefOpToken with ocColRowName. */ |
130 | | SC_DLLPUBLIC formula::FormulaToken* AddColRowName( const ScSingleRefData& rRef ); |
131 | | SC_DLLPUBLIC virtual formula::FormulaToken* MergeArray( ) override; |
132 | | |
133 | | /** Merge very last SingleRef+ocRange+SingleRef combination into DoubleRef |
134 | | and adjust pCode array, or do nothing if conditions not met. */ |
135 | | void MergeRangeReference( const ScAddress & rPos ); |
136 | | |
137 | | /// Assign XML string placeholder to the array |
138 | | void AssignXMLString( const OUString &rText, const OUString &rFormulaNmsp ); |
139 | | |
140 | | /** Assignment with incrementing references of FormulaToken entries |
141 | | (not copied!) */ |
142 | | ScTokenArray& operator=( const ScTokenArray& ); |
143 | | ScTokenArray& operator=( ScTokenArray&& ); |
144 | | |
145 | | /** |
146 | | * Make all absolute references external references pointing to the old document |
147 | | * |
148 | | * @param rOldDoc old document |
149 | | * @param rNewDoc new document |
150 | | * @param rPos position of the cell to determine if the reference is in the copied area |
151 | | * @param bRangeName set for range names, range names have special handling for absolute sheet ref + relative col/row ref |
152 | | */ |
153 | | void ReadjustAbsolute3DReferences( const ScDocument& rOldDoc, ScDocument& rNewDoc, const ScAddress& rPos, bool bRangeName = false ); |
154 | | |
155 | | /** |
156 | | * Make all absolute references pointing to the copied range if the range is copied too |
157 | | * @param bCheckCopyArea should reference pointing into the copy area be adjusted independently from being absolute, should be true only for copy&paste between documents |
158 | | */ |
159 | | void AdjustAbsoluteRefs( const ScDocument& rOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCheckCopyArea ); |
160 | | |
161 | | /** Adjust relative tab references when copying a formula to a new table. |
162 | | Non-zero relative tab offsets are recalculated so they still resolve |
163 | | to the original target sheet from the new position. Same-sheet |
164 | | relative refs (offset 0) are not modified. |
165 | | If the target tab was newly inserted, the references pointing to |
166 | | tabs at or after the insertion point are additionally shifted by |
167 | | one. */ |
168 | | void AdjustRelativeTabRefs(SCTAB nOldTab, SCTAB nNewTab, |
169 | | sc::TargetTabState eMode = sc::TargetTabState::Existing); |
170 | | |
171 | | /** When copying a sheet-local named expression, move sheet references that |
172 | | point to the originating sheet to point to the new sheet instead. |
173 | | */ |
174 | | void AdjustSheetLocalNameReferences( SCTAB nOldTab, SCTAB nNewTab ); |
175 | | |
176 | | /** Returns true if the sheet nTab is referenced in code. Relative sheet |
177 | | references are evaluated using nPosTab. |
178 | | */ |
179 | | bool ReferencesSheet( SCTAB nTab, SCTAB nPosTab ) const; |
180 | | |
181 | | /** |
182 | | * Adjust all references in response to shifting of cells during cell |
183 | | * insertion and deletion. |
184 | | * |
185 | | * @param rCxt context that stores details of shifted region. |
186 | | * @param rOldPos old cell position prior to shifting. |
187 | | */ |
188 | | sc::RefUpdateResult AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos ); |
189 | | |
190 | | sc::RefUpdateResult AdjustReferenceOnMove( |
191 | | const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos ); |
192 | | |
193 | | /** |
194 | | * Move reference positions in response to column reordering. A range |
195 | | * reference gets moved only when the whole range fits in a single column. |
196 | | * |
197 | | * @param rPos position of this formula cell |
198 | | * @param nTab sheet where columns are reordered. |
199 | | * @param nRow1 top row of reordered range. |
200 | | * @param nRow2 bottom row of reordered range. |
201 | | * @param rColMap old-to-new column mapping. |
202 | | */ |
203 | | void MoveReferenceColReorder( |
204 | | const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, |
205 | | const sc::ColRowReorderMapType& rColMap ); |
206 | | |
207 | | void MoveReferenceRowReorder( |
208 | | const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, |
209 | | const sc::ColRowReorderMapType& rRowMap ); |
210 | | |
211 | | /** |
212 | | * Adjust all references in named expression. In named expression, we only |
213 | | * update absolute positions, and leave relative positions intact. |
214 | | * |
215 | | * @param rCxt context that stores details of shifted region |
216 | | * |
217 | | * @return update result. |
218 | | */ |
219 | | sc::RefUpdateResult AdjustReferenceInName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos ); |
220 | | |
221 | | sc::RefUpdateResult AdjustReferenceInMovedName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos ); |
222 | | |
223 | | /** |
224 | | * Adjust all references on sheet deletion. |
225 | | * |
226 | | * @param nDelPos position of sheet being deleted. |
227 | | * @param nSheets number of sheets to delete. |
228 | | * @param rOldPos position of formula cell prior to the deletion. |
229 | | * |
230 | | * @return true if at least one reference has changed its sheet reference. |
231 | | */ |
232 | | sc::RefUpdateResult AdjustReferenceOnDeletedTab( const sc::RefUpdateDeleteTabContext& rCxt, const ScAddress& rOldPos ); |
233 | | |
234 | | sc::RefUpdateResult AdjustReferenceOnInsertedTab( const sc::RefUpdateInsertTabContext& rCxt, const ScAddress& rOldPos ); |
235 | | |
236 | | sc::RefUpdateResult AdjustReferenceOnMovedTab( const sc::RefUpdateMoveTabContext& rCxt, const ScAddress& rOldPos ); |
237 | | |
238 | | /** |
239 | | * Adjust all internal references on base position change. |
240 | | */ |
241 | | void AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const ScAddress& rNewPos ); |
242 | | |
243 | | /** |
244 | | * Adjust all internal references on base position change if they point to |
245 | | * a sheet other than the one of rOldPos. |
246 | | */ |
247 | | void AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rOldPos, const ScAddress& rNewPos ); |
248 | | |
249 | | /** |
250 | | * Adjust internal range references on base position change to justify / |
251 | | * put in order the relative references. |
252 | | */ |
253 | | void AdjustReferenceOnCopy( const ScAddress& rNewPos ); |
254 | | |
255 | | /** |
256 | | * Clear sheet deleted flag from internal reference tokens if the sheet |
257 | | * index falls within specified range. Note that when a reference is on a |
258 | | * sheet that's been deleted, its referenced sheet index retains the |
259 | | * original index of the deleted sheet. |
260 | | * |
261 | | * @param rPos position of formula cell |
262 | | * @param nStartTab index of first sheet, inclusive. |
263 | | * @param nEndTab index of last sheet, inclusive. |
264 | | */ |
265 | | void ClearTabDeleted( const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab ); |
266 | | |
267 | | void CheckRelativeReferenceBounds( |
268 | | const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const; |
269 | | |
270 | | void CheckRelativeReferenceBounds( |
271 | | const ScAddress& rPos, SCROW nGroupLen, const ScRange& rRange, std::vector<SCROW>& rBounds ) const; |
272 | | |
273 | | void CheckExpandReferenceBounds( |
274 | | const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const; |
275 | | |
276 | | /** |
277 | | * Create a string representation of formula token array without modifying |
278 | | * the internal state of the token array. |
279 | | */ |
280 | | SC_DLLPUBLIC OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const; |
281 | | |
282 | | SC_DLLPUBLIC void WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ); |
283 | | |
284 | | sal_Int32 GetWeight() const; |
285 | | |
286 | 93.8k | bool IsEnabledForOpenCL() const { return mbOpenCLEnabled; } |
287 | 0 | bool IsEnabledForThreading() const { return mbThreadingEnabled; } |
288 | | |
289 | | #if DEBUG_FORMULA_COMPILER |
290 | | void Dump() const; |
291 | | #endif |
292 | | }; |
293 | | |
294 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |