/src/libreoffice/sc/inc/rangenam.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 "global.hxx" |
23 | | #include "address.hxx" |
24 | | #include <formula/grammar.hxx> |
25 | | #include "scdllapi.h" |
26 | | #include "calcmacros.hxx" |
27 | | |
28 | | #include <memory> |
29 | | #include <map> |
30 | | #include <vector> |
31 | | |
32 | | class ScDocument; |
33 | | class ScTokenArray; |
34 | | |
35 | | namespace sc { |
36 | | |
37 | | struct RefUpdateContext; |
38 | | struct RefUpdateInsertTabContext; |
39 | | struct RefUpdateDeleteTabContext; |
40 | | struct RefUpdateMoveTabContext; |
41 | | class CompileFormulaContext; |
42 | | |
43 | | } |
44 | | |
45 | | class ScRangeData |
46 | | { |
47 | | public: |
48 | | enum class Type //specialization to typed_flags outside of class |
49 | | { |
50 | | Name = 0x0000, |
51 | | Database = 0x0001, |
52 | | Criteria = 0x0002, |
53 | | PrintArea = 0x0004, |
54 | | ColHeader = 0x0008, |
55 | | RowHeader = 0x0010, |
56 | | AbsArea = 0x0020, |
57 | | RefArea = 0x0040, |
58 | | AbsPos = 0x0080, |
59 | | Hidden = 0x0100 |
60 | | }; |
61 | | |
62 | | enum class IsNameValidType |
63 | | { |
64 | | NAME_VALID, |
65 | | NAME_INVALID_CELL_REF, |
66 | | NAME_INVALID_BAD_STRING |
67 | | }; |
68 | | |
69 | | private: |
70 | | OUString aName; |
71 | | OUString aUpperName; // #i62977# for faster searching (aName is never modified after ctor) |
72 | | OUString maNewName; ///< used for formulas after changing names in the dialog |
73 | | std::unique_ptr<ScTokenArray> |
74 | | pCode; |
75 | | ScAddress aPos; |
76 | | Type eType; |
77 | | ScDocument& rDoc; |
78 | | formula::FormulaGrammar::Grammar eTempGrammar; // needed for unresolved XML compiles |
79 | | sal_uInt16 nIndex; |
80 | | bool bModified; // is set/cleared by UpdateReference |
81 | | |
82 | | void CompileRangeData( const OUString& rSymbol, bool bSetError ); |
83 | | void InitCode(); |
84 | | public: |
85 | | |
86 | | SC_DLLPUBLIC ScRangeData( ScDocument& rDoc, |
87 | | const OUString& rName, |
88 | | const OUString& rSymbol, |
89 | | const ScAddress& rAdr = ScAddress(), |
90 | | Type nType = Type::Name, |
91 | | const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT ); |
92 | | SC_DLLPUBLIC ScRangeData( ScDocument& rDoc, |
93 | | const OUString& rName, |
94 | | const ScTokenArray& rArr, |
95 | | const ScAddress& rAdr = ScAddress(), |
96 | | Type nType = Type::Name ); |
97 | | SC_DLLPUBLIC ScRangeData( ScDocument& rDoc, |
98 | | const OUString& rName, |
99 | | const ScAddress& rTarget ); |
100 | | // rTarget is ABSPOS jump label |
101 | | |
102 | | /* Exact copy, not recompiled, no other index (!), nothing... except if |
103 | | * pDocument or pPos are passed, those values are assigned instead of the |
104 | | * copies. */ |
105 | | ScRangeData( const ScRangeData& rScRangeData, ScDocument* pDocument = nullptr, const ScAddress* pPos = nullptr ); |
106 | | |
107 | | SC_DLLPUBLIC ~ScRangeData(); |
108 | | |
109 | | bool operator== (const ScRangeData& rData) const; |
110 | | |
111 | 0 | void GetName( OUString& rName ) const { rName = maNewName.isEmpty() ? aName : maNewName; } |
112 | 8.67k | const OUString& GetName() const { return maNewName.isEmpty() ? aName : maNewName; } |
113 | 13.4k | const OUString& GetUpperName() const { return aUpperName; } |
114 | 0 | const ScAddress& GetPos() const { return aPos; } |
115 | | // The index has to be unique. If index=0 a new index value is assigned. |
116 | 14.0k | void SetIndex( sal_uInt16 nInd ) { nIndex = nInd; } |
117 | 47.5k | sal_uInt16 GetIndex() const { return nIndex; } |
118 | | /// Does not change the name, but sets maNewName for formula update after dialog. |
119 | 0 | void SetNewName( const OUString& rNewName ) { maNewName = rNewName; } |
120 | 10.1k | ScTokenArray* GetCode() { return pCode.get(); } |
121 | | SC_DLLPUBLIC void SetCode( const ScTokenArray& ); |
122 | 11.6k | const ScTokenArray* GetCode() const { return pCode.get(); } |
123 | | SC_DLLPUBLIC FormulaError GetErrCode() const; |
124 | | bool HasReferences() const; |
125 | | void AddType( Type nType ); |
126 | 0 | Type GetType() const { return eType; } |
127 | | bool HasType( Type nType ) const; |
128 | | SC_DLLPUBLIC sal_uInt32 GetUnoType() const; |
129 | | SC_DLLPUBLIC OUString GetSymbol( const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT ) const; |
130 | | SC_DLLPUBLIC OUString GetSymbol( const ScAddress& rPos, const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT ) const; |
131 | | void UpdateSymbol( OUStringBuffer& rBuffer, const ScAddress& ); |
132 | | |
133 | | /** |
134 | | * @param nLocalTab sheet index where this name belongs, or -1 for global |
135 | | * name. |
136 | | */ |
137 | | void UpdateReference( sc::RefUpdateContext& rCxt, SCTAB nLocalTab ); |
138 | 0 | bool IsModified() const { return bModified; } |
139 | | |
140 | | SC_DLLPUBLIC void GuessPosition(); |
141 | | |
142 | | void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest ); |
143 | | void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY ); |
144 | | |
145 | | SC_DLLPUBLIC bool IsReference( ScRange& rRef ) const; |
146 | | bool IsReference( ScRange& rRef, const ScAddress& rPos ) const; |
147 | | SC_DLLPUBLIC bool IsValidReference( ScRange& rRef ) const; |
148 | | bool IsRangeAtBlock( const ScRange& ) const; |
149 | | |
150 | | void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt, SCTAB nLocalTab ); |
151 | | void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt, SCTAB nLocalTab ); |
152 | | void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nLocalTab ); |
153 | | |
154 | | void ValidateTabRefs(); |
155 | | |
156 | | static void MakeValidName( const ScDocument& rDoc, OUString& rName ); |
157 | | |
158 | | SC_DLLPUBLIC static IsNameValidType IsNameValid( const OUString& rName, const ScDocument& rDoc ); |
159 | | |
160 | | bool HasPossibleAddressConflict() const; |
161 | | |
162 | | void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); |
163 | | |
164 | | #if DEBUG_FORMULA_COMPILER |
165 | | void Dump() const; |
166 | | #endif |
167 | | }; |
168 | | namespace o3tl |
169 | | { |
170 | | template<> struct typed_flags<ScRangeData::Type> : is_typed_flags<ScRangeData::Type, 0x1ff> {}; |
171 | | } |
172 | | |
173 | | |
174 | | inline void ScRangeData::AddType( Type nType ) |
175 | 0 | { |
176 | 0 | eType = eType|nType; |
177 | 0 | } |
178 | | |
179 | | inline bool ScRangeData::HasType( Type nType ) const |
180 | 0 | { |
181 | 0 | return ( ( eType & nType ) == nType ); |
182 | 0 | } |
183 | | |
184 | | extern "C" int ScRangeData_QsortNameCompare( const void*, const void* ); |
185 | | |
186 | | class ScRangeName |
187 | | { |
188 | | private: |
189 | | typedef std::vector<ScRangeData*> IndexDataType; |
190 | | typedef ::std::map<OUString, std::unique_ptr<ScRangeData>> DataType; |
191 | | DataType m_Data; |
192 | | IndexDataType maIndexToData; |
193 | | // Use for optimization, true if any of the contained names resolves |
194 | | // as a valid cell address (e.g. 'day1' with 16k columns). |
195 | | mutable bool mHasPossibleAddressConflict : 1; |
196 | | mutable bool mHasPossibleAddressConflictDirty : 1; |
197 | | |
198 | | void checkHasPossibleAddressConflict() const; |
199 | | |
200 | | public: |
201 | | /// Map that stores non-managed pointers to ScRangeName instances. |
202 | | typedef ::std::map<SCTAB, const ScRangeName*> TabNameCopyMap; |
203 | | |
204 | | typedef DataType::const_iterator const_iterator; |
205 | | typedef DataType::iterator iterator; |
206 | | |
207 | | ScRangeName(); |
208 | | SC_DLLPUBLIC ScRangeName(const ScRangeName& r); |
209 | | |
210 | | SC_DLLPUBLIC const ScRangeData* findByRange(const ScRange& rRange) const; |
211 | | SC_DLLPUBLIC ScRangeData* findByUpperName(const OUString& rName); |
212 | | SC_DLLPUBLIC const ScRangeData* findByUpperName(const OUString& rName) const; |
213 | | SC_DLLPUBLIC ScRangeData* findByIndex(sal_uInt16 i) const; |
214 | | void UpdateReference( sc::RefUpdateContext& rCxt, SCTAB nLocalTab = -1 ); |
215 | | void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt, SCTAB nLocalTab = -1 ); |
216 | | void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt, SCTAB nLocalTab = -1 ); |
217 | | void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nLocalTab = -1 ); |
218 | | void UpdateTranspose(const ScRange& rSource, const ScAddress& rDest); |
219 | | void UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY); |
220 | | |
221 | | /** Compile those names that couldn't be resolved during loading and |
222 | | inserting because they may have referred a name that was inserted later. |
223 | | */ |
224 | | void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); |
225 | | |
226 | | /** Copy names while copying a sheet if they reference the sheet to be copied. |
227 | | |
228 | | Assumes that new sheet was already inserted, global names have been |
229 | | updated/adjusted, but sheet-local names on nOldTab are not, as is the |
230 | | case in ScDocument::CopyTab() |
231 | | |
232 | | @param nLocalTab |
233 | | -1 when operating on global names, else sheet/tab of |
234 | | sheet-local name scope. The already adjusted tab on which to |
235 | | find the name. |
236 | | |
237 | | @param nOldTab |
238 | | The original unadjusted tab position. |
239 | | |
240 | | @param nNewTab |
241 | | The new tab position. |
242 | | */ |
243 | | void CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab, |
244 | | const ScDocument& rOldDoc, ScDocument& rNewDoc, const bool bGlobalNamesToLocal ) const; |
245 | | |
246 | 2.57k | SC_DLLPUBLIC const_iterator begin() const { return m_Data.begin(); } |
247 | 2.57k | SC_DLLPUBLIC const_iterator end() const { return m_Data.end(); } |
248 | 0 | SC_DLLPUBLIC size_t size() const { return m_Data.size(); } |
249 | 0 | SC_DLLPUBLIC size_t index_size() const { return maIndexToData.size(); } |
250 | 1.81k | bool empty() const { return m_Data.empty(); } |
251 | | |
252 | | /** Insert object into set. |
253 | | @ATTENTION: The underlying ::std::map<std::unique_ptr>::insert(p) takes |
254 | | ownership of p and if it can't insert it deletes the object! So, if |
255 | | this insert here returns false the object where p pointed to is gone! |
256 | | |
257 | | @param bReuseFreeIndex |
258 | | If the ScRangeData p points to has an index value of 0: |
259 | | If `TRUE` then reuse a free index slot if available. |
260 | | If `FALSE` then assign a new index slot. The Manage Names |
261 | | dialog uses this so that deleting and adding ranges in the same |
262 | | run is guaranteed to not reuse previously assigned indexes. |
263 | | */ |
264 | | SC_DLLPUBLIC bool insert( ScRangeData* p, bool bReuseFreeIndex = true ); |
265 | | |
266 | | void erase(const ScRangeData& r); |
267 | | void erase(const OUString& rName); |
268 | | |
269 | | /** |
270 | | * Erase by iterator position. Note that this method doesn't check for |
271 | | * iterator's validity. The caller must make sure that the iterator is |
272 | | * valid. |
273 | | */ |
274 | | void erase(const_iterator itr); |
275 | | |
276 | | void clear(); |
277 | | bool operator== (const ScRangeName& r) const; |
278 | | |
279 | | bool hasPossibleAddressConflict() const |
280 | 1.13M | { |
281 | 1.13M | if( mHasPossibleAddressConflictDirty ) |
282 | 3.29k | checkHasPossibleAddressConflict(); |
283 | 1.13M | return mHasPossibleAddressConflict; |
284 | 1.13M | } |
285 | | }; |
286 | | |
287 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |