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