Line data Source code
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 : #ifndef INCLUDED_SC_INC_TOKENARRAY_HXX
21 : #define INCLUDED_SC_INC_TOKENARRAY_HXX
22 :
23 : #include <formula/token.hxx>
24 : #include "scdllapi.h"
25 : #include "types.hxx"
26 : #include "calcmacros.hxx"
27 : #include "address.hxx"
28 : #include "global.hxx"
29 : #include <formula/tokenarray.hxx>
30 :
31 : namespace sc {
32 :
33 : struct RefUpdateContext;
34 : struct RefUpdateInsertTabContext;
35 : struct RefUpdateDeleteTabContext;
36 : struct RefUpdateMoveTabContext;
37 : struct RefUpdateResult;
38 : struct TokenStringContext;
39 : class ColRowReorderMapType;
40 :
41 : }
42 :
43 : struct ScRawToken;
44 : struct ScSingleRefData;
45 : struct ScComplexRefData;
46 :
47 : class SC_DLLPUBLIC ScTokenArray : public formula::FormulaTokenArray
48 : {
49 : friend class ScCompiler;
50 :
51 : bool ImplGetReference( ScRange& rRange, const ScAddress& rPos, bool bValidOnly ) const;
52 :
53 : size_t mnHashValue;
54 : ScFormulaVectorState meVectorState;
55 :
56 : public:
57 : ScTokenArray();
58 : /// Assignment with references to FormulaToken entries (not copied!)
59 : ScTokenArray( const ScTokenArray& );
60 : virtual ~ScTokenArray();
61 : void ClearScTokenArray();
62 : ScTokenArray* Clone() const; /// True copy!
63 :
64 : // An estimate of the number of cells referenced by the token array
65 : sal_Int32 GetWeight() const;
66 :
67 : void GenHash();
68 15916 : size_t GetHash() const { return mnHashValue;}
69 :
70 7 : ScFormulaVectorState GetVectorState() const { return meVectorState;}
71 :
72 : /**
73 : * If the array contains at least one relative row reference or named
74 : * expression, it's variant. Otherwise invariant.
75 : */
76 : bool IsInvariant() const;
77 :
78 : /// Exactly and only one range (valid or deleted)
79 : bool IsReference( ScRange& rRange, const ScAddress& rPos ) const;
80 : /// Exactly and only one valid range (no #REF!s)
81 : bool IsValidReference( ScRange& rRange, const ScAddress& rPos ) const;
82 :
83 : /** Determines the extent of direct adjacent
84 : references. Only use with real functions, e.g.
85 : GetOuterFuncOpCode() == ocSum ! */
86 : bool GetAdjacentExtendOfOuterFuncRefs( SCCOLROW& nExtend,
87 : const ScAddress& rPos, ScDirection );
88 :
89 : formula::FormulaToken* AddRawToken( const ScRawToken& );
90 : virtual bool AddFormulaToken(
91 : const css::sheet::FormulaToken& rToken,
92 : svl::SharedStringPool& rSPool,
93 : formula::ExternalReferenceHelper* _pRef) SAL_OVERRIDE;
94 : virtual void CheckToken( const formula::FormulaToken& r ) SAL_OVERRIDE;
95 : virtual formula::FormulaToken* AddOpCode( OpCode eCode ) SAL_OVERRIDE;
96 : /** ScSingleRefToken with ocPush. */
97 : formula::FormulaToken* AddSingleReference( const ScSingleRefData& rRef );
98 : /** ScSingleRefOpToken with ocMatRef. */
99 : formula::FormulaToken* AddMatrixSingleReference( const ScSingleRefData& rRef );
100 : formula::FormulaToken* AddDoubleReference( const ScComplexRefData& rRef );
101 : formula::FormulaToken* AddRangeName( sal_uInt16 n, bool bGlobal );
102 : formula::FormulaToken* AddDBRange( sal_uInt16 n );
103 : formula::FormulaToken* AddExternalName( sal_uInt16 nFileId, const OUString& rName );
104 : formula::FormulaToken* AddExternalSingleReference( sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef );
105 : formula::FormulaToken* AddExternalDoubleReference( sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef );
106 : formula::FormulaToken* AddMatrix( const ScMatrixRef& p );
107 : /** ScSingleRefOpToken with ocColRowName. */
108 : formula::FormulaToken* AddColRowName( const ScSingleRefData& rRef );
109 : virtual formula::FormulaToken* MergeArray( ) SAL_OVERRIDE;
110 :
111 : /** Merge very last SingleRef+ocRange+SingleRef combination into DoubleRef
112 : and adjust pCode array, or do nothing if conditions not met.
113 : Unconditionally returns last token from the resulting pCode array, or
114 : NULL if there is no pCode (which actually would be caller's fault). */
115 : formula::FormulaToken* MergeRangeReference( const ScAddress & rPos );
116 :
117 : /// Assign XML string placeholder to the array
118 : void AssignXMLString( const OUString &rText, const OUString &rFormulaNmsp );
119 :
120 : /// Assignment with references to FormulaToken entries (not copied!)
121 : ScTokenArray& operator=( const ScTokenArray& );
122 :
123 : /// Make 3D references point to old referenced position even if relative
124 : void ReadjustRelative3DReferences(
125 : const ScAddress& rOldPos,
126 : const ScAddress& rNewPos );
127 :
128 : /**
129 : * Make all absolute references external references pointing to the old document
130 : *
131 : * @param pOldDoc old document
132 : * @param pNewDoc new document
133 : * @param rPos position of the cell to determine if the reference is in the copied area
134 : * @param bRangeName set for range names, range names have special handling for absolute sheet ref + relative col/row ref
135 : */
136 : void ReadjustAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos, bool bRangeName = false );
137 :
138 : /**
139 : * Make all absolute references pointing to the copied range if the range is copied too
140 : * @param bCheckCopyArea should references pointing into the copy area be adjusted independently from being absolute, should be true only for copy&paste between documents
141 : */
142 : void AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bRangeName = false, bool bCheckCopyArea = false );
143 :
144 : /**
145 : * Adjust all references in response to shifting of cells during cell
146 : * insertion and deletion.
147 : *
148 : * @param rCxt context that stores details of shifted region.
149 : * @param rOldPos old cell position prior to shifting.
150 : */
151 : sc::RefUpdateResult AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos );
152 :
153 : sc::RefUpdateResult AdjustReferenceOnMove(
154 : const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos );
155 :
156 : /**
157 : * Move reference positions that are within specified moved range.
158 : *
159 : * @param rPos position of this formula cell
160 : */
161 : sc::RefUpdateResult MoveReference( const ScAddress& rPos, const sc::RefUpdateContext& rCxt );
162 :
163 : /**
164 : * Move reference positions in response to column reordering. A range
165 : * reference gets moved only when the whole range fits in a single column.
166 : *
167 : * @param rPos position of this formula cell
168 : * @param nTab sheet where columns are reordered.
169 : * @param nRow1 top row of reordered range.
170 : * @param nRow2 bottom row of reordered range.
171 : * @param rColMap old-to-new column mapping.
172 : */
173 : void MoveReferenceColReorder(
174 : const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2,
175 : const sc::ColRowReorderMapType& rColMap );
176 :
177 : void MoveReferenceRowReorder(
178 : const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2,
179 : const sc::ColRowReorderMapType& rRowMap );
180 :
181 : /**
182 : * Adjust all references in named expression. In named expression, we only
183 : * update absolute positions, and leave relative positions intact.
184 : *
185 : * @param rCxt context that stores details of shifted region
186 : *
187 : * @return update result.
188 : */
189 : sc::RefUpdateResult AdjustReferenceInName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos );
190 :
191 : sc::RefUpdateResult AdjustReferenceInMovedName( const sc::RefUpdateContext& rCxt, const ScAddress& rPos );
192 :
193 : /**
194 : * Adjust all references on sheet deletion.
195 : *
196 : * @param nDelPos position of sheet being deleted.
197 : * @param nSheets number of sheets to delete.
198 : * @param rOldPos position of formula cell prior to the deletion.
199 : *
200 : * @return true if at least one reference has changed its sheet reference.
201 : */
202 : sc::RefUpdateResult AdjustReferenceOnDeletedTab( sc::RefUpdateDeleteTabContext& rCxt, const ScAddress& rOldPos );
203 :
204 : sc::RefUpdateResult AdjustReferenceOnInsertedTab( sc::RefUpdateInsertTabContext& rCxt, const ScAddress& rOldPos );
205 :
206 : sc::RefUpdateResult AdjustReferenceOnMovedTab( sc::RefUpdateMoveTabContext& rCxt, const ScAddress& rOldPos );
207 :
208 : /**
209 : * Adjust all internal references on base position change.
210 : */
211 : void AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const ScAddress& rNewPos );
212 :
213 : /**
214 : * Adjust all internal references on base position change if they point to
215 : * a sheet other than the one of rOldPos.
216 : */
217 : void AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rOldPos, const ScAddress& rNewPos );
218 :
219 : /**
220 : * Clear sheet deleted flag from internal reference tokens if the sheet
221 : * index falls within specified range. Note that when a reference is on a
222 : * sheet that's been deleted, its referenced sheet index retains the
223 : * original index of the deleted sheet.
224 : *
225 : * @param rPos position of formula cell
226 : * @param nStartTab index of first sheet, inclusive.
227 : * @param nEndTab index of last sheet, inclusive.
228 : */
229 : void ClearTabDeleted( const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab );
230 :
231 : void CheckRelativeReferenceBounds(
232 : const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
233 :
234 : void CheckRelativeReferenceBounds(
235 : const ScAddress& rPos, SCROW nGroupLen, const ScRange& rRange, std::vector<SCROW>& rBounds ) const;
236 :
237 : void CheckExpandReferenceBounds(
238 : const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
239 :
240 : /**
241 : * Create a string representation of formula token array without modifying
242 : * the internal state of the token array.
243 : */
244 : OUString CreateString( sc::TokenStringContext& rCxt, const ScAddress& rPos ) const;
245 :
246 : void WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow );
247 : bool NeedsWrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow ) const;
248 :
249 : #if DEBUG_FORMULA_COMPILER
250 : void Dump() const;
251 : #endif
252 : };
253 :
254 : #endif // INCLUDED_SC_INC_TOKENARRAY_HXX
255 :
256 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|