LibreOffice Module sc (master) 1
rangenam.cxx
Go to the documentation of this file.
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#include <string.h>
21#include <memory>
24#include <com/sun/star/sheet/NamedRangeFlag.hpp>
25#include <osl/diagnose.h>
26
27#include <token.hxx>
28#include <tokenarray.hxx>
29#include <rangenam.hxx>
30#include <rangeutl.hxx>
31#include <global.hxx>
32#include <compiler.hxx>
33#include <refupdat.hxx>
34#include <document.hxx>
35#include <refupdatecontext.hxx>
37
39
40using namespace formula;
41using ::std::pair;
42
43// ScRangeData
44
46 const OUString& rName,
47 const OUString& rSymbol,
48 const ScAddress& rAddress,
49 Type nType,
50 const FormulaGrammar::Grammar eGrammar ) :
51 aName ( rName ),
52 aUpperName ( ScGlobal::getCharClass().uppercase( rName ) ),
53 aPos ( rAddress ),
54 eType ( nType ),
55 rDoc ( rDok ),
56 eTempGrammar( eGrammar ),
57 nIndex ( 0 ),
58 bModified ( false )
59{
60 if (!rSymbol.isEmpty())
61 {
62 // Let the compiler set an error on unknown names for a subsequent
63 // CompileUnresolvedXML().
64 const bool bImporting = rDoc.IsImportingXML();
65 CompileRangeData( rSymbol, bImporting);
66 if (bImporting)
68 }
69 else
70 {
71 // #i63513#/#i65690# don't leave pCode as NULL.
72 // Copy ctor default-constructs pCode if it was NULL, so it's initialized here, too,
73 // to ensure same behavior if unnecessary copying is left out.
74
75 pCode.reset( new ScTokenArray(rDoc) );
76 pCode->SetFromRangeName(true);
77 }
78}
79
81 const OUString& rName,
82 const ScTokenArray& rArr,
83 const ScAddress& rAddress,
84 Type nType ) :
85 aName ( rName ),
86 aUpperName ( ScGlobal::getCharClass().uppercase( rName ) ),
87 pCode ( new ScTokenArray( rArr ) ),
88 aPos ( rAddress ),
89 eType ( nType ),
90 rDoc ( rDok ),
91 eTempGrammar( FormulaGrammar::GRAM_UNSPECIFIED ),
92 nIndex ( 0 ),
93 bModified ( false )
94{
95 pCode->SetFromRangeName(true);
96 InitCode();
97}
98
100 const OUString& rName,
101 const ScAddress& rTarget ) :
102 aName ( rName ),
103 aUpperName ( ScGlobal::getCharClass().uppercase( rName ) ),
104 pCode ( new ScTokenArray(rDok) ),
105 aPos ( rTarget ),
106 eType ( Type::Name ),
107 rDoc ( rDok ),
108 eTempGrammar( FormulaGrammar::GRAM_UNSPECIFIED ),
109 nIndex ( 0 ),
110 bModified ( false )
111{
112 ScSingleRefData aRefData;
113 aRefData.InitAddress( rTarget );
114 aRefData.SetFlag3D( true );
115 pCode->AddSingleReference( aRefData );
116 pCode->SetFromRangeName(true);
117 ScCompiler aComp( rDoc, aPos, *pCode, rDoc.GetGrammar() );
118 aComp.CompileTokenArray();
119 if ( pCode->GetCodeError() == FormulaError::NONE )
121}
122
123ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument, const ScAddress* pPos) :
124 aName (rScRangeData.aName),
125 aUpperName (rScRangeData.aUpperName),
126 pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone().release() : new ScTokenArray(*pDocument)), // make real copy (not copy-ctor)
127 aPos (pPos ? *pPos : rScRangeData.aPos),
128 eType (rScRangeData.eType),
129 rDoc (pDocument ? *pDocument : rScRangeData.rDoc),
130 eTempGrammar(rScRangeData.eTempGrammar),
131 nIndex (rScRangeData.nIndex),
132 bModified (rScRangeData.bModified)
133{
134 pCode->SetFromRangeName(true);
135}
136
138{
139}
140
141void ScRangeData::CompileRangeData( const OUString& rSymbol, bool bSetError )
142{
143 if (eTempGrammar == FormulaGrammar::GRAM_UNSPECIFIED)
144 {
145 OSL_FAIL( "ScRangeData::CompileRangeData: unspecified grammar");
146 // Anything is almost as bad as this, but we might have the best choice
147 // if not loading documents.
148 eTempGrammar = FormulaGrammar::GRAM_NATIVE;
149 }
150
151 ScCompiler aComp( rDoc, aPos, eTempGrammar );
152 if (bSetError)
154 pCode = aComp.CompileString( rSymbol );
155 pCode->SetFromRangeName(true);
156 if( pCode->GetCodeError() != FormulaError::NONE )
157 return;
158
161 if( p )
162 {
163 // first token is a reference
164 /* FIXME: wouldn't that need a check if it's exactly one reference? */
165 if( p->GetType() == svSingleRef )
167 else
169 }
170 // For manual input set an error for an incomplete formula.
171 if (!rDoc.IsImportingXML())
172 {
173 aComp.CompileTokenArray();
174 pCode->DelRPN();
175 }
176}
177
179{
180 if (pCode->GetCodeError() == FormulaError::NoName)
181 {
182 // Reconstruct the symbol/formula and then recompile.
183 OUString aSymbol;
185 ScCompiler aComp(rCxt, aPos, *pCode);
186 aComp.CreateStringFromTokenArray( aSymbol);
187 // Don't let the compiler set an error for unknown names on final
188 // compile, errors are handled by the interpreter thereafter.
189 CompileRangeData( aSymbol, false);
191 }
192}
193
194#if DEBUG_FORMULA_COMPILER
195void ScRangeData::Dump() const
196{
197 cout << "-- ScRangeData" << endl;
198 cout << " name: " << aName << endl;
199 cout << " ref position: (col=" << aPos.Col() << ", row=" << aPos.Row() << ", sheet=" << aPos.Tab() << ")" << endl;
200
201 if (pCode)
202 pCode->Dump();
203}
204#endif
205
207{
208 // set a position that allows "absoluting" of all relative references
209 // in CalcAbsIfRel without errors
210
211 OSL_ENSURE(aPos == ScAddress(), "position will go lost now");
212
213 SCCOL nMinCol = 0;
214 SCROW nMinRow = 0;
215 SCTAB nMinTab = 0;
216
219 while ( ( t = aIter.GetNextReference() ) != nullptr )
220 {
221 ScSingleRefData& rRef1 = *t->GetSingleRef();
222 if ( rRef1.IsColRel() && rRef1.Col() < nMinCol )
223 nMinCol = rRef1.Col();
224 if ( rRef1.IsRowRel() && rRef1.Row() < nMinRow )
225 nMinRow = rRef1.Row();
226 if ( rRef1.IsTabRel() && rRef1.Tab() < nMinTab )
227 nMinTab = rRef1.Tab();
228
229 if ( t->GetType() == svDoubleRef )
230 {
231 ScSingleRefData& rRef2 = t->GetDoubleRef()->Ref2;
232 if ( rRef2.IsColRel() && rRef2.Col() < nMinCol )
233 nMinCol = rRef2.Col();
234 if ( rRef2.IsRowRel() && rRef2.Row() < nMinRow )
235 nMinRow = rRef2.Row();
236 if ( rRef2.IsTabRel() && rRef2.Tab() < nMinTab )
237 nMinTab = rRef2.Tab();
238 }
239 }
240
241 aPos = ScAddress( static_cast<SCCOL>(-nMinCol), static_cast<SCROW>(-nMinRow), static_cast<SCTAB>(-nMinTab) );
242}
243
244OUString ScRangeData::GetSymbol( const FormulaGrammar::Grammar eGrammar ) const
245{
246 ScCompiler aComp(rDoc, aPos, *pCode, eGrammar);
247 OUString symbol;
248 aComp.CreateStringFromTokenArray( symbol );
249 return symbol;
250}
251
252OUString ScRangeData::GetSymbol( const ScAddress& rPos, const FormulaGrammar::Grammar eGrammar ) const
253{
254 OUString aStr;
255 ScCompiler aComp(rDoc, rPos, *pCode, eGrammar);
257 return aStr;
258}
259
260void ScRangeData::UpdateSymbol( OUStringBuffer& rBuffer, const ScAddress& rPos )
261{
262 ScTokenArray aTemp( pCode->CloneValue() );
264 aComp.MoveRelWrap();
265 aComp.CreateStringFromTokenArray( rBuffer );
266}
267
269{
270 sc::RefUpdateResult aRes = pCode->AdjustReferenceInName(rCxt, aPos);
272 if (aRes.mbReferenceModified)
273 rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
274}
275
276void ScRangeData::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
277{
278 bool bChanged = false;
279
282
283 while ( ( t = aIter.GetNextReference() ) != nullptr )
284 {
285 if( t->GetType() != svIndex )
286 {
287 SingleDoubleRefModifier aMod( *t );
288 ScComplexRefData& rRef = aMod.Ref();
289 // Update only absolute references
290 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
291 (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
292 ( t->GetType() == svSingleRef ||
293 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
294 (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
295 {
296 ScRange aAbs = rRef.toAbs(rDoc, aPos);
297 // Check if the absolute reference of this range is pointing to the transposed source
298 if (ScRefUpdate::UpdateTranspose(rDoc, rSource, rDest, aAbs) != UR_NOTHING)
299 {
300 rRef.SetRange(rDoc.GetSheetLimits(), aAbs, aPos);
301 bChanged = true;
302 }
303 }
304 }
305 }
306
307 bModified = bChanged;
308}
309
310void ScRangeData::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
311{
312 bool bChanged = false;
313
316
317 while ( ( t = aIter.GetNextReference() ) != nullptr )
318 {
319 if( t->GetType() != svIndex )
320 {
321 SingleDoubleRefModifier aMod( *t );
322 ScComplexRefData& rRef = aMod.Ref();
323 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
324 (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
325 ( t->GetType() == svSingleRef ||
326 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
327 (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
328 {
329 ScRange aAbs = rRef.toAbs(rDoc, aPos);
330 if (ScRefUpdate::UpdateGrow(rArea, nGrowX, nGrowY, aAbs) != UR_NOTHING)
331 {
332 rRef.SetRange(rDoc.GetSheetLimits(), aAbs, aPos);
333 bChanged = true;
334 }
335 }
336 }
337 }
338
339 bModified = bChanged; // has to be evaluated immediately afterwards
340}
341
342bool ScRangeData::operator== (const ScRangeData& rData) const // for Undo
343{
344 if ( nIndex != rData.nIndex ||
345 aName != rData.aName ||
346 aPos != rData.aPos ||
347 eType != rData.eType ) return false;
348
349 sal_uInt16 nLen = pCode->GetLen();
350 if ( nLen != rData.pCode->GetLen() ) return false;
351
352 FormulaToken** ppThis = pCode->GetArray();
353 FormulaToken** ppOther = rData.pCode->GetArray();
354
355 for ( sal_uInt16 i=0; i<nLen; i++ )
356 if ( ppThis[i] != ppOther[i] && !(*ppThis[i] == *ppOther[i]) )
357 return false;
358
359 return true;
360}
361
362bool ScRangeData::IsRangeAtBlock( const ScRange& rBlock ) const
363{
364 bool bRet = false;
365 ScRange aRange;
366 if ( IsReference(aRange) )
367 bRet = ( rBlock == aRange );
368 return bRet;
369}
370
372{
374 return pCode->IsReference(rRange, aPos);
375
376 return false;
377}
378
379bool ScRangeData::IsReference( ScRange& rRange, const ScAddress& rPos ) const
380{
381 if ( (eType & ( Type::AbsArea | Type::RefArea | Type::AbsPos ) ) && pCode )
382 return pCode->IsReference(rRange, rPos);
383
384 return false;
385}
386
388{
389 if ( (eType & ( Type::AbsArea | Type::RefArea | Type::AbsPos ) ) && pCode )
390 return pCode->IsValidReference(rRange, aPos);
391
392 return false;
393}
394
396{
397 sc::RefUpdateResult aRes = pCode->AdjustReferenceOnInsertedTab(rCxt, aPos);
398 if (aRes.mbReferenceModified)
399 rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
400
401 if (rCxt.mnInsertPos <= aPos.Tab())
402 aPos.IncTab(rCxt.mnSheets);
403}
404
406{
407 sc::RefUpdateResult aRes = pCode->AdjustReferenceOnDeletedTab(rCxt, aPos);
408 if (aRes.mbReferenceModified)
409 rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
410
412}
413
415{
416 sc::RefUpdateResult aRes = pCode->AdjustReferenceOnMovedTab(rCxt, aPos);
417 if (aRes.mbReferenceModified)
418 rCxt.maUpdatedNames.setUpdatedName(nLocalTab, nIndex);
419
420 aPos.SetTab(rCxt.getNewTab(aPos.Tab()));
421}
422
423void ScRangeData::MakeValidName( const ScDocument& rDoc, OUString& rName )
424{
425
426 // strip leading invalid characters
427 sal_Int32 nPos = 0;
428 sal_Int32 nLen = rName.getLength();
430 ++nPos;
431 if ( nPos>0 )
432 rName = rName.copy(nPos);
433
434 // if the first character is an invalid start character, precede with '_'
435 if ( !rName.isEmpty() && !ScCompiler::IsCharFlagAllConventions( rName, 0, ScCharFlags::CharName ) )
436 rName = "_" + rName;
437
438 // replace invalid with '_'
439 nLen = rName.getLength();
440 for (nPos=0; nPos<nLen; nPos++)
441 {
443 rName = rName.replaceAt( nPos, 1, u"_" );
444 }
445
446 // Ensure that the proposed name is not a reference under any convention,
447 // same as in IsNameValid()
448 ScAddress aAddr;
449 ScRange aRange;
450 for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
451 {
452 ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
453 // Don't check Parse on VALID, any partial only VALID may result in
454 // #REF! during compile later!
455 while (aRange.Parse(rName, rDoc, details) != ScRefFlags::ZERO ||
456 aAddr.Parse(rName, rDoc, details) != ScRefFlags::ZERO)
457 {
458 // Range Parse is partially valid also with invalid sheet name,
459 // Address Parse ditto, during compile name would generate a #REF!
460 if ( rName.indexOf( '.' ) != -1 )
461 rName = rName.replaceFirst( ".", "_" );
462 else
463 rName = "_" + rName;
464 }
465 }
466}
467
469{
470 /* XXX If changed, sc/source/filter/ftools/ftools.cxx
471 * ScfTools::ConvertToScDefinedName needs to be changed too. */
472 char const a('.');
473 if (rName.indexOf(a) != -1)
475 sal_Int32 nPos = 0;
476 sal_Int32 nLen = rName.getLength();
479 while ( nPos < nLen )
480 {
483 }
484 ScAddress aAddr;
485 ScRange aRange;
486 for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
487 {
488 ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
489 // Don't check Parse on VALID, any partial only VALID may result in
490 // #REF! during compile later!
491 if (aRange.Parse(rName, rDoc, details) != ScRefFlags::ZERO ||
492 aAddr.Parse(rName, rDoc, details) != ScRefFlags::ZERO )
493 {
495 }
496 }
498}
499
501{
502 // Similar to part of IsNameValid(), but only check if the name is a valid address.
503 ScAddress aAddr;
504 for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
505 {
506 ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
507 // Don't check Parse on VALID, any partial only VALID may result in
508 // #REF! during compile later!
509 if(aAddr.Parse(aUpperName, rDoc, details) != ScRefFlags::ZERO)
510 return true;
511 }
512 return false;
513}
514
516{
517 return pCode ? pCode->GetCodeError() : FormulaError::NONE;
518}
519
521{
522 return pCode->HasReferences();
523}
524
525sal_uInt32 ScRangeData::GetUnoType() const
526{
527 sal_uInt32 nUnoType = 0;
528 if ( HasType(Type::Criteria) ) nUnoType |= css::sheet::NamedRangeFlag::FILTER_CRITERIA;
529 if ( HasType(Type::PrintArea) ) nUnoType |= css::sheet::NamedRangeFlag::PRINT_AREA;
532 return nUnoType;
533}
534
536{
537 // try to make sure all relative references and the reference position
538 // are within existing tables, so they can be represented as text
539 // (if the range of used tables is more than the existing tables,
540 // the result may still contain invalid tables, because the relative
541 // references aren't changed so formulas stay the same)
542
543 // find range of used tables
544
545 SCTAB nMinTab = aPos.Tab();
546 SCTAB nMaxTab = nMinTab;
549 while ( ( t = aIter.GetNextReference() ) != nullptr )
550 {
551 ScSingleRefData& rRef1 = *t->GetSingleRef();
552 ScAddress aAbs = rRef1.toAbs(rDoc, aPos);
553 if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
554 {
555 if (aAbs.Tab() < nMinTab)
556 nMinTab = aAbs.Tab();
557 if (aAbs.Tab() > nMaxTab)
558 nMaxTab = aAbs.Tab();
559 }
560 if ( t->GetType() == svDoubleRef )
561 {
562 ScSingleRefData& rRef2 = t->GetDoubleRef()->Ref2;
563 aAbs = rRef2.toAbs(rDoc, aPos);
564 if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
565 {
566 if (aAbs.Tab() < nMinTab)
567 nMinTab = aAbs.Tab();
568 if (aAbs.Tab() > nMaxTab)
569 nMaxTab = aAbs.Tab();
570 }
571 }
572 }
573
574 SCTAB nTabCount = rDoc.GetTableCount();
575 if ( nMaxTab < nTabCount || nMinTab <= 0 )
576 return;
577
578 // move position and relative tab refs
579 // The formulas that use the name are not changed by this
580
581 SCTAB nMove = nMinTab;
582 ScAddress aOldPos = aPos;
583 aPos.SetTab( aPos.Tab() - nMove );
584
585 aIter.Reset();
586 while ( ( t = aIter.GetNextReference() ) != nullptr )
587 {
588 switch (t->GetType())
589 {
590 case svSingleRef:
591 {
592 ScSingleRefData& rRef = *t->GetSingleRef();
593 if (!rRef.IsTabDeleted())
594 {
595 ScAddress aAbs = rRef.toAbs(rDoc, aOldPos);
596 rRef.SetAddress(rDoc.GetSheetLimits(), aAbs, aPos);
597 }
598 }
599 break;
600 case svDoubleRef:
601 {
602 ScComplexRefData& rRef = *t->GetDoubleRef();
603 if (!rRef.Ref1.IsTabDeleted())
604 {
605 ScAddress aAbs = rRef.Ref1.toAbs(rDoc, aOldPos);
606 rRef.Ref1.SetAddress(rDoc.GetSheetLimits(), aAbs, aPos);
607 }
608 if (!rRef.Ref2.IsTabDeleted())
609 {
610 ScAddress aAbs = rRef.Ref2.toAbs(rDoc, aOldPos);
611 rRef.Ref2.SetAddress(rDoc.GetSheetLimits(), aAbs, aPos);
612 }
613 }
614 break;
615 default:
616 ;
617 }
618 }
619}
620
622{
623 pCode.reset(new ScTokenArray( rArr ));
624 pCode->SetFromRangeName(true);
625 InitCode();
626}
627
629{
630 if( pCode->GetCodeError() == FormulaError::NONE )
631 {
633 if( p ) // exact one reference at first
634 {
635 if( p->GetType() == svSingleRef )
637 else
639 }
640 }
641}
642
643extern "C"
644int ScRangeData_QsortNameCompare( const void* p1, const void* p2 )
645{
646 return static_cast<int>(ScGlobal::GetCollator().compareString(
647 (*static_cast<const ScRangeData* const *>(p1))->GetName(),
648 (*static_cast<const ScRangeData* const *>(p2))->GetName() ));
649}
650
651namespace {
652
656class MatchByRange
657{
658 const ScRange& mrRange;
659public:
660 explicit MatchByRange(const ScRange& rRange) : mrRange(rRange) {}
661 bool operator() (std::pair<OUString const, std::unique_ptr<ScRangeData>> const& r) const
662 {
663 return r.second->IsRangeAtBlock(mrRange);
664 }
665};
666
667}
668
670 : mHasPossibleAddressConflict(false)
671 , mHasPossibleAddressConflictDirty(false)
672{
673}
674
676 : mHasPossibleAddressConflict( r.mHasPossibleAddressConflict )
677 , mHasPossibleAddressConflictDirty( r.mHasPossibleAddressConflictDirty )
678{
679 for (auto const& it : r.m_Data)
680 {
681 m_Data.insert(std::make_pair(it.first, std::make_unique<ScRangeData>(*it.second)));
682 }
683 // std::map was cloned, so each collection needs its own index to data.
684 maIndexToData.resize( r.maIndexToData.size(), nullptr);
685 for (auto const& itr : m_Data)
686 {
687 size_t nPos = itr.second->GetIndex() - 1;
688 if (nPos >= maIndexToData.size())
689 {
690 OSL_FAIL( "ScRangeName copy-ctor: maIndexToData size doesn't fit");
691 maIndexToData.resize(nPos+1, nullptr);
692 }
693 maIndexToData[nPos] = itr.second.get();
694 }
695}
696
698{
699 DataType::const_iterator itr = std::find_if(
700 m_Data.begin(), m_Data.end(), MatchByRange(rRange));
701 return itr == m_Data.end() ? nullptr : itr->second.get();
702}
703
705{
706 DataType::iterator itr = m_Data.find(rName);
707 return itr == m_Data.end() ? nullptr : itr->second.get();
708}
709
710const ScRangeData* ScRangeName::findByUpperName(const OUString& rName) const
711{
712 DataType::const_iterator itr = m_Data.find(rName);
713 return itr == m_Data.end() ? nullptr : itr->second.get();
714}
715
717{
718 if (!i)
719 // index should never be zero.
720 return nullptr;
721
722 size_t nPos = i - 1;
723 return nPos < maIndexToData.size() ? maIndexToData[nPos] : nullptr;
724}
725
727{
728 if (rCxt.meMode == URM_COPY)
729 // Copying cells does not modify named expressions.
730 return;
731
732 for (auto const& itr : m_Data)
733 {
734 itr.second->UpdateReference(rCxt, nLocalTab);
735 }
736}
737
739{
740 for (auto const& itr : m_Data)
741 {
742 itr.second->UpdateInsertTab(rCxt, nLocalTab);
743 }
744}
745
747{
748 for (auto const& itr : m_Data)
749 {
750 itr.second->UpdateDeleteTab(rCxt, nLocalTab);
751 }
752}
753
755{
756 for (auto const& itr : m_Data)
757 {
758 itr.second->UpdateMoveTab(rCxt, nLocalTab);
759 }
760}
761
762void ScRangeName::UpdateTranspose(const ScRange& rSource, const ScAddress& rDest)
763{
764 for (auto const& itr : m_Data)
765 {
766 itr.second->UpdateTranspose(rSource, rDest);
767 }
768}
769
770void ScRangeName::UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY)
771{
772 for (auto const& itr : m_Data)
773 {
774 itr.second->UpdateGrow(rArea, nGrowX, nGrowY);
775 }
776}
777
779{
780 for (auto const& itr : m_Data)
781 {
782 itr.second->CompileUnresolvedXML(rCxt);
783 }
784}
785
786void ScRangeName::CopyUsedNames( const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab,
787 const ScDocument& rOldDoc, ScDocument& rNewDoc, const bool bGlobalNamesToLocal ) const
788{
789 for (auto const& itr : m_Data)
790 {
791 SCTAB nSheet = (nLocalTab < 0) ? nLocalTab : nOldTab;
792 sal_uInt16 nIndex = itr.second->GetIndex();
793 ScAddress aOldPos( itr.second->GetPos());
794 aOldPos.SetTab( nOldTab);
795 ScAddress aNewPos( aOldPos);
796 aNewPos.SetTab( nNewTab);
797 ScRangeData* pRangeData = nullptr;
798 rOldDoc.CopyAdjustRangeName( nSheet, nIndex, pRangeData, rNewDoc, aNewPos, aOldPos, bGlobalNamesToLocal, false);
799 }
800}
801
802bool ScRangeName::insert( ScRangeData* p, bool bReuseFreeIndex )
803{
804 if (!p)
805 return false;
806
807 if (!p->GetIndex())
808 {
809 // Assign a new index. An index must be unique and is never 0.
810 if (bReuseFreeIndex)
811 {
812 IndexDataType::iterator itr = std::find(
813 maIndexToData.begin(), maIndexToData.end(), static_cast<ScRangeData*>(nullptr));
814 if (itr != maIndexToData.end())
815 {
816 // Empty slot exists. Re-use it.
817 size_t nPos = std::distance(maIndexToData.begin(), itr);
818 p->SetIndex(nPos + 1);
819 }
820 else
821 // No empty slot. Append it to the end.
822 p->SetIndex(maIndexToData.size() + 1);
823 }
824 else
825 {
826 p->SetIndex(maIndexToData.size() + 1);
827 }
828 }
829
830 OUString aName(p->GetUpperName());
831 erase(aName); // ptr_map won't insert it if a duplicate name exists.
832 pair<DataType::iterator, bool> r =
833 m_Data.insert(std::make_pair(aName, std::unique_ptr<ScRangeData>(p)));
834 if (r.second)
835 {
836 // Data inserted. Store its index for mapping.
837 size_t nPos = p->GetIndex() - 1;
838 if (nPos >= maIndexToData.size())
839 maIndexToData.resize(nPos+1, nullptr);
842 }
843 return r.second;
844}
845
847{
848 erase(r.GetUpperName());
849}
850
851void ScRangeName::erase(const OUString& rName)
852{
853 DataType::const_iterator itr = m_Data.find(rName);
854 if (itr != m_Data.end())
855 erase(itr);
856}
857
859{
860 sal_uInt16 nIndex = itr->second->GetIndex();
861 m_Data.erase(itr);
862 OSL_ENSURE( 0 < nIndex && nIndex <= maIndexToData.size(), "ScRangeName::erase: bad index");
863 if (0 < nIndex && nIndex <= maIndexToData.size())
864 maIndexToData[nIndex-1] = nullptr;
867}
868
870{
871 m_Data.clear();
872 maIndexToData.clear();
875}
876
878{
881 for (auto const& itr : m_Data)
882 {
883 if( itr.second->HasPossibleAddressConflict())
884 {
886 return;
887 }
888 }
889}
890
892{
893 return std::equal(m_Data.begin(), m_Data.end(), r.m_Data.begin(), r.m_Data.end(),
894 [](const DataType::value_type& lhs, const DataType::value_type& rhs) {
895 return (lhs.first == rhs.first) && (*lhs.second == *rhs.second);
896 });
897}
898
899/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
sal_Int32 compareString(const OUString &s1, const OUString &s2) const
void IncTab(SCTAB nDelta=1)
Definition: address.hxx:320
SCTAB Tab() const
Definition: address.hxx:283
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1537
SCROW Row() const
Definition: address.hxx:274
void SetTab(SCTAB nTabP)
Definition: address.hxx:295
SCCOL Col() const
Definition: address.hxx:279
@ EXTENDED_ERROR_DETECTION_NAME_NO_BREAK
Definition: compiler.hxx:188
static bool IsCharFlagAllConventions(OUString const &rStr, sal_Int32 nPos, ScCharFlags nFlags)
If the character is allowed as tested by nFlags (SC_COMPILER_C_... bits) for all known address conven...
Definition: compiler.cxx:5214
void SetExtendedErrorDetection(ExtendedErrorDetection eVal)
Definition: compiler.hxx:477
void MoveRelWrap()
Definition: compiler.cxx:5189
std::unique_ptr< ScTokenArray > CompileString(const OUString &rFormula)
Tokenize formula expression string into an array of tokens.
Definition: compiler.cxx:4691
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:898
SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck(const ScTokenArray &rCode)
Check token array and set link check if ocDde/ocWebservice is contained.
Definition: documen8.cxx:1149
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
Definition: document.hxx:1010
bool CopyAdjustRangeName(SCTAB &rSheet, sal_uInt16 &rIndex, ScRangeData *&rpRangeData, ScDocument &rNewDoc, const ScAddress &rNewPos, const ScAddress &rOldPos, const bool bGlobalNamesToLocal, const bool bUsedByFormula) const
If necessary (name references sheet rOldPos.Tab()) copy and adjust named expression/range from sheet-...
Definition: document10.cxx:801
bool IsImportingXML() const
Definition: document.hxx:2227
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
static SC_DLLPUBLIC CollatorWrapper & GetCollator()
case-insensitive collator
Definition: global.cxx:1095
SC_DLLPUBLIC bool IsReference(ScRange &rRef) const
Definition: rangenam.cxx:371
bool HasType(Type nType) const
Definition: rangenam.hxx:178
Type eType
Definition: rangenam.hxx:75
void CompileUnresolvedXML(sc::CompileFormulaContext &rCxt)
Definition: rangenam.cxx:178
bool HasPossibleAddressConflict() const
Definition: rangenam.cxx:500
ScAddress aPos
Definition: rangenam.hxx:74
sal_uInt32 GetUnoType() const
Definition: rangenam.cxx:525
std::unique_ptr< ScTokenArray > pCode
Definition: rangenam.hxx:73
formula::FormulaGrammar::Grammar eTempGrammar
Definition: rangenam.hxx:77
SC_DLLPUBLIC FormulaError GetErrCode() const
Definition: rangenam.cxx:515
void UpdateInsertTab(sc::RefUpdateInsertTabContext &rCxt, SCTAB nLocalTab)
Definition: rangenam.cxx:395
SC_DLLPUBLIC void GuessPosition()
Definition: rangenam.cxx:206
void UpdateDeleteTab(sc::RefUpdateDeleteTabContext &rCxt, SCTAB nLocalTab)
Definition: rangenam.cxx:405
static void MakeValidName(const ScDocument &rDoc, OUString &rName)
Definition: rangenam.cxx:423
void InitCode()
Definition: rangenam.cxx:628
sal_uInt16 nIndex
Definition: rangenam.hxx:78
OUString aName
Definition: rangenam.hxx:69
void UpdateSymbol(OUStringBuffer &rBuffer, const ScAddress &)
Definition: rangenam.cxx:260
void CompileRangeData(const OUString &rSymbol, bool bSetError)
Definition: rangenam.cxx:141
void UpdateReference(sc::RefUpdateContext &rCxt, SCTAB nLocalTab)
Definition: rangenam.cxx:268
SC_DLLPUBLIC ~ScRangeData()
Definition: rangenam.cxx:137
SC_DLLPUBLIC bool IsValidReference(ScRange &rRef) const
Definition: rangenam.cxx:387
SC_DLLPUBLIC void SetCode(const ScTokenArray &)
Definition: rangenam.cxx:621
void UpdateTranspose(const ScRange &rSource, const ScAddress &rDest)
Definition: rangenam.cxx:276
void ValidateTabRefs()
Definition: rangenam.cxx:535
void UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY)
Definition: rangenam.cxx:310
static SC_DLLPUBLIC IsNameValidType IsNameValid(const OUString &rName, const ScDocument &rDoc)
Definition: rangenam.cxx:468
bool IsRangeAtBlock(const ScRange &) const
Definition: rangenam.cxx:362
SC_DLLPUBLIC OUString GetSymbol(const formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT) const
Definition: rangenam.cxx:244
bool HasReferences() const
Definition: rangenam.cxx:520
SC_DLLPUBLIC ScRangeData(ScDocument &rDoc, const OUString &rName, const OUString &rSymbol, const ScAddress &rAdr=ScAddress(), Type nType=Type::Name, const formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT)
Definition: rangenam.cxx:45
const OUString & GetUpperName() const
Definition: rangenam.hxx:112
bool bModified
Definition: rangenam.hxx:79
bool operator==(const ScRangeData &rData) const
Definition: rangenam.cxx:342
void UpdateMoveTab(sc::RefUpdateMoveTabContext &rCxt, SCTAB nLocalTab)
Definition: rangenam.cxx:414
ScDocument & rDoc
Definition: rangenam.hxx:76
OUString aUpperName
Definition: rangenam.hxx:70
void UpdateDeleteTab(sc::RefUpdateDeleteTabContext &rCxt, SCTAB nLocalTab=-1)
Definition: rangenam.cxx:746
void CopyUsedNames(const SCTAB nLocalTab, const SCTAB nOldTab, const SCTAB nNewTab, const ScDocument &rOldDoc, ScDocument &rNewDoc, const bool bGlobalNamesToLocal) const
Copy names while copying a sheet if they reference the sheet to be copied.
Definition: rangenam.cxx:786
SC_DLLPUBLIC ScRangeData * findByIndex(sal_uInt16 i) const
Definition: rangenam.cxx:716
void UpdateReference(sc::RefUpdateContext &rCxt, SCTAB nLocalTab=-1)
Definition: rangenam.cxx:726
void CompileUnresolvedXML(sc::CompileFormulaContext &rCxt)
Compile those names that couldn't be resolved during loading and inserting because they may have refe...
Definition: rangenam.cxx:778
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:704
void clear()
Definition: rangenam.cxx:869
void UpdateInsertTab(sc::RefUpdateInsertTabContext &rCxt, SCTAB nLocalTab=-1)
Definition: rangenam.cxx:738
void UpdateMoveTab(sc::RefUpdateMoveTabContext &rCxt, SCTAB nLocalTab=-1)
Definition: rangenam.cxx:754
IndexDataType maIndexToData
Definition: rangenam.hxx:191
void erase(const ScRangeData &r)
Definition: rangenam.cxx:846
bool mHasPossibleAddressConflictDirty
Definition: rangenam.hxx:195
DataType::const_iterator const_iterator
Definition: rangenam.hxx:203
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:802
bool mHasPossibleAddressConflict
Definition: rangenam.hxx:194
void UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY)
Definition: rangenam.cxx:770
void UpdateTranspose(const ScRange &rSource, const ScAddress &rDest)
Definition: rangenam.cxx:762
void checkHasPossibleAddressConflict() const
Definition: rangenam.cxx:877
DataType m_Data
Definition: rangenam.hxx:190
SC_DLLPUBLIC const ScRangeData * findByRange(const ScRange &rRange) const
Definition: rangenam.cxx:697
bool operator==(const ScRangeName &r) const
Definition: rangenam.cxx:891
ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
Definition: address.cxx:1700
static ScRefUpdateRes UpdateTranspose(const ScDocument &rDoc, const ScRange &rSource, const ScAddress &rDest, ScRange &rRef)
Definition: refupdat.cxx:531
static ScRefUpdateRes UpdateGrow(const ScRange &rArea, SCCOL nGrowX, SCROW nGrowY, ScRange &rRef)
Definition: refupdat.cxx:555
ScComplexRefData & Ref()
Definition: token.hxx:437
void CreateStringFromTokenArray(OUString &rFormula)
void setGrammar(formula::FormulaGrammar::Grammar eGram)
void setUpdatedName(SCTAB nTab, sal_uInt16 nIndex)
virtual OUString GetName() const override
float u
FormulaError
FilterGroup & rTarget
DocumentType eType
@ URM_COPY
Definition: global.hxx:303
sal_Int32 nIndex
OUString aName
void * p
uno_Any a
sal_uInt16 nPos
aStr
svIndex
svDoubleRef
svSingleRef
int i
PyRef getCharClass(const Runtime &)
css::uno::Reference< css::animations::XAnimationNode > Clone(const css::uno::Reference< css::animations::XAnimationNode > &xSourceNode, const SdPage *pSource=nullptr, const SdPage *pTarget=nullptr)
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
int ScRangeData_QsortNameCompare(const void *p1, const void *p2)
Definition: rangenam.cxx:644
@ UR_NOTHING
Reference not affected, no change at all.
Definition: refupdat.hxx:31
TOOLS_DLLPUBLIC SvStream & endl(SvStream &rStr)
Complex reference (a range) into the sheet.
Definition: refdata.hxx:123
SC_DLLPUBLIC ScRange toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:493
ScSingleRefData Ref2
Definition: refdata.hxx:125
void SetRange(const ScSheetLimits &rLimits, const ScRange &rRange, const ScAddress &rPos)
Set a new range, assuming that the ordering of the range matches the ordering of the reference data f...
Definition: refdata.cxx:498
ScSingleRefData Ref1
Definition: refdata.hxx:124
static void UpdateDeleteTab(ScAddress &rAddr, const sc::RefUpdateDeleteTabContext &rCxt)
This is for the base-cell-address of a defined name or conditional format, not for references.
Definition: rangeutl.cxx:1059
Single reference (one address) into the sheet.
Definition: refdata.hxx:30
SCCOL Col() const
Definition: refdata.cxx:247
void SetAddress(const ScSheetLimits &rLimits, const ScAddress &rAddr, const ScAddress &rPos)
Definition: refdata.cxx:213
void InitAddress(const ScAddress &rAdr)
InitAddress: InitFlags and set address.
Definition: refdata.cxx:27
SCTAB Tab() const
Definition: refdata.cxx:254
bool IsTabRel() const
Definition: refdata.hxx:69
SCROW Row() const
Definition: refdata.cxx:240
bool IsRowRel() const
Definition: refdata.hxx:67
ScAddress toAbs(const ScSheetLimits &rLimits, const ScAddress &rPos) const
Definition: refdata.cxx:193
bool IsColRel() const
Definition: refdata.hxx:65
bool IsTabDeleted() const
Definition: refdata.hxx:86
void SetFlag3D(bool bVal)
Definition: refdata.hxx:89
bool IsFlag3D() const
Definition: refdata.hxx:90
Context for reference update during shifting, moving or copying of cell ranges.
UpdateRefMode meMode
update mode - insert/delete, copy, or move.
UpdatedRangeNames maUpdatedNames
SCTAB getNewTab(SCTAB nOldTab) const
bool mbReferenceModified
This flag indicates whether any reference in the token array has been modified.
@ COLUMN_HEADER
Definition: tabview.hxx:59
@ ROW_HEADER
Definition: tabview.hxx:60
OUString Name
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17