xref: /aoo41x/main/sc/source/core/tool/rangeutl.cxx (revision 22407013)
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
10b3f79822SAndrew Rist  *
11b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist  *
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.
19b3f79822SAndrew Rist  *
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 // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <tools/debug.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include "rangeutl.hxx"
34cdf0e10cSrcweir #include "document.hxx"
35cdf0e10cSrcweir #include "global.hxx"
36cdf0e10cSrcweir #include "dbcolect.hxx"
37cdf0e10cSrcweir #include "rangenam.hxx"
38cdf0e10cSrcweir #include "scresid.hxx"
39cdf0e10cSrcweir #include "globstr.hrc"
40cdf0e10cSrcweir #include "convuno.hxx"
41cdf0e10cSrcweir #include "externalrefmgr.hxx"
42cdf0e10cSrcweir #include "compiler.hxx"
43cdf0e10cSrcweir 
44cdf0e10cSrcweir using ::rtl::OUString;
45cdf0e10cSrcweir using ::rtl::OUStringBuffer;
46cdf0e10cSrcweir using ::formula::FormulaGrammar;
47cdf0e10cSrcweir using namespace ::com::sun::star;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //------------------------------------------------------------------------
50cdf0e10cSrcweir 
MakeArea(const String & rAreaStr,ScArea & rArea,ScDocument * pDoc,SCTAB nTab,ScAddress::Details const & rDetails) const51cdf0e10cSrcweir sal_Bool ScRangeUtil::MakeArea( const String&	rAreaStr,
52cdf0e10cSrcweir 							ScArea&			rArea,
53cdf0e10cSrcweir 							ScDocument*		pDoc,
54cdf0e10cSrcweir 							SCTAB			nTab,
55cdf0e10cSrcweir 							ScAddress::Details const & rDetails ) const
56cdf0e10cSrcweir {
57cdf0e10cSrcweir 	// Eingabe in rAreaStr: "$Tabelle1.$A1:$D17"
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 	// BROKEN BROKEN BROKEN
60cdf0e10cSrcweir 	// but it is only used in the consolidate dialog.  Ignore for now.
61cdf0e10cSrcweir 
62cdf0e10cSrcweir 	sal_Bool		nSuccess	= sal_False;
63cdf0e10cSrcweir 	sal_uInt16		nPointPos	= rAreaStr.Search('.');
64cdf0e10cSrcweir 	sal_uInt16		nColonPos	= rAreaStr.Search(':');
65cdf0e10cSrcweir 	String		aStrArea( rAreaStr );
66cdf0e10cSrcweir 	ScRefAddress	startPos;
67cdf0e10cSrcweir 	ScRefAddress	endPos;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir 	if ( nColonPos == STRING_NOTFOUND )
70cdf0e10cSrcweir 		if ( nPointPos != STRING_NOTFOUND )
71cdf0e10cSrcweir 		{
72cdf0e10cSrcweir 			aStrArea += ':';
73cdf0e10cSrcweir 			aStrArea += rAreaStr.Copy( nPointPos+1 ); // '.' nicht mitkopieren
74cdf0e10cSrcweir 		}
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 	nSuccess = ConvertDoubleRef( pDoc, aStrArea, nTab, startPos, endPos, rDetails );
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 	if ( nSuccess )
79cdf0e10cSrcweir 		rArea = ScArea( startPos.Tab(),
80cdf0e10cSrcweir 						startPos.Col(),	startPos.Row(),
81cdf0e10cSrcweir 						endPos.Col(),	endPos.Row() );
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	return nSuccess;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir //------------------------------------------------------------------------
87cdf0e10cSrcweir 
CutPosString(const String & theAreaStr,String & thePosStr) const88cdf0e10cSrcweir void ScRangeUtil::CutPosString( const String&	theAreaStr,
89cdf0e10cSrcweir 								String&			thePosStr ) const
90cdf0e10cSrcweir {
91cdf0e10cSrcweir 	String	aPosStr;
92cdf0e10cSrcweir 	// BROKEN BROKEN BROKEN
93cdf0e10cSrcweir 	// but it is only used in the consolidate dialog.  Ignore for now.
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	sal_uInt16	nColonPos = theAreaStr.Search(':');
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 	if ( nColonPos != STRING_NOTFOUND )
98cdf0e10cSrcweir 		aPosStr = theAreaStr.Copy( 0, nColonPos ); // ':' nicht mitkopieren
99cdf0e10cSrcweir 	else
100cdf0e10cSrcweir 		aPosStr = theAreaStr;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	thePosStr = aPosStr;
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir //------------------------------------------------------------------------
106cdf0e10cSrcweir 
IsAbsTabArea(const String & rAreaStr,ScDocument * pDoc,ScArea *** pppAreas,sal_uInt16 * pAreaCount,sal_Bool,ScAddress::Details const & rDetails) const107cdf0e10cSrcweir sal_Bool ScRangeUtil::IsAbsTabArea( const String& 	rAreaStr,
108cdf0e10cSrcweir 								ScDocument*		pDoc,
109cdf0e10cSrcweir 								ScArea***		pppAreas,
110cdf0e10cSrcweir 								sal_uInt16*			pAreaCount,
111cdf0e10cSrcweir                                 sal_Bool            /* bAcceptCellRef */,
112cdf0e10cSrcweir 								ScAddress::Details const & rDetails ) const
113cdf0e10cSrcweir {
114cdf0e10cSrcweir 	DBG_ASSERT( pDoc, "Kein Dokument uebergeben!" );
115cdf0e10cSrcweir 	if ( !pDoc )
116cdf0e10cSrcweir 		return sal_False;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 	// BROKEN BROKEN BROKEN
119cdf0e10cSrcweir 	// but it is only used in the consolidate dialog.  Ignore for now.
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	/*
122cdf0e10cSrcweir 	 * Erwartet wird ein String der Form
123cdf0e10cSrcweir 	 *		"$Tabelle1.$A$1:$Tabelle3.$D$17"
124cdf0e10cSrcweir 	 * Wenn bAcceptCellRef == sal_True ist, wird auch ein String der Form
125cdf0e10cSrcweir 	 *		"$Tabelle1.$A$1"
126cdf0e10cSrcweir 	 * akzeptiert.
127cdf0e10cSrcweir 	 *
128cdf0e10cSrcweir 	 * als Ergebnis wird ein ScArea-Array angelegt,
129cdf0e10cSrcweir 	 * welches ueber ppAreas bekannt gegeben wird und auch
130cdf0e10cSrcweir 	 * wieder geloescht werden muss!
131cdf0e10cSrcweir 	 */
132cdf0e10cSrcweir 
133cdf0e10cSrcweir 	sal_Bool	bStrOk = sal_False;
134cdf0e10cSrcweir 	String	aTempAreaStr(rAreaStr);
135cdf0e10cSrcweir 	String	aStartPosStr;
136cdf0e10cSrcweir 	String	aEndPosStr;
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 	if ( STRING_NOTFOUND == aTempAreaStr.Search(':') )
139cdf0e10cSrcweir 	{
140cdf0e10cSrcweir 		aTempAreaStr.Append(':');
141cdf0e10cSrcweir 		aTempAreaStr.Append(rAreaStr);
142cdf0e10cSrcweir 	}
143cdf0e10cSrcweir 
144cdf0e10cSrcweir 	sal_uInt16	 nColonPos = aTempAreaStr.Search(':');
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 	if (   STRING_NOTFOUND != nColonPos
147cdf0e10cSrcweir 		&& STRING_NOTFOUND != aTempAreaStr.Search('.') )
148cdf0e10cSrcweir 	{
149cdf0e10cSrcweir 		ScRefAddress	aStartPos;
150cdf0e10cSrcweir 		ScRefAddress	aEndPos;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 		aStartPosStr = aTempAreaStr.Copy( 0,		   nColonPos  );
153cdf0e10cSrcweir 		aEndPosStr	 = aTempAreaStr.Copy( nColonPos+1, STRING_LEN );
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 		if ( ConvertSingleRef( pDoc, aStartPosStr, 0, aStartPos, rDetails ) )
156cdf0e10cSrcweir 		{
157cdf0e10cSrcweir 			if ( ConvertSingleRef( pDoc, aEndPosStr, aStartPos.Tab(), aEndPos, rDetails ) )
158cdf0e10cSrcweir 			{
159cdf0e10cSrcweir 				aStartPos.SetRelCol( sal_False );
160cdf0e10cSrcweir 				aStartPos.SetRelRow( sal_False );
161cdf0e10cSrcweir 				aStartPos.SetRelTab( sal_False );
162cdf0e10cSrcweir 				aEndPos.SetRelCol( sal_False );
163cdf0e10cSrcweir 				aEndPos.SetRelRow( sal_False );
164cdf0e10cSrcweir 				aEndPos.SetRelTab( sal_False );
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 				bStrOk = sal_True;
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 				if ( pppAreas && pAreaCount ) // Array zurueckgegeben?
169cdf0e10cSrcweir 				{
170cdf0e10cSrcweir 					SCTAB		nStartTab	= aStartPos.Tab();
171cdf0e10cSrcweir 					SCTAB		nEndTab		= aEndPos.Tab();
172cdf0e10cSrcweir 					sal_uInt16		nTabCount	= static_cast<sal_uInt16>(nEndTab-nStartTab+1);
173cdf0e10cSrcweir 					ScArea** 	theAreas	= new ScArea*[nTabCount];
174cdf0e10cSrcweir 					SCTAB		nTab		= 0;
175cdf0e10cSrcweir 					sal_uInt16		i			= 0;
176cdf0e10cSrcweir 					ScArea		theArea( 0, aStartPos.Col(), aStartPos.Row(),
177cdf0e10cSrcweir 											aEndPos.Col(), aEndPos.Row() );
178cdf0e10cSrcweir 
179cdf0e10cSrcweir 					nTab = nStartTab;
180cdf0e10cSrcweir 					for ( i=0; i<nTabCount; i++ )
181cdf0e10cSrcweir 					{
182cdf0e10cSrcweir 						theAreas[i] = new ScArea( theArea );
183cdf0e10cSrcweir 						theAreas[i]->nTab = nTab;
184cdf0e10cSrcweir 						nTab++;
185cdf0e10cSrcweir 					}
186cdf0e10cSrcweir 					*pppAreas   = theAreas;
187cdf0e10cSrcweir 					*pAreaCount = nTabCount;
188cdf0e10cSrcweir 				}
189cdf0e10cSrcweir 			}
190cdf0e10cSrcweir 		}
191cdf0e10cSrcweir 	}
192cdf0e10cSrcweir 
193cdf0e10cSrcweir 	return bStrOk;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir //------------------------------------------------------------------------
197cdf0e10cSrcweir 
IsAbsArea(const String & rAreaStr,ScDocument * pDoc,SCTAB nTab,String * pCompleteStr,ScRefAddress * pStartPos,ScRefAddress * pEndPos,ScAddress::Details const & rDetails) const198cdf0e10cSrcweir sal_Bool ScRangeUtil::IsAbsArea( const String&	rAreaStr,
199cdf0e10cSrcweir 							 ScDocument*	pDoc,
200cdf0e10cSrcweir 							 SCTAB			nTab,
201cdf0e10cSrcweir 							 String*		pCompleteStr,
202cdf0e10cSrcweir 							 ScRefAddress*	pStartPos,
203cdf0e10cSrcweir 							 ScRefAddress*	pEndPos,
204cdf0e10cSrcweir 							 ScAddress::Details const & rDetails ) const
205cdf0e10cSrcweir {
206cdf0e10cSrcweir 	sal_Bool		bIsAbsArea = sal_False;
207cdf0e10cSrcweir 	ScRefAddress	startPos;
208cdf0e10cSrcweir 	ScRefAddress	endPos;
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 	bIsAbsArea = ConvertDoubleRef( pDoc, rAreaStr, nTab, startPos, endPos, rDetails );
211cdf0e10cSrcweir 
212cdf0e10cSrcweir 	if ( bIsAbsArea )
213cdf0e10cSrcweir 	{
214cdf0e10cSrcweir 		startPos.SetRelCol( sal_False );
215cdf0e10cSrcweir 		startPos.SetRelRow( sal_False );
216cdf0e10cSrcweir 		startPos.SetRelTab( sal_False );
217cdf0e10cSrcweir 		endPos  .SetRelCol( sal_False );
218cdf0e10cSrcweir 		endPos  .SetRelRow( sal_False );
219cdf0e10cSrcweir 		endPos  .SetRelTab( sal_False );
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 		if ( pCompleteStr )
222cdf0e10cSrcweir 		{
223cdf0e10cSrcweir 			*pCompleteStr  = startPos.GetRefString( pDoc, MAXTAB+1, rDetails );
224cdf0e10cSrcweir 			*pCompleteStr += ':';
225cdf0e10cSrcweir 			*pCompleteStr += endPos  .GetRefString( pDoc, nTab, rDetails );
226cdf0e10cSrcweir 		}
227cdf0e10cSrcweir 
228cdf0e10cSrcweir 		if ( pStartPos && pEndPos )
229cdf0e10cSrcweir 		{
230cdf0e10cSrcweir 			*pStartPos = startPos;
231cdf0e10cSrcweir 			*pEndPos   = endPos;
232cdf0e10cSrcweir 		}
233cdf0e10cSrcweir 	}
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 	return bIsAbsArea;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir //------------------------------------------------------------------------
239cdf0e10cSrcweir 
IsAbsPos(const String & rPosStr,ScDocument * pDoc,SCTAB nTab,String * pCompleteStr,ScRefAddress * pPosTripel,ScAddress::Details const & rDetails) const240cdf0e10cSrcweir sal_Bool ScRangeUtil::IsAbsPos( const String&	rPosStr,
241cdf0e10cSrcweir 							ScDocument*		pDoc,
242cdf0e10cSrcweir 							SCTAB			nTab,
243cdf0e10cSrcweir 							String*			pCompleteStr,
244cdf0e10cSrcweir 							ScRefAddress*	pPosTripel,
245cdf0e10cSrcweir 							ScAddress::Details const & rDetails ) const
246cdf0e10cSrcweir {
247cdf0e10cSrcweir 	sal_Bool		bIsAbsPos = sal_False;
248cdf0e10cSrcweir 	ScRefAddress	thePos;
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 	bIsAbsPos = ConvertSingleRef( pDoc, rPosStr, nTab, thePos, rDetails );
251cdf0e10cSrcweir 	thePos.SetRelCol( sal_False );
252cdf0e10cSrcweir 	thePos.SetRelRow( sal_False );
253cdf0e10cSrcweir 	thePos.SetRelTab( sal_False );
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	if ( bIsAbsPos )
256cdf0e10cSrcweir 	{
257cdf0e10cSrcweir 		if ( pPosTripel )
258cdf0e10cSrcweir 			*pPosTripel = thePos;
259cdf0e10cSrcweir 		if ( pCompleteStr )
260cdf0e10cSrcweir 			*pCompleteStr = thePos.GetRefString( pDoc, MAXTAB+1, rDetails );
261cdf0e10cSrcweir 	}
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 	return bIsAbsPos;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir //------------------------------------------------------------------------
267cdf0e10cSrcweir 
MakeRangeFromName(const String & rName,ScDocument * pDoc,SCTAB nCurTab,ScRange & rRange,RutlNameScope eScope,ScAddress::Details const & rDetails) const268cdf0e10cSrcweir sal_Bool ScRangeUtil::MakeRangeFromName	(
269cdf0e10cSrcweir 	const String&	rName,
270cdf0e10cSrcweir 	ScDocument*		pDoc,
271cdf0e10cSrcweir 	SCTAB			nCurTab,
272cdf0e10cSrcweir 	ScRange&		rRange,
273cdf0e10cSrcweir 	RutlNameScope 	eScope,
274cdf0e10cSrcweir 	ScAddress::Details const & rDetails ) const
275cdf0e10cSrcweir {
276cdf0e10cSrcweir 	sal_Bool bResult=sal_False;
277cdf0e10cSrcweir 	ScRangeUtil		aRangeUtil;
278cdf0e10cSrcweir     SCTAB nTab = 0;
279cdf0e10cSrcweir     SCCOL nColStart = 0;
280cdf0e10cSrcweir     SCCOL nColEnd = 0;
281cdf0e10cSrcweir     SCROW nRowStart = 0;
282cdf0e10cSrcweir     SCROW nRowEnd = 0;
283cdf0e10cSrcweir 
284cdf0e10cSrcweir 	if( eScope==RUTL_NAMES )
285cdf0e10cSrcweir 	{
286cdf0e10cSrcweir 		ScRangeName& rRangeNames = *(pDoc->GetRangeName());
287cdf0e10cSrcweir 		sal_uInt16		 nAt		 = 0;
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 		if ( rRangeNames.SearchName( rName, nAt ) )
290cdf0e10cSrcweir 		{
291cdf0e10cSrcweir 			ScRangeData* pData = rRangeNames[nAt];
292cdf0e10cSrcweir 			String		 aStrArea;
293cdf0e10cSrcweir 			ScRefAddress	 aStartPos;
294cdf0e10cSrcweir 			ScRefAddress	 aEndPos;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 			pData->GetSymbol( aStrArea );
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 			if ( IsAbsArea( aStrArea, pDoc, nCurTab,
299cdf0e10cSrcweir 							NULL, &aStartPos, &aEndPos, rDetails ) )
300cdf0e10cSrcweir 			{
301cdf0e10cSrcweir 				nTab	   = aStartPos.Tab();
302cdf0e10cSrcweir 				nColStart  = aStartPos.Col();
303cdf0e10cSrcweir 				nRowStart  = aStartPos.Row();
304cdf0e10cSrcweir 				nColEnd    = aEndPos.Col();
305cdf0e10cSrcweir 				nRowEnd    = aEndPos.Row();
306cdf0e10cSrcweir 				bResult	   = sal_True;
307cdf0e10cSrcweir 			}
308cdf0e10cSrcweir 			else
309cdf0e10cSrcweir 			{
310cdf0e10cSrcweir 				CutPosString( aStrArea, aStrArea );
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 				if ( IsAbsPos( aStrArea, pDoc, nCurTab,
313cdf0e10cSrcweir 										  NULL, &aStartPos, rDetails ) )
314cdf0e10cSrcweir 				{
315cdf0e10cSrcweir 					nTab	   = aStartPos.Tab();
316cdf0e10cSrcweir 					nColStart  = nColEnd = aStartPos.Col();
317cdf0e10cSrcweir 					nRowStart  = nRowEnd = aStartPos.Row();
318cdf0e10cSrcweir 					bResult	   = sal_True;
319cdf0e10cSrcweir 				}
320cdf0e10cSrcweir 			}
321cdf0e10cSrcweir 		}
322cdf0e10cSrcweir 	}
323cdf0e10cSrcweir 	else if( eScope==RUTL_DBASE )
324cdf0e10cSrcweir 	{
325cdf0e10cSrcweir 		ScDBCollection&	rDbNames = *(pDoc->GetDBCollection());
326cdf0e10cSrcweir 		sal_uInt16		 	nAt = 0;
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 		if ( rDbNames.SearchName( rName, nAt ) )
329cdf0e10cSrcweir 		{
330cdf0e10cSrcweir 			ScDBData* pData = rDbNames[nAt];
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 			pData->GetArea( nTab, nColStart, nRowStart,
333cdf0e10cSrcweir 								  nColEnd,	 nRowEnd );
334cdf0e10cSrcweir 			bResult = sal_True;
335cdf0e10cSrcweir 		}
336cdf0e10cSrcweir 	}
337cdf0e10cSrcweir 	else
338cdf0e10cSrcweir 	{
339cdf0e10cSrcweir 		DBG_ERROR( "ScRangeUtil::MakeRangeFromName" );
340cdf0e10cSrcweir 	}
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 	if( bResult )
343cdf0e10cSrcweir 	{
344cdf0e10cSrcweir 		rRange = ScRange( nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab );
345cdf0e10cSrcweir 	}
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 	return bResult;
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir //========================================================================
351cdf0e10cSrcweir 
AssignString(OUString & rString,const OUString & rNewStr,sal_Bool bAppendStr,sal_Unicode cSeperator)352cdf0e10cSrcweir void ScRangeStringConverter::AssignString(
353cdf0e10cSrcweir 		OUString& rString,
354cdf0e10cSrcweir 		const OUString& rNewStr,
355cdf0e10cSrcweir         sal_Bool bAppendStr,
356cdf0e10cSrcweir         sal_Unicode cSeperator)
357cdf0e10cSrcweir {
358cdf0e10cSrcweir 	if( bAppendStr )
359cdf0e10cSrcweir 	{
360cdf0e10cSrcweir 		if( rNewStr.getLength() )
361cdf0e10cSrcweir 		{
362cdf0e10cSrcweir 			if( rString.getLength() )
363cdf0e10cSrcweir                 rString += rtl::OUString(cSeperator);
364cdf0e10cSrcweir 			rString += rNewStr;
365cdf0e10cSrcweir 		}
366cdf0e10cSrcweir 	}
367cdf0e10cSrcweir 	else
368cdf0e10cSrcweir 		rString = rNewStr;
369cdf0e10cSrcweir }
370cdf0e10cSrcweir 
IndexOf(const OUString & rString,sal_Unicode cSearchChar,sal_Int32 nOffset,sal_Unicode cQuote)371cdf0e10cSrcweir sal_Int32 ScRangeStringConverter::IndexOf(
372cdf0e10cSrcweir 		const OUString& rString,
373cdf0e10cSrcweir 		sal_Unicode cSearchChar,
374cdf0e10cSrcweir 		sal_Int32 nOffset,
375cdf0e10cSrcweir 		sal_Unicode cQuote )
376cdf0e10cSrcweir {
377cdf0e10cSrcweir 	sal_Int32		nLength		= rString.getLength();
378cdf0e10cSrcweir 	sal_Int32		nIndex		= nOffset;
379cdf0e10cSrcweir 	sal_Bool		bQuoted		= sal_False;
380cdf0e10cSrcweir 	sal_Bool		bExitLoop	= sal_False;
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 	while( !bExitLoop && (nIndex < nLength) )
383cdf0e10cSrcweir 	{
384cdf0e10cSrcweir 		sal_Unicode cCode = rString[ nIndex ];
385cdf0e10cSrcweir 		bExitLoop = (cCode == cSearchChar) && !bQuoted;
386cdf0e10cSrcweir 		bQuoted = (bQuoted != (cCode == cQuote));
387cdf0e10cSrcweir 		if( !bExitLoop )
388cdf0e10cSrcweir 			nIndex++;
389cdf0e10cSrcweir 	}
390cdf0e10cSrcweir 	return (nIndex < nLength) ? nIndex : -1;
391cdf0e10cSrcweir }
392cdf0e10cSrcweir 
IndexOfDifferent(const OUString & rString,sal_Unicode cSearchChar,sal_Int32 nOffset)393cdf0e10cSrcweir sal_Int32 ScRangeStringConverter::IndexOfDifferent(
394cdf0e10cSrcweir 		const OUString& rString,
395cdf0e10cSrcweir 		sal_Unicode cSearchChar,
396cdf0e10cSrcweir 		sal_Int32 nOffset )
397cdf0e10cSrcweir {
398cdf0e10cSrcweir 	sal_Int32		nLength		= rString.getLength();
399cdf0e10cSrcweir 	sal_Int32		nIndex		= nOffset;
400cdf0e10cSrcweir 	sal_Bool		bExitLoop	= sal_False;
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 	while( !bExitLoop && (nIndex < nLength) )
403cdf0e10cSrcweir 	{
404cdf0e10cSrcweir 		bExitLoop = (rString[ nIndex ] != cSearchChar);
405cdf0e10cSrcweir 		if( !bExitLoop )
406cdf0e10cSrcweir 			nIndex++;
407cdf0e10cSrcweir 	}
408cdf0e10cSrcweir 	return (nIndex < nLength) ? nIndex : -1;
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
GetTokenByOffset(OUString & rToken,const OUString & rString,sal_Int32 & nOffset,sal_Unicode cSeperator,sal_Unicode cQuote)411cdf0e10cSrcweir void ScRangeStringConverter::GetTokenByOffset(
412cdf0e10cSrcweir 		OUString& rToken,
413cdf0e10cSrcweir 		const OUString& rString,
414cdf0e10cSrcweir 		sal_Int32& nOffset,
415cdf0e10cSrcweir         sal_Unicode cSeperator,
416cdf0e10cSrcweir 		sal_Unicode cQuote)
417cdf0e10cSrcweir {
418cdf0e10cSrcweir 	sal_Int32 nLength = rString.getLength();
419cdf0e10cSrcweir 	if( nOffset >= nLength )
420cdf0e10cSrcweir 	{
421cdf0e10cSrcweir 		rToken = OUString();
422cdf0e10cSrcweir 		nOffset = -1;
423cdf0e10cSrcweir 	}
424cdf0e10cSrcweir 	else
425cdf0e10cSrcweir 	{
426cdf0e10cSrcweir 		sal_Int32 nTokenEnd = IndexOf( rString, cSeperator, nOffset, cQuote );
427cdf0e10cSrcweir 		if( nTokenEnd < 0 )
428cdf0e10cSrcweir 			nTokenEnd = nLength;
429cdf0e10cSrcweir 		rToken = rString.copy( nOffset, nTokenEnd - nOffset );
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 		sal_Int32 nNextBegin = IndexOfDifferent( rString, cSeperator, nTokenEnd );
432cdf0e10cSrcweir 		nOffset = (nNextBegin < 0) ? nLength : nNextBegin;
433cdf0e10cSrcweir 	}
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
AppendTableName(OUStringBuffer & rBuf,const OUString & rTabName,sal_Unicode)436cdf0e10cSrcweir void ScRangeStringConverter::AppendTableName(OUStringBuffer& rBuf, const OUString& rTabName, sal_Unicode /* cQuote */)
437cdf0e10cSrcweir {
438cdf0e10cSrcweir     // quote character is always "'"
439cdf0e10cSrcweir     String aQuotedTab(rTabName);
440cdf0e10cSrcweir     ScCompiler::CheckTabQuotes(aQuotedTab, ::formula::FormulaGrammar::CONV_OOO);
441cdf0e10cSrcweir     rBuf.append(aQuotedTab);
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
GetTokenCount(const OUString & rString,sal_Unicode cSeperator,sal_Unicode cQuote)444cdf0e10cSrcweir sal_Int32 ScRangeStringConverter::GetTokenCount( const OUString& rString, sal_Unicode cSeperator, sal_Unicode cQuote )
445cdf0e10cSrcweir {
446cdf0e10cSrcweir 	OUString	sToken;
447cdf0e10cSrcweir 	sal_Int32	nCount = 0;
448cdf0e10cSrcweir 	sal_Int32	nOffset = 0;
449cdf0e10cSrcweir 	while( nOffset >= 0 )
450cdf0e10cSrcweir 	{
451cdf0e10cSrcweir 		GetTokenByOffset( sToken, rString, nOffset, cQuote, cSeperator );
452cdf0e10cSrcweir 		if( nOffset >= 0 )
453cdf0e10cSrcweir 			nCount++;
454cdf0e10cSrcweir 	}
455cdf0e10cSrcweir 	return nCount;
456cdf0e10cSrcweir }
457cdf0e10cSrcweir 
458cdf0e10cSrcweir //___________________________________________________________________
459cdf0e10cSrcweir 
GetAddressFromString(ScAddress & rAddress,const OUString & rAddressStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Int32 & nOffset,sal_Unicode cSeperator,sal_Unicode cQuote)460cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetAddressFromString(
461cdf0e10cSrcweir 		ScAddress& rAddress,
462cdf0e10cSrcweir 		const OUString& rAddressStr,
463cdf0e10cSrcweir 		const ScDocument* pDocument,
464cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
465cdf0e10cSrcweir 		sal_Int32& nOffset,
466cdf0e10cSrcweir         sal_Unicode cSeperator,
467cdf0e10cSrcweir         sal_Unicode cQuote )
468cdf0e10cSrcweir {
469cdf0e10cSrcweir 	OUString sToken;
470cdf0e10cSrcweir 	GetTokenByOffset( sToken, rAddressStr, nOffset, cSeperator, cQuote );
471cdf0e10cSrcweir 	if( nOffset >= 0 )
472cdf0e10cSrcweir     {
473cdf0e10cSrcweir         if ((rAddress.Parse( sToken, const_cast<ScDocument*>(pDocument), eConv ) & SCA_VALID) == SCA_VALID)
474cdf0e10cSrcweir             return true;
475cdf0e10cSrcweir     }
476cdf0e10cSrcweir 	return sal_False;
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
GetRangeFromString(ScRange & rRange,const OUString & rRangeStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Int32 & nOffset,sal_Unicode cSeperator,sal_Unicode cQuote)479cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetRangeFromString(
480cdf0e10cSrcweir 		ScRange& rRange,
481cdf0e10cSrcweir 		const OUString& rRangeStr,
482cdf0e10cSrcweir 		const ScDocument* pDocument,
483cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
484cdf0e10cSrcweir 		sal_Int32& nOffset,
485cdf0e10cSrcweir         sal_Unicode cSeperator,
486cdf0e10cSrcweir         sal_Unicode cQuote )
487cdf0e10cSrcweir {
488cdf0e10cSrcweir 	OUString sToken;
489cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
490cdf0e10cSrcweir 	GetTokenByOffset( sToken, rRangeStr, nOffset, cSeperator, cQuote );
491cdf0e10cSrcweir 	if( nOffset >= 0 )
492cdf0e10cSrcweir 	{
493cdf0e10cSrcweir         sal_Int32 nIndex = IndexOf( sToken, ':', 0, cQuote );
494cdf0e10cSrcweir         String aUIString(sToken);
495cdf0e10cSrcweir 
496cdf0e10cSrcweir         if( nIndex < 0 )
497cdf0e10cSrcweir         {
498cdf0e10cSrcweir             if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
499cdf0e10cSrcweir                 aUIString.Erase( 0, 1 );
500cdf0e10cSrcweir             bResult = ((rRange.aStart.Parse( aUIString, const_cast<ScDocument*> (pDocument), eConv) & SCA_VALID) == SCA_VALID);
501cdf0e10cSrcweir             rRange.aEnd = rRange.aStart;
502cdf0e10cSrcweir         }
503cdf0e10cSrcweir         else
504cdf0e10cSrcweir         {
505cdf0e10cSrcweir             if ( aUIString.GetChar(0) == (sal_Unicode) '.' )
506cdf0e10cSrcweir             {
507cdf0e10cSrcweir                 aUIString.Erase( 0, 1 );
508cdf0e10cSrcweir                 --nIndex;
509cdf0e10cSrcweir             }
510cdf0e10cSrcweir 
511cdf0e10cSrcweir             if ( nIndex < aUIString.Len() - 1 &&
512cdf0e10cSrcweir                     aUIString.GetChar((xub_StrLen)nIndex + 1) == (sal_Unicode) '.' )
513cdf0e10cSrcweir                 aUIString.Erase( (xub_StrLen)nIndex + 1, 1 );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir             bResult = ((rRange.Parse(aUIString, const_cast<ScDocument*> (pDocument), eConv) & SCA_VALID) == SCA_VALID);
516cdf0e10cSrcweir 
517cdf0e10cSrcweir             // #i77703# chart ranges in the file format contain both sheet names, even for an external reference sheet.
518cdf0e10cSrcweir             // This isn't parsed by ScRange, so try to parse the two Addresses then.
519cdf0e10cSrcweir             if (!bResult)
520cdf0e10cSrcweir             {
521cdf0e10cSrcweir                 bResult = ((rRange.aStart.Parse( aUIString.Copy(0, (xub_StrLen)nIndex), const_cast<ScDocument*>(pDocument),
522cdf0e10cSrcweir                                 eConv) & SCA_VALID) == SCA_VALID) &&
523cdf0e10cSrcweir                           ((rRange.aEnd.Parse( aUIString.Copy((xub_StrLen)nIndex+1), const_cast<ScDocument*>(pDocument),
524cdf0e10cSrcweir                                 eConv) & SCA_VALID) == SCA_VALID);
525cdf0e10cSrcweir             }
526cdf0e10cSrcweir         }
527cdf0e10cSrcweir     }
528cdf0e10cSrcweir 	return bResult;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
GetRangeListFromString(ScRangeList & rRangeList,const OUString & rRangeListStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Unicode cQuote)531cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetRangeListFromString(
532cdf0e10cSrcweir 		ScRangeList& rRangeList,
533cdf0e10cSrcweir 		const OUString& rRangeListStr,
534cdf0e10cSrcweir 		const ScDocument* pDocument,
535cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
536cdf0e10cSrcweir         sal_Unicode cSeperator,
537cdf0e10cSrcweir         sal_Unicode cQuote )
538cdf0e10cSrcweir {
539cdf0e10cSrcweir     sal_Bool bRet = sal_True;
540cdf0e10cSrcweir 	DBG_ASSERT( rRangeListStr.getLength(), "ScXMLConverter::GetRangeListFromString - empty string!" );
541cdf0e10cSrcweir 	sal_Int32 nOffset = 0;
542cdf0e10cSrcweir 	while( nOffset >= 0 )
543cdf0e10cSrcweir 	{
544cdf0e10cSrcweir 		ScRange* pRange = new ScRange;
545cdf0e10cSrcweir 		if( GetRangeFromString( *pRange, rRangeListStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
546cdf0e10cSrcweir 			rRangeList.Insert( pRange, LIST_APPEND );
547cdf0e10cSrcweir         else if (nOffset > -1)
548cdf0e10cSrcweir             bRet = sal_False;
549cdf0e10cSrcweir 	}
550cdf0e10cSrcweir     return bRet;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 
554cdf0e10cSrcweir //___________________________________________________________________
555cdf0e10cSrcweir 
GetAreaFromString(ScArea & rArea,const OUString & rRangeStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Int32 & nOffset,sal_Unicode cSeperator,sal_Unicode cQuote)556cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetAreaFromString(
557cdf0e10cSrcweir 		ScArea& rArea,
558cdf0e10cSrcweir 		const OUString& rRangeStr,
559cdf0e10cSrcweir 		const ScDocument* pDocument,
560cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
561cdf0e10cSrcweir 		sal_Int32& nOffset,
562cdf0e10cSrcweir         sal_Unicode cSeperator,
563cdf0e10cSrcweir         sal_Unicode cQuote )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir 	ScRange aScRange;
566cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
567cdf0e10cSrcweir 	if( GetRangeFromString( aScRange, rRangeStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
568cdf0e10cSrcweir 	{
569cdf0e10cSrcweir 		rArea.nTab = aScRange.aStart.Tab();
570cdf0e10cSrcweir 		rArea.nColStart = aScRange.aStart.Col();
571cdf0e10cSrcweir 		rArea.nRowStart = aScRange.aStart.Row();
572cdf0e10cSrcweir 		rArea.nColEnd = aScRange.aEnd.Col();
573cdf0e10cSrcweir 		rArea.nRowEnd = aScRange.aEnd.Row();
574cdf0e10cSrcweir 		bResult = sal_True;
575cdf0e10cSrcweir 	}
576cdf0e10cSrcweir 	return bResult;
577cdf0e10cSrcweir }
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 
580cdf0e10cSrcweir //___________________________________________________________________
581cdf0e10cSrcweir 
GetAddressFromString(table::CellAddress & rAddress,const OUString & rAddressStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Int32 & nOffset,sal_Unicode cSeperator,sal_Unicode cQuote)582cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetAddressFromString(
583cdf0e10cSrcweir 		table::CellAddress& rAddress,
584cdf0e10cSrcweir 		const OUString& rAddressStr,
585cdf0e10cSrcweir 		const ScDocument* pDocument,
586cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
587cdf0e10cSrcweir 		sal_Int32& nOffset,
588cdf0e10cSrcweir         sal_Unicode cSeperator,
589cdf0e10cSrcweir         sal_Unicode cQuote )
590cdf0e10cSrcweir {
591cdf0e10cSrcweir 	ScAddress aScAddress;
592cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
593cdf0e10cSrcweir 	if( GetAddressFromString( aScAddress, rAddressStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
594cdf0e10cSrcweir 	{
595cdf0e10cSrcweir 		ScUnoConversion::FillApiAddress( rAddress, aScAddress );
596cdf0e10cSrcweir 		bResult = sal_True;
597cdf0e10cSrcweir 	}
598cdf0e10cSrcweir 	return bResult;
599cdf0e10cSrcweir }
600cdf0e10cSrcweir 
GetRangeFromString(table::CellRangeAddress & rRange,const OUString & rRangeStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Int32 & nOffset,sal_Unicode cSeperator,sal_Unicode cQuote)601cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetRangeFromString(
602cdf0e10cSrcweir 		table::CellRangeAddress& rRange,
603cdf0e10cSrcweir 		const OUString& rRangeStr,
604cdf0e10cSrcweir 		const ScDocument* pDocument,
605cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
606cdf0e10cSrcweir 		sal_Int32& nOffset,
607cdf0e10cSrcweir         sal_Unicode cSeperator,
608cdf0e10cSrcweir         sal_Unicode cQuote )
609cdf0e10cSrcweir {
610cdf0e10cSrcweir 	ScRange aScRange;
611cdf0e10cSrcweir 	sal_Bool bResult(sal_False);
612cdf0e10cSrcweir 	if( GetRangeFromString( aScRange, rRangeStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
613cdf0e10cSrcweir 	{
614cdf0e10cSrcweir 		ScUnoConversion::FillApiRange( rRange, aScRange );
615cdf0e10cSrcweir 		bResult = sal_True;
616cdf0e10cSrcweir 	}
617cdf0e10cSrcweir 	return bResult;
618cdf0e10cSrcweir }
619cdf0e10cSrcweir 
GetRangeListFromString(uno::Sequence<table::CellRangeAddress> & rRangeSeq,const OUString & rRangeListStr,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Unicode cQuote)620cdf0e10cSrcweir sal_Bool ScRangeStringConverter::GetRangeListFromString(
621cdf0e10cSrcweir 		uno::Sequence< table::CellRangeAddress >& rRangeSeq,
622cdf0e10cSrcweir 		const OUString& rRangeListStr,
623cdf0e10cSrcweir 		const ScDocument* pDocument,
624cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
625cdf0e10cSrcweir         sal_Unicode cSeperator,
626cdf0e10cSrcweir         sal_Unicode cQuote )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir     sal_Bool bRet = sal_True;
629cdf0e10cSrcweir 	DBG_ASSERT( rRangeListStr.getLength(), "ScXMLConverter::GetRangeListFromString - empty string!" );
630cdf0e10cSrcweir 	table::CellRangeAddress aRange;
631cdf0e10cSrcweir 	sal_Int32 nOffset = 0;
632cdf0e10cSrcweir 	while( nOffset >= 0 )
633cdf0e10cSrcweir 	{
634cdf0e10cSrcweir 		if( GetRangeFromString( aRange, rRangeListStr, pDocument, eConv, nOffset, cSeperator, cQuote ) && (nOffset >= 0) )
635cdf0e10cSrcweir 		{
636cdf0e10cSrcweir 			rRangeSeq.realloc( rRangeSeq.getLength() + 1 );
637cdf0e10cSrcweir 			rRangeSeq[ rRangeSeq.getLength() - 1 ] = aRange;
638cdf0e10cSrcweir 		}
639cdf0e10cSrcweir         else
640cdf0e10cSrcweir             bRet = sal_False;
641cdf0e10cSrcweir 	}
642cdf0e10cSrcweir     return bRet;
643cdf0e10cSrcweir }
644cdf0e10cSrcweir 
645cdf0e10cSrcweir 
646cdf0e10cSrcweir //___________________________________________________________________
647cdf0e10cSrcweir 
GetStringFromAddress(OUString & rString,const ScAddress & rAddress,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Bool bAppendStr,sal_uInt16 nFormatFlags)648cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromAddress(
649cdf0e10cSrcweir 		OUString& rString,
650cdf0e10cSrcweir 		const ScAddress& rAddress,
651cdf0e10cSrcweir 		const ScDocument* pDocument,
652cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
653cdf0e10cSrcweir         sal_Unicode cSeperator,
654cdf0e10cSrcweir 		sal_Bool bAppendStr,
655cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
656cdf0e10cSrcweir {
657cdf0e10cSrcweir 	if (pDocument && pDocument->HasTable(rAddress.Tab()))
658cdf0e10cSrcweir 	{
659cdf0e10cSrcweir 		String sAddress;
660cdf0e10cSrcweir 		rAddress.Format( sAddress, nFormatFlags, (ScDocument*) pDocument, eConv );
661cdf0e10cSrcweir 		AssignString( rString, sAddress, bAppendStr, cSeperator );
662cdf0e10cSrcweir 	}
663cdf0e10cSrcweir }
664cdf0e10cSrcweir 
GetStringFromRange(OUString & rString,const ScRange & rRange,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Bool bAppendStr,sal_uInt16 nFormatFlags)665cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromRange(
666cdf0e10cSrcweir 		OUString& rString,
667cdf0e10cSrcweir 		const ScRange& rRange,
668cdf0e10cSrcweir 		const ScDocument* pDocument,
669cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
670cdf0e10cSrcweir         sal_Unicode cSeperator,
671cdf0e10cSrcweir 		sal_Bool bAppendStr,
672cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
673cdf0e10cSrcweir {
674cdf0e10cSrcweir 	if (pDocument && pDocument->HasTable(rRange.aStart.Tab()))
675cdf0e10cSrcweir 	{
676cdf0e10cSrcweir 		ScAddress aStartAddress( rRange.aStart );
677cdf0e10cSrcweir 		ScAddress aEndAddress( rRange.aEnd );
678cdf0e10cSrcweir 		String sStartAddress;
679cdf0e10cSrcweir 		String sEndAddress;
680cdf0e10cSrcweir 		aStartAddress.Format( sStartAddress, nFormatFlags, (ScDocument*) pDocument, eConv );
681cdf0e10cSrcweir 		aEndAddress.Format( sEndAddress, nFormatFlags, (ScDocument*) pDocument, eConv );
682cdf0e10cSrcweir 		OUString sOUStartAddress( sStartAddress );
683cdf0e10cSrcweir         sOUStartAddress += OUString(':');
684cdf0e10cSrcweir 		sOUStartAddress += OUString( sEndAddress );
685cdf0e10cSrcweir 		AssignString( rString, sOUStartAddress, bAppendStr, cSeperator );
686cdf0e10cSrcweir 	}
687cdf0e10cSrcweir }
688cdf0e10cSrcweir 
GetStringFromRangeList(OUString & rString,const ScRangeList * pRangeList,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_uInt16 nFormatFlags)689cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromRangeList(
690cdf0e10cSrcweir 		OUString& rString,
691cdf0e10cSrcweir 		const ScRangeList* pRangeList,
692cdf0e10cSrcweir 		const ScDocument* pDocument,
693cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
694cdf0e10cSrcweir         sal_Unicode cSeperator,
695cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir 	OUString sRangeListStr;
698cdf0e10cSrcweir 	if( pRangeList )
699cdf0e10cSrcweir 	{
700cdf0e10cSrcweir 		sal_Int32 nCount = pRangeList->Count();
701cdf0e10cSrcweir 		for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
702cdf0e10cSrcweir 		{
703cdf0e10cSrcweir 			const ScRange* pRange = pRangeList->GetObject( nIndex );
704cdf0e10cSrcweir 			if( pRange )
705cdf0e10cSrcweir 				GetStringFromRange( sRangeListStr, *pRange, pDocument, eConv, cSeperator, sal_True, nFormatFlags );
706cdf0e10cSrcweir 		}
707cdf0e10cSrcweir 	}
708cdf0e10cSrcweir 	rString = sRangeListStr;
709cdf0e10cSrcweir }
710cdf0e10cSrcweir 
711cdf0e10cSrcweir 
712cdf0e10cSrcweir //___________________________________________________________________
713cdf0e10cSrcweir 
GetStringFromArea(OUString & rString,const ScArea & rArea,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Bool bAppendStr,sal_uInt16 nFormatFlags)714cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromArea(
715cdf0e10cSrcweir 		OUString& rString,
716cdf0e10cSrcweir 		const ScArea& rArea,
717cdf0e10cSrcweir 		const ScDocument* pDocument,
718cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
719cdf0e10cSrcweir         sal_Unicode cSeperator,
720cdf0e10cSrcweir 		sal_Bool bAppendStr,
721cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
722cdf0e10cSrcweir {
723cdf0e10cSrcweir 	ScRange aRange( rArea.nColStart, rArea.nRowStart, rArea.nTab, rArea.nColEnd, rArea.nRowEnd, rArea.nTab );
724cdf0e10cSrcweir 	GetStringFromRange( rString, aRange, pDocument, eConv, cSeperator, bAppendStr, nFormatFlags );
725cdf0e10cSrcweir }
726cdf0e10cSrcweir 
727cdf0e10cSrcweir 
728cdf0e10cSrcweir //___________________________________________________________________
729cdf0e10cSrcweir 
GetStringFromAddress(OUString & rString,const table::CellAddress & rAddress,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Bool bAppendStr,sal_uInt16 nFormatFlags)730cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromAddress(
731cdf0e10cSrcweir 		OUString& rString,
732cdf0e10cSrcweir 		const table::CellAddress& rAddress,
733cdf0e10cSrcweir 		const ScDocument* pDocument,
734cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
735cdf0e10cSrcweir         sal_Unicode cSeperator,
736cdf0e10cSrcweir 		sal_Bool bAppendStr,
737cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
738cdf0e10cSrcweir {
739cdf0e10cSrcweir 	ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet );
740cdf0e10cSrcweir 	GetStringFromAddress( rString, aScAddress, pDocument, eConv, cSeperator, bAppendStr, nFormatFlags );
741cdf0e10cSrcweir }
742cdf0e10cSrcweir 
GetStringFromRange(OUString & rString,const table::CellRangeAddress & rRange,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_Bool bAppendStr,sal_uInt16 nFormatFlags)743cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromRange(
744cdf0e10cSrcweir 		OUString& rString,
745cdf0e10cSrcweir 		const table::CellRangeAddress& rRange,
746cdf0e10cSrcweir 		const ScDocument* pDocument,
747cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
748cdf0e10cSrcweir         sal_Unicode cSeperator,
749cdf0e10cSrcweir 		sal_Bool bAppendStr,
750cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir 	ScRange aScRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), rRange.Sheet,
753cdf0e10cSrcweir 		static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), rRange.Sheet );
754cdf0e10cSrcweir 	GetStringFromRange( rString, aScRange, pDocument, eConv, cSeperator, bAppendStr, nFormatFlags );
755cdf0e10cSrcweir }
756cdf0e10cSrcweir 
GetStringFromRangeList(OUString & rString,const uno::Sequence<table::CellRangeAddress> & rRangeSeq,const ScDocument * pDocument,FormulaGrammar::AddressConvention eConv,sal_Unicode cSeperator,sal_uInt16 nFormatFlags)757cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromRangeList(
758cdf0e10cSrcweir 		OUString& rString,
759cdf0e10cSrcweir 		const uno::Sequence< table::CellRangeAddress >& rRangeSeq,
760cdf0e10cSrcweir 		const ScDocument* pDocument,
761cdf0e10cSrcweir         FormulaGrammar::AddressConvention eConv,
762cdf0e10cSrcweir         sal_Unicode cSeperator,
763cdf0e10cSrcweir 		sal_uInt16 nFormatFlags )
764cdf0e10cSrcweir {
765cdf0e10cSrcweir 	OUString sRangeListStr;
766cdf0e10cSrcweir 	sal_Int32 nCount = rRangeSeq.getLength();
767cdf0e10cSrcweir 	for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
768cdf0e10cSrcweir 	{
769cdf0e10cSrcweir 		const table::CellRangeAddress& rRange = rRangeSeq[ nIndex ];
770cdf0e10cSrcweir 		GetStringFromRange( sRangeListStr, rRange, pDocument, eConv, cSeperator, sal_True, nFormatFlags );
771cdf0e10cSrcweir 	}
772cdf0e10cSrcweir 	rString = sRangeListStr;
773cdf0e10cSrcweir }
774cdf0e10cSrcweir 
lcl_appendCellAddress(rtl::OUStringBuffer & rBuf,ScDocument * pDoc,const ScAddress & rCell,const ScAddress::ExternalInfo & rExtInfo)775cdf0e10cSrcweir static void lcl_appendCellAddress(
776cdf0e10cSrcweir     rtl::OUStringBuffer& rBuf, ScDocument* pDoc, const ScAddress& rCell,
777cdf0e10cSrcweir     const ScAddress::ExternalInfo& rExtInfo)
778cdf0e10cSrcweir {
779cdf0e10cSrcweir     if (rExtInfo.mbExternal)
780cdf0e10cSrcweir     {
781cdf0e10cSrcweir         ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
782cdf0e10cSrcweir         const String* pFilePath = pRefMgr->getExternalFileName(rExtInfo.mnFileId, true);
783cdf0e10cSrcweir         if (!pFilePath)
784cdf0e10cSrcweir             return;
785cdf0e10cSrcweir 
786cdf0e10cSrcweir         sal_Unicode cQuote = '\'';
787cdf0e10cSrcweir         rBuf.append(cQuote);
788cdf0e10cSrcweir         rBuf.append(*pFilePath);
789cdf0e10cSrcweir         rBuf.append(cQuote);
790cdf0e10cSrcweir         rBuf.append(sal_Unicode('#'));
791cdf0e10cSrcweir         rBuf.append(sal_Unicode('$'));
792cdf0e10cSrcweir         ScRangeStringConverter::AppendTableName(rBuf, rExtInfo.maTabName);
793cdf0e10cSrcweir         rBuf.append(sal_Unicode('.'));
794cdf0e10cSrcweir 
795cdf0e10cSrcweir         String aAddr;
796cdf0e10cSrcweir         rCell.Format(aAddr, SCA_ABS, NULL, ::formula::FormulaGrammar::CONV_OOO);
797cdf0e10cSrcweir         rBuf.append(aAddr);
798cdf0e10cSrcweir     }
799cdf0e10cSrcweir     else
800cdf0e10cSrcweir     {
801cdf0e10cSrcweir         String aAddr;
802cdf0e10cSrcweir         rCell.Format(aAddr, SCA_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
803cdf0e10cSrcweir         rBuf.append(aAddr);
804cdf0e10cSrcweir     }
805cdf0e10cSrcweir }
806cdf0e10cSrcweir 
lcl_appendCellRangeAddress(rtl::OUStringBuffer & rBuf,ScDocument * pDoc,const ScAddress & rCell1,const ScAddress & rCell2,const ScAddress::ExternalInfo & rExtInfo1,const ScAddress::ExternalInfo & rExtInfo2)807cdf0e10cSrcweir static void lcl_appendCellRangeAddress(
808cdf0e10cSrcweir     rtl::OUStringBuffer& rBuf, ScDocument* pDoc, const ScAddress& rCell1, const ScAddress& rCell2,
809cdf0e10cSrcweir     const ScAddress::ExternalInfo& rExtInfo1, const ScAddress::ExternalInfo& rExtInfo2)
810cdf0e10cSrcweir {
811cdf0e10cSrcweir     if (rExtInfo1.mbExternal)
812cdf0e10cSrcweir     {
813cdf0e10cSrcweir         DBG_ASSERT(rExtInfo2.mbExternal, "2nd address is not external!?");
814cdf0e10cSrcweir         DBG_ASSERT(rExtInfo1.mnFileId == rExtInfo2.mnFileId, "File IDs do not match between 1st and 2nd addresses.");
815cdf0e10cSrcweir 
816cdf0e10cSrcweir         ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
817cdf0e10cSrcweir         const String* pFilePath = pRefMgr->getExternalFileName(rExtInfo1.mnFileId, true);
818cdf0e10cSrcweir         if (!pFilePath)
819cdf0e10cSrcweir             return;
820cdf0e10cSrcweir 
821cdf0e10cSrcweir         sal_Unicode cQuote = '\'';
822cdf0e10cSrcweir         rBuf.append(cQuote);
823cdf0e10cSrcweir         rBuf.append(*pFilePath);
824cdf0e10cSrcweir         rBuf.append(cQuote);
825cdf0e10cSrcweir         rBuf.append(sal_Unicode('#'));
826cdf0e10cSrcweir         rBuf.append(sal_Unicode('$'));
827cdf0e10cSrcweir         ScRangeStringConverter::AppendTableName(rBuf, rExtInfo1.maTabName);
828cdf0e10cSrcweir         rBuf.append(sal_Unicode('.'));
829cdf0e10cSrcweir 
830cdf0e10cSrcweir         String aAddr;
831cdf0e10cSrcweir         rCell1.Format(aAddr, SCA_ABS, NULL, ::formula::FormulaGrammar::CONV_OOO);
832cdf0e10cSrcweir         rBuf.append(aAddr);
833cdf0e10cSrcweir 
834cdf0e10cSrcweir         rBuf.appendAscii(":");
835cdf0e10cSrcweir 
836cdf0e10cSrcweir         if (rExtInfo1.maTabName != rExtInfo2.maTabName)
837cdf0e10cSrcweir         {
838cdf0e10cSrcweir             rBuf.append(sal_Unicode('$'));
839cdf0e10cSrcweir             ScRangeStringConverter::AppendTableName(rBuf, rExtInfo2.maTabName);
840cdf0e10cSrcweir             rBuf.append(sal_Unicode('.'));
841cdf0e10cSrcweir         }
842cdf0e10cSrcweir 
843cdf0e10cSrcweir         rCell2.Format(aAddr, SCA_ABS, NULL, ::formula::FormulaGrammar::CONV_OOO);
844cdf0e10cSrcweir         rBuf.append(aAddr);
845cdf0e10cSrcweir     }
846cdf0e10cSrcweir     else
847cdf0e10cSrcweir     {
848cdf0e10cSrcweir         ScRange aRange;
849cdf0e10cSrcweir         aRange.aStart = rCell1;
850cdf0e10cSrcweir         aRange.aEnd   = rCell2;
851cdf0e10cSrcweir         String aAddr;
852cdf0e10cSrcweir         aRange.Format(aAddr, SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
853cdf0e10cSrcweir         rBuf.append(aAddr);
854cdf0e10cSrcweir     }
855cdf0e10cSrcweir }
856cdf0e10cSrcweir 
GetStringFromXMLRangeString(OUString & rString,const OUString & rXMLRange,ScDocument * pDoc)857cdf0e10cSrcweir void ScRangeStringConverter::GetStringFromXMLRangeString( OUString& rString, const OUString& rXMLRange, ScDocument* pDoc )
858cdf0e10cSrcweir {
859cdf0e10cSrcweir     const sal_Unicode cSep = ' ';
860cdf0e10cSrcweir     const sal_Unicode cQuote = '\'';
861cdf0e10cSrcweir 
862cdf0e10cSrcweir     OUStringBuffer aRetStr;
863cdf0e10cSrcweir     sal_Int32 nOffset = 0;
864cdf0e10cSrcweir     bool bFirst = true;
865cdf0e10cSrcweir 
866cdf0e10cSrcweir     while (nOffset >= 0)
867cdf0e10cSrcweir     {
868cdf0e10cSrcweir         OUString aToken;
869cdf0e10cSrcweir         GetTokenByOffset(aToken, rXMLRange, nOffset, cSep, cQuote);
870cdf0e10cSrcweir         if (nOffset < 0)
871cdf0e10cSrcweir             break;
872cdf0e10cSrcweir 
873cdf0e10cSrcweir         sal_Int32 nSepPos = IndexOf(aToken, ':', 0, cQuote);
874cdf0e10cSrcweir         if (nSepPos >= 0)
875cdf0e10cSrcweir         {
876cdf0e10cSrcweir             // Cell range
877cdf0e10cSrcweir             OUString aBeginCell = aToken.copy(0, nSepPos);
878cdf0e10cSrcweir             OUString aEndCell   = aToken.copy(nSepPos+1);
879cdf0e10cSrcweir 
880cdf0e10cSrcweir             if (!aBeginCell.getLength() || !aEndCell.getLength())
881cdf0e10cSrcweir                 // both cell addresses must exist for this to work.
882cdf0e10cSrcweir                 continue;
883cdf0e10cSrcweir 
884cdf0e10cSrcweir             sal_Int32 nEndCellDotPos = aEndCell.indexOf('.');
885cdf0e10cSrcweir             if (nEndCellDotPos <= 0)
886cdf0e10cSrcweir             {
887cdf0e10cSrcweir                 // initialize buffer with table name...
888cdf0e10cSrcweir                 sal_Int32 nDotPos = IndexOf(aBeginCell, sal_Unicode('.'), 0, cQuote);
889cdf0e10cSrcweir                 OUStringBuffer aBuf = aBeginCell.copy(0, nDotPos);
890cdf0e10cSrcweir 
891cdf0e10cSrcweir                 if (nEndCellDotPos == 0)
892cdf0e10cSrcweir                 {
893cdf0e10cSrcweir                     // workaround for old syntax (probably pre-chart2 age?)
894cdf0e10cSrcweir                     // e.g. Sheet1.A1:.B2
895cdf0e10cSrcweir                     aBuf.append(aEndCell);
896cdf0e10cSrcweir                 }
897cdf0e10cSrcweir                 else if (nEndCellDotPos < 0)
898cdf0e10cSrcweir                 {
899cdf0e10cSrcweir                     // sheet name in the end cell is omitted (e.g. Sheet2.A1:B2).
900cdf0e10cSrcweir                     aBuf.append(sal_Unicode('.'));
901cdf0e10cSrcweir                     aBuf.append(aEndCell);
902cdf0e10cSrcweir                 }
903cdf0e10cSrcweir                 aEndCell = aBuf.makeStringAndClear();
904cdf0e10cSrcweir             }
905cdf0e10cSrcweir 
906cdf0e10cSrcweir             ScAddress::ExternalInfo aExtInfo1, aExtInfo2;
907cdf0e10cSrcweir             ScAddress aCell1, aCell2;
908cdf0e10cSrcweir             rtl::OUString aBuf;
909cdf0e10cSrcweir             sal_uInt16 nRet = aCell1.Parse(aBeginCell, pDoc, FormulaGrammar::CONV_OOO, &aExtInfo1);
910cdf0e10cSrcweir             if ((nRet & SCA_VALID) != SCA_VALID)
911cdf0e10cSrcweir                 // first cell is invalid.
912cdf0e10cSrcweir                 continue;
913cdf0e10cSrcweir 
914cdf0e10cSrcweir             nRet = aCell2.Parse(aEndCell, pDoc, FormulaGrammar::CONV_OOO, &aExtInfo2);
915cdf0e10cSrcweir             if ((nRet & SCA_VALID) != SCA_VALID)
916cdf0e10cSrcweir                 // second cell is invalid.
917cdf0e10cSrcweir                 continue;
918cdf0e10cSrcweir 
919cdf0e10cSrcweir             if (aExtInfo1.mnFileId != aExtInfo2.mnFileId || aExtInfo1.mbExternal != aExtInfo2.mbExternal)
920cdf0e10cSrcweir                 // external info inconsistency.
921cdf0e10cSrcweir                 continue;
922cdf0e10cSrcweir 
923cdf0e10cSrcweir             // All looks good!
924cdf0e10cSrcweir 
925cdf0e10cSrcweir             if (bFirst)
926cdf0e10cSrcweir                 bFirst = false;
927cdf0e10cSrcweir             else
928cdf0e10cSrcweir                 aRetStr.appendAscii(";");
929cdf0e10cSrcweir 
930cdf0e10cSrcweir             lcl_appendCellRangeAddress(aRetStr, pDoc, aCell1, aCell2, aExtInfo1, aExtInfo2);
931cdf0e10cSrcweir         }
932cdf0e10cSrcweir         else
933cdf0e10cSrcweir         {
934cdf0e10cSrcweir             // Chart always saves ranges using CONV_OOO convention.
935cdf0e10cSrcweir             ScAddress::ExternalInfo aExtInfo;
936cdf0e10cSrcweir             ScAddress aCell;
937cdf0e10cSrcweir             sal_uInt16 nRet = aCell.Parse(aToken, pDoc, ::formula::FormulaGrammar::CONV_OOO, &aExtInfo);
938cdf0e10cSrcweir             if ((nRet & SCA_VALID) != SCA_VALID)
939cdf0e10cSrcweir                 continue;
940cdf0e10cSrcweir 
941cdf0e10cSrcweir             // Looks good!
942cdf0e10cSrcweir 
943cdf0e10cSrcweir             if (bFirst)
944cdf0e10cSrcweir                 bFirst = false;
945cdf0e10cSrcweir             else
946cdf0e10cSrcweir                 aRetStr.appendAscii(";");
947cdf0e10cSrcweir 
948cdf0e10cSrcweir             lcl_appendCellAddress(aRetStr, pDoc, aCell, aExtInfo);
949cdf0e10cSrcweir         }
950cdf0e10cSrcweir     }
951cdf0e10cSrcweir 
952cdf0e10cSrcweir     rString = aRetStr.makeStringAndClear();
953cdf0e10cSrcweir }
954cdf0e10cSrcweir 
955cdf0e10cSrcweir //========================================================================
956cdf0e10cSrcweir 
ScArea(SCTAB tab,SCCOL colStart,SCROW rowStart,SCCOL colEnd,SCROW rowEnd)957cdf0e10cSrcweir ScArea::ScArea( SCTAB tab,
958cdf0e10cSrcweir 				SCCOL colStart, SCROW rowStart,
959cdf0e10cSrcweir 				SCCOL colEnd,   SCROW rowEnd ) :
960cdf0e10cSrcweir 		nTab	 ( tab ),
961cdf0e10cSrcweir 		nColStart( colStart ),	nRowStart( rowStart ),
962cdf0e10cSrcweir 		nColEnd	 ( colEnd ),	nRowEnd  ( rowEnd )
963cdf0e10cSrcweir {
964cdf0e10cSrcweir }
965cdf0e10cSrcweir 
966cdf0e10cSrcweir //------------------------------------------------------------------------
967cdf0e10cSrcweir 
ScArea(const ScArea & r)968cdf0e10cSrcweir ScArea::ScArea( const ScArea& r ) :
969cdf0e10cSrcweir 		nTab	 ( r.nTab ),
970cdf0e10cSrcweir 		nColStart( r.nColStart ),	nRowStart( r.nRowStart ),
971cdf0e10cSrcweir 		nColEnd  ( r.nColEnd ),		nRowEnd  ( r.nRowEnd )
972cdf0e10cSrcweir {
973cdf0e10cSrcweir }
974cdf0e10cSrcweir 
975cdf0e10cSrcweir //------------------------------------------------------------------------
976cdf0e10cSrcweir 
operator =(const ScArea & r)977cdf0e10cSrcweir ScArea& ScArea::operator=( const ScArea& r )
978cdf0e10cSrcweir {
979cdf0e10cSrcweir 	nTab		= r.nTab;
980cdf0e10cSrcweir 	nColStart	= r.nColStart;
981cdf0e10cSrcweir 	nRowStart	= r.nRowStart;
982cdf0e10cSrcweir 	nColEnd		= r.nColEnd;
983cdf0e10cSrcweir 	nRowEnd		= r.nRowEnd;
984cdf0e10cSrcweir 	return *this;
985cdf0e10cSrcweir }
986cdf0e10cSrcweir 
987cdf0e10cSrcweir //------------------------------------------------------------------------
988cdf0e10cSrcweir 
operator ==(const ScArea & r) const989cdf0e10cSrcweir sal_Bool ScArea::operator==( const ScArea& r ) const
990cdf0e10cSrcweir {
991cdf0e10cSrcweir 	return (   (nTab		== r.nTab)
992cdf0e10cSrcweir 			&& (nColStart	== r.nColStart)
993cdf0e10cSrcweir 			&& (nRowStart	== r.nRowStart)
994cdf0e10cSrcweir 			&& (nColEnd		== r.nColEnd)
995cdf0e10cSrcweir 			&& (nRowEnd		== r.nRowEnd) );
996cdf0e10cSrcweir }
997cdf0e10cSrcweir 
998cdf0e10cSrcweir //------------------------------------------------------------------------
999cdf0e10cSrcweir 
ScAreaNameIterator(ScDocument * pDoc)1000*22407013SOliver-Rainer Wittmann ScAreaNameIterator::ScAreaNameIterator( ScDocument* pDoc )
1001cdf0e10cSrcweir {
1002cdf0e10cSrcweir 	pRangeName = pDoc->GetRangeName();
1003cdf0e10cSrcweir 	pDBCollection = pDoc->GetDBCollection();
1004cdf0e10cSrcweir 	nPos = 0;
1005cdf0e10cSrcweir 	bFirstPass = sal_True;
1006cdf0e10cSrcweir }
1007cdf0e10cSrcweir 
Next(String & rName,ScRange & rRange)1008cdf0e10cSrcweir sal_Bool ScAreaNameIterator::Next( String& rName, ScRange& rRange )
1009cdf0e10cSrcweir {
1010*22407013SOliver-Rainer Wittmann     for (;;)
1011*22407013SOliver-Rainer Wittmann     {
1012*22407013SOliver-Rainer Wittmann         if ( bFirstPass )									// erst Bereichsnamen
1013*22407013SOliver-Rainer Wittmann         {
1014*22407013SOliver-Rainer Wittmann             if ( pRangeName && nPos < pRangeName->GetCount() )
1015*22407013SOliver-Rainer Wittmann             {
1016*22407013SOliver-Rainer Wittmann                 ScRangeData* pData = (*pRangeName)[nPos++];
1017*22407013SOliver-Rainer Wittmann                 if ( pData && pData->IsValidReference(rRange) )
1018*22407013SOliver-Rainer Wittmann                 {
1019*22407013SOliver-Rainer Wittmann                     rName = pData->GetName();
1020*22407013SOliver-Rainer Wittmann                     return sal_True;							// gefunden
1021*22407013SOliver-Rainer Wittmann                 }
1022*22407013SOliver-Rainer Wittmann             }
1023*22407013SOliver-Rainer Wittmann             else
1024*22407013SOliver-Rainer Wittmann             {
1025*22407013SOliver-Rainer Wittmann                 bFirstPass = sal_False;
1026*22407013SOliver-Rainer Wittmann                 nPos = 0;
1027*22407013SOliver-Rainer Wittmann             }
1028*22407013SOliver-Rainer Wittmann         }
1029*22407013SOliver-Rainer Wittmann         if ( !bFirstPass )									// dann DB-Bereiche
1030*22407013SOliver-Rainer Wittmann         {
1031*22407013SOliver-Rainer Wittmann             if ( pDBCollection && nPos < pDBCollection->GetCount() )
1032*22407013SOliver-Rainer Wittmann             {
1033*22407013SOliver-Rainer Wittmann                 ScDBData* pData = (*pDBCollection)[nPos++];
1034*22407013SOliver-Rainer Wittmann                 if ( pData
1035*22407013SOliver-Rainer Wittmann                      && !pData->IsInternalUnnamed()
1036*22407013SOliver-Rainer Wittmann                      && !pData->IsInternalForAutoFilter() )
1037*22407013SOliver-Rainer Wittmann                 {
1038*22407013SOliver-Rainer Wittmann                     pData->GetArea( rRange );
1039*22407013SOliver-Rainer Wittmann                     rName = pData->GetName();
1040*22407013SOliver-Rainer Wittmann                     return sal_True;							// gefunden
1041*22407013SOliver-Rainer Wittmann                 }
1042*22407013SOliver-Rainer Wittmann             }
1043*22407013SOliver-Rainer Wittmann             else
1044*22407013SOliver-Rainer Wittmann                 return sal_False;								// gibt nichts mehr
1045*22407013SOliver-Rainer Wittmann         }
1046*22407013SOliver-Rainer Wittmann     }
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir 
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir 
1051cdf0e10cSrcweir 
1052