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_RANGENAM_HXX 21 #define INCLUDED_SC_INC_RANGENAM_HXX 22 23 #include "global.hxx" 24 #include "address.hxx" 25 #include <formula/grammar.hxx> 26 #include "scdllapi.h" 27 #include "calcmacros.hxx" 28 29 #include <memory> 30 #include <map> 31 #include <vector> 32 33 class ScDocument; 34 class ScTokenArray; 35 36 namespace sc { 37 38 struct RefUpdateContext; 39 struct RefUpdateInsertTabContext; 40 struct RefUpdateDeleteTabContext; 41 struct RefUpdateMoveTabContext; 42 class CompileFormulaContext; 43 44 } 45 46 class ScRangeData 47 { 48 public: 49 enum class Type //specialization to typed_flags outside of class 50 { 51 Name = 0x0000, 52 Database = 0x0001, 53 Criteria = 0x0002, 54 PrintArea = 0x0004, 55 ColHeader = 0x0008, 56 RowHeader = 0x0010, 57 AbsArea = 0x0020, 58 RefArea = 0x0040, 59 AbsPos = 0x0080 60 }; 61 62 enum 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 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 sal_uInt32 GetUnoType() const; 129 SC_DLLPUBLIC void GetSymbol( OUString& rSymbol, const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT ) const; 130 SC_DLLPUBLIC void GetSymbol( OUString& rSymbol, 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 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 void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); 161 162 #if DEBUG_FORMULA_COMPILER 163 void Dump() const; 164 #endif 165 }; 166 namespace o3tl 167 { 168 template<> struct typed_flags<ScRangeData::Type> : is_typed_flags<ScRangeData::Type, 0xff> {}; 169 } 170 171 172 inline void ScRangeData::AddType( Type nType ) 173 { 174 eType = eType|nType; 175 } 176 177 inline bool ScRangeData::HasType( Type nType ) const 178 { 179 return ( ( eType & nType ) == nType ); 180 } 181 182 extern "C" int ScRangeData_QsortNameCompare( const void*, const void* ); 183 184 class ScRangeName 185 { 186 private: 187 typedef std::vector<ScRangeData*> IndexDataType; 188 typedef ::std::map<OUString, std::unique_ptr<ScRangeData>> DataType; 189 DataType m_Data; 190 IndexDataType maIndexToData; 191 192 public: 193 /// Map that stores non-managed pointers to ScRangeName instances. 194 typedef ::std::map<SCTAB, const ScRangeName*> TabNameCopyMap; 195 196 typedef DataType::const_iterator const_iterator; 197 typedef DataType::iterator iterator; 198 199 ScRangeName(); 200 SC_DLLPUBLIC ScRangeName(const ScRangeName& r); 201 202 SC_DLLPUBLIC const ScRangeData* findByRange(const ScRange& rRange) const; 203 SC_DLLPUBLIC ScRangeData* findByUpperName(const OUString& rName); 204 SC_DLLPUBLIC const ScRangeData* findByUpperName(const OUString& rName) const; 205 SC_DLLPUBLIC ScRangeData* findByIndex(sal_uInt16 i) const; 206 void UpdateReference( sc::RefUpdateContext& rCxt, SCTAB nLocalTab = -1 ); 207 void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt, SCTAB nLocalTab = -1 ); 208 void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt, SCTAB nLocalTab = -1 ); 209 void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt, SCTAB nLocalTab = -1 ); 210 void UpdateTranspose(const ScRange& rSource, const ScAddress& rDest); 211 void UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY); 212 213 /** Compile those names that couldn't be resolved during loading and 214 inserting because they may have referred a name that was inserted later. 215 */ 216 void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); 217 218 /** Copy names while copying a sheet if they reference the sheet to be copied. 219 220 Assumes that new sheet was already inserted, global names have been 221 updated/adjusted, but sheet-local names on nOldTab are not, as is the 222 case in ScDocument::CopyTab() 223 224 @param nLocalTab 225 -1 when operating on global names, else sheet/tab of 226 sheet-local name scope. The already adjusted tab on which to 227 find the name. 228 229 @param nOldTab 230 The original unadjusted tab position. 231 232 @param nNewTab 233 The new tab position. 234 */ 235 void CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab, 236 const ScDocument& rOldDoc, ScDocument& rNewDoc, const bool bGlobalNamesToLocal ) const; 237 238 SC_DLLPUBLIC const_iterator begin() const; 239 SC_DLLPUBLIC const_iterator end() const; 240 SC_DLLPUBLIC iterator begin(); 241 SC_DLLPUBLIC iterator end(); 242 SC_DLLPUBLIC size_t size() const; 243 bool empty() const; 244 245 /** Insert object into set. 246 @ATTENTION: The underlying ::std::map<std::unique_ptr>::insert(p) takes 247 ownership of p and if it can't insert it deletes the object! So, if 248 this insert here returns false the object where p pointed to is gone! 249 250 @param bReuseFreeIndex 251 If the ScRangeData p points to has an index value of 0: 252 If `TRUE` then reuse a free index slot if available. 253 If `FALSE` then assign a new index slot. The Manage Names 254 dialog uses this so that deleting and adding ranges in the same 255 run is guaranteed to not reuse previously assigned indexes. 256 */ 257 SC_DLLPUBLIC bool insert( ScRangeData* p, bool bReuseFreeIndex = true ); 258 259 void erase(const ScRangeData& r); 260 void erase(const OUString& rName); 261 262 /** 263 * Erase by iterator position. Note that this method doesn't check for 264 * iterator's validity. The caller must make sure that the iterator is 265 * valid. 266 */ 267 void erase(const iterator& itr); 268 void clear(); 269 bool operator== (const ScRangeName& r) const; 270 }; 271 272 #endif 273 274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 275
