update dev300-m57
[ooovba.git] / sc / source / core / tool / rangenam.cxx
blob52651b75b2678185bcd1fb678781c06bdeb3fa67
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"
52 #include "indexmap.hxx"
54 using namespace formula;
56 //========================================================================
57 // ScRangeData
58 //========================================================================
60 // Interner ctor fuer das Suchen nach einem Index
62 ScRangeData::ScRangeData( USHORT n )
63 : pCode( NULL ), nIndex( n ), bModified( FALSE ), mnMaxRow(-1), mnMaxCol(-1)
66 ScRangeData::ScRangeData( ScDocument* pDok,
67 const String& rName,
68 const String& rSymbol,
69 const ScAddress& rAddress,
70 RangeType nType,
71 const FormulaGrammar::Grammar eGrammar ) :
72 aName ( rName ),
73 aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
74 pCode ( NULL ),
75 aPos ( rAddress ),
76 eType ( nType ),
77 pDoc ( pDok ),
78 nIndex ( 0 ),
79 bModified ( FALSE ),
80 mnMaxRow (-1),
81 mnMaxCol (-1)
83 if (rSymbol.Len() > 0)
85 ScCompiler aComp( pDoc, aPos );
86 aComp.SetGrammar(eGrammar);
87 pCode = aComp.CompileString( rSymbol );
88 if( !pCode->GetCodeError() )
90 pCode->Reset();
91 FormulaToken* p = pCode->GetNextReference();
92 if( p )// genau eine Referenz als erstes
94 if( p->GetType() == svSingleRef )
95 eType = eType | RT_ABSPOS;
96 else
97 eType = eType | RT_ABSAREA;
99 // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
100 // Dies ist fuer die manuelle Eingabe
101 aComp.CompileTokenArray();
102 pCode->DelRPN();
105 else
107 // #i63513#/#i65690# don't leave pCode as NULL.
108 // Copy ctor default-constructs pCode if it was NULL, so it's initialized here, too,
109 // to ensure same behavior if unnecessary copying is left out.
111 pCode = new ScTokenArray();
115 ScRangeData::ScRangeData( ScDocument* pDok,
116 const String& rName,
117 const ScTokenArray& rArr,
118 const ScAddress& rAddress,
119 RangeType nType ) :
120 aName ( rName ),
121 aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
122 pCode ( new ScTokenArray( rArr ) ),
123 aPos ( rAddress ),
124 eType ( nType ),
125 pDoc ( pDok ),
126 nIndex ( 0 ),
127 bModified ( FALSE ),
128 mnMaxRow (-1),
129 mnMaxCol (-1)
131 if( !pCode->GetCodeError() )
133 pCode->Reset();
134 FormulaToken* p = pCode->GetNextReference();
135 if( p )// genau eine Referenz als erstes
137 if( p->GetType() == svSingleRef )
138 eType = eType | RT_ABSPOS;
139 else
140 eType = eType | RT_ABSAREA;
142 // Die Importfilter haben diesen Test nicht,
143 // da die benannten Bereiche z.T. noch unvollstaendig sind.
144 // if( !pCode->GetCodeLen() )
145 // {
146 // // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
147 // ScCompiler aComp( pDok, aPos, *pCode );
148 // aComp.CompileTokenArray();
149 // pCode->DelRPN();
150 // }
154 ScRangeData::ScRangeData( ScDocument* pDok,
155 const String& rName,
156 const ScAddress& rTarget ) :
157 aName ( rName ),
158 aUpperName ( ScGlobal::pCharClass->upper( rName ) ),
159 pCode ( new ScTokenArray() ),
160 aPos ( rTarget ),
161 eType ( RT_NAME ),
162 pDoc ( pDok ),
163 nIndex ( 0 ),
164 bModified ( FALSE ),
165 mnMaxRow (-1),
166 mnMaxCol (-1)
168 ScSingleRefData aRefData;
169 aRefData.InitAddress( rTarget );
170 aRefData.SetFlag3D( TRUE );
171 pCode->AddSingleReference( aRefData );
172 ScCompiler aComp( pDoc, aPos, *pCode );
173 aComp.SetGrammar(pDoc->GetGrammar());
174 aComp.CompileTokenArray();
175 if ( !pCode->GetCodeError() )
176 eType |= RT_ABSPOS;
179 ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
180 ScDataObject(),
181 aName (rScRangeData.aName),
182 aUpperName (rScRangeData.aUpperName),
183 pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()), // echte Kopie erzeugen (nicht copy-ctor)
184 aPos (rScRangeData.aPos),
185 eType (rScRangeData.eType),
186 pDoc (rScRangeData.pDoc),
187 nIndex (rScRangeData.nIndex),
188 bModified (rScRangeData.bModified),
189 mnMaxRow (rScRangeData.mnMaxRow),
190 mnMaxCol (rScRangeData.mnMaxCol)
193 ScRangeData::~ScRangeData()
195 delete pCode;
198 ScDataObject* ScRangeData::Clone() const
200 return new ScRangeData(*this);
203 void ScRangeData::GuessPosition()
205 // setzt eine Position, mit der alle relative Referenzen bei CalcAbsIfRel
206 // ohne Fehler verabsolutiert werden koennen
208 DBG_ASSERT(aPos == ScAddress(), "die Position geht jetzt verloren");
210 SCsCOL nMinCol = 0;
211 SCsROW nMinRow = 0;
212 SCsTAB nMinTab = 0;
214 ScToken* t;
215 pCode->Reset();
216 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
218 ScSingleRefData& rRef1 = t->GetSingleRef();
219 if ( rRef1.IsColRel() && rRef1.nRelCol < nMinCol )
220 nMinCol = rRef1.nRelCol;
221 if ( rRef1.IsRowRel() && rRef1.nRelRow < nMinRow )
222 nMinRow = rRef1.nRelRow;
223 if ( rRef1.IsTabRel() && rRef1.nRelTab < nMinTab )
224 nMinTab = rRef1.nRelTab;
226 if ( t->GetType() == svDoubleRef )
228 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
229 if ( rRef2.IsColRel() && rRef2.nRelCol < nMinCol )
230 nMinCol = rRef2.nRelCol;
231 if ( rRef2.IsRowRel() && rRef2.nRelRow < nMinRow )
232 nMinRow = rRef2.nRelRow;
233 if ( rRef2.IsTabRel() && rRef2.nRelTab < nMinTab )
234 nMinTab = rRef2.nRelTab;
238 aPos = ScAddress( (SCCOL)(-nMinCol), (SCROW)(-nMinRow), (SCTAB)(-nMinTab) );
240 //! Test
241 // DBG_ERROR(String("Pos ")+String((SCCOL)(-nMinCol))+String("/")+
242 // String((SCROW)(-nMinRow))+String("/")+String((SCTAB)(-nMinTab)));
245 void ScRangeData::GetSymbol( String& rSymbol, const FormulaGrammar::Grammar eGrammar ) const
247 ScCompiler aComp(pDoc, aPos, *pCode);
248 aComp.SetGrammar(eGrammar);
249 aComp.CreateStringFromTokenArray( rSymbol );
252 void ScRangeData::UpdateSymbol( rtl::OUStringBuffer& rBuffer, const ScAddress& rPos,
253 const FormulaGrammar::Grammar eGrammar )
255 ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
256 ScCompiler aComp( pDoc, rPos, *pTemp.get());
257 aComp.SetGrammar(eGrammar);
258 aComp.MoveRelWrap(GetMaxCol(), GetMaxRow());
259 aComp.CreateStringFromTokenArray( rBuffer );
262 void ScRangeData::UpdateReference( UpdateRefMode eUpdateRefMode,
263 const ScRange& r,
264 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
266 BOOL bChanged = FALSE;
268 pCode->Reset();
269 if( pCode->GetNextReference() )
271 BOOL bSharedFormula = ((eType & RT_SHARED) == RT_SHARED);
272 ScCompiler aComp( pDoc, aPos, *pCode );
273 aComp.SetGrammar(pDoc->GetGrammar());
274 const BOOL bRelRef = aComp.UpdateNameReference( eUpdateRefMode, r,
275 nDx, nDy, nDz,
276 bChanged, bSharedFormula);
277 if (bSharedFormula)
279 if (bRelRef)
280 eType = eType | RT_SHAREDMOD;
281 else
282 eType = eType & ~RT_SHAREDMOD;
286 bModified = bChanged;
290 void ScRangeData::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
292 BOOL bChanged = FALSE;
294 ScToken* t;
295 pCode->Reset();
297 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
299 if( t->GetType() != svIndex )
301 SingleDoubleRefModifier aMod( *t );
302 ScComplexRefData& rRef = aMod.Ref();
303 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
304 (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
305 ( t->GetType() == svSingleRef ||
306 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
307 (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
309 if ( ScRefUpdate::UpdateTranspose( pDoc, rSource, rDest, rRef ) != UR_NOTHING )
310 bChanged = TRUE;
315 bModified = bChanged;
318 void ScRangeData::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
320 BOOL bChanged = FALSE;
322 ScToken* t;
323 pCode->Reset();
325 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
327 if( t->GetType() != svIndex )
329 SingleDoubleRefModifier aMod( *t );
330 ScComplexRefData& rRef = aMod.Ref();
331 if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
332 (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
333 ( t->GetType() == svSingleRef ||
334 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
335 (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
337 if ( ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY, rRef ) != UR_NOTHING )
338 bChanged = TRUE;
343 bModified = bChanged; // muss direkt hinterher ausgewertet werden
346 BOOL ScRangeData::operator== (const ScRangeData& rData) const // fuer Undo
348 if ( nIndex != rData.nIndex ||
349 aName != rData.aName ||
350 aPos != rData.aPos ||
351 eType != rData.eType ) return FALSE;
353 USHORT nLen = pCode->GetLen();
354 if ( nLen != rData.pCode->GetLen() ) return FALSE;
356 FormulaToken** ppThis = pCode->GetArray();
357 FormulaToken** ppOther = rData.pCode->GetArray();
359 for ( USHORT i=0; i<nLen; i++ )
360 if ( ppThis[i] != ppOther[i] && !(*ppThis[i] == *ppOther[i]) )
361 return FALSE;
363 return TRUE;
366 //UNUSED2009-05 BOOL ScRangeData::IsRangeAtCursor( const ScAddress& rPos, BOOL bStartOnly ) const
367 //UNUSED2009-05 {
368 //UNUSED2009-05 BOOL bRet = FALSE;
369 //UNUSED2009-05 ScRange aRange;
370 //UNUSED2009-05 if ( IsReference(aRange) )
371 //UNUSED2009-05 {
372 //UNUSED2009-05 if ( bStartOnly )
373 //UNUSED2009-05 bRet = ( rPos == aRange.aStart );
374 //UNUSED2009-05 else
375 //UNUSED2009-05 bRet = ( aRange.In( rPos ) );
376 //UNUSED2009-05 }
377 //UNUSED2009-05 return bRet;
378 //UNUSED2009-05 }
380 BOOL ScRangeData::IsRangeAtBlock( const ScRange& rBlock ) const
382 BOOL bRet = FALSE;
383 ScRange aRange;
384 if ( IsReference(aRange) )
385 bRet = ( rBlock == aRange );
386 return bRet;
389 BOOL ScRangeData::IsReference( ScRange& rRange ) const
391 if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS )) && pCode )
392 return pCode->IsReference( rRange );
394 return FALSE;
397 BOOL ScRangeData::IsReference( ScRange& rRange, const ScAddress& rPos ) const
399 if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
401 ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
402 ScCompiler aComp( pDoc, rPos, *pTemp);
403 aComp.SetGrammar(pDoc->GetGrammar());
404 aComp.MoveRelWrap(MAXCOL, MAXROW);
405 return pTemp->IsReference( rRange );
408 return FALSE;
411 BOOL ScRangeData::IsValidReference( ScRange& rRange ) const
413 if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
414 return pCode->IsValidReference( rRange );
416 return FALSE;
419 void ScRangeData::UpdateTabRef(SCTAB nOldTable, USHORT nFlag, SCTAB nNewTable)
421 pCode->Reset();
422 if( pCode->GetNextReference() )
424 ScRangeData* pRangeData = NULL; // must not be dereferenced
425 BOOL bChanged;
426 ScCompiler aComp( pDoc, aPos, *pCode);
427 aComp.SetGrammar(pDoc->GetGrammar());
428 switch (nFlag)
430 case 1: // einfache InsertTab (doc.cxx)
431 pRangeData = aComp.UpdateInsertTab(nOldTable, TRUE ); // und CopyTab (doc2.cxx)
432 break;
433 case 2: // einfaches delete (doc.cxx)
434 pRangeData = aComp.UpdateDeleteTab(nOldTable, FALSE, TRUE, bChanged);
435 break;
436 case 3: // move (doc2.cxx)
438 pRangeData = aComp.UpdateMoveTab(nOldTable, nNewTable, TRUE );
440 break;
441 default:
443 DBG_ERROR("ScRangeName::UpdateTabRef: Unknown Flag");
445 break;
447 if (eType&RT_SHARED)
449 if (pRangeData)
450 eType = eType | RT_SHAREDMOD;
451 else
452 eType = eType & ~RT_SHAREDMOD;
457 // wie beim Uebernehmen von Namen in Excel
459 void ScRangeData::MakeValidName( String& rName ) // static
461 //ScCompiler::InitSymbolsNative();
463 // ungueltige Zeichen vorne weglassen
464 xub_StrLen nPos = 0;
465 xub_StrLen nLen = rName.Len();
466 while ( nPos < nLen && !ScCompiler::IsWordChar( rName, nPos) )
467 ++nPos;
468 if ( nPos>0 )
469 rName.Erase(0,nPos);
471 // wenn vorne ein ungueltiges Anfangszeichen steht, '_' davor
472 if ( rName.Len() && !ScCompiler::IsCharWordChar( rName, 0 ) )
473 rName.Insert('_',0);
475 // ungueltige durch '_' ersetzen
476 nLen = rName.Len();
477 for (nPos=0; nPos<nLen; nPos++)
479 if ( !ScCompiler::IsWordChar( rName, nPos) )
480 rName.SetChar( nPos, '_' );
483 // Name darf keine Referenz beinhalten, wie in IsNameValid
484 ScAddress aAddr;
485 ScRange aRange;
486 int nConv = FormulaGrammar::CONV_UNSPECIFIED; // use int so that op++ works
488 // Ensure that the proposed name is not an address under any convention
489 while ( ++nConv != FormulaGrammar::CONV_LAST )
491 ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
492 while( aRange.Parse( rName, NULL, details )
493 || aAddr.Parse( rName, NULL, details ) )
495 //! Range Parse auch bei Bereich mit ungueltigem Tabellennamen gueltig
496 //! Address Parse dito, Name erzeugt deswegen bei Compile ein #REF!
497 if ( rName.SearchAndReplace( ':', '_' ) == STRING_NOTFOUND
498 && rName.SearchAndReplace( '.', '_' ) == STRING_NOTFOUND )
499 rName.Insert('_',0);
504 BOOL ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
506 /* If changed, ScfTools::ConvertToScDefinedName (sc/source/filter/ftools/ftools.cxx)
507 needs to be changed too. */
508 xub_StrLen nPos = 0;
509 xub_StrLen nLen = rName.Len();
510 if ( !nLen || !ScCompiler::IsCharWordChar( rName, nPos++ ) )
511 return FALSE;
512 while ( nPos < nLen )
514 if ( !ScCompiler::IsWordChar( rName, nPos++ ) )
515 return FALSE;
517 // Parse nicht auf VALID pruefen, es reicht, wenn irgendein Bestandteil
518 // erkannt wurde
519 ScRange aRange;
520 if( aRange.Parse( rName, pDoc ) ) // THIS IS WRONG
521 return FALSE;
522 else
524 ScAddress aAddr;
525 if ( aAddr.Parse( rName, pDoc ) ) // THIS IS WRONG
526 return FALSE;
528 return TRUE;
531 void ScRangeData::SetMaxRow(SCROW nRow)
533 mnMaxRow = nRow;
536 SCROW ScRangeData::GetMaxRow() const
538 return mnMaxRow >= 0 ? mnMaxRow : MAXROW;
541 void ScRangeData::SetMaxCol(SCCOL nCol)
543 mnMaxCol = nCol;
546 SCCOL ScRangeData::GetMaxCol() const
548 return mnMaxCol >= 0 ? mnMaxCol : MAXCOL;
552 USHORT ScRangeData::GetErrCode()
554 return pCode ? pCode->GetCodeError() : 0;
557 BOOL ScRangeData::HasReferences() const
559 pCode->Reset();
560 return BOOL( pCode->GetNextReference() != NULL );
563 // bei TransferTab von einem in ein anderes Dokument anpassen,
564 // um Referenzen auf die eigene Tabelle mitzubekommen
566 void ScRangeData::TransferTabRef( SCTAB nOldTab, SCTAB nNewTab )
568 long nTabDiff = (long)nNewTab - nOldTab;
569 long nPosDiff = (long)nNewTab - aPos.Tab();
570 aPos.SetTab( nNewTab );
571 ScToken* t;
572 pCode->Reset();
573 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
575 ScSingleRefData& rRef1 = t->GetSingleRef();
576 if ( rRef1.IsTabRel() )
577 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nPosDiff );
578 else
579 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nTabDiff );
580 if ( t->GetType() == svDoubleRef )
582 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
583 if ( rRef2.IsTabRel() )
584 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nPosDiff );
585 else
586 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nTabDiff );
592 void ScRangeData::ReplaceRangeNamesInUse( const ScIndexMap& rMap )
594 BOOL bCompile = FALSE;
595 for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
597 if ( p->GetOpCode() == ocName )
599 const USHORT nOldIndex = p->GetIndex();
600 const USHORT nNewIndex = rMap.Find( nOldIndex );
601 if ( nOldIndex != nNewIndex )
603 p->SetIndex( nNewIndex );
604 bCompile = TRUE;
608 if ( bCompile )
610 ScCompiler aComp( pDoc, aPos, *pCode);
611 aComp.SetGrammar(pDoc->GetGrammar());
612 aComp.CompileTokenArray();
616 void ScRangeData::ReplaceRangeNamesInUse( const IndexMap& rMap )
618 bool bCompile = false;
619 for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
621 if ( p->GetOpCode() == ocName )
623 const sal_uInt16 nOldIndex = p->GetIndex();
624 IndexMap::const_iterator itr = rMap.find(nOldIndex);
625 const sal_uInt16 nNewIndex = itr == rMap.end() ? nOldIndex : itr->second;
626 if ( nOldIndex != nNewIndex )
628 p->SetIndex( nNewIndex );
629 bCompile = true;
633 if ( bCompile )
635 ScCompiler aComp( pDoc, aPos, *pCode);
636 aComp.SetGrammar(pDoc->GetGrammar());
637 aComp.CompileTokenArray();
642 void ScRangeData::ValidateTabRefs()
644 // try to make sure all relative references and the reference position
645 // are within existing tables, so they can be represented as text
646 // (if the range of used tables is more than the existing tables,
647 // the result may still contain invalid tables, because the relative
648 // references aren't changed so formulas stay the same)
650 // find range of used tables
652 SCTAB nMinTab = aPos.Tab();
653 SCTAB nMaxTab = nMinTab;
654 ScToken* t;
655 pCode->Reset();
656 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
658 ScSingleRefData& rRef1 = t->GetSingleRef();
659 if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
661 if ( rRef1.nTab < nMinTab )
662 nMinTab = rRef1.nTab;
663 if ( rRef1.nTab > nMaxTab )
664 nMaxTab = rRef1.nTab;
666 if ( t->GetType() == svDoubleRef )
668 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
669 if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
671 if ( rRef2.nTab < nMinTab )
672 nMinTab = rRef2.nTab;
673 if ( rRef2.nTab > nMaxTab )
674 nMaxTab = rRef2.nTab;
679 SCTAB nTabCount = pDoc->GetTableCount();
680 if ( nMaxTab >= nTabCount && nMinTab > 0 )
682 // move position and relative tab refs
683 // The formulas that use the name are not changed by this
685 SCTAB nMove = nMinTab;
686 aPos.SetTab( aPos.Tab() - nMove );
688 pCode->Reset();
689 while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
691 ScSingleRefData& rRef1 = t->GetSingleRef();
692 if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
693 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab - nMove );
694 if ( t->GetType() == svDoubleRef )
696 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
697 if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
698 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab - nMove );
705 extern "C" int
706 #ifdef WNT
707 __cdecl
708 #endif
709 ScRangeData_QsortNameCompare( const void* p1, const void* p2 )
711 return (int) ScGlobal::pCollator->compareString(
712 (*(const ScRangeData**)p1)->GetName(),
713 (*(const ScRangeData**)p2)->GetName() );
717 //========================================================================
718 // ScRangeName
719 //========================================================================
721 ScRangeName::ScRangeName(const ScRangeName& rScRangeName, ScDocument* pDocument) :
722 ScSortedCollection ( rScRangeName ),
723 pDoc ( pDocument ),
724 nSharedMaxIndex (rScRangeName.nSharedMaxIndex)
726 for (USHORT i = 0; i < nCount; i++)
728 ((ScRangeData*)At(i))->SetDocument(pDocument);
729 ((ScRangeData*)At(i))->SetIndex(((ScRangeData*)rScRangeName.At(i))->GetIndex());
733 short ScRangeName::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
735 USHORT i1 = ((ScRangeData*)pKey1)->GetIndex();
736 USHORT i2 = ((ScRangeData*)pKey2)->GetIndex();
737 return (short) i1 - (short) i2;
740 BOOL ScRangeName::SearchNameUpper( const String& rUpperName, USHORT& rIndex ) const
742 // SearchNameUpper must be called with an upper-case search string
744 USHORT i = 0;
745 while (i < nCount)
747 if ( ((*this)[i])->GetUpperName() == rUpperName )
749 rIndex = i;
750 return TRUE;
752 i++;
754 return FALSE;
757 BOOL ScRangeName::SearchName( const String& rName, USHORT& rIndex ) const
759 if ( nCount > 0 )
760 return SearchNameUpper( ScGlobal::pCharClass->upper( rName ), rIndex );
761 else
762 return FALSE;
765 void ScRangeName::UpdateReference( UpdateRefMode eUpdateRefMode,
766 const ScRange& rRange,
767 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
769 for (USHORT i=0; i<nCount; i++)
770 ((ScRangeData*)pItems[i])->UpdateReference(eUpdateRefMode, rRange,
771 nDx, nDy, nDz);
774 void ScRangeName::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
776 for (USHORT i=0; i<nCount; i++)
777 ((ScRangeData*)pItems[i])->UpdateTranspose( rSource, rDest );
780 void ScRangeName::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
782 for (USHORT i=0; i<nCount; i++)
783 ((ScRangeData*)pItems[i])->UpdateGrow( rArea, nGrowX, nGrowY );
786 BOOL ScRangeName::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
788 return *(ScRangeData*)pKey1 == *(ScRangeData*)pKey2;
791 BOOL ScRangeName::Insert(ScDataObject* pScDataObject)
793 if (!((ScRangeData*)pScDataObject)->GetIndex()) // schon gesetzt?
795 ((ScRangeData*)pScDataObject)->SetIndex( GetEntryIndex() );
798 return ScSortedCollection::Insert(pScDataObject);
801 // Suche nach einem freien Index
803 USHORT ScRangeName::GetEntryIndex()
805 USHORT nLast = 0;
806 for ( USHORT i = 0; i < nCount; i++ )
808 USHORT nIdx = ((ScRangeData*)pItems[i])->GetIndex();
809 if( nIdx > nLast )
811 nLast = nIdx;
814 return nLast + 1;
817 ScRangeData* ScRangeName::FindIndex( USHORT nIndex )
819 ScRangeData aDataObj( nIndex );
820 USHORT n;
821 if( Search( &aDataObj, n ) )
822 return (*this)[ n ];
823 else
824 return NULL;
827 //UNUSED2009-05 ScRangeData* ScRangeName::GetRangeAtCursor( const ScAddress& rPos, BOOL bStartOnly ) const
828 //UNUSED2009-05 {
829 //UNUSED2009-05 if ( pItems )
830 //UNUSED2009-05 {
831 //UNUSED2009-05 for ( USHORT i = 0; i < nCount; i++ )
832 //UNUSED2009-05 if ( ((ScRangeData*)pItems[i])->IsRangeAtCursor( rPos, bStartOnly ) )
833 //UNUSED2009-05 return (ScRangeData*)pItems[i];
834 //UNUSED2009-05 }
835 //UNUSED2009-05 return NULL;
836 //UNUSED2009-05 }
838 ScRangeData* ScRangeName::GetRangeAtBlock( const ScRange& rBlock ) const
840 if ( pItems )
842 for ( USHORT i = 0; i < nCount; i++ )
843 if ( ((ScRangeData*)pItems[i])->IsRangeAtBlock( rBlock ) )
844 return (ScRangeData*)pItems[i];
846 return NULL;
849 void ScRangeName::UpdateTabRef(SCTAB nOldTable, USHORT nFlag, SCTAB nNewTable)
851 for (USHORT i=0; i<nCount; i++)
852 ((ScRangeData*)pItems[i])->UpdateTabRef(nOldTable, nFlag, nNewTable);