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