Avoid potential negative array index access to cached text.
[LibreOffice.git] / sc / inc / rangenam.hxx
blob881a2e876bda51f48b966b5faf390061b9d3263c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include "global.hxx"
23 #include "address.hxx"
24 #include <formula/grammar.hxx>
25 #include "scdllapi.h"
26 #include "calcmacros.hxx"
28 #include <memory>
29 #include <map>
30 #include <vector>
32 class ScDocument;
33 class ScTokenArray;
35 namespace sc {
37 struct RefUpdateContext;
38 struct RefUpdateInsertTabContext;
39 struct RefUpdateDeleteTabContext;
40 struct RefUpdateMoveTabContext;
41 class CompileFormulaContext;
45 class ScRangeData
47 public:
48 enum class Type //specialization to typed_flags outside of class
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
62 enum class IsNameValidType
64 NAME_VALID,
65 NAME_INVALID_CELL_REF,
66 NAME_INVALID_BAD_STRING
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
82 void CompileRangeData( const OUString& rSymbol, bool bSetError );
83 void InitCode();
84 public:
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
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 );
107 SC_DLLPUBLIC ~ScRangeData();
109 bool operator== (const ScRangeData& rData) const;
111 void GetName( OUString& rName ) const { rName = maNewName.isEmpty() ? aName : maNewName; }
112 const OUString& GetName() const { return maNewName.isEmpty() ? aName : maNewName; }
113 const OUString& GetUpperName() const { return aUpperName; }
114 const ScAddress& GetPos() const { return aPos; }
115 // The index has to be unique. If index=0 a new index value is assigned.
116 void SetIndex( sal_uInt16 nInd ) { nIndex = nInd; }
117 sal_uInt16 GetIndex() const { return nIndex; }
118 /// Does not change the name, but sets maNewName for formula update after dialog.
119 void SetNewName( const OUString& rNewName ) { maNewName = rNewName; }
120 ScTokenArray* GetCode() { return pCode.get(); }
121 SC_DLLPUBLIC void SetCode( const ScTokenArray& );
122 const ScTokenArray* GetCode() const { return pCode.get(); }
123 SC_DLLPUBLIC FormulaError GetErrCode() const;
124 bool HasReferences() const;
125 void AddType( Type nType );
126 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& );
134 * @param nLocalTab sheet index where this name belongs, or -1 for global
135 * name.
137 void UpdateReference( sc::RefUpdateContext& rCxt, SCTAB nLocalTab );
138 bool IsModified() const { return bModified; }
140 SC_DLLPUBLIC void GuessPosition();
142 void UpdateTranspose( const ScRange& rSource, const ScAddress& rDest );
143 void UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
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;
150 void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt, SCTAB nLocalTab );
151 void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt, SCTAB nLocalTab );
152 void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nLocalTab );
154 void ValidateTabRefs();
156 static void MakeValidName( const ScDocument& rDoc, OUString& rName );
158 SC_DLLPUBLIC static IsNameValidType IsNameValid( const OUString& rName, const ScDocument& rDoc );
160 bool HasPossibleAddressConflict() const;
162 void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt );
164 #if DEBUG_FORMULA_COMPILER
165 void Dump() const;
166 #endif
168 namespace o3tl
170 template<> struct typed_flags<ScRangeData::Type> : is_typed_flags<ScRangeData::Type, 0x1ff> {};
174 inline void ScRangeData::AddType( Type nType )
176 eType = eType|nType;
179 inline bool ScRangeData::HasType( Type nType ) const
181 return ( ( eType & nType ) == nType );
184 extern "C" int ScRangeData_QsortNameCompare( const void*, const void* );
186 class ScRangeName
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;
198 void checkHasPossibleAddressConflict() const;
200 public:
201 /// Map that stores non-managed pointers to ScRangeName instances.
202 typedef ::std::map<SCTAB, const ScRangeName*> TabNameCopyMap;
204 typedef DataType::const_iterator const_iterator;
205 typedef DataType::iterator iterator;
207 ScRangeName();
208 SC_DLLPUBLIC ScRangeName(const ScRangeName& r);
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);
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.
224 void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt );
226 /** Copy names while copying a sheet if they reference the sheet to be copied.
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()
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.
237 @param nOldTab
238 The original unadjusted tab position.
240 @param nNewTab
241 The new tab position.
243 void CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab,
244 const ScDocument& rOldDoc, ScDocument& rNewDoc, const bool bGlobalNamesToLocal ) const;
246 SC_DLLPUBLIC const_iterator begin() const { return m_Data.begin(); }
247 SC_DLLPUBLIC const_iterator end() const { return m_Data.end(); }
248 SC_DLLPUBLIC size_t size() const { return m_Data.size(); }
249 SC_DLLPUBLIC size_t index_size() const { return maIndexToData.size(); }
250 bool empty() const { return m_Data.empty(); }
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!
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.
264 SC_DLLPUBLIC bool insert( ScRangeData* p, bool bReuseFreeIndex = true );
266 void erase(const ScRangeData& r);
267 void erase(const OUString& rName);
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.
274 void erase(const_iterator itr);
276 void clear();
277 bool operator== (const ScRangeName& r) const;
279 bool hasPossibleAddressConflict() const
281 if( mHasPossibleAddressConflictDirty )
282 checkHasPossibleAddressConflict();
283 return mHasPossibleAddressConflict;
287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */