xref: /trunk/main/sc/source/core/tool/rangenam.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b3f79822SAndrew Rist  * distributed with this work for additional information
6b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17b3f79822SAndrew Rist  * specific language governing permissions and limitations
18b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20b3f79822SAndrew Rist  *************************************************************/
21b3f79822SAndrew Rist 
22b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir //------------------------------------------------------------------------
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <tools/debug.hxx>
31cdf0e10cSrcweir #include <string.h>
32cdf0e10cSrcweir #include <memory>
33cdf0e10cSrcweir #include <unotools/collatorwrapper.hxx>
34cdf0e10cSrcweir #include <unotools/transliterationwrapper.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "token.hxx"
37cdf0e10cSrcweir #include "tokenarray.hxx"
38cdf0e10cSrcweir #include "rangenam.hxx"
39cdf0e10cSrcweir #include "global.hxx"
40cdf0e10cSrcweir #include "compiler.hxx"
41cdf0e10cSrcweir #include "rangeutl.hxx"
42cdf0e10cSrcweir #include "rechead.hxx"
43cdf0e10cSrcweir #include "refupdat.hxx"
44cdf0e10cSrcweir #include "document.hxx"
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace formula;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir //========================================================================
49cdf0e10cSrcweir // ScRangeData
50cdf0e10cSrcweir //========================================================================
51cdf0e10cSrcweir 
52cdf0e10cSrcweir // Interner ctor fuer das Suchen nach einem Index
53cdf0e10cSrcweir 
ScRangeData(sal_uInt16 n)54cdf0e10cSrcweir ScRangeData::ScRangeData( sal_uInt16 n )
55*dffa72deSWang Lei            : pCode( NULL ), nIndex( n ), bModified( sal_False ), mnMaxRow(-1), mnMaxCol(-1), aRangeNameScope( MAXTABCOUNT )
56cdf0e10cSrcweir {}
57cdf0e10cSrcweir 
ScRangeData(ScDocument * pDok,const String & rName,const String & rSymbol,const ScAddress & rAddress,RangeType nType,const FormulaGrammar::Grammar eGrammar)58cdf0e10cSrcweir ScRangeData::ScRangeData( ScDocument* pDok,
59cdf0e10cSrcweir                           const String& rName,
60cdf0e10cSrcweir                           const String& rSymbol,
61cdf0e10cSrcweir                           const ScAddress& rAddress,
62cdf0e10cSrcweir                           RangeType nType,
63cdf0e10cSrcweir                           const FormulaGrammar::Grammar eGrammar ) :
64cdf0e10cSrcweir                 aName       ( rName ),
65cdf0e10cSrcweir                 aUpperName  ( ScGlobal::pCharClass->upper( rName ) ),
66cdf0e10cSrcweir                 pCode       ( NULL ),
67cdf0e10cSrcweir                 aPos        ( rAddress ),
68cdf0e10cSrcweir                 eType       ( nType ),
69cdf0e10cSrcweir                 pDoc        ( pDok ),
70cdf0e10cSrcweir                 nIndex      ( 0 ),
71cdf0e10cSrcweir                 bModified   ( sal_False ),
72cdf0e10cSrcweir                 mnMaxRow    (-1),
73*dffa72deSWang Lei                 mnMaxCol    (-1),
74*dffa72deSWang Lei                 aRangeNameScope( MAXTABCOUNT )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     if (rSymbol.Len() > 0)
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         ScCompiler aComp( pDoc, aPos );
79cdf0e10cSrcweir         aComp.SetGrammar(eGrammar);
80cdf0e10cSrcweir         pCode = aComp.CompileString( rSymbol );
81cdf0e10cSrcweir         if( !pCode->GetCodeError() )
82cdf0e10cSrcweir         {
83cdf0e10cSrcweir             pCode->Reset();
84cdf0e10cSrcweir             FormulaToken* p = pCode->GetNextReference();
85cdf0e10cSrcweir             if( p )// genau eine Referenz als erstes
86cdf0e10cSrcweir             {
87cdf0e10cSrcweir                 if( p->GetType() == svSingleRef )
88cdf0e10cSrcweir                     eType = eType | RT_ABSPOS;
89cdf0e10cSrcweir                 else
90cdf0e10cSrcweir                     eType = eType | RT_ABSAREA;
91cdf0e10cSrcweir             }
92cdf0e10cSrcweir             // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
93cdf0e10cSrcweir             // Dies ist fuer die manuelle Eingabe
94cdf0e10cSrcweir             aComp.CompileTokenArray();
95cdf0e10cSrcweir             pCode->DelRPN();
96cdf0e10cSrcweir         }
97cdf0e10cSrcweir     }
98cdf0e10cSrcweir     else
99cdf0e10cSrcweir     {
100cdf0e10cSrcweir         // #i63513#/#i65690# don't leave pCode as NULL.
101cdf0e10cSrcweir         // Copy ctor default-constructs pCode if it was NULL, so it's initialized here, too,
102cdf0e10cSrcweir         // to ensure same behavior if unnecessary copying is left out.
103cdf0e10cSrcweir 
104cdf0e10cSrcweir         pCode = new ScTokenArray();
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir }
107cdf0e10cSrcweir 
ScRangeData(ScDocument * pDok,const String & rName,const ScTokenArray & rArr,const ScAddress & rAddress,RangeType nType)108cdf0e10cSrcweir ScRangeData::ScRangeData( ScDocument* pDok,
109cdf0e10cSrcweir                           const String& rName,
110cdf0e10cSrcweir                           const ScTokenArray& rArr,
111cdf0e10cSrcweir                           const ScAddress& rAddress,
112cdf0e10cSrcweir                           RangeType nType ) :
113cdf0e10cSrcweir                 aName       ( rName ),
114cdf0e10cSrcweir                 aUpperName  ( ScGlobal::pCharClass->upper( rName ) ),
115cdf0e10cSrcweir                 pCode       ( new ScTokenArray( rArr ) ),
116cdf0e10cSrcweir                 aPos        ( rAddress ),
117cdf0e10cSrcweir                 eType       ( nType ),
118cdf0e10cSrcweir                 pDoc        ( pDok ),
119cdf0e10cSrcweir                 nIndex      ( 0 ),
120cdf0e10cSrcweir                 bModified   ( sal_False ),
121cdf0e10cSrcweir                 mnMaxRow    (-1),
122*dffa72deSWang Lei                 mnMaxCol    (-1),
123*dffa72deSWang Lei                 aRangeNameScope( MAXTABCOUNT )
124cdf0e10cSrcweir {
125cdf0e10cSrcweir     if( !pCode->GetCodeError() )
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir         pCode->Reset();
128cdf0e10cSrcweir         FormulaToken* p = pCode->GetNextReference();
129cdf0e10cSrcweir         if( p )// genau eine Referenz als erstes
130cdf0e10cSrcweir         {
131cdf0e10cSrcweir             if( p->GetType() == svSingleRef )
132cdf0e10cSrcweir                 eType = eType | RT_ABSPOS;
133cdf0e10cSrcweir             else
134cdf0e10cSrcweir                 eType = eType | RT_ABSAREA;
135cdf0e10cSrcweir         }
136cdf0e10cSrcweir         // Die Importfilter haben diesen Test nicht,
137cdf0e10cSrcweir         // da die benannten Bereiche z.T. noch unvollstaendig sind.
138cdf0e10cSrcweir //      if( !pCode->GetCodeLen() )
139cdf0e10cSrcweir //      {
140cdf0e10cSrcweir //          // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
141cdf0e10cSrcweir //          ScCompiler aComp( pDok, aPos, *pCode );
142cdf0e10cSrcweir //          aComp.CompileTokenArray();
143cdf0e10cSrcweir //          pCode->DelRPN();
144cdf0e10cSrcweir //      }
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir }
147cdf0e10cSrcweir 
ScRangeData(ScDocument * pDok,const String & rName,const ScAddress & rTarget)148cdf0e10cSrcweir ScRangeData::ScRangeData( ScDocument* pDok,
149cdf0e10cSrcweir                           const String& rName,
150cdf0e10cSrcweir                           const ScAddress& rTarget ) :
151cdf0e10cSrcweir                 aName       ( rName ),
152cdf0e10cSrcweir                 aUpperName  ( ScGlobal::pCharClass->upper( rName ) ),
153cdf0e10cSrcweir                 pCode       ( new ScTokenArray() ),
154cdf0e10cSrcweir                 aPos        ( rTarget ),
155cdf0e10cSrcweir                 eType       ( RT_NAME ),
156cdf0e10cSrcweir                 pDoc        ( pDok ),
157cdf0e10cSrcweir                 nIndex      ( 0 ),
158cdf0e10cSrcweir                 bModified   ( sal_False ),
159cdf0e10cSrcweir                 mnMaxRow    (-1),
160*dffa72deSWang Lei                 mnMaxCol    (-1),
161*dffa72deSWang Lei                 aRangeNameScope( MAXTABCOUNT )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir     ScSingleRefData aRefData;
164cdf0e10cSrcweir     aRefData.InitAddress( rTarget );
165cdf0e10cSrcweir     aRefData.SetFlag3D( sal_True );
166cdf0e10cSrcweir     pCode->AddSingleReference( aRefData );
167cdf0e10cSrcweir     ScCompiler aComp( pDoc, aPos, *pCode );
168cdf0e10cSrcweir     aComp.SetGrammar(pDoc->GetGrammar());
169cdf0e10cSrcweir     aComp.CompileTokenArray();
170cdf0e10cSrcweir     if ( !pCode->GetCodeError() )
171cdf0e10cSrcweir         eType |= RT_ABSPOS;
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
ScRangeData(const ScRangeData & rScRangeData)174cdf0e10cSrcweir ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
175cdf0e10cSrcweir     ScDataObject(),
176cdf0e10cSrcweir     aName   (rScRangeData.aName),
177cdf0e10cSrcweir     aUpperName  (rScRangeData.aUpperName),
178cdf0e10cSrcweir     pCode       (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()),        // echte Kopie erzeugen (nicht copy-ctor)
179cdf0e10cSrcweir     aPos        (rScRangeData.aPos),
180cdf0e10cSrcweir     eType       (rScRangeData.eType),
181cdf0e10cSrcweir     pDoc        (rScRangeData.pDoc),
182cdf0e10cSrcweir     nIndex      (rScRangeData.nIndex),
183cdf0e10cSrcweir     bModified   (rScRangeData.bModified),
184cdf0e10cSrcweir     mnMaxRow    (rScRangeData.mnMaxRow),
185*dffa72deSWang Lei     mnMaxCol    (rScRangeData.mnMaxCol),
186*dffa72deSWang Lei     aRangeNameScope (rScRangeData.aRangeNameScope)
187cdf0e10cSrcweir {}
188cdf0e10cSrcweir 
~ScRangeData()189cdf0e10cSrcweir ScRangeData::~ScRangeData()
190cdf0e10cSrcweir {
191cdf0e10cSrcweir     delete pCode;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
Clone() const194cdf0e10cSrcweir ScDataObject* ScRangeData::Clone() const
195cdf0e10cSrcweir {
196cdf0e10cSrcweir     return new ScRangeData(*this);
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
GuessPosition()199cdf0e10cSrcweir void ScRangeData::GuessPosition()
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     //  setzt eine Position, mit der alle relative Referenzen bei CalcAbsIfRel
202cdf0e10cSrcweir     //  ohne Fehler verabsolutiert werden koennen
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     DBG_ASSERT(aPos == ScAddress(), "die Position geht jetzt verloren");
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     SCsCOL nMinCol = 0;
207cdf0e10cSrcweir     SCsROW nMinRow = 0;
208cdf0e10cSrcweir     SCsTAB nMinTab = 0;
209cdf0e10cSrcweir 
210cdf0e10cSrcweir     ScToken* t;
211cdf0e10cSrcweir     pCode->Reset();
212cdf0e10cSrcweir     while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir         ScSingleRefData& rRef1 = t->GetSingleRef();
215cdf0e10cSrcweir         if ( rRef1.IsColRel() && rRef1.nRelCol < nMinCol )
216cdf0e10cSrcweir             nMinCol = rRef1.nRelCol;
217cdf0e10cSrcweir         if ( rRef1.IsRowRel() && rRef1.nRelRow < nMinRow )
218cdf0e10cSrcweir             nMinRow = rRef1.nRelRow;
219cdf0e10cSrcweir         if ( rRef1.IsTabRel() && rRef1.nRelTab < nMinTab )
220cdf0e10cSrcweir             nMinTab = rRef1.nRelTab;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir         if ( t->GetType() == svDoubleRef )
223cdf0e10cSrcweir         {
224cdf0e10cSrcweir             ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
225cdf0e10cSrcweir             if ( rRef2.IsColRel() && rRef2.nRelCol < nMinCol )
226cdf0e10cSrcweir                 nMinCol = rRef2.nRelCol;
227cdf0e10cSrcweir             if ( rRef2.IsRowRel() && rRef2.nRelRow < nMinRow )
228cdf0e10cSrcweir                 nMinRow = rRef2.nRelRow;
229cdf0e10cSrcweir             if ( rRef2.IsTabRel() && rRef2.nRelTab < nMinTab )
230cdf0e10cSrcweir                 nMinTab = rRef2.nRelTab;
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir     }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir     aPos = ScAddress( (SCCOL)(-nMinCol), (SCROW)(-nMinRow), (SCTAB)(-nMinTab) );
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     //! Test
237cdf0e10cSrcweir //  DBG_ERROR(String("Pos ")+String((SCCOL)(-nMinCol))+String("/")+
238cdf0e10cSrcweir //          String((SCROW)(-nMinRow))+String("/")+String((SCTAB)(-nMinTab)));
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
GetSymbol(String & rSymbol,const FormulaGrammar::Grammar eGrammar) const241cdf0e10cSrcweir void ScRangeData::GetSymbol( String& rSymbol, const FormulaGrammar::Grammar eGrammar ) const
242cdf0e10cSrcweir {
243cdf0e10cSrcweir     ScCompiler aComp(pDoc, aPos, *pCode);
244cdf0e10cSrcweir     aComp.SetGrammar(eGrammar);
245cdf0e10cSrcweir     aComp.CreateStringFromTokenArray( rSymbol );
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
UpdateSymbol(rtl::OUStringBuffer & rBuffer,const ScAddress & rPos,const FormulaGrammar::Grammar eGrammar)248cdf0e10cSrcweir void ScRangeData::UpdateSymbol( rtl::OUStringBuffer& rBuffer, const ScAddress& rPos,
249cdf0e10cSrcweir                                 const FormulaGrammar::Grammar eGrammar )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir     ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
252cdf0e10cSrcweir     ScCompiler aComp( pDoc, rPos, *pTemp.get());
253cdf0e10cSrcweir     aComp.SetGrammar(eGrammar);
254cdf0e10cSrcweir     aComp.MoveRelWrap(GetMaxCol(), GetMaxRow());
255cdf0e10cSrcweir     aComp.CreateStringFromTokenArray( rBuffer );
256cdf0e10cSrcweir }
257cdf0e10cSrcweir 
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & r,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)258cdf0e10cSrcweir void ScRangeData::UpdateReference(  UpdateRefMode eUpdateRefMode,
259cdf0e10cSrcweir                                     const ScRange& r,
260cdf0e10cSrcweir                                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     sal_Bool bChanged = sal_False;
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     pCode->Reset();
265cdf0e10cSrcweir     if( pCode->GetNextReference() )
266cdf0e10cSrcweir     {
267cdf0e10cSrcweir         sal_Bool bSharedFormula = ((eType & RT_SHARED) == RT_SHARED);
268cdf0e10cSrcweir         ScCompiler aComp( pDoc, aPos, *pCode );
269cdf0e10cSrcweir         aComp.SetGrammar(pDoc->GetGrammar());
270cdf0e10cSrcweir         const sal_Bool bRelRef = aComp.UpdateNameReference( eUpdateRefMode, r,
271cdf0e10cSrcweir                                                     nDx, nDy, nDz,
272cdf0e10cSrcweir                                                     bChanged, bSharedFormula);
273cdf0e10cSrcweir         if (bSharedFormula)
274cdf0e10cSrcweir         {
275cdf0e10cSrcweir             if (bRelRef)
276cdf0e10cSrcweir                 eType = eType | RT_SHAREDMOD;
277cdf0e10cSrcweir             else
278cdf0e10cSrcweir                 eType = eType & ~RT_SHAREDMOD;
279cdf0e10cSrcweir         }
280cdf0e10cSrcweir     }
281cdf0e10cSrcweir 
282cdf0e10cSrcweir     bModified = bChanged;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 
UpdateTranspose(const ScRange & rSource,const ScAddress & rDest)286cdf0e10cSrcweir void ScRangeData::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     sal_Bool bChanged = sal_False;
289cdf0e10cSrcweir 
290cdf0e10cSrcweir     ScToken* t;
291cdf0e10cSrcweir     pCode->Reset();
292cdf0e10cSrcweir 
293cdf0e10cSrcweir     while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir         if( t->GetType() != svIndex )
296cdf0e10cSrcweir         {
297cdf0e10cSrcweir             SingleDoubleRefModifier aMod( *t );
298cdf0e10cSrcweir             ScComplexRefData& rRef = aMod.Ref();
299cdf0e10cSrcweir             if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
300cdf0e10cSrcweir                     (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
301cdf0e10cSrcweir                 ( t->GetType() == svSingleRef ||
302cdf0e10cSrcweir                 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
303cdf0e10cSrcweir                     (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
304cdf0e10cSrcweir             {
305cdf0e10cSrcweir                 if ( ScRefUpdate::UpdateTranspose( pDoc, rSource, rDest, rRef ) != UR_NOTHING )
306cdf0e10cSrcweir                     bChanged = sal_True;
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir         }
309cdf0e10cSrcweir     }
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     bModified = bChanged;
312cdf0e10cSrcweir }
313cdf0e10cSrcweir 
UpdateGrow(const ScRange & rArea,SCCOL nGrowX,SCROW nGrowY)314cdf0e10cSrcweir void ScRangeData::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
315cdf0e10cSrcweir {
316cdf0e10cSrcweir     sal_Bool bChanged = sal_False;
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     ScToken* t;
319cdf0e10cSrcweir     pCode->Reset();
320cdf0e10cSrcweir 
321cdf0e10cSrcweir     while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
322cdf0e10cSrcweir     {
323cdf0e10cSrcweir         if( t->GetType() != svIndex )
324cdf0e10cSrcweir         {
325cdf0e10cSrcweir             SingleDoubleRefModifier aMod( *t );
326cdf0e10cSrcweir             ScComplexRefData& rRef = aMod.Ref();
327cdf0e10cSrcweir             if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() &&
328cdf0e10cSrcweir                     (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) &&
329cdf0e10cSrcweir                 ( t->GetType() == svSingleRef ||
330cdf0e10cSrcweir                 (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() &&
331cdf0e10cSrcweir                     (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel()))))
332cdf0e10cSrcweir             {
333cdf0e10cSrcweir                 if ( ScRefUpdate::UpdateGrow( rArea,nGrowX,nGrowY, rRef ) != UR_NOTHING )
334cdf0e10cSrcweir                     bChanged = sal_True;
335cdf0e10cSrcweir             }
336cdf0e10cSrcweir         }
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     bModified = bChanged;           // muss direkt hinterher ausgewertet werden
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
operator ==(const ScRangeData & rData) const342cdf0e10cSrcweir sal_Bool ScRangeData::operator== (const ScRangeData& rData) const       // fuer Undo
343cdf0e10cSrcweir {
344cdf0e10cSrcweir     if ( nIndex != rData.nIndex ||
345cdf0e10cSrcweir          aName  != rData.aName  ||
346cdf0e10cSrcweir          aPos   != rData.aPos   ||
347*dffa72deSWang Lei          eType  != rData.eType   || aRangeNameScope  != rData.aRangeNameScope  ) return sal_False;
348cdf0e10cSrcweir 
349cdf0e10cSrcweir     sal_uInt16 nLen = pCode->GetLen();
350cdf0e10cSrcweir     if ( nLen != rData.pCode->GetLen() ) return sal_False;
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     FormulaToken** ppThis = pCode->GetArray();
353cdf0e10cSrcweir     FormulaToken** ppOther = rData.pCode->GetArray();
354cdf0e10cSrcweir 
355cdf0e10cSrcweir     for ( sal_uInt16 i=0; i<nLen; i++ )
356cdf0e10cSrcweir         if ( ppThis[i] != ppOther[i] && !(*ppThis[i] == *ppOther[i]) )
357cdf0e10cSrcweir             return sal_False;
358cdf0e10cSrcweir 
359cdf0e10cSrcweir     return sal_True;
360cdf0e10cSrcweir }
361cdf0e10cSrcweir 
362cdf0e10cSrcweir //UNUSED2009-05 sal_Bool ScRangeData::IsRangeAtCursor( const ScAddress& rPos, sal_Bool bStartOnly ) const
363cdf0e10cSrcweir //UNUSED2009-05 {
364cdf0e10cSrcweir //UNUSED2009-05     sal_Bool bRet = sal_False;
365cdf0e10cSrcweir //UNUSED2009-05     ScRange aRange;
366cdf0e10cSrcweir //UNUSED2009-05     if ( IsReference(aRange) )
367cdf0e10cSrcweir //UNUSED2009-05     {
368cdf0e10cSrcweir //UNUSED2009-05         if ( bStartOnly )
369cdf0e10cSrcweir //UNUSED2009-05             bRet = ( rPos == aRange.aStart );
370cdf0e10cSrcweir //UNUSED2009-05         else
371cdf0e10cSrcweir //UNUSED2009-05             bRet = ( aRange.In( rPos ) );
372cdf0e10cSrcweir //UNUSED2009-05     }
373cdf0e10cSrcweir //UNUSED2009-05     return bRet;
374cdf0e10cSrcweir //UNUSED2009-05 }
375cdf0e10cSrcweir 
IsRangeAtBlock(const ScRange & rBlock) const376cdf0e10cSrcweir sal_Bool ScRangeData::IsRangeAtBlock( const ScRange& rBlock ) const
377cdf0e10cSrcweir {
378cdf0e10cSrcweir     sal_Bool bRet = sal_False;
379cdf0e10cSrcweir     ScRange aRange;
380cdf0e10cSrcweir     if ( IsReference(aRange) )
381cdf0e10cSrcweir         bRet = ( rBlock == aRange );
382cdf0e10cSrcweir     return bRet;
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
IsReference(ScRange & rRange) const385cdf0e10cSrcweir sal_Bool ScRangeData::IsReference( ScRange& rRange ) const
386cdf0e10cSrcweir {
387cdf0e10cSrcweir     if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS )) && pCode )
388cdf0e10cSrcweir         return pCode->IsReference( rRange );
389cdf0e10cSrcweir 
390cdf0e10cSrcweir     return sal_False;
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
IsReference(ScRange & rRange,const ScAddress & rPos) const393cdf0e10cSrcweir sal_Bool ScRangeData::IsReference( ScRange& rRange, const ScAddress& rPos ) const
394cdf0e10cSrcweir {
395cdf0e10cSrcweir     if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir         ::std::auto_ptr<ScTokenArray> pTemp( pCode->Clone() );
398cdf0e10cSrcweir         ScCompiler aComp( pDoc, rPos, *pTemp);
399cdf0e10cSrcweir         aComp.SetGrammar(pDoc->GetGrammar());
400cdf0e10cSrcweir         aComp.MoveRelWrap(MAXCOL, MAXROW);
401cdf0e10cSrcweir         return pTemp->IsReference( rRange );
402cdf0e10cSrcweir     }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir     return sal_False;
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
IsValidReference(ScRange & rRange) const407cdf0e10cSrcweir sal_Bool ScRangeData::IsValidReference( ScRange& rRange ) const
408cdf0e10cSrcweir {
409cdf0e10cSrcweir     if ( (eType & ( RT_ABSAREA | RT_REFAREA | RT_ABSPOS ) ) && pCode )
410cdf0e10cSrcweir         return pCode->IsValidReference( rRange );
411cdf0e10cSrcweir 
412cdf0e10cSrcweir     return sal_False;
413cdf0e10cSrcweir }
414cdf0e10cSrcweir 
415*dffa72deSWang Lei /* modification to update named range scope */
UpdateTabRef(SCTAB nOldTable,sal_uInt16 nFlag,SCTAB nNewTable)416cdf0e10cSrcweir void ScRangeData::UpdateTabRef(SCTAB nOldTable, sal_uInt16 nFlag, SCTAB nNewTable)
417cdf0e10cSrcweir {
418cdf0e10cSrcweir     pCode->Reset();
419cdf0e10cSrcweir     if( pCode->GetNextReference() )
420cdf0e10cSrcweir     {
421cdf0e10cSrcweir         ScRangeData* pRangeData = NULL;     // must not be dereferenced
422cdf0e10cSrcweir         sal_Bool bChanged;
423cdf0e10cSrcweir         ScCompiler aComp( pDoc, aPos, *pCode);
424cdf0e10cSrcweir         aComp.SetGrammar(pDoc->GetGrammar());
425cdf0e10cSrcweir         switch (nFlag)
426cdf0e10cSrcweir         {
427cdf0e10cSrcweir             case 1:                                     // einfache InsertTab (doc.cxx)
428*dffa72deSWang Lei             case 4:
429*dffa72deSWang Lei                    pRangeData = aComp.UpdateInsertTab(nOldTable, true );    // und CopyTab (doc2.cxx)
430*dffa72deSWang Lei                 if ( (aRangeNameScope != MAXTABCOUNT) && ( aRangeNameScope >= nOldTable) && ( aRangeNameScope != MAXTAB ) )
431*dffa72deSWang Lei                     aRangeNameScope ++;
432cdf0e10cSrcweir                 break;
433cdf0e10cSrcweir             case 2:                                     // einfaches delete (doc.cxx)
434*dffa72deSWang Lei                 pRangeData = aComp.UpdateDeleteTab(nOldTable, false, true, bChanged);
435*dffa72deSWang Lei                 if  ( aRangeNameScope != MAXTABCOUNT && aRangeNameScope > nOldTable )
436*dffa72deSWang Lei                                     aRangeNameScope --;
437cdf0e10cSrcweir                 break;
438cdf0e10cSrcweir             case 3:                                     // move (doc2.cxx)
439cdf0e10cSrcweir             {
440*dffa72deSWang Lei                 pRangeData = aComp.UpdateMoveTab(nOldTable, nNewTable, true );
441*dffa72deSWang Lei                 if ( aRangeNameScope != MAXTABCOUNT )
442*dffa72deSWang Lei                 {
443*dffa72deSWang Lei                     if ( aRangeNameScope == nOldTable )
444*dffa72deSWang Lei                         aRangeNameScope = nNewTable;
445*dffa72deSWang Lei                     else if ( (aRangeNameScope > nOldTable) && (aRangeNameScope <= nNewTable) )
446*dffa72deSWang Lei                         aRangeNameScope--;
447*dffa72deSWang Lei                     else if ( (aRangeNameScope >= nNewTable) && (aRangeNameScope < nOldTable) )
448*dffa72deSWang Lei                         aRangeNameScope++;
449*dffa72deSWang Lei                 }
450*dffa72deSWang Lei             }
451*dffa72deSWang Lei             break;
452*dffa72deSWang Lei             case 5:
453*dffa72deSWang Lei             {
454*dffa72deSWang Lei                                 //when copying a sheet, this will be invoked to update the new name range's address in the new sheet
455*dffa72deSWang Lei                                 //only need to update the address if the address's tab same as the range scope. because if they are different, the address's tab have been updated in ScRangeName::UpdateTabRef()
456*dffa72deSWang Lei                                 //for example, in sheet5(scope is sheet5), there are two name range, one address is sheet5, the other is sheet4, if copy sheet5 to sheet1
457*dffa72deSWang Lei                                 //only need to change the first one's address to sheet1
458*dffa72deSWang Lei                 pRangeData = aComp.UpdateMoveTab(nOldTable, nNewTable, true , true);
459*dffa72deSWang Lei                 aRangeNameScope = nNewTable;
460cdf0e10cSrcweir             }
461cdf0e10cSrcweir             break;
462cdf0e10cSrcweir             default:
463cdf0e10cSrcweir             {
464cdf0e10cSrcweir                 DBG_ERROR("ScRangeName::UpdateTabRef: Unknown Flag");
465cdf0e10cSrcweir             }
466cdf0e10cSrcweir                 break;
467cdf0e10cSrcweir         }
468cdf0e10cSrcweir         if (eType&RT_SHARED)
469cdf0e10cSrcweir         {
470cdf0e10cSrcweir             if (pRangeData)
471cdf0e10cSrcweir                 eType = eType | RT_SHAREDMOD;
472cdf0e10cSrcweir             else
473cdf0e10cSrcweir                 eType = eType & ~RT_SHAREDMOD;
474cdf0e10cSrcweir         }
475cdf0e10cSrcweir     }
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 
MakeValidName(String & rName)479cdf0e10cSrcweir void ScRangeData::MakeValidName( String& rName )        // static
480cdf0e10cSrcweir {
481cdf0e10cSrcweir     //ScCompiler::InitSymbolsNative();
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     // strip leading invalid characters
484cdf0e10cSrcweir     xub_StrLen nPos = 0;
485cdf0e10cSrcweir     xub_StrLen nLen = rName.Len();
486cdf0e10cSrcweir     while ( nPos < nLen && !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME) )
487cdf0e10cSrcweir         ++nPos;
488cdf0e10cSrcweir     if ( nPos>0 )
489cdf0e10cSrcweir         rName.Erase(0,nPos);
490cdf0e10cSrcweir 
491cdf0e10cSrcweir     // if the first character is an invalid start character, precede with '_'
492cdf0e10cSrcweir     if ( rName.Len() && !ScCompiler::IsCharFlagAllConventions( rName, 0, SC_COMPILER_C_CHAR_NAME ) )
493cdf0e10cSrcweir         rName.Insert('_',0);
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     // replace invalid with '_'
496cdf0e10cSrcweir     nLen = rName.Len();
497cdf0e10cSrcweir     for (nPos=0; nPos<nLen; nPos++)
498cdf0e10cSrcweir     {
499cdf0e10cSrcweir         if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos, SC_COMPILER_C_NAME) )
500cdf0e10cSrcweir             rName.SetChar( nPos, '_' );
501cdf0e10cSrcweir     }
502cdf0e10cSrcweir 
503cdf0e10cSrcweir     // Ensure that the proposed name is not a reference under any convention,
504cdf0e10cSrcweir     // same as in IsNameValid()
505cdf0e10cSrcweir     ScAddress aAddr;
506cdf0e10cSrcweir     ScRange aRange;
507cdf0e10cSrcweir     for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
508cdf0e10cSrcweir     {
509cdf0e10cSrcweir         ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
510cdf0e10cSrcweir         // Don't check Parse on VALID, any partial only VALID may result in
511cdf0e10cSrcweir         // #REF! during compile later!
512cdf0e10cSrcweir         while (aRange.Parse( rName, NULL, details) || aAddr.Parse( rName, NULL, details))
513cdf0e10cSrcweir         {
514cdf0e10cSrcweir             //! Range Parse is partially valid also with invalid sheet name,
515cdf0e10cSrcweir             //! Address Parse dito, during compile name would generate a #REF!
516cdf0e10cSrcweir             if ( rName.SearchAndReplace( '.', '_' ) == STRING_NOTFOUND )
517cdf0e10cSrcweir                 rName.Insert('_',0);
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir     }
520cdf0e10cSrcweir }
521cdf0e10cSrcweir 
IsNameValid(const String & rName,ScDocument * pDoc)522cdf0e10cSrcweir sal_Bool ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
523cdf0e10cSrcweir {
524cdf0e10cSrcweir     /* XXX If changed, sc/source/filter/ftools/ftools.cxx
525cdf0e10cSrcweir      * ScfTools::ConvertToScDefinedName needs to be changed too. */
526cdf0e10cSrcweir     xub_StrLen nPos = 0;
527cdf0e10cSrcweir     xub_StrLen nLen = rName.Len();
528cdf0e10cSrcweir     if ( !nLen || !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_CHAR_NAME ) )
529cdf0e10cSrcweir         return sal_False;
530cdf0e10cSrcweir     while ( nPos < nLen )
531cdf0e10cSrcweir     {
532cdf0e10cSrcweir         if ( !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_NAME ) )
533cdf0e10cSrcweir             return sal_False;
534cdf0e10cSrcweir     }
535cdf0e10cSrcweir     ScAddress aAddr;
536cdf0e10cSrcweir     ScRange aRange;
537cdf0e10cSrcweir     for (int nConv = FormulaGrammar::CONV_UNSPECIFIED; ++nConv < FormulaGrammar::CONV_LAST; )
538cdf0e10cSrcweir     {
539cdf0e10cSrcweir         ScAddress::Details details( static_cast<FormulaGrammar::AddressConvention>( nConv ) );
540cdf0e10cSrcweir         // Don't check Parse on VALID, any partial only VALID may result in
541cdf0e10cSrcweir         // #REF! during compile later!
542cdf0e10cSrcweir         if (aRange.Parse( rName, pDoc, details) || aAddr.Parse( rName, pDoc, details))
543cdf0e10cSrcweir             return sal_False;
544cdf0e10cSrcweir     }
545cdf0e10cSrcweir     return sal_True;
546cdf0e10cSrcweir }
547cdf0e10cSrcweir 
SetMaxRow(SCROW nRow)548cdf0e10cSrcweir void ScRangeData::SetMaxRow(SCROW nRow)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir     mnMaxRow = nRow;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir 
GetMaxRow() const553cdf0e10cSrcweir SCROW ScRangeData::GetMaxRow() const
554cdf0e10cSrcweir {
555cdf0e10cSrcweir     return mnMaxRow >= 0 ? mnMaxRow : MAXROW;
556cdf0e10cSrcweir }
557cdf0e10cSrcweir 
SetMaxCol(SCCOL nCol)558cdf0e10cSrcweir void ScRangeData::SetMaxCol(SCCOL nCol)
559cdf0e10cSrcweir {
560cdf0e10cSrcweir     mnMaxCol = nCol;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir 
GetMaxCol() const563cdf0e10cSrcweir SCCOL ScRangeData::GetMaxCol() const
564cdf0e10cSrcweir {
565cdf0e10cSrcweir     return mnMaxCol >= 0 ? mnMaxCol : MAXCOL;
566cdf0e10cSrcweir }
567cdf0e10cSrcweir 
568*dffa72deSWang Lei /* MAXTABCOUNT - Global, 0 - sheet1, 1 - sheet2, ...        */
569*dffa72deSWang Lei /*  MAXTABCOUNT -- Global               */
570*dffa72deSWang Lei /*  return value: FALSE -- set fail         */
571*dffa72deSWang Lei /*                TRUE  -- set successfully */
SetRangeScope(SCTAB Scope)572*dffa72deSWang Lei bool ScRangeData::SetRangeScope( SCTAB Scope )
573*dffa72deSWang Lei {
574*dffa72deSWang Lei      if ( Scope <= MAXTABCOUNT && Scope >=0 )
575*dffa72deSWang Lei      {
576*dffa72deSWang Lei         aRangeNameScope = Scope;
577*dffa72deSWang Lei             return true;
578*dffa72deSWang Lei      }
579*dffa72deSWang Lei          return false;
580*dffa72deSWang Lei 
581*dffa72deSWang Lei }
582*dffa72deSWang Lei 
GetScopeSheetName() const583*dffa72deSWang Lei  String ScRangeData::GetScopeSheetName() const
584*dffa72deSWang Lei {
585*dffa72deSWang Lei     if ( aRangeNameScope != MAXTABCOUNT )
586*dffa72deSWang Lei     {
587*dffa72deSWang Lei             String aTableName;
588*dffa72deSWang Lei             pDoc->GetName( aRangeNameScope, aTableName );
589*dffa72deSWang Lei             return aTableName;
590*dffa72deSWang Lei     }
591*dffa72deSWang Lei         return EMPTY_STRING;
592*dffa72deSWang Lei }
593*dffa72deSWang Lei /* end add */
594*dffa72deSWang Lei 
595cdf0e10cSrcweir 
GetErrCode()596cdf0e10cSrcweir sal_uInt16 ScRangeData::GetErrCode()
597cdf0e10cSrcweir {
598cdf0e10cSrcweir     return pCode ? pCode->GetCodeError() : 0;
599cdf0e10cSrcweir }
600cdf0e10cSrcweir 
HasReferences() const601cdf0e10cSrcweir sal_Bool ScRangeData::HasReferences() const
602cdf0e10cSrcweir {
603cdf0e10cSrcweir     pCode->Reset();
604cdf0e10cSrcweir     return sal_Bool( pCode->GetNextReference() != NULL );
605cdf0e10cSrcweir }
606cdf0e10cSrcweir 
607cdf0e10cSrcweir // bei TransferTab von einem in ein anderes Dokument anpassen,
608cdf0e10cSrcweir // um Referenzen auf die eigene Tabelle mitzubekommen
609cdf0e10cSrcweir 
TransferTabRef(SCTAB nOldTab,SCTAB nNewTab)610cdf0e10cSrcweir void ScRangeData::TransferTabRef( SCTAB nOldTab, SCTAB nNewTab )
611cdf0e10cSrcweir {
612cdf0e10cSrcweir     long nTabDiff = (long)nNewTab - nOldTab;
613cdf0e10cSrcweir     long nPosDiff = (long)nNewTab - aPos.Tab();
614cdf0e10cSrcweir     aPos.SetTab( nNewTab );
615cdf0e10cSrcweir     ScToken* t;
616cdf0e10cSrcweir     pCode->Reset();
617cdf0e10cSrcweir     while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
618cdf0e10cSrcweir     {
619cdf0e10cSrcweir         ScSingleRefData& rRef1 = t->GetSingleRef();
620cdf0e10cSrcweir         if ( rRef1.IsTabRel() )
621cdf0e10cSrcweir             rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nPosDiff );
622cdf0e10cSrcweir         else
623cdf0e10cSrcweir             rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab + nTabDiff );
624cdf0e10cSrcweir         if ( t->GetType() == svDoubleRef )
625cdf0e10cSrcweir         {
626cdf0e10cSrcweir             ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
627cdf0e10cSrcweir             if ( rRef2.IsTabRel() )
628cdf0e10cSrcweir                 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nPosDiff );
629cdf0e10cSrcweir             else
630cdf0e10cSrcweir                 rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab + nTabDiff );
631cdf0e10cSrcweir         }
632cdf0e10cSrcweir     }
633cdf0e10cSrcweir }
634cdf0e10cSrcweir 
ReplaceRangeNamesInUse(const IndexMap & rMap)635cdf0e10cSrcweir void ScRangeData::ReplaceRangeNamesInUse( const IndexMap& rMap )
636cdf0e10cSrcweir {
637cdf0e10cSrcweir     bool bCompile = false;
638cdf0e10cSrcweir     for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() )
639cdf0e10cSrcweir     {
640cdf0e10cSrcweir         if ( p->GetOpCode() == ocName )
641cdf0e10cSrcweir         {
642cdf0e10cSrcweir             const sal_uInt16 nOldIndex = p->GetIndex();
643cdf0e10cSrcweir             IndexMap::const_iterator itr = rMap.find(nOldIndex);
644cdf0e10cSrcweir             const sal_uInt16 nNewIndex = itr == rMap.end() ? nOldIndex : itr->second;
645cdf0e10cSrcweir             if ( nOldIndex != nNewIndex )
646cdf0e10cSrcweir             {
647cdf0e10cSrcweir                 p->SetIndex( nNewIndex );
648cdf0e10cSrcweir                 bCompile = true;
649cdf0e10cSrcweir             }
650cdf0e10cSrcweir         }
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir     if ( bCompile )
653cdf0e10cSrcweir     {
654cdf0e10cSrcweir         ScCompiler aComp( pDoc, aPos, *pCode);
655cdf0e10cSrcweir         aComp.SetGrammar(pDoc->GetGrammar());
656cdf0e10cSrcweir         aComp.CompileTokenArray();
657cdf0e10cSrcweir     }
658cdf0e10cSrcweir }
659cdf0e10cSrcweir 
660cdf0e10cSrcweir 
ValidateTabRefs()661cdf0e10cSrcweir void ScRangeData::ValidateTabRefs()
662cdf0e10cSrcweir {
663cdf0e10cSrcweir     //  try to make sure all relative references and the reference position
664cdf0e10cSrcweir     //  are within existing tables, so they can be represented as text
665cdf0e10cSrcweir     //  (if the range of used tables is more than the existing tables,
666cdf0e10cSrcweir     //  the result may still contain invalid tables, because the relative
667cdf0e10cSrcweir     //  references aren't changed so formulas stay the same)
668cdf0e10cSrcweir 
669cdf0e10cSrcweir     //  find range of used tables
670cdf0e10cSrcweir 
671cdf0e10cSrcweir     SCTAB nMinTab = aPos.Tab();
672cdf0e10cSrcweir     SCTAB nMaxTab = nMinTab;
673cdf0e10cSrcweir     ScToken* t;
674cdf0e10cSrcweir     pCode->Reset();
675cdf0e10cSrcweir     while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
676cdf0e10cSrcweir     {
677cdf0e10cSrcweir         ScSingleRefData& rRef1 = t->GetSingleRef();
678cdf0e10cSrcweir         if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
679cdf0e10cSrcweir         {
680cdf0e10cSrcweir             if ( rRef1.nTab < nMinTab )
681cdf0e10cSrcweir                 nMinTab = rRef1.nTab;
682cdf0e10cSrcweir             if ( rRef1.nTab > nMaxTab )
683cdf0e10cSrcweir                 nMaxTab = rRef1.nTab;
684cdf0e10cSrcweir         }
685cdf0e10cSrcweir         if ( t->GetType() == svDoubleRef )
686cdf0e10cSrcweir         {
687cdf0e10cSrcweir             ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
688cdf0e10cSrcweir             if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
689cdf0e10cSrcweir             {
690cdf0e10cSrcweir                 if ( rRef2.nTab < nMinTab )
691cdf0e10cSrcweir                     nMinTab = rRef2.nTab;
692cdf0e10cSrcweir                 if ( rRef2.nTab > nMaxTab )
693cdf0e10cSrcweir                     nMaxTab = rRef2.nTab;
694cdf0e10cSrcweir             }
695cdf0e10cSrcweir         }
696cdf0e10cSrcweir     }
697cdf0e10cSrcweir 
698cdf0e10cSrcweir     SCTAB nTabCount = pDoc->GetTableCount();
699cdf0e10cSrcweir     if ( nMaxTab >= nTabCount && nMinTab > 0 )
700cdf0e10cSrcweir     {
701cdf0e10cSrcweir         //  move position and relative tab refs
702cdf0e10cSrcweir         //  The formulas that use the name are not changed by this
703cdf0e10cSrcweir 
704cdf0e10cSrcweir         SCTAB nMove = nMinTab;
705cdf0e10cSrcweir         aPos.SetTab( aPos.Tab() - nMove );
706cdf0e10cSrcweir 
707cdf0e10cSrcweir         pCode->Reset();
708cdf0e10cSrcweir         while ( ( t = static_cast<ScToken*>(pCode->GetNextReference()) ) != NULL )
709cdf0e10cSrcweir         {
710cdf0e10cSrcweir             ScSingleRefData& rRef1 = t->GetSingleRef();
711cdf0e10cSrcweir             if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
712cdf0e10cSrcweir                 rRef1.nTab = sal::static_int_cast<SCsTAB>( rRef1.nTab - nMove );
713cdf0e10cSrcweir             if ( t->GetType() == svDoubleRef )
714cdf0e10cSrcweir             {
715cdf0e10cSrcweir                 ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
716cdf0e10cSrcweir                 if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
717cdf0e10cSrcweir                     rRef2.nTab = sal::static_int_cast<SCsTAB>( rRef2.nTab - nMove );
718cdf0e10cSrcweir             }
719cdf0e10cSrcweir         }
720cdf0e10cSrcweir     }
721cdf0e10cSrcweir }
722cdf0e10cSrcweir 
723cdf0e10cSrcweir 
724cdf0e10cSrcweir extern "C" int
725cdf0e10cSrcweir #ifdef WNT
726cdf0e10cSrcweir __cdecl
727cdf0e10cSrcweir #endif
ScRangeData_QsortNameCompare(const void * p1,const void * p2)728cdf0e10cSrcweir ScRangeData_QsortNameCompare( const void* p1, const void* p2 )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir     return (int) ScGlobal::GetCollator()->compareString(
731cdf0e10cSrcweir             (*(const ScRangeData**)p1)->GetName(),
732cdf0e10cSrcweir             (*(const ScRangeData**)p2)->GetName() );
733cdf0e10cSrcweir }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir 
736cdf0e10cSrcweir //========================================================================
737cdf0e10cSrcweir // ScRangeName
738cdf0e10cSrcweir //========================================================================
739cdf0e10cSrcweir 
ScRangeName(const ScRangeName & rScRangeName,ScDocument * pDocument)740cdf0e10cSrcweir ScRangeName::ScRangeName(const ScRangeName& rScRangeName, ScDocument* pDocument) :
741cdf0e10cSrcweir                 ScSortedCollection ( rScRangeName ),
742cdf0e10cSrcweir                 pDoc ( pDocument ),
743cdf0e10cSrcweir                 nSharedMaxIndex (rScRangeName.nSharedMaxIndex)
744cdf0e10cSrcweir {
745cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < nCount; i++)
746cdf0e10cSrcweir     {
747cdf0e10cSrcweir         ((ScRangeData*)At(i))->SetDocument(pDocument);
748cdf0e10cSrcweir         ((ScRangeData*)At(i))->SetIndex(((ScRangeData*)rScRangeName.At(i))->GetIndex());
749cdf0e10cSrcweir     }
750cdf0e10cSrcweir }
751cdf0e10cSrcweir 
Compare(ScDataObject * pKey1,ScDataObject * pKey2) const752cdf0e10cSrcweir short ScRangeName::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
753cdf0e10cSrcweir {
754cdf0e10cSrcweir     sal_uInt16 i1 = ((ScRangeData*)pKey1)->GetIndex();
755cdf0e10cSrcweir     sal_uInt16 i2 = ((ScRangeData*)pKey2)->GetIndex();
756cdf0e10cSrcweir     return (short) i1 - (short) i2;
757cdf0e10cSrcweir }
758cdf0e10cSrcweir 
759*dffa72deSWang Lei /* added  for scope support */
HasRangeinSheetScope(SCTAB Scope)760*dffa72deSWang Lei bool ScRangeName::HasRangeinSheetScope(SCTAB Scope)
761*dffa72deSWang Lei {
762*dffa72deSWang Lei     for (sal_uInt16 i = 0; i < nCount; i++)
763*dffa72deSWang Lei         if  (((*this)[i])->GetRangeScope() == Scope)
764*dffa72deSWang Lei             return true;
765*dffa72deSWang Lei 
766*dffa72deSWang Lei     return false;
767*dffa72deSWang Lei }
768*dffa72deSWang Lei /* if Scope is global, no range will be removed */
769*dffa72deSWang Lei /* if no range is removed, return value is false */
RemoveRangeinScope(SCTAB Scope)770*dffa72deSWang Lei bool ScRangeName::RemoveRangeinScope(SCTAB Scope)
771*dffa72deSWang Lei {
772*dffa72deSWang Lei      bool bRemoved = false;
773*dffa72deSWang Lei 
774*dffa72deSWang Lei      if ( Scope == MAXTABCOUNT )
775*dffa72deSWang Lei          return bRemoved;
776*dffa72deSWang Lei 
777*dffa72deSWang Lei      sal_uInt16 i = 0;
778*dffa72deSWang Lei      while (i < nCount)
779*dffa72deSWang Lei      {
780*dffa72deSWang Lei           if  (((*this)[i])->GetRangeScope() == Scope)
781*dffa72deSWang Lei           {
782*dffa72deSWang Lei                Free( (*this)[i] );
783*dffa72deSWang Lei                bRemoved = true;
784*dffa72deSWang Lei           }
785*dffa72deSWang Lei           else
786*dffa72deSWang Lei                i++;
787*dffa72deSWang Lei      }
788*dffa72deSWang Lei 
789*dffa72deSWang Lei      return bRemoved;
790*dffa72deSWang Lei }
791*dffa72deSWang Lei /* it's designed for "Copy Sheet" action. So no name conflict check when copy range to new scope */
792*dffa72deSWang Lei /* if the old scope or the new scope is global, no range will be copied */
793*dffa72deSWang Lei /* if no range is copied, the return value is false */
CopyRangeinScope(SCTAB oldScope,SCTAB newScope)794*dffa72deSWang Lei bool ScRangeName::CopyRangeinScope(SCTAB oldScope, SCTAB newScope)
795*dffa72deSWang Lei {
796*dffa72deSWang Lei        bool bCopied = false;
797*dffa72deSWang Lei 
798*dffa72deSWang Lei        if ( (oldScope == MAXTABCOUNT)||(newScope ==MAXTABCOUNT) )
799*dffa72deSWang Lei            return bCopied;
800*dffa72deSWang Lei 
801*dffa72deSWang Lei        sal_uInt16 originalCount = nCount;
802*dffa72deSWang Lei        for ( sal_uInt16 i = 0; i < originalCount; i++)
803*dffa72deSWang Lei            if ( ((*this)[i])->GetRangeScope() == oldScope)
804*dffa72deSWang Lei            {
805*dffa72deSWang Lei                  ScRangeData * aCopiedRange = (ScRangeData *)(*this)[i]->Clone();
806*dffa72deSWang Lei                  aCopiedRange->UpdateTabRef(oldScope, 5 , newScope);
807*dffa72deSWang Lei                  aCopiedRange->SetIndex(GetEntryIndex());
808*dffa72deSWang Lei                  Insert( aCopiedRange );
809*dffa72deSWang Lei                  bCopied = true;
810*dffa72deSWang Lei            }
811*dffa72deSWang Lei 
812*dffa72deSWang Lei        return bCopied;
813*dffa72deSWang Lei }
814*dffa72deSWang Lei /* end add */
SearchNameUpper(const String & rUpperName,sal_uInt16 & rIndex,SCTAB Scope) const815*dffa72deSWang Lei bool ScRangeName::SearchNameUpper( const String& rUpperName, sal_uInt16& rIndex, SCTAB Scope ) const
816cdf0e10cSrcweir {
817cdf0e10cSrcweir     // SearchNameUpper must be called with an upper-case search string
818cdf0e10cSrcweir 
819cdf0e10cSrcweir     sal_uInt16 i = 0;
820cdf0e10cSrcweir     while (i < nCount)
821cdf0e10cSrcweir     {
822*dffa72deSWang Lei         if ( (((*this)[i])->GetUpperName() == rUpperName)
823*dffa72deSWang Lei             && (((*this)[i])->GetRangeScope() == Scope ))
824cdf0e10cSrcweir         {
825cdf0e10cSrcweir             rIndex = i;
826*dffa72deSWang Lei             return true;
827cdf0e10cSrcweir         }
828cdf0e10cSrcweir         i++;
829cdf0e10cSrcweir     }
830*dffa72deSWang Lei     return false;
831cdf0e10cSrcweir }
832cdf0e10cSrcweir 
SearchName(const String & rName,sal_uInt16 & rIndex,SCTAB Scope) const833*dffa72deSWang Lei bool ScRangeName::SearchName( const String& rName, sal_uInt16& rIndex, SCTAB Scope ) const
834cdf0e10cSrcweir {
835cdf0e10cSrcweir     if ( nCount > 0 )
836*dffa72deSWang Lei         return SearchNameUpper( ScGlobal::pCharClass->upper( rName ), rIndex, Scope );
837cdf0e10cSrcweir     else
838*dffa72deSWang Lei         return false;
839cdf0e10cSrcweir }
840cdf0e10cSrcweir 
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & rRange,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)841cdf0e10cSrcweir void ScRangeName::UpdateReference(  UpdateRefMode eUpdateRefMode,
842cdf0e10cSrcweir                                     const ScRange& rRange,
843cdf0e10cSrcweir                                     SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
844cdf0e10cSrcweir {
845cdf0e10cSrcweir     for (sal_uInt16 i=0; i<nCount; i++)
846cdf0e10cSrcweir         ((ScRangeData*)pItems[i])->UpdateReference(eUpdateRefMode, rRange,
847cdf0e10cSrcweir                                                    nDx, nDy, nDz);
848cdf0e10cSrcweir }
849cdf0e10cSrcweir 
UpdateTranspose(const ScRange & rSource,const ScAddress & rDest)850cdf0e10cSrcweir void ScRangeName::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir     for (sal_uInt16 i=0; i<nCount; i++)
853cdf0e10cSrcweir         ((ScRangeData*)pItems[i])->UpdateTranspose( rSource, rDest );
854cdf0e10cSrcweir }
855cdf0e10cSrcweir 
UpdateGrow(const ScRange & rArea,SCCOL nGrowX,SCROW nGrowY)856cdf0e10cSrcweir void ScRangeName::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
857cdf0e10cSrcweir {
858cdf0e10cSrcweir     for (sal_uInt16 i=0; i<nCount; i++)
859cdf0e10cSrcweir         ((ScRangeData*)pItems[i])->UpdateGrow( rArea, nGrowX, nGrowY );
860cdf0e10cSrcweir }
861cdf0e10cSrcweir 
IsEqual(ScDataObject * pKey1,ScDataObject * pKey2) const862cdf0e10cSrcweir sal_Bool ScRangeName::IsEqual(ScDataObject* pKey1, ScDataObject* pKey2) const
863cdf0e10cSrcweir {
864cdf0e10cSrcweir     return *(ScRangeData*)pKey1 == *(ScRangeData*)pKey2;
865cdf0e10cSrcweir }
866cdf0e10cSrcweir 
Insert(ScDataObject * pScDataObject)867cdf0e10cSrcweir sal_Bool ScRangeName::Insert(ScDataObject* pScDataObject)
868cdf0e10cSrcweir {
869cdf0e10cSrcweir     if (!((ScRangeData*)pScDataObject)->GetIndex())     // schon gesetzt?
870cdf0e10cSrcweir     {
871cdf0e10cSrcweir         ((ScRangeData*)pScDataObject)->SetIndex( GetEntryIndex() );
872cdf0e10cSrcweir     }
873cdf0e10cSrcweir 
874cdf0e10cSrcweir     return ScSortedCollection::Insert(pScDataObject);
875cdf0e10cSrcweir }
876cdf0e10cSrcweir 
877cdf0e10cSrcweir // Suche nach einem freien Index
878cdf0e10cSrcweir 
GetEntryIndex()879cdf0e10cSrcweir sal_uInt16 ScRangeName::GetEntryIndex()
880cdf0e10cSrcweir {
881cdf0e10cSrcweir     sal_uInt16 nLast = 0;
882cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < nCount; i++ )
883cdf0e10cSrcweir     {
884cdf0e10cSrcweir         sal_uInt16 nIdx = ((ScRangeData*)pItems[i])->GetIndex();
885cdf0e10cSrcweir         if( nIdx > nLast )
886cdf0e10cSrcweir         {
887cdf0e10cSrcweir             nLast = nIdx;
888cdf0e10cSrcweir         }
889cdf0e10cSrcweir     }
890cdf0e10cSrcweir     return nLast + 1;
891cdf0e10cSrcweir }
892cdf0e10cSrcweir 
FindIndex(sal_uInt16 nIndex)893cdf0e10cSrcweir ScRangeData* ScRangeName::FindIndex( sal_uInt16 nIndex )
894cdf0e10cSrcweir {
895cdf0e10cSrcweir     ScRangeData aDataObj( nIndex );
896cdf0e10cSrcweir     sal_uInt16 n;
897cdf0e10cSrcweir     if( Search( &aDataObj, n ) )
898cdf0e10cSrcweir         return (*this)[ n ];
899cdf0e10cSrcweir     else
900cdf0e10cSrcweir         return NULL;
901cdf0e10cSrcweir }
902cdf0e10cSrcweir 
903cdf0e10cSrcweir //UNUSED2009-05 ScRangeData* ScRangeName::GetRangeAtCursor( const ScAddress& rPos, sal_Bool bStartOnly ) const
904cdf0e10cSrcweir //UNUSED2009-05 {
905cdf0e10cSrcweir //UNUSED2009-05     if ( pItems )
906cdf0e10cSrcweir //UNUSED2009-05     {
907cdf0e10cSrcweir //UNUSED2009-05         for ( sal_uInt16 i = 0; i < nCount; i++ )
908cdf0e10cSrcweir //UNUSED2009-05             if ( ((ScRangeData*)pItems[i])->IsRangeAtCursor( rPos, bStartOnly ) )
909cdf0e10cSrcweir //UNUSED2009-05                 return (ScRangeData*)pItems[i];
910cdf0e10cSrcweir //UNUSED2009-05     }
911cdf0e10cSrcweir //UNUSED2009-05     return NULL;
912cdf0e10cSrcweir //UNUSED2009-05 }
913cdf0e10cSrcweir 
GetRangeAtBlock(const ScRange & rBlock) const914cdf0e10cSrcweir ScRangeData* ScRangeName::GetRangeAtBlock( const ScRange& rBlock ) const
915cdf0e10cSrcweir {
916cdf0e10cSrcweir     if ( pItems )
917cdf0e10cSrcweir     {
918cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < nCount; i++ )
919cdf0e10cSrcweir             if ( ((ScRangeData*)pItems[i])->IsRangeAtBlock( rBlock ) )
920cdf0e10cSrcweir                 return (ScRangeData*)pItems[i];
921cdf0e10cSrcweir     }
922cdf0e10cSrcweir     return NULL;
923cdf0e10cSrcweir }
924cdf0e10cSrcweir 
UpdateTabRef(SCTAB nOldTable,sal_uInt16 nFlag,SCTAB nNewTable)925cdf0e10cSrcweir void ScRangeName::UpdateTabRef(SCTAB nOldTable, sal_uInt16 nFlag, SCTAB nNewTable)
926cdf0e10cSrcweir {
927*dffa72deSWang Lei        if (nFlag == 2)
928*dffa72deSWang Lei            RemoveRangeinScope( nOldTable );
929*dffa72deSWang Lei 
930cdf0e10cSrcweir        for (sal_uInt16 i=0; i<nCount; i++)
931cdf0e10cSrcweir             ((ScRangeData*)pItems[i])->UpdateTabRef(nOldTable, nFlag, nNewTable);
932cdf0e10cSrcweir 
933*dffa72deSWang Lei        if (nFlag ==4)
934*dffa72deSWang Lei        {
935*dffa72deSWang Lei             SCTAB copyScope = nOldTable > nNewTable ? nNewTable : nNewTable+1;
936*dffa72deSWang Lei             CopyRangeinScope( copyScope, nOldTable);
937*dffa72deSWang Lei        }
938*dffa72deSWang Lei }
939