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