Update ooo320-m1
[ooovba.git] / sc / source / core / tool / rangenam.cxx
blob5e5b8495d95f6029c7c8e663965561fe7abae84b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rangenam.cxx,v $
10 * $Revision: 1.28.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 //------------------------------------------------------------------------
37 #include <tools/debug.hxx>
38 #include <string.h>
39 #include <memory>
40 #include <unotools/collatorwrapper.hxx>
41 #include <unotools/transliterationwrapper.hxx>
43 #include "token.hxx"
44 #include "tokenarray.hxx"
45 #include "rangenam.hxx"
46 #include "global.hxx"
47 #include "compiler.hxx"
48 #include "rangeutl.hxx"
49 #include "rechead.hxx"
50 #include "refupdat.hxx"
51 #include "document.hxx"
53 using namespace formula;
55 //========================================================================
56 // ScRangeData
57 //========================================================================
59 // Interner ctor fuer das Suchen nach einem Index
61 ScRangeData::ScRangeData( USHORT n )
62 : pCode( NULL ), nIndex( n ), bModified( FALSE ), mnMaxRow(-1), mnMaxCol(-1)
65 ScRangeData::ScRangeData( ScDocument* pDok,
66 const String& rName,
67 const String& rSymbol,
68 const ScAddress& rAddress,
69 RangeType nType,
70 const FormulaGrammar::Grammar eGrammar ) :
71 aName ( rName ),
72 aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
73 pCode ( NULL ),
74 aPos ( rAddress ),
75 eType ( nType ),
76 pDoc ( pDok ),
77 nIndex ( 0 ),
78 bModified ( FALSE ),
79 mnMaxRow (-1),
80 mnMaxCol (-1)
82 if (rSymbol.Len() > 0)
84 ScCompiler aComp( pDoc, aPos );
85 aComp.SetGrammar(eGrammar);
86 pCode = aComp.CompileString( rSymbol );
87 if( !pCode->GetCodeError() )
89 pCode->Reset();
90 FormulaToken* p = pCode->GetNextReference();
91 if( p )// genau eine Referenz als erstes
93 if( p->GetType() == svSingleRef )
94 eType = eType | RT_ABSPOS;
95 else
96 eType = eType | RT_ABSAREA;
98 // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
99 // Dies ist fuer die manuelle Eingabe
100 aComp.CompileTokenArray();
101 pCode->DelRPN();
104 else
106 // #i63513#/#i65690# don't leave pCode as NULL.
107 // Copy ctor default-constructs pCode if it was NULL, so it's initialized here, too,
108 // to ensure same behavior if unnecessary copying is left out.
110 pCode = new ScTokenArray();
114 ScRangeData::ScRangeData( ScDocument* pDok,
115 const String& rName,
116 const ScTokenArray& rArr,
117 const ScAddress& rAddress,
118 RangeType nType ) :
119 aName ( rName ),
120 aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
121 pCode ( new ScTokenArray( rArr ) ),
122 aPos ( rAddress ),
123 eType ( nType ),
124 pDoc ( pDok ),
125 nIndex ( 0 ),
126 bModified ( FALSE ),
127 mnMaxRow (-1),
128 mnMaxCol (-1)
130 if( !pCode->GetCodeError() )
132 pCode->Reset();
133 FormulaToken* p = pCode->GetNextReference();
134 if( p )// genau eine Referenz als erstes
136 if( p->GetType() == svSingleRef )
137 eType = eType | RT_ABSPOS;
138 else
139 eType = eType | RT_ABSAREA;
141 // Die Importfilter haben diesen Test nicht,
142 // da die benannten Bereiche z.T. noch unvollstaendig sind.
143 // if( !pCode->GetCodeLen() )
144 // {
145 // // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
146 // ScCompiler aComp( pDok, aPos, *pCode );
147 // aComp.CompileTokenArray();
148 // pCode->DelRPN();
149 // }
153 ScRangeData::ScRangeData( ScDocument* pDok,
154 const String& rName,
155 const ScAddress& rTarget ) :
156 aName ( rName ),
157 aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
158 pCode ( new ScTokenArray() ),
159 aPos ( rTarget ),
160 eType ( RT_NAME ),
161 pDoc ( pDok ),
162 nIndex ( 0 ),
163 bModified ( FALSE ),
164 mnMaxRow (-1),
165 mnMaxCol (-1)
167 ScSingleRefData aRefData;
168 aRefData.InitAddress( rTarget );
169 aRefData.SetFlag3D( TRUE );
170 pCode->AddSingleReference( aRefData );
171 ScCompiler aComp( pDoc, aPos, *pCode );
172 aComp.SetGrammar(pDoc->GetGrammar());
173 aComp.CompileTokenArray();
174 if ( !pCode->GetCodeError() )
175 eType |= RT_ABSPOS;
178 ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
179 ScDataObject(),
180 aName (rScRangeData.aName),
181 aUpperName (rScRangeData.aUpperName),
182 pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()), // echte Kopie erzeugen (nicht copy-ctor)
183 aPos (rScRangeData.aPos),
184 eType (rScRangeData.eType),
185 pDoc (rScRangeData.pDoc),
186 nIndex (rScRangeData.nIndex),
187 bModified (rScRangeData.bModified),
188 mnMaxRow (rScRangeData.mnMaxRow),
189 mnMaxCol (rScRangeData.mnMaxCol)
192 ScRangeData::~ScRangeData()
194 delete pCode;
197 ScDataObject* ScRangeData::Clone() const
199 return new ScRangeData(*this);
202 void ScRangeData::GuessPosition()
204 // setzt eine Position, mit der alle relative Referenzen bei CalcAbsIfRel
205 // ohne Fehler verabsolutiert werden koennen
207 DBG_ASSERT(aPos == ScAddress(), "die Position geht jetzt verloren");
209 SCsCOL nMinCol = 0;
210 SCsROW nMinRow = 0;
211 SCsTAB nMinTab = 0;
213 ScToken* t;
214 pCode->Reset();
215 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
217 ScSingleRefData& rRef1 = t->GetSingleRef();
218 if ( rRef1.IsColRel() && rRef1.nRelCol < nMinCol )
219 nMinCol = rRef1.nRelCol;
220 if ( rRef1.IsRowRel() && rRef1.nRelRow < nMinRow )
221 nMinRow = rRef1.nRelRow;
222 if ( rRef1.IsTabRel() && rRef1.nRelTab < nMinTab )
223 nMinTab = rRef1.nRelTab;
225 if ( t->GetType() == svDoubleRef )
227 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
228 if ( rRef2.IsColRel() && rRef2.nRelCol < nMinCol )
229 nMinCol = rRef2.nRelCol;
230 if ( rRef2.IsRowRel() && rRef2.nRelRow < nMinRow )
231 nMinRow = rRef2.nRelRow;
232 if ( rRef2.IsTabRel() && rRef2.nRelTab < nMinTab )
233 nMinTab = rRef2.nRelTab;
237 aPos = ScAddress( (SCCOL)(-nMinCol), (SCROW)(-nMinRow), (SCTAB)(-nMinTab) );
239 //! Test
240 // DBG_ERROR(String("Pos ")+String((SCCOL)(-nMinCol))+String("/")+
241 // String((SCROW)(-nMinRow))+String("/")+String((SCTAB)(-nMinTab)));
244 void ScRangeData::GetSymbol( String& rSymbol, const FormulaGrammar::Grammar eGrammar ) const
246 ScCompiler aComp(pDoc, aPos, *pCode);
247 aComp.SetGrammar(eGrammar);
248 aComp.CreateStringFromTokenArray( rSymbol );
251 void ScRangeData::UpdateSymbol( rtl::OUStringBuffer& rBuffer, const ScAddress& rPos,
252 const FormulaGrammar::Grammar eGrammar )
254 ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
255 ScCompiler aComp( pDoc, rPos, *pTemp.get());
256 aComp.SetGrammar(eGrammar);
257 aComp.MoveRelWrap(GetMaxCol(), GetMaxRow());
258 aComp.CreateStringFromTokenArray( rBuffer );
261 void ScRangeData::UpdateReference( UpdateRefMode eUpdateRefMode,
262 const ScRange& r,
263 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
265 BOOL bChanged = FALSE;
267 pCode->Reset();
268 if( pCode->GetNextReference() )
270 BOOL bSharedFormula = ((eType & RT_SHARED) == RT_SHARED);
271 ScCompiler aComp( pDoc, aPos, *pCode );
272 aComp.SetGrammar(pDoc->GetGrammar());
273 const BOOL bRelRef = aComp.UpdateNameReference( eUpdateRefMode, r,
274 nDx, nDy, nDz,
275 bChanged, bSharedFormula);
276 if (bSharedFormula)
278 if (bRelRef)
279 eType = eType | RT_SHAREDMOD;
280 else
281 eType = eType & ~RT_SHAREDMOD;
285 bModified = bChanged;
289 void ScRangeData::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
291 BOOL bChanged = FALSE;
293 ScToken* t;
294 pCode->Reset();
296 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
298 if( t->GetType() != svIndex )
300 SingleDoubleRefModifier aMod( *t );
301 ScComplexRefData& rRef = aMod.Ref();
302 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
303 (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
304 ( t->GetType() == svSingleRef ||
305 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
306 (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
308 if ( ScRefUpdate::UpdateTranspose( pDoc, rSource, rDest, rRef ) != UR_NOTHING )
309 bChanged = TRUE;
314 bModified = bChanged;
317 void ScRangeData::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
319 BOOL bChanged = FALSE;
321 ScToken* t;
322 pCode->Reset();
324 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
326 if( t->GetType() != svIndex )
328 SingleDoubleRefModifier aMod( *t );
329 ScComplexRefData& rRef = aMod.Ref();
330 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
331 (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
332 ( t->GetType() == svSingleRef ||
333 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
334 (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
336 if ( ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY, rRef ) != UR_NOTHING )
337 bChanged = TRUE;
342 bModified = bChanged; // muss direkt hinterher ausgewertet werden
345 BOOL ScRangeData::operator== (const ScRangeData& rData) const // fuer Undo
347 if ( nIndex != rData.nIndex ||
348 aName != rData.aName ||
349 aPos != rData.aPos ||
350 eType != rData.eType ) return FALSE;
352 USHORT nLen = pCode->GetLen();
353 if ( nLen != rData.pCode->GetLen() ) return FALSE;
355 FormulaToken** ppThis = pCode->GetArray();
356 FormulaToken** ppOther = rData.pCode->GetArray();
358 for ( USHORT i=0; i<nLen; i++ )
359 if ( ppThis[i] != ppOther[i] && !(*ppThis[i] == *ppOther[i]) )
360 return FALSE;
362 return TRUE;
365 //UNUSED2009-05 BOOL ScRangeData::IsRangeAtCursor( const ScAddress& rPos, BOOL bStartOnly ) const
366 //UNUSED2009-05 {
367 //UNUSED2009-05 BOOL bRet = FALSE;
368 //UNUSED2009-05 ScRange aRange;
369 //UNUSED2009-05 if ( IsReference(aRange) )
370 //UNUSED2009-05 {
371 //UNUSED2009-05 if ( bStartOnly )
372 //UNUSED2009-05 bRet = ( rPos == aRange.aStart );
373 //UNUSED2009-05 else
374 //UNUSED2009-05 bRet = ( aRange.In( rPos ) );
375 //UNUSED2009-05 }
376 //UNUSED2009-05 return bRet;
377 //UNUSED2009-05 }
379 BOOL ScRangeData::IsRangeAtBlock( const ScRange& rBlock ) const
381 BOOL bRet = FALSE;
382 ScRange aRange;
383 if ( IsReference(aRange) )
384 bRet = ( rBlock == aRange );
385 return bRet;
388 BOOL ScRangeData::IsReference( ScRange& rRange ) const
390 if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS )) && pCode )
391 return pCode->IsReference( rRange );
393 return FALSE;
396 BOOL ScRangeData::IsReference( ScRange& rRange, const ScAddress& rPos ) const
398 if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
400 ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
401 ScCompiler aComp( pDoc, rPos, *pTemp);
402 aComp.SetGrammar(pDoc->GetGrammar());
403 aComp.MoveRelWrap(MAXCOL, MAXROW);
404 return pTemp->IsReference( rRange );
407 return FALSE;
410 BOOL ScRangeData::IsValidReference( ScRange& rRange ) const
412 if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
413 return pCode->IsValidReference( rRange );
415 return FALSE;
418 void ScRangeData::UpdateTabRef(SCTAB nOldTable, USHORT nFlag, SCTAB nNewTable)
420 pCode->Reset();
421 if( pCode->GetNextReference() )
423 ScRangeData* pRangeData = NULL; // must not be dereferenced
424 BOOL bChanged;
425 ScCompiler aComp( pDoc, aPos, *pCode);
426 aComp.SetGrammar(pDoc->GetGrammar());
427 switch (nFlag)
429 case 1: // einfache InsertTab (doc.cxx)
430 pRangeData = aComp.UpdateInsertTab(nOldTable, TRUE ); // und CopyTab (doc2.cxx)
431 break;
432 case 2: // einfaches delete (doc.cxx)
433 pRangeData = aComp.UpdateDeleteTab(nOldTable, FALSE, TRUE, bChanged);
434 break;
435 case 3: // move (doc2.cxx)
437 pRangeData = aComp.UpdateMoveTab(nOldTable, nNewTable, TRUE );
439 break;
440 default:
442 DBG_ERROR("ScRangeName::UpdateTabRef: Unknown Flag");
444 break;
446 if (eType&RT_SHARED)
448 if (pRangeData)
449 eType = eType | RT_SHAREDMOD;
450 else
451 eType = eType & ~RT_SHAREDMOD;
457 void ScRangeData::MakeValidName( String& rName ) // static
459 //ScCompiler::InitSymbolsNative();
461 // strip leading invalid characters
462 xub_StrLen nPos = 0;
463 xub_StrLen nLen = rName.Len();
464 while ( nPos < nLen && !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME) )
465 ++nPos;
466 if ( nPos>0 )
467 rName.Erase(0,nPos);
469 // if the first character is an invalid start character, precede with '_'
470 if ( rName.Len() && !ScCompiler::IsCharFlagAllConventions( rName, 0, SC_COMPILER_C_CHAR_NAME ) )
471 rName.Insert('_',0);
473 // replace invalid with '_'
474 nLen = rName.Len();
475 for (nPos=0; nPos<nLen; nPos++)
477 if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME) )
478 rName.SetChar( nPos, '_' );
481 // Ensure that the proposed name is not a reference under any convention,
482 // same as in IsNameValid()
483 ScAddress aAddr;
484 ScRange aRange;
485 for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
487 ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
488 // Don't check Parse on VALID, any partial only VALID may result in
489 // #REF! during compile later!
490 while (aRange.Parse( rName, NULL, details) || aAddr.Parse( rName, NULL, details))
492 //! Range Parse is partially valid also with invalid sheet name,
493 //! Address Parse dito, during compile name would generate a #REF!
494 if ( rName.SearchAndReplace( '.', '_' ) == STRING_NOTFOUND )
495 rName.Insert('_',0);
500 BOOL ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
502 /* XXX If changed, sc/source/filter/ftools/ftools.cxx
503 * ScfTools::ConvertToScDefinedName needs to be changed too. */
504 xub_StrLen nPos = 0;
505 xub_StrLen nLen = rName.Len();
506 if ( !nLen || !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_CHAR_NAME ) )
507 return FALSE;
508 while ( nPos < nLen )
510 if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_NAME ) )
511 return FALSE;
513 ScAddress aAddr;
514 ScRange aRange;
515 for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
517 ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
518 // Don't check Parse on VALID, any partial only VALID may result in
519 // #REF! during compile later!
520 if (aRange.Parse( rName, pDoc, details) || aAddr.Parse( rName, pDoc, details))
521 return FALSE;
523 return TRUE;
526 void ScRangeData::SetMaxRow(SCROW nRow)
528 mnMaxRow = nRow;
531 SCROW ScRangeData::GetMaxRow() const
533 return mnMaxRow >= 0 ? mnMaxRow : MAXROW;
536 void ScRangeData::SetMaxCol(SCCOL nCol)
538 mnMaxCol = nCol;
541 SCCOL ScRangeData::GetMaxCol() const
543 return mnMaxCol >= 0 ? mnMaxCol : MAXCOL;
547 USHORT ScRangeData::GetErrCode()
549 return pCode ? pCode->GetCodeError() : 0;
552 BOOL ScRangeData::HasReferences() const
554 pCode->Reset();
555 return BOOL( pCode->GetNextReference() != NULL );
558 // bei TransferTab von einem in ein anderes Dokument anpassen,
559 // um Referenzen auf die eigene Tabelle mitzubekommen
561 void ScRangeData::TransferTabRef( SCTAB nOldTab, SCTAB nNewTab )
563 long nTabDiff = (long)nNewTab - nOldTab;
564 long nPosDiff = (long)nNewTab - aPos.Tab();
565 aPos.SetTab( nNewTab );
566 ScToken* t;
567 pCode->Reset();
568 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
570 ScSingleRefData& rRef1 = t->GetSingleRef();
571 if ( rRef1.IsTabRel() )
572 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nPosDiff );
573 else
574 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nTabDiff );
575 if ( t->GetType() == svDoubleRef )
577 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
578 if ( rRef2.IsTabRel() )
579 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nPosDiff );
580 else
581 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nTabDiff );
586 void ScRangeData::ReplaceRangeNamesInUse( const IndexMap& rMap )
588 bool bCompile = false;
589 for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
591 if ( p->GetOpCode() == ocName )
593 const sal_uInt16 nOldIndex = p->GetIndex();
594 IndexMap::const_iterator itr = rMap.find(nOldIndex);
595 const sal_uInt16 nNewIndex = itr == rMap.end() ? nOldIndex : itr->second;
596 if ( nOldIndex != nNewIndex )
598 p->SetIndex( nNewIndex );
599 bCompile = true;
603 if ( bCompile )
605 ScCompiler aComp( pDoc, aPos, *pCode);
606 aComp.SetGrammar(pDoc->GetGrammar());
607 aComp.CompileTokenArray();
612 void ScRangeData::ValidateTabRefs()
614 // try to make sure all relative references and the reference position
615 // are within existing tables, so they can be represented as text
616 // (if the range of used tables is more than the existing tables,
617 // the result may still contain invalid tables, because the relative
618 // references aren't changed so formulas stay the same)
620 // find range of used tables
622 SCTAB nMinTab = aPos.Tab();
623 SCTAB nMaxTab = nMinTab;
624 ScToken* t;
625 pCode->Reset();
626 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
628 ScSingleRefData& rRef1 = t->GetSingleRef();
629 if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
631 if ( rRef1.nTab < nMinTab )
632 nMinTab = rRef1.nTab;
633 if ( rRef1.nTab > nMaxTab )
634 nMaxTab = rRef1.nTab;
636 if ( t->GetType() == svDoubleRef )
638 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
639 if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
641 if ( rRef2.nTab < nMinTab )
642 nMinTab = rRef2.nTab;
643 if ( rRef2.nTab > nMaxTab )
644 nMaxTab = rRef2.nTab;
649 SCTAB nTabCount = pDoc->GetTableCount();
650 if ( nMaxTab >= nTabCount && nMinTab > 0 )
652 // move position and relative tab refs
653 // The formulas that use the name are not changed by this
655 SCTAB nMove = nMinTab;
656 aPos.SetTab( aPos.Tab() - nMove );
658 pCode->Reset();
659 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
661 ScSingleRefData& rRef1 = t->GetSingleRef();
662 if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
663 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab - nMove );
664 if ( t->GetType() == svDoubleRef )
666 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
667 if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
668 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab - nMove );
675 extern "C" int
676 #ifdef WNT
677 __cdecl
678 #endif
679 ScRangeData_QsortNameCompare( const void* p1, const void* p2 )
681 return (int) ScGlobal::GetCollator()->compareString(
682 (*(const ScRangeData**)p1)->GetName(),
683 (*(const ScRangeData**)p2)->GetName() );
687 //========================================================================
688 // ScRangeName
689 //========================================================================
691 ScRangeName::ScRangeName(const ScRangeName& rScRangeName, ScDocument* pDocument) :
692 ScSortedCollection ( rScRangeName ),
693 pDoc ( pDocument ),
694 nSharedMaxIndex (rScRangeName.nSharedMaxIndex)
696 for (USHORT i = 0; i < nCount; i++)
698 ((ScRangeData*)At(i))->SetDocument(pDocument);
699 ((ScRangeData*)At(i))->SetIndex(((ScRangeData*)rScRangeName.At(i))->GetIndex());
703 short ScRangeName::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
705 USHORT i1 = ((ScRangeData*)pKey1)->GetIndex();
706 USHORT i2 = ((ScRangeData*)pKey2)->GetIndex();
707 return (short) i1 - (short) i2;
710 BOOL ScRangeName::SearchNameUpper( const String& rUpperName, USHORT& rIndex ) const
712 // SearchNameUpper must be called with an upper-case search string
714 USHORT i = 0;
715 while (i < nCount)
717 if ( ((*this)[i])->GetUpperName() == rUpperName )
719 rIndex = i;
720 return TRUE;
722 i++;
724 return FALSE;
727 BOOL ScRangeName::SearchName( const String& rName, USHORT& rIndex ) const
729 if ( nCount > 0 )
730 return SearchNameUpper( ScGlobal::pCharClass->upper( rName ), rIndex );
731 else
732 return FALSE;
735 void ScRangeName::UpdateReference( UpdateRefMode eUpdateRefMode,
736 const ScRange& rRange,
737 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
739 for (USHORT i=0; i<nCount; i++)
740 ((ScRangeData*)pItems[i])->UpdateReference(eUpdateRefMode, rRange,
741 nDx, nDy, nDz);
744 void ScRangeName::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
746 for (USHORT i=0; i<nCount; i++)
747 ((ScRangeData*)pItems[i])->UpdateTranspose( rSource, rDest );
750 void ScRangeName::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
752 for (USHORT i=0; i<nCount; i++)
753 ((ScRangeData*)pItems[i])->UpdateGrow( rArea, nGrowX, nGrowY );
756 BOOL ScRangeName::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
758 return *(ScRangeData*)pKey1 == *(ScRangeData*)pKey2;
761 BOOL ScRangeName::Insert(ScDataObject* pScDataObject)
763 if (!((ScRangeData*)pScDataObject)->GetIndex()) // schon gesetzt?
765 ((ScRangeData*)pScDataObject)->SetIndex( GetEntryIndex() );
768 return ScSortedCollection::Insert(pScDataObject);
771 // Suche nach einem freien Index
773 USHORT ScRangeName::GetEntryIndex()
775 USHORT nLast = 0;
776 for ( USHORT i = 0; i < nCount; i++ )
778 USHORT nIdx = ((ScRangeData*)pItems[i])->GetIndex();
779 if( nIdx > nLast )
781 nLast = nIdx;
784 return nLast + 1;
787 ScRangeData* ScRangeName::FindIndex( USHORT nIndex )
789 ScRangeData aDataObj( nIndex );
790 USHORT n;
791 if( Search( &aDataObj, n ) )
792 return (*this)[ n ];
793 else
794 return NULL;
797 //UNUSED2009-05 ScRangeData* ScRangeName::GetRangeAtCursor( const ScAddress& rPos, BOOL bStartOnly ) const
798 //UNUSED2009-05 {
799 //UNUSED2009-05 if ( pItems )
800 //UNUSED2009-05 {
801 //UNUSED2009-05 for ( USHORT i = 0; i < nCount; i++ )
802 //UNUSED2009-05 if ( ((ScRangeData*)pItems[i])->IsRangeAtCursor( rPos, bStartOnly ) )
803 //UNUSED2009-05 return (ScRangeData*)pItems[i];
804 //UNUSED2009-05 }
805 //UNUSED2009-05 return NULL;
806 //UNUSED2009-05 }
808 ScRangeData* ScRangeName::GetRangeAtBlock( const ScRange& rBlock ) const
810 if ( pItems )
812 for ( USHORT i = 0; i < nCount; i++ )
813 if ( ((ScRangeData*)pItems[i])->IsRangeAtBlock( rBlock ) )
814 return (ScRangeData*)pItems[i];
816 return NULL;
819 void ScRangeName::UpdateTabRef(SCTAB nOldTable, USHORT nFlag, SCTAB nNewTable)
821 for (USHORT i=0; i<nCount; i++)
822 ((ScRangeData*)pItems[i])->UpdateTabRef(nOldTable, nFlag, nNewTable);