Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "addressconverter.hxx"
21 :
22 : #include <com/sun/star/container/XIndexAccess.hpp>
23 : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
24 : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
25 : #include <osl/diagnose.h>
26 : #include <rtl/strbuf.hxx>
27 : #include <rtl/ustrbuf.hxx>
28 : #include <oox/core/filterbase.hxx>
29 : #include <oox/helper/containerhelper.hxx>
30 : #include "biffinputstream.hxx"
31 :
32 : namespace oox {
33 : namespace xls {
34 :
35 : using namespace ::com::sun::star::container;
36 : using namespace ::com::sun::star::sheet;
37 : using namespace ::com::sun::star::table;
38 : using namespace ::com::sun::star::uno;
39 :
40 : namespace {
41 :
42 : //! TODO: this limit may change, is there a way to obtain it via API?
43 : const sal_Int16 API_MAXTAB = MAXTAB;
44 :
45 : const sal_Int32 OOX_MAXCOL = static_cast< sal_Int32 >( (1 << 14) - 1 );
46 : const sal_Int32 OOX_MAXROW = static_cast< sal_Int32 >( (1 << 20) - 1 );
47 : const sal_Int16 OOX_MAXTAB = static_cast< sal_Int16 >( (1 << 15) - 1 );
48 :
49 : const sal_Int32 BIFF2_MAXCOL = 255;
50 : const sal_Int32 BIFF2_MAXROW = 16383;
51 : const sal_Int16 BIFF2_MAXTAB = 0;
52 :
53 : const sal_Int32 BIFF3_MAXCOL = BIFF2_MAXCOL;
54 : const sal_Int32 BIFF3_MAXROW = BIFF2_MAXROW;
55 : const sal_Int16 BIFF3_MAXTAB = BIFF2_MAXTAB;
56 :
57 : const sal_Int32 BIFF4_MAXCOL = BIFF3_MAXCOL;
58 : const sal_Int32 BIFF4_MAXROW = BIFF3_MAXROW;
59 : const sal_Int16 BIFF4_MAXTAB = 32767;
60 :
61 : const sal_Int32 BIFF5_MAXCOL = BIFF4_MAXCOL;
62 : const sal_Int32 BIFF5_MAXROW = BIFF4_MAXROW;
63 : const sal_Int16 BIFF5_MAXTAB = BIFF4_MAXTAB;
64 :
65 : const sal_Int32 BIFF8_MAXCOL = BIFF5_MAXCOL;
66 : const sal_Int32 BIFF8_MAXROW = 65535;
67 : const sal_Int16 BIFF8_MAXTAB = BIFF5_MAXTAB;
68 :
69 : } // namespace
70 :
71 272 : CellAddress ApiCellRangeList::getBaseAddress() const
72 : {
73 272 : if( mvAddresses.empty() )
74 0 : return CellAddress();
75 272 : return CellAddress( mvAddresses.front().Sheet, mvAddresses.front().StartColumn, mvAddresses.front().StartRow );
76 : }
77 :
78 0 : com::sun::star::uno::Sequence< CellRangeAddress > ApiCellRangeList::toSequence() const
79 : {
80 0 : return ContainerHelper::vectorToSequence( mvAddresses );
81 : }
82 :
83 0 : void BinAddress::read( SequenceInputStream& rStrm )
84 : {
85 0 : rStrm >> mnRow >> mnCol;
86 0 : }
87 :
88 0 : void BinAddress::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
89 : {
90 0 : mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
91 0 : mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
92 0 : }
93 :
94 0 : void BinRange::read( SequenceInputStream& rStrm )
95 : {
96 0 : rStrm >> maFirst.mnRow >> maLast.mnRow >> maFirst.mnCol >> maLast.mnCol;
97 0 : }
98 :
99 0 : void BinRange::read( BiffInputStream& rStrm, bool bCol16Bit, bool bRow32Bit )
100 : {
101 0 : maFirst.mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
102 0 : maLast.mnRow = bRow32Bit ? rStrm.readInt32() : rStrm.readuInt16();
103 0 : maFirst.mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
104 0 : maLast.mnCol = bCol16Bit ? rStrm.readuInt16() : rStrm.readuInt8();
105 0 : }
106 :
107 0 : void BinRangeList::read( SequenceInputStream& rStrm )
108 : {
109 0 : sal_Int32 nCount = rStrm.readInt32();
110 0 : mvRanges.resize( getLimitedValue< size_t, sal_Int64 >( nCount, 0, rStrm.getRemaining() / 16 ) );
111 0 : for( ::std::vector< BinRange >::iterator aIt = mvRanges.begin(), aEnd = mvRanges.end(); aIt != aEnd; ++aIt )
112 0 : aIt->read( rStrm );
113 0 : }
114 :
115 128 : AddressConverter::AddressConverter( const WorkbookHelper& rHelper ) :
116 : WorkbookHelper( rHelper ),
117 : mbColOverflow( false ),
118 : mbRowOverflow( false ),
119 128 : mbTabOverflow( false )
120 : {
121 128 : maDConChars.set( 0xFFFF, '\x01', 0xFFFF, '\x02', 0xFFFF );
122 128 : switch( getFilterType() )
123 : {
124 : case FILTER_OOXML:
125 128 : initializeMaxPos( OOX_MAXTAB, OOX_MAXCOL, OOX_MAXROW );
126 128 : maLinkChars.set( 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF );
127 128 : break;
128 0 : case FILTER_BIFF: switch( getBiff() )
129 : {
130 : case BIFF2:
131 0 : initializeMaxPos( BIFF2_MAXTAB, BIFF2_MAXCOL, BIFF2_MAXROW );
132 0 : maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, 0xFFFF );
133 0 : break;
134 : case BIFF3:
135 0 : initializeMaxPos( BIFF3_MAXTAB, BIFF3_MAXCOL, BIFF3_MAXROW );
136 0 : maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, 0xFFFF );
137 0 : break;
138 : case BIFF4:
139 0 : initializeMaxPos( BIFF4_MAXTAB, BIFF4_MAXCOL, BIFF4_MAXROW );
140 0 : maLinkChars.set( 0xFFFF, '\x01', '\x02', 0xFFFF, '\x00' );
141 0 : break;
142 : case BIFF5:
143 0 : initializeMaxPos( BIFF5_MAXTAB, BIFF5_MAXCOL, BIFF5_MAXROW );
144 0 : maLinkChars.set( '\x04', '\x01', '\x02', '\x03', '\x00' );
145 0 : break;
146 : case BIFF8:
147 0 : initializeMaxPos( BIFF8_MAXTAB, BIFF8_MAXCOL, BIFF8_MAXROW );
148 0 : maLinkChars.set( '\x04', '\x01', 0xFFFF, '\x02', '\x00' );
149 0 : break;
150 0 : case BIFF_UNKNOWN: break;
151 : }
152 0 : break;
153 : case FILTER_UNKNOWN:
154 0 : initializeMaxPos( 0, 0, 0 );
155 0 : maLinkChars.set( 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF );
156 0 : break;
157 : }
158 128 : }
159 :
160 1710 : bool AddressConverter::parseOoxAddress2d(
161 : sal_Int32& ornColumn, sal_Int32& ornRow,
162 : const OUString& rString, sal_Int32 nStart, sal_Int32 nLength )
163 : {
164 1710 : ornColumn = ornRow = 0;
165 1710 : if( (nStart < 0) || (nStart >= rString.getLength()) || (nLength < 2) )
166 144 : return false;
167 :
168 1566 : const sal_Unicode* pcChar = rString.getStr() + nStart;
169 1566 : const sal_Unicode* pcEndChar = pcChar + ::std::min( nLength, rString.getLength() - nStart );
170 :
171 1566 : enum { STATE_COL, STATE_ROW } eState = STATE_COL;
172 8360 : while( pcChar < pcEndChar )
173 : {
174 5228 : sal_Unicode cChar = *pcChar;
175 5228 : switch( eState )
176 : {
177 : case STATE_COL:
178 : {
179 3132 : if( ('a' <= cChar) && (cChar <= 'z') )
180 0 : (cChar -= 'a') += 'A';
181 3132 : if( ('A' <= cChar) && (cChar <= 'Z') )
182 : {
183 : /* Return, if 1-based column index is already 6 characters
184 : long (12356631 is column index for column AAAAAA). */
185 1566 : if( ornColumn >= 12356631 )
186 0 : return false;
187 1566 : (ornColumn *= 26) += (cChar - 'A' + 1);
188 : }
189 1566 : else if( ornColumn > 0 )
190 : {
191 1566 : --pcChar;
192 1566 : eState = STATE_ROW;
193 : }
194 : else
195 0 : return false;
196 : }
197 3132 : break;
198 :
199 : case STATE_ROW:
200 : {
201 2096 : if( ('0' <= cChar) && (cChar <= '9') )
202 : {
203 : // return, if 1-based row is already 9 digits long
204 2096 : if( ornRow >= 100000000 )
205 0 : return false;
206 2096 : (ornRow *= 10) += (cChar - '0');
207 : }
208 : else
209 0 : return false;
210 : }
211 2096 : break;
212 : }
213 5228 : ++pcChar;
214 : }
215 :
216 1566 : --ornColumn;
217 1566 : --ornRow;
218 1566 : return (ornColumn >= 0) && (ornRow >= 0);
219 : }
220 :
221 13158 : bool AddressConverter::parseOoxAddress2d( sal_Int32& ornColumn, sal_Int32& ornRow, const char* pStr )
222 : {
223 13158 : ornColumn = ornRow = 0;
224 :
225 13158 : enum { STATE_COL, STATE_ROW } eState = STATE_COL;
226 :
227 75806 : while (*pStr)
228 : {
229 49490 : char cChar = *pStr;
230 49490 : switch( eState )
231 : {
232 : case STATE_COL:
233 : {
234 26316 : if( ('a' <= cChar) && (cChar <= 'z') )
235 0 : (cChar -= 'a') += 'A';
236 26316 : if( ('A' <= cChar) && (cChar <= 'Z') )
237 : {
238 : /* Return, if 1-based column index is already 6 characters
239 : long (12356631 is column index for column AAAAAA). */
240 13158 : if( ornColumn >= 12356631 )
241 0 : return false;
242 13158 : (ornColumn *= 26) += (cChar - 'A' + 1);
243 : }
244 13158 : else if( ornColumn > 0 )
245 : {
246 13158 : --pStr;
247 13158 : eState = STATE_ROW;
248 : }
249 : else
250 0 : return false;
251 : }
252 26316 : break;
253 :
254 : case STATE_ROW:
255 : {
256 23174 : if( ('0' <= cChar) && (cChar <= '9') )
257 : {
258 : // return, if 1-based row is already 9 digits long
259 23174 : if( ornRow >= 100000000 )
260 0 : return false;
261 23174 : (ornRow *= 10) += (cChar - '0');
262 : }
263 : else
264 0 : return false;
265 : }
266 23174 : break;
267 : }
268 49490 : ++pStr;
269 : }
270 :
271 13158 : --ornColumn;
272 13158 : --ornRow;
273 13158 : return (ornColumn >= 0) && (ornRow >= 0);
274 : }
275 :
276 5024 : bool AddressConverter::parseOoxRange2d(
277 : sal_Int32& ornStartColumn, sal_Int32& ornStartRow,
278 : sal_Int32& ornEndColumn, sal_Int32& ornEndRow,
279 : const OUString& rString, sal_Int32 nStart, sal_Int32 nLength )
280 : {
281 5024 : ornStartColumn = ornStartRow = ornEndColumn = ornEndRow = 0;
282 5024 : if( (nStart < 0) || (nStart >= rString.getLength()) || (nLength < 2) )
283 4246 : return false;
284 :
285 778 : sal_Int32 nEnd = nStart + ::std::min( nLength, rString.getLength() - nStart );
286 778 : sal_Int32 nColonPos = rString.indexOf( ':', nStart );
287 778 : if( (nStart < nColonPos) && (nColonPos + 1 < nEnd) )
288 : {
289 : return
290 924 : parseOoxAddress2d( ornStartColumn, ornStartRow, rString, nStart, nColonPos - nStart ) &&
291 924 : parseOoxAddress2d( ornEndColumn, ornEndRow, rString, nColonPos + 1, nLength - nColonPos - 1 );
292 : }
293 :
294 316 : if( parseOoxAddress2d( ornStartColumn, ornStartRow, rString, nStart, nLength ) )
295 : {
296 316 : ornEndColumn = ornStartColumn;
297 316 : ornEndRow = ornStartRow;
298 316 : return true;
299 : }
300 :
301 0 : return false;
302 : }
303 :
304 15920 : bool AddressConverter::checkCol( sal_Int32 nCol, bool bTrackOverflow )
305 : {
306 15920 : bool bValid = (0 <= nCol) && (nCol <= maMaxPos.Column);
307 15920 : if( !bValid && bTrackOverflow )
308 132 : mbColOverflow = true;
309 15920 : return bValid;
310 : }
311 :
312 17452 : bool AddressConverter::checkRow( sal_Int32 nRow, bool bTrackOverflow )
313 : {
314 17452 : bool bValid = (0 <= nRow) && (nRow <= maMaxPos.Row);
315 17452 : if( !bValid && bTrackOverflow )
316 0 : mbRowOverflow = true;
317 17452 : return bValid;
318 : }
319 :
320 14384 : bool AddressConverter::checkTab( sal_Int16 nSheet, bool bTrackOverflow )
321 : {
322 14384 : bool bValid = (0 <= nSheet) && (nSheet <= maMaxPos.Sheet);
323 14384 : if( !bValid && bTrackOverflow )
324 0 : mbTabOverflow |= (nSheet > maMaxPos.Sheet); // do not warn for deleted refs (-1)
325 14384 : return bValid;
326 : }
327 :
328 13546 : bool AddressConverter::checkCellAddress( const CellAddress& rAddress, bool bTrackOverflow )
329 : {
330 : return
331 27092 : checkTab( rAddress.Sheet, bTrackOverflow ) &&
332 27092 : checkCol( rAddress.Column, bTrackOverflow ) &&
333 27092 : checkRow( rAddress.Row, bTrackOverflow );
334 : }
335 :
336 470 : bool AddressConverter::convertToCellAddressUnchecked( CellAddress& orAddress,
337 : const OUString& rString, sal_Int16 nSheet )
338 : {
339 470 : orAddress.Sheet = nSheet;
340 470 : return parseOoxAddress2d( orAddress.Column, orAddress.Row, rString );
341 : }
342 :
343 13158 : bool AddressConverter::convertToCellAddressUnchecked(
344 : com::sun::star::table::CellAddress& orAddress, const char* pStr, sal_Int16 nSheet ) const
345 : {
346 13158 : orAddress.Sheet = nSheet;
347 13158 : return parseOoxAddress2d(orAddress.Column, orAddress.Row, pStr);
348 : }
349 :
350 470 : bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
351 : const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
352 : {
353 : return
354 796 : convertToCellAddressUnchecked( orAddress, rString, nSheet ) &&
355 796 : checkCellAddress( orAddress, bTrackOverflow );
356 : }
357 :
358 13158 : bool AddressConverter::convertToCellAddress(
359 : com::sun::star::table::CellAddress& rAddress,
360 : const char* pStr, sal_Int16 nSheet, bool bTrackOverflow )
361 : {
362 13158 : if (!convertToCellAddressUnchecked(rAddress, pStr, nSheet))
363 0 : return false;
364 :
365 13158 : return checkCellAddress(rAddress, bTrackOverflow);
366 : }
367 :
368 454 : CellAddress AddressConverter::createValidCellAddress(
369 : const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
370 : {
371 454 : CellAddress aAddress;
372 454 : if( !convertToCellAddress( aAddress, rString, nSheet, bTrackOverflow ) )
373 : {
374 144 : aAddress.Sheet = getLimitedValue< sal_Int16, sal_Int16 >( nSheet, 0, maMaxPos.Sheet );
375 144 : aAddress.Column = ::std::min( aAddress.Column, maMaxPos.Column );
376 144 : aAddress.Row = ::std::min( aAddress.Row, maMaxPos.Row );
377 : }
378 454 : return aAddress;
379 : }
380 :
381 50 : void AddressConverter::convertToCellAddressUnchecked( CellAddress& orAddress,
382 : const BinAddress& rBinAddress, sal_Int16 nSheet )
383 : {
384 50 : orAddress.Sheet = nSheet;
385 50 : orAddress.Column = rBinAddress.mnCol;
386 50 : orAddress.Row = rBinAddress.mnRow;
387 50 : }
388 :
389 50 : bool AddressConverter::convertToCellAddress( CellAddress& orAddress,
390 : const BinAddress& rBinAddress, sal_Int16 nSheet, bool bTrackOverflow )
391 : {
392 50 : convertToCellAddressUnchecked( orAddress, rBinAddress, nSheet );
393 50 : return checkCellAddress( orAddress, bTrackOverflow );
394 : }
395 :
396 50 : CellAddress AddressConverter::createValidCellAddress(
397 : const BinAddress& rBinAddress, sal_Int16 nSheet, bool bTrackOverflow )
398 : {
399 50 : CellAddress aAddress;
400 50 : if( !convertToCellAddress( aAddress, rBinAddress, nSheet, bTrackOverflow ) )
401 : {
402 0 : aAddress.Sheet = getLimitedValue< sal_Int16, sal_Int16 >( nSheet, 0, maMaxPos.Sheet );
403 0 : aAddress.Column = getLimitedValue< sal_Int32, sal_Int32 >( rBinAddress.mnCol, 0, maMaxPos.Column );
404 0 : aAddress.Row = getLimitedValue< sal_Int32, sal_Int32 >( rBinAddress.mnRow, 0, maMaxPos.Row );
405 : }
406 50 : return aAddress;
407 : }
408 :
409 838 : bool AddressConverter::checkCellRange( const CellRangeAddress& rRange, bool bAllowOverflow, bool bTrackOverflow )
410 : {
411 : return
412 1676 : (checkCol( rRange.EndColumn, bTrackOverflow ) || bAllowOverflow) && // bAllowOverflow after checkCol to track overflow!
413 1676 : (checkRow( rRange.EndRow, bTrackOverflow ) || bAllowOverflow) && // bAllowOverflow after checkRow to track overflow!
414 1676 : checkTab( rRange.Sheet, bTrackOverflow ) &&
415 2514 : checkCol( rRange.StartColumn, bTrackOverflow ) &&
416 1676 : checkRow( rRange.StartRow, bTrackOverflow );
417 : }
418 :
419 830 : bool AddressConverter::validateCellRange( CellRangeAddress& orRange, bool bAllowOverflow, bool bTrackOverflow )
420 : {
421 830 : if( orRange.StartColumn > orRange.EndColumn )
422 0 : ::std::swap( orRange.StartColumn, orRange.EndColumn );
423 830 : if( orRange.StartRow > orRange.EndRow )
424 0 : ::std::swap( orRange.StartRow, orRange.EndRow );
425 830 : if( !checkCellRange( orRange, bAllowOverflow, bTrackOverflow ) )
426 0 : return false;
427 830 : if( orRange.EndColumn > maMaxPos.Column )
428 0 : orRange.EndColumn = maMaxPos.Column;
429 830 : if( orRange.EndRow > maMaxPos.Row )
430 0 : orRange.EndRow = maMaxPos.Row;
431 830 : return true;
432 : }
433 :
434 5024 : bool AddressConverter::convertToCellRangeUnchecked( CellRangeAddress& orRange,
435 : const OUString& rString, sal_Int16 nSheet )
436 : {
437 5024 : orRange.Sheet = nSheet;
438 5024 : return parseOoxRange2d( orRange.StartColumn, orRange.StartRow, orRange.EndColumn, orRange.EndRow, rString );
439 : }
440 :
441 4742 : bool AddressConverter::convertToCellRange( CellRangeAddress& orRange,
442 : const OUString& rString, sal_Int16 nSheet, bool bAllowOverflow, bool bTrackOverflow )
443 : {
444 : return
445 5238 : convertToCellRangeUnchecked( orRange, rString, nSheet ) &&
446 5238 : validateCellRange( orRange, bAllowOverflow, bTrackOverflow );
447 : }
448 :
449 0 : void AddressConverter::convertToCellRangeUnchecked( CellRangeAddress& orRange,
450 : const BinRange& rBinRange, sal_Int16 nSheet )
451 : {
452 0 : orRange.Sheet = nSheet;
453 0 : orRange.StartColumn = rBinRange.maFirst.mnCol;
454 0 : orRange.StartRow = rBinRange.maFirst.mnRow;
455 0 : orRange.EndColumn = rBinRange.maLast.mnCol;
456 0 : orRange.EndRow = rBinRange.maLast.mnRow;
457 0 : }
458 :
459 0 : bool AddressConverter::convertToCellRange( CellRangeAddress& orRange,
460 : const BinRange& rBinRange, sal_Int16 nSheet, bool bAllowOverflow, bool bTrackOverflow )
461 : {
462 0 : convertToCellRangeUnchecked( orRange, rBinRange, nSheet );
463 0 : return validateCellRange( orRange, bAllowOverflow, bTrackOverflow );
464 : }
465 :
466 0 : void AddressConverter::validateCellRangeList( ApiCellRangeList& orRanges, bool bTrackOverflow )
467 : {
468 0 : for( size_t nIndex = orRanges.size(); nIndex > 0; --nIndex )
469 0 : if( !validateCellRange( orRanges[ nIndex - 1 ], true, bTrackOverflow ) )
470 0 : orRanges.erase( orRanges.begin() + nIndex - 1 );
471 0 : }
472 :
473 330 : void AddressConverter::convertToCellRangeList( ApiCellRangeList& orRanges,
474 : const OUString& rString, sal_Int16 nSheet, bool bTrackOverflow )
475 : {
476 330 : sal_Int32 nPos = 0;
477 330 : sal_Int32 nLen = rString.getLength();
478 330 : CellRangeAddress aRange;
479 990 : while( (0 <= nPos) && (nPos < nLen) )
480 : {
481 330 : OUString aToken = rString.getToken( 0, ' ', nPos );
482 330 : if( !aToken.isEmpty() && convertToCellRange( aRange, aToken, nSheet, true, bTrackOverflow ) )
483 330 : orRanges.push_back( aRange );
484 330 : }
485 330 : }
486 :
487 0 : void AddressConverter::convertToCellRangeList( ApiCellRangeList& orRanges,
488 : const BinRangeList& rBinRanges, sal_Int16 nSheet, bool bTrackOverflow )
489 : {
490 0 : CellRangeAddress aRange;
491 0 : for( ::std::vector< BinRange >::const_iterator aIt = rBinRanges.begin(), aEnd = rBinRanges.end(); aIt != aEnd; ++aIt )
492 0 : if( convertToCellRange( aRange, *aIt, nSheet, true, bTrackOverflow ) )
493 0 : orRanges.push_back( aRange );
494 0 : }
495 :
496 : // private --------------------------------------------------------------------
497 :
498 256 : void AddressConverter::ControlCharacters::set(
499 : sal_Unicode cThisWorkbook, sal_Unicode cExternal,
500 : sal_Unicode cThisSheet, sal_Unicode cInternal, sal_Unicode cSameSheet )
501 : {
502 256 : mcThisWorkbook = cThisWorkbook;
503 256 : mcExternal = cExternal;
504 256 : mcThisSheet = cThisSheet;
505 256 : mcInternal = cInternal;
506 256 : mcSameSheet = cSameSheet;
507 256 : }
508 :
509 128 : void AddressConverter::initializeMaxPos(
510 : sal_Int16 nMaxXlsTab, sal_Int32 nMaxXlsCol, sal_Int32 nMaxXlsRow )
511 : {
512 128 : maMaxXlsPos.Sheet = nMaxXlsTab;
513 128 : maMaxXlsPos.Column = nMaxXlsCol;
514 128 : maMaxXlsPos.Row = nMaxXlsRow;
515 :
516 : // maximum cell position in Calc
517 : try
518 : {
519 128 : Reference< XIndexAccess > xSheetsIA( getDocument()->getSheets(), UNO_QUERY_THROW );
520 256 : Reference< XCellRangeAddressable > xAddressable( xSheetsIA->getByIndex( 0 ), UNO_QUERY_THROW );
521 128 : CellRangeAddress aRange = xAddressable->getRangeAddress();
522 128 : maMaxApiPos = CellAddress( API_MAXTAB, aRange.EndColumn, aRange.EndRow );
523 256 : maMaxPos = getBaseFilter().isImportFilter() ? maMaxApiPos : maMaxXlsPos;
524 : }
525 0 : catch( Exception& )
526 : {
527 : OSL_FAIL( "AddressConverter::AddressConverter - cannot get sheet limits" );
528 : }
529 128 : }
530 :
531 : } // namespace xls
532 48 : } // namespace oox
533 :
534 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|