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 "addressconverter.hxx"
30 : :
31 : : #include <com/sun/star/container/XIndexAccess.hpp>
32 : : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
33 : : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
34 : : #include <osl/diagnose.h>
35 : : #include <rtl/strbuf.hxx>
36 : : #include <rtl/ustrbuf.hxx>
37 : : #include "oox/core/filterbase.hxx"
38 : : #include "biffinputstream.hxx"
39 : :
40 : : namespace oox {
41 : : namespace xls {
42 : :
43 : : // ============================================================================
44 : :
45 : : using namespace ::com::sun::star::container;
46 : : using namespace ::com::sun::star::sheet;
47 : : using namespace ::com::sun::star::table;
48 : : using namespace ::com::sun::star::uno;
49 : :
50 : : using ::rtl::OStringBuffer;
51 : : using ::rtl::OUString;
52 : : using ::rtl::OUStringBuffer;
53 : : using ::rtl::OUStringToOString;
54 : :
55 : : // ============================================================================
56 : :
57 : : namespace {
58 : :
59 : : //! TODO: this limit may change, is there a way to obtain it via API?
60 : : const sal_Int16 API_MAXTAB = 255;
61 : :
62 : : const sal_Int32 OOX_MAXCOL = static_cast< sal_Int32 >( (1 << 14) - 1 );
63 : : const sal_Int32 OOX_MAXROW = static_cast< sal_Int32 >( (1 << 20) - 1 );
64 : : const sal_Int16 OOX_MAXTAB = static_cast< sal_Int16 >( (1 << 15) - 1 );
65 : :
66 : : const sal_Int32 BIFF2_MAXCOL = 255;
67 : : const sal_Int32 BIFF2_MAXROW = 16383;
68 : : const sal_Int16 BIFF2_MAXTAB = 0;
69 : :
70 : : const sal_Int32 BIFF3_MAXCOL = BIFF2_MAXCOL;
71 : : const sal_Int32 BIFF3_MAXROW = BIFF2_MAXROW;
72 : : const sal_Int16 BIFF3_MAXTAB = BIFF2_MAXTAB;
73 : :
74 : : const sal_Int32 BIFF4_MAXCOL = BIFF3_MAXCOL;
75 : : const sal_Int32 BIFF4_MAXROW = BIFF3_MAXROW;
76 : : const sal_Int16 BIFF4_MAXTAB = 32767;
77 : :
78 : : const sal_Int32 BIFF5_MAXCOL = BIFF4_MAXCOL;
79 : : const sal_Int32 BIFF5_MAXROW = BIFF4_MAXROW;
80 : : const sal_Int16 BIFF5_MAXTAB = BIFF4_MAXTAB;
81 : :
82 : : const sal_Int32 BIFF8_MAXCOL = BIFF5_MAXCOL;
83 : : const sal_Int32 BIFF8_MAXROW = 65535;
84 : : const sal_Int16 BIFF8_MAXTAB = BIFF5_MAXTAB;
85 : :
86 : : const sal_Unicode BIFF_URL_DRIVE = '\x01'; /// DOS drive letter or UNC path.
87 : : const sal_Unicode BIFF_URL_ROOT = '\x02'; /// Root directory of current drive.
88 : : const sal_Unicode BIFF_URL_SUBDIR = '\x03'; /// Subdirectory delimiter.
89 : : const sal_Unicode BIFF_URL_PARENT = '\x04'; /// Parent directory.
90 : : const sal_Unicode BIFF_URL_RAW = '\x05'; /// Unencoded URL.
91 : : const sal_Unicode BIFF_URL_INSTALL = '\x06'; /// Application installation directory.
92 : : const sal_Unicode BIFF_URL_INSTALL2 = '\x07'; /// Alternative application installation directory.
93 : : const sal_Unicode BIFF_URL_LIBRARY = '\x08'; /// Library directory in application installation.
94 : : const sal_Unicode BIFF4_URL_SHEET = '\x09'; /// BIFF4 internal sheet.
95 : : const sal_Unicode BIFF_URL_UNC = '@'; /// UNC path root.
96 : :
97 : : const sal_Unicode BIFF_DCON_ENCODED = '\x01'; /// First character of an encoded path from DCON* records.
98 : : const sal_Unicode BIFF_DCON_INTERN = '\x02'; /// First character of an encoded sheet name from DCON* records.
99 : :
100 : : } // namespace
101 : :
102 : : // ============================================================================
103 : : // ============================================================================
104 : :
105 : 0 : CellAddress ApiCellRangeList::getBaseAddress() const
106 : : {
107 [ # # ]: 0 : if( empty() )
108 : 0 : return CellAddress();
109 : 0 : return CellAddress( front().Sheet, front().StartColumn, front().StartRow );
110 : : }
111 : :
112 : : // ============================================================================
113 : :
114 : 0 : void BinAddress::read( SequenceInputStream& rStrm )
115 : : {
116 : 0 : rStrm >> mnRow >> mnCol;
117 : 0 : }
118 : :
119 : 0 : void BinAddress::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
120 : : {
121 [ # # ]: 0 : mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
122 [ # # ]: 0 : mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
123 : 0 : }
124 : :
125 : : // ============================================================================
126 : :
127 : 0 : void BinRange::read( SequenceInputStream& rStrm )
128 : : {
129 : 0 : rStrm >> maFirst.mnRow >> maLast.mnRow >> maFirst.mnCol >> maLast.mnCol;
130 : 0 : }
131 : :
132 : 0 : void BinRange::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
133 : : {
134 [ # # ]: 0 : maFirst.mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
135 [ # # ]: 0 : maLast.mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
136 [ # # ]: 0 : maFirst.mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
137 [ # # ]: 0 : maLast.mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
138 : 0 : }
139 : :
140 : : // ============================================================================
141 : :
142 : 0 : void BinRangeList::read( SequenceInputStream& rStrm )
143 : : {
144 : 0 : sal_Int32 nCount = rStrm.readInt32();
145 : 0 : resize( getLimitedValue< size_t, sal_Int64 >( nCount, 0, rStrm.getRemaining() / 16 ) );
146 [ # # ][ # # ]: 0 : for( iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
147 [ # # ]: 0 : aIt->read( rStrm );
148 : 0 : }
149 : :
150 : : // ============================================================================
151 : :
152 : 24 : AddressConverter::AddressConverter( const WorkbookHelper& rHelper ) :
153 : : WorkbookHelper( rHelper ),
154 : : mbColOverflow( false ),
155 : : mbRowOverflow( false ),
156 : 24 : mbTabOverflow( false )
157 : : {
158 : 24 : maDConChars.set( 0xFFFF, '\x01', 0xFFFF, '\x02', 0xFFFF );
159 [ + - - - ]: 24 : switch( getFilterType() )
[ + - ]
160 : : {
161 : : case FILTER_OOXML:
162 [ + - ]: 24 : initializeMaxPos( OOX_MAXTAB, OOX_MAXCOL, OOX_MAXROW );
163 : 24 : break;
164 [ # # ][ # # : 0 : case FILTER_BIFF: switch( getBiff() )
# # # #
# ]
165 : : {
166 : : case BIFF2:
167 [ # # ]: 0 : initializeMaxPos( BIFF2_MAXTAB, BIFF2_MAXCOL, BIFF2_MAXROW );
168 : 0 : maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, 0xFFFF );
169 : 0 : break;
170 : : case BIFF3:
171 [ # # ]: 0 : initializeMaxPos( BIFF3_MAXTAB, BIFF3_MAXCOL, BIFF3_MAXROW );
172 : 0 : maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, 0xFFFF );
173 : 0 : break;
174 : : case BIFF4:
175 [ # # ]: 0 : initializeMaxPos( BIFF4_MAXTAB, BIFF4_MAXCOL, BIFF4_MAXROW );
176 : 0 : maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, '\x00' );
177 : 0 : break;
178 : : case BIFF5:
179 [ # # ]: 0 : initializeMaxPos( BIFF5_MAXTAB, BIFF5_MAXCOL, BIFF5_MAXROW );
180 : 0 : maLinkChars.set( '\x04', '\x01', '\x02', '\x03', '\x00' );
181 : 0 : break;
182 : : case BIFF8:
183 [ # # ]: 0 : initializeMaxPos( BIFF8_MAXTAB, BIFF8_MAXCOL, BIFF8_MAXROW );
184 : 0 : maLinkChars.set( '\x04', '\x01', 0xFFFF, '\x02', '\x00' );
185 : 0 : break;
186 : 0 : case BIFF_UNKNOWN: break;
187 : : }
188 : 0 : break;
189 : 0 : case FILTER_UNKNOWN: break;
190 : : }
191 : 24 : }
192 : :
193 : : // ----------------------------------------------------------------------------
194 : :
195 : 714 : bool AddressConverter::parseOoxAddress2d(
196 : : sal_Int32& ornColumn, sal_Int32& ornRow,
197 : : const OUString& rString, sal_Int32 nStart, sal_Int32 nLength )
198 : : {
199 : 714 : ornColumn = ornRow = 0;
200 [ + - ][ + + ]: 714 : if( (nStart < 0) || (nStart >= rString.getLength()) || (nLength < 2) )
[ - + ][ + + ]
201 : 15 : return false;
202 : :
203 : 699 : const sal_Unicode* pcChar = rString.getStr() + nStart;
204 [ + - ]: 699 : const sal_Unicode* pcEndChar = pcChar + ::std::min( nLength, rString.getLength() - nStart );
205 : :
206 : 699 : enum { STATE_COL, STATE_ROW } eState = STATE_COL;
207 [ + + ]: 2892 : while( pcChar < pcEndChar )
208 : : {
209 : 2193 : sal_Unicode cChar = *pcChar;
210 [ + + - ]: 2193 : switch( eState )
211 : : {
212 : : case STATE_COL:
213 : : {
214 [ - + ][ # # ]: 1398 : if( ('a' <= cChar) && (cChar <= 'z') )
215 : 0 : (cChar -= 'a') += 'A';
216 [ + + ][ + - ]: 1398 : if( ('A' <= cChar) && (cChar <= 'Z') )
217 : : {
218 : : /* Return, if 1-based column index is already 6 characters
219 : : long (12356631 is column index for column AAAAAA). */
220 [ - + ]: 699 : if( ornColumn >= 12356631 )
221 : 0 : return false;
222 : 699 : (ornColumn *= 26) += (cChar - 'A' + 1);
223 : : }
224 [ + - ]: 699 : else if( ornColumn > 0 )
225 : : {
226 : 699 : --pcChar;
227 : 699 : eState = STATE_ROW;
228 : : }
229 : : else
230 : 0 : return false;
231 : : }
232 : 1398 : break;
233 : :
234 : : case STATE_ROW:
235 : : {
236 [ + - ][ + - ]: 795 : if( ('0' <= cChar) && (cChar <= '9') )
237 : : {
238 : : // return, if 1-based row is already 9 digits long
239 [ - + ]: 795 : if( ornRow >= 100000000 )
240 : 0 : return false;
241 : 795 : (ornRow *= 10) += (cChar - '0');
242 : : }
243 : : else
244 : 0 : return false;
245 : : }
246 : 795 : break;
247 : : }
248 : 2193 : ++pcChar;
249 : : }
250 : :
251 : 699 : --ornColumn;
252 : 699 : --ornRow;
253 [ + - ][ + - ]: 714 : return (ornColumn >= 0) && (ornRow >= 0);
254 : : }
255 : :
256 : 219 : bool AddressConverter::parseOoxRange2d(
257 : : sal_Int32& ornStartColumn, sal_Int32& ornStartRow,
258 : : sal_Int32& ornEndColumn, sal_Int32& ornEndRow,
259 : : const OUString& rString, sal_Int32 nStart, sal_Int32 nLength )
260 : : {
261 : 219 : ornStartColumn = ornStartRow = ornEndColumn = ornEndRow = 0;
262 [ + - ][ + + ]: 219 : if( (nStart < 0) || (nStart >= rString.getLength()) || (nLength < 2) )
[ - + ][ + + ]
263 : 99 : return false;
264 : :
265 [ + - ]: 120 : sal_Int32 nEnd = nStart + ::std::min( nLength, rString.getLength() - nStart );
266 : 120 : sal_Int32 nColonPos = rString.indexOf( ':', nStart );
267 [ + - ][ + + ]: 120 : if( (nStart < nColonPos) && (nColonPos + 1 < nEnd) )
268 : : {
269 : : return
270 : 42 : parseOoxAddress2d( ornStartColumn, ornStartRow, rString, nStart, nColonPos - nStart ) &&
271 [ + - ][ + - ]: 42 : parseOoxAddress2d( ornEndColumn, ornEndRow, rString, nColonPos + 1, nLength - nColonPos - 1 );
272 : : }
273 : :
274 [ + - ]: 78 : if( parseOoxAddress2d( ornStartColumn, ornStartRow, rString, nStart, nLength ) )
275 : : {
276 : 78 : ornEndColumn = ornStartColumn;
277 : 78 : ornEndRow = ornStartRow;
278 : 78 : return true;
279 : : }
280 : :
281 : 219 : return false;
282 : : }
283 : :
284 : : // ----------------------------------------------------------------------------
285 : :
286 : 942 : bool AddressConverter::checkCol( sal_Int32 nCol, bool bTrackOverflow )
287 : : {
288 [ + - ][ + + ]: 942 : bool bValid = (0 <= nCol) && (nCol <= maMaxPos.Column);
289 [ + + ][ + - ]: 942 : if( !bValid && bTrackOverflow )
290 : 42 : mbColOverflow = true;
291 : 942 : return bValid;
292 : : }
293 : :
294 : 1047 : bool AddressConverter::checkRow( sal_Int32 nRow, bool bTrackOverflow )
295 : : {
296 [ + - ][ + - ]: 1047 : bool bValid = (0 <= nRow) && (nRow <= maMaxPos.Row);
297 [ - + ][ # # ]: 1047 : if( !bValid && bTrackOverflow )
298 : 0 : mbRowOverflow = true;
299 : 1047 : return bValid;
300 : : }
301 : :
302 : 672 : bool AddressConverter::checkTab( sal_Int16 nSheet, bool bTrackOverflow )
303 : : {
304 [ + - ][ + - ]: 672 : bool bValid = (0 <= nSheet) && (nSheet <= maMaxPos.Sheet);
305 [ - + ][ # # ]: 672 : if( !bValid && bTrackOverflow )
306 : 0 : mbTabOverflow |= (nSheet > maMaxPos.Sheet); // do not warn for deleted refs (-1)
307 : 672 : return bValid;
308 : : }
309 : :
310 : : // ----------------------------------------------------------------------------
311 : :
312 : 546 : bool AddressConverter::checkCellAddress( const CellAddress& rAddress, bool bTrackOverflow )
313 : : {
314 : : return
315 : 546 : checkTab( rAddress.Sheet, bTrackOverflow ) &&
316 : 546 : checkCol( rAddress.Column, bTrackOverflow ) &&
317 [ + - ]: 1092 : checkRow( rAddress.Row, bTrackOverflow );
[ + - + - ]
318 : : }
319 : :
320 : 552 : bool AddressConverter::convertToCellAddressUnchecked( CellAddress& orAddress,
321 : : const OUString& rString, sal_Int16 nSheet )
322 : : {
323 : 552 : orAddress.Sheet = nSheet;
324 : 552 : return parseOoxAddress2d( orAddress.Column, orAddress.Row, rString );
325 : : }
326 : :
327 : 552 : bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
328 : : const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
329 : : {
330 : : return
331 : 552 : convertToCellAddressUnchecked( orAddress, rString, nSheet ) &&
332 [ + - ][ + + ]: 552 : checkCellAddress( orAddress, bTrackOverflow );
333 : : }
334 : :
335 : 108 : CellAddress AddressConverter::createValidCellAddress(
336 : : const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
337 : : {
338 : 108 : CellAddress aAddress;
339 [ + + ]: 108 : if( !convertToCellAddress( aAddress, rString, nSheet, bTrackOverflow ) )
340 : : {
341 : 15 : aAddress.Sheet = getLimitedValue< sal_Int16, sal_Int16 >( nSheet, 0, maMaxPos.Sheet );
342 : 15 : aAddress.Column = ::std::min( aAddress.Column, maMaxPos.Column );
343 : 15 : aAddress.Row = ::std::min( aAddress.Row, maMaxPos.Row );
344 : : }
345 : 108 : return aAddress;
346 : : }
347 : :
348 : 6 : void AddressConverter::convertToCellAddressUnchecked( CellAddress& orAddress,
349 : : const BinAddress& rBinAddress, sal_Int16 nSheet )
350 : : {
351 : 6 : orAddress.Sheet = nSheet;
352 : 6 : orAddress.Column = rBinAddress.mnCol;
353 : 6 : orAddress.Row = rBinAddress.mnRow;
354 : 6 : }
355 : :
356 : 6 : bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
357 : : const BinAddress& rBinAddress, sal_Int16 nSheet, bool bTrackOverflow )
358 : : {
359 : 6 : convertToCellAddressUnchecked( orAddress, rBinAddress, nSheet );
360 : 6 : return checkCellAddress( orAddress, bTrackOverflow );
361 : : }
362 : :
363 : 6 : CellAddress AddressConverter::createValidCellAddress(
364 : : const BinAddress& rBinAddress, sal_Int16 nSheet, bool bTrackOverflow )
365 : : {
366 : 6 : CellAddress aAddress;
367 [ - + ]: 6 : if( !convertToCellAddress( aAddress, rBinAddress, nSheet, bTrackOverflow ) )
368 : : {
369 : 0 : aAddress.Sheet = getLimitedValue< sal_Int16, sal_Int16 >( nSheet, 0, maMaxPos.Sheet );
370 : 0 : aAddress.Column = getLimitedValue< sal_Int32, sal_Int32 >( rBinAddress.mnCol, 0, maMaxPos.Column );
371 : 0 : aAddress.Row = getLimitedValue< sal_Int32, sal_Int32 >( rBinAddress.mnRow, 0, maMaxPos.Row );
372 : : }
373 : 6 : return aAddress;
374 : : }
375 : :
376 : : // ----------------------------------------------------------------------------
377 : :
378 : 126 : bool AddressConverter::checkCellRange( const CellRangeAddress& rRange, bool bAllowOverflow, bool bTrackOverflow )
379 : : {
380 : : return
381 : 126 : (checkCol( rRange.EndColumn, bTrackOverflow ) || bAllowOverflow) && // bAllowOverflow after checkCol to track overflow!
382 : 126 : (checkRow( rRange.EndRow, bTrackOverflow ) || bAllowOverflow) && // bAllowOverflow after checkRow to track overflow!
383 : 126 : checkTab( rRange.Sheet, bTrackOverflow ) &&
384 : 126 : checkCol( rRange.StartColumn, bTrackOverflow ) &&
385 [ # # - + ]: 504 : checkRow( rRange.StartRow, bTrackOverflow );
[ # # + -
+ - ][ + - ]
[ - + ]
386 : : }
387 : :
388 : 126 : bool AddressConverter::validateCellRange( CellRangeAddress& orRange, bool bAllowOverflow, bool bTrackOverflow )
389 : : {
390 [ - + ]: 126 : if( orRange.StartColumn > orRange.EndColumn )
391 : 0 : ::std::swap( orRange.StartColumn, orRange.EndColumn );
392 [ - + ]: 126 : if( orRange.StartRow > orRange.EndRow )
393 : 0 : ::std::swap( orRange.StartRow, orRange.EndRow );
394 [ - + ]: 126 : if( !checkCellRange( orRange, bAllowOverflow, bTrackOverflow ) )
395 : 0 : return false;
396 [ - + ]: 126 : if( orRange.EndColumn > maMaxPos.Column )
397 : 0 : orRange.EndColumn = maMaxPos.Column;
398 [ - + ]: 126 : if( orRange.EndRow > maMaxPos.Row )
399 : 0 : orRange.EndRow = maMaxPos.Row;
400 : 126 : return true;
401 : : }
402 : :
403 : 219 : bool AddressConverter::convertToCellRangeUnchecked( CellRangeAddress& orRange,
404 : : const OUString& rString, sal_Int16 nSheet )
405 : : {
406 : 219 : orRange.Sheet = nSheet;
407 : 219 : return parseOoxRange2d( orRange.StartColumn, orRange.StartRow, orRange.EndColumn, orRange.EndRow, rString );
408 : : }
409 : :
410 : 153 : bool AddressConverter::convertToCellRange( CellRangeAddress& orRange,
411 : : const OUString& rString, sal_Int16 nSheet, bool bAllowOverflow, bool bTrackOverflow )
412 : : {
413 : : return
414 : 153 : convertToCellRangeUnchecked( orRange, rString, nSheet ) &&
415 [ + - ][ + + ]: 153 : validateCellRange( orRange, bAllowOverflow, bTrackOverflow );
416 : : }
417 : :
418 : 0 : void AddressConverter::convertToCellRangeUnchecked( CellRangeAddress& orRange,
419 : : const BinRange& rBinRange, sal_Int16 nSheet )
420 : : {
421 : 0 : orRange.Sheet = nSheet;
422 : 0 : orRange.StartColumn = rBinRange.maFirst.mnCol;
423 : 0 : orRange.StartRow = rBinRange.maFirst.mnRow;
424 : 0 : orRange.EndColumn = rBinRange.maLast.mnCol;
425 : 0 : orRange.EndRow = rBinRange.maLast.mnRow;
426 : 0 : }
427 : :
428 : 0 : bool AddressConverter::convertToCellRange( CellRangeAddress& orRange,
429 : : const BinRange& rBinRange, sal_Int16 nSheet, bool bAllowOverflow, bool bTrackOverflow )
430 : : {
431 : 0 : convertToCellRangeUnchecked( orRange, rBinRange, nSheet );
432 : 0 : return validateCellRange( orRange, bAllowOverflow, bTrackOverflow );
433 : : }
434 : :
435 : : // ----------------------------------------------------------------------------
436 : :
437 : 0 : void AddressConverter::validateCellRangeList( ApiCellRangeList& orRanges, bool bTrackOverflow )
438 : : {
439 [ # # ]: 0 : for( size_t nIndex = orRanges.size(); nIndex > 0; --nIndex )
440 [ # # ]: 0 : if( !validateCellRange( orRanges[ nIndex - 1 ], true, bTrackOverflow ) )
441 [ # # ][ # # ]: 0 : orRanges.erase( orRanges.begin() + nIndex - 1 );
[ # # ]
442 : 0 : }
443 : :
444 : 48 : void AddressConverter::convertToCellRangeList( ApiCellRangeList& orRanges,
445 : : const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
446 : : {
447 : 48 : sal_Int32 nPos = 0;
448 : 48 : sal_Int32 nLen = rString.getLength();
449 : 48 : CellRangeAddress aRange;
450 [ + + ][ + - ]: 96 : while( (0 <= nPos) && (nPos < nLen) )
[ + + ]
451 : : {
452 : 48 : OUString aToken = rString.getToken( 0, ' ', nPos );
453 [ + - ][ + - ]: 48 : if( !aToken.isEmpty() && convertToCellRange( aRange, aToken, nSheet, true, bTrackOverflow ) )
[ + - ][ + - ]
454 [ + - ]: 48 : orRanges.push_back( aRange );
455 : 48 : }
456 : 48 : }
457 : :
458 : 0 : void AddressConverter::convertToCellRangeList( ApiCellRangeList& orRanges,
459 : : const BinRangeList& rBinRanges, sal_Int16 nSheet, bool bTrackOverflow )
460 : : {
461 : 0 : CellRangeAddress aRange;
462 [ # # ][ # # ]: 0 : for( BinRangeList::const_iterator aIt = rBinRanges.begin(), aEnd = rBinRanges.end(); aIt != aEnd; ++aIt )
463 [ # # ]: 0 : if( convertToCellRange( aRange, *aIt, nSheet, true, bTrackOverflow ) )
464 [ # # ]: 0 : orRanges.push_back( aRange );
465 : 0 : }
466 : :
467 : : // private --------------------------------------------------------------------
468 : :
469 : 24 : void AddressConverter::ControlCharacters::set(
470 : : sal_Unicode cThisWorkbook, sal_Unicode cExternal,
471 : : sal_Unicode cThisSheet, sal_Unicode cInternal, sal_Unicode cSameSheet )
472 : : {
473 : 24 : mcThisWorkbook = cThisWorkbook;
474 : 24 : mcExternal = cExternal;
475 : 24 : mcThisSheet = cThisSheet;
476 : 24 : mcInternal = cInternal;
477 : 24 : mcSameSheet = cSameSheet;
478 : 24 : }
479 : :
480 : 24 : void AddressConverter::initializeMaxPos(
481 : : sal_Int16 nMaxXlsTab, sal_Int32 nMaxXlsCol, sal_Int32 nMaxXlsRow )
482 : : {
483 : 24 : maMaxXlsPos.Sheet = nMaxXlsTab;
484 : 24 : maMaxXlsPos.Column = nMaxXlsCol;
485 : 24 : maMaxXlsPos.Row = nMaxXlsRow;
486 : :
487 : : // maximum cell position in Calc
488 : : try
489 : : {
490 [ + - ][ + - ]: 24 : Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
[ + - ][ + - ]
491 [ + - ][ + - ]: 24 : Reference< XCellRangeAddressable > xAddressable( xSheetsIA->getByIndex( 0 ), UNO_QUERY_THROW );
[ + - ]
492 [ + - ][ + - ]: 24 : CellRangeAddress aRange = xAddressable->getRangeAddress();
493 : 24 : maMaxApiPos = CellAddress( API_MAXTAB, aRange.EndColumn, aRange.EndRow );
494 [ + - ][ + - ]: 24 : maMaxPos = getBaseFilter().isImportFilter() ? maMaxApiPos : maMaxXlsPos;
[ # # ][ + - ]
495 : : }
496 : 0 : catch( Exception& )
497 : : {
498 : : OSL_FAIL( "AddressConverter::AddressConverter - cannot get sheet limits" );
499 : : }
500 : 24 : }
501 : :
502 : : // ============================================================================
503 : :
504 : : } // namespace xls
505 [ + - ][ + - ]: 24 : } // namespace oox
506 : :
507 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|