1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SC_SOURCE_FILTER_INC_ADDRESSCONVERTER_HXX
21 #define INCLUDED_SC_SOURCE_FILTER_INC_ADDRESSCONVERTER_HXX
24 #include <com/sun/star/table/CellAddress.hpp>
25 #include <com/sun/star/table/CellRangeAddress.hpp>
26 #include "workbookhelper.hxx"
31 class BiffInputStream
;
33 /** A vector of com.sun.star.table.CellRangeAddress elements and additional
35 class ApiCellRangeList
38 inline explicit ApiCellRangeList() : mvAddresses() {}
40 size_t size() const { return mvAddresses
.size(); }
42 bool empty() const { return mvAddresses
.empty(); }
44 const css::table::CellRangeAddress
& front() const
45 { return mvAddresses
.front(); }
47 css::table::CellRangeAddress
& operator[]( size_t i
)
48 { return mvAddresses
[ i
]; }
50 ::std::vector
< css::table::CellRangeAddress
>::const_iterator
begin() const
51 { return mvAddresses
.begin(); }
52 ::std::vector
< css::table::CellRangeAddress
>::iterator
begin()
53 { return mvAddresses
.begin(); }
55 ::std::vector
< css::table::CellRangeAddress
>::const_iterator
end() const
56 { return mvAddresses
.end(); }
58 ::std::vector
< css::table::CellRangeAddress
>::reverse_iterator
rbegin()
59 { return mvAddresses
.rbegin(); }
61 ::std::vector
< css::table::CellRangeAddress
>::reverse_iterator
rend()
62 { return mvAddresses
.rend(); }
64 void clear() { mvAddresses
.clear(); }
66 void erase( ::std::vector
< css::table::CellRangeAddress
>::iterator it
)
67 { mvAddresses
.erase( it
); }
69 void pop_back() { mvAddresses
.pop_back(); }
71 void push_back( const css::table::CellRangeAddress
& rAddress
)
72 { mvAddresses
.push_back( rAddress
); }
74 /** Returns the base address of this range list (top-left cell of first range). */
75 ScAddress
getBaseAddress() const;
77 /** Converts to a sequence. */
78 css::uno::Sequence
< css::table::CellRangeAddress
>
82 ::std::vector
< css::table::CellRangeAddress
> mvAddresses
;
85 /** A 2D cell address struct for binary filters. */
91 inline explicit BinAddress() : mnCol( 0 ), mnRow( 0 ) {}
92 inline explicit BinAddress( sal_Int32 nCol
, sal_Int32 nRow
) : mnCol( nCol
), mnRow( nRow
) {}
93 inline explicit BinAddress( const css::table::CellAddress
& rAddr
) : mnCol( rAddr
.Column
), mnRow( rAddr
.Row
) {}
94 inline explicit BinAddress( const ScAddress
& rAddr
) : mnCol( rAddr
.Col() ), mnRow( rAddr
.Row() ) {}
96 void read( SequenceInputStream
& rStrm
);
97 void read( BiffInputStream
& rStrm
);
100 inline bool operator<( const BinAddress
& rL
, const BinAddress
& rR
)
102 return (rL
.mnCol
< rR
.mnCol
) || ((rL
.mnCol
== rR
.mnCol
) && (rL
.mnRow
< rR
.mnRow
));
105 inline SequenceInputStream
& operator>>( SequenceInputStream
& rStrm
, BinAddress
& orPos
)
111 inline BiffInputStream
& operator>>( BiffInputStream
& rStrm
, BinAddress
& orPos
)
117 /** A 2D cell range address struct for binary filters. */
123 void read( SequenceInputStream
& rStrm
);
124 void read( BiffInputStream
& rStrm
);
127 inline SequenceInputStream
& operator>>( SequenceInputStream
& rStrm
, BinRange
& orRange
)
129 orRange
.read( rStrm
);
133 inline BiffInputStream
& operator>>( BiffInputStream
& rStrm
, BinRange
& orRange
)
135 orRange
.read( rStrm
);
139 /** A 2D cell range address list for binary filters. */
143 inline explicit BinRangeList() : mvRanges() {}
145 ::std::vector
< BinRange
>::const_iterator
begin() const { return mvRanges
.begin(); }
146 ::std::vector
< BinRange
>::const_iterator
end() const { return mvRanges
.end(); }
148 void read( SequenceInputStream
& rStrm
);
151 ::std::vector
< BinRange
> mvRanges
;
154 inline SequenceInputStream
& operator>>( SequenceInputStream
& rStrm
, BinRangeList
& orRanges
)
156 orRanges
.read( rStrm
);
160 /** Different target types that can be encoded in a BIFF URL. */
163 BIFF_TARGETTYPE_URL
, /// URL, URL with sheet name, or sheet name.
164 BIFF_TARGETTYPE_SAMESHEET
, /// Target for special '!A1' syntax to refer to current sheet.
165 BIFF_TARGETTYPE_LIBRARY
, /// Library directory in application installation.
166 BIFF_TARGETTYPE_DDE_OLE
, /// DDE server/topic or OLE class/target.
167 BIFF_TARGETTYPE_UNKNOWN
/// Unknown/unsupported target type.
170 /** Converter for cell addresses and cell ranges for OOXML and BIFF filters.
172 class AddressConverter
: public WorkbookHelper
175 explicit AddressConverter( const WorkbookHelper
& rHelper
);
177 /** Tries to parse the passed string for a 2d cell address in A1 notation.
179 This function accepts all strings that match the regular expression
180 "[a-zA-Z]{1,6}0*[1-9][0-9]{0,8}" (without quotes), i.e. 1 to 6 letters
181 for the column index (translated to 0-based column indexes from 0 to
182 321,272,405), and 1 to 9 digits for the 1-based row index (translated
183 to 0-based row indexes from 0 to 999,999,998). The row number part may
184 contain leading zeros, they will be ignored. It is up to the caller to
185 handle cell addresses outside of a specific valid range (e.g. the
188 @param ornColumn (out-parameter) Returns the converted column index.
189 @param ornRow (out-parameter) returns the converted row index.
190 @param rString The string containing the cell address.
191 @param nStart Start index of string part in rString to be parsed.
192 @param nLength Length of string part in rString to be parsed.
194 @return true = Parsed string was valid, returned values can be used.
196 static bool parseOoxAddress2d(
197 sal_Int32
& ornColumn
, sal_Int32
& ornRow
,
198 const OUString
& rString
,
199 sal_Int32 nStart
= 0,
200 sal_Int32 nLength
= SAL_MAX_INT32
);
202 static bool parseOoxAddress2d(
203 sal_Int32
& ornColumn
, sal_Int32
& ornRow
, const char* pStr
);
205 /** Tries to parse the passed string for a 2d cell range in A1 notation.
207 This function accepts all strings that match the regular expression
208 "ADDR(:ADDR)?" (without quotes), where ADDR is a cell address accepted
209 by the parseOoxAddress2d() function of this class. It is up to the
210 caller to handle cell ranges outside of a specific valid range (e.g.
211 the entire spreadsheet).
213 @param ornStartColumn (out-parameter) Returns the converted start column index.
214 @param ornStartRow (out-parameter) returns the converted start row index.
215 @param ornEndColumn (out-parameter) Returns the converted end column index.
216 @param ornEndRow (out-parameter) returns the converted end row index.
217 @param rString The string containing the cell address.
218 @param nStart Start index of string part in rString to be parsed.
220 @return true = Parsed string was valid, returned values can be used.
222 static bool parseOoxRange2d(
223 sal_Int32
& ornStartColumn
, sal_Int32
& ornStartRow
,
224 sal_Int32
& ornEndColumn
, sal_Int32
& ornEndRow
,
225 const OUString
& rString
,
226 sal_Int32 nStart
= 0 );
228 /** Returns the biggest valid cell address in the own Calc document. */
229 inline const ScAddress
&
230 getMaxApiAddress() const { return maMaxApiPos
; }
232 /** Returns the biggest valid cell address in the imported/exported
234 inline const ScAddress
&
235 getMaxXlsAddress() const { return maMaxXlsPos
; }
237 /** Returns the biggest valid cell address in both Calc and the
238 imported/exported Excel document. */
239 inline const ScAddress
&
240 getMaxAddress() const { return maMaxPos
; }
242 /** Checks if the passed column index is valid.
244 @param nCol The column index to check.
245 @param bTrackOverflow true = Update the internal overflow flag, if the
246 column index is outside of the supported limits.
247 @return true = Passed column index is valid (no index overflow).
249 bool checkCol( sal_Int32 nCol
, bool bTrackOverflow
);
251 /** Checks if the passed row index is valid.
253 @param nRow The row index to check.
254 @param bTrackOverflow true = Update the internal overflow flag, if the
255 row index is outside of the supported limits.
256 @return true = Passed row index is valid (no index overflow).
258 bool checkRow( sal_Int32 nRow
, bool bTrackOverflow
);
260 /** Checks if the passed sheet index is valid.
262 @param nSheet The sheet index to check.
263 @param bTrackOverflow true = Update the internal overflow flag, if the
264 sheet index is outside of the supported limits.
265 @return true = Passed sheet index is valid (no index overflow).
267 bool checkTab( sal_Int16 nSheet
, bool bTrackOverflow
);
269 /** Checks the passed cell address if it fits into the spreadsheet limits.
271 @param rAddress The cell address to be checked.
272 @param bTrackOverflow true = Update the internal overflow flags, if
273 the address is outside of the supported sheet limits.
274 @return true = Passed address is valid (no index overflow).
276 bool checkCellAddress(
277 const css::table::CellAddress
& rAddress
,
278 bool bTrackOverflow
);
280 /** Checks the passed cell address if it fits into the spreadsheet limits.
282 @param rAddress The cell address to be checked.
283 @param bTrackOverflow true = Update the internal overflow flags, if
284 the address is outside of the supported sheet limits.
285 @return true = Passed address is valid (no index overflow).
287 bool checkCellAddress(
288 const ScAddress
& rAddress
,
289 bool bTrackOverflow
);
291 /** Converts the passed string to a single cell address, without checking
294 @param orAddress (out-parameter) Returns the converted cell address.
295 @param rString Cell address string in A1 notation.
296 @param nSheet Sheet index to be inserted into orAddress.
297 @return true = Cell address could be parsed from the passed string.
299 static bool convertToCellAddressUnchecked(
300 css::table::CellAddress
& orAddress
,
301 const OUString
& rString
,
304 /** Converts the passed string to a single cell address, without checking
307 @param orAddress (out-parameter) Returns the converted cell address.
308 @param rString Cell address string in A1 notation.
309 @param nSheet Sheet index to be inserted into orAddress.
310 @return true = Cell address could be parsed from the passed string.
312 static bool convertToCellAddressUnchecked(
313 ScAddress
& orAddress
,
314 const OUString
& rString
,
317 static bool convertToCellAddressUnchecked(
318 css::table::CellAddress
& orAddress
, const char* pStr
, sal_Int16 nSheet
);
320 static bool convertToCellAddressUnchecked(
321 ScAddress
& orAddress
, const char* pStr
, sal_Int16 nSheet
);
323 /** Tries to convert the passed string to a single cell address.
325 @param orAddress (out-parameter) Returns the converted cell address.
326 @param rString Cell address string in A1 notation.
327 @param nSheet Sheet index to be inserted into orAddress (will be checked).
328 @param bTrackOverflow true = Update the internal overflow flags, if
329 the address is outside of the supported sheet limits.
330 @return true = Converted address is valid (no index overflow).
332 bool convertToCellAddress(
333 ScAddress
& orAddress
,
334 const OUString
& rString
,
336 bool bTrackOverflow
);
338 bool convertToCellAddress(
340 const char* pStr
, sal_Int16 nSheet
, bool bTrackOverflow
);
342 /** Returns a valid cell address by moving it into allowed dimensions.
344 @param rString Cell address string in A1 notation.
345 @param nSheet Sheet index for the returned address (will be checked).
346 @param bTrackOverflow true = Update the internal overflow flags, if
347 the address is outside of the supported sheet limits.
348 @return A valid API cell address struct. */
349 ScAddress
createValidCellAddress(
350 const OUString
& rString
,
352 bool bTrackOverflow
);
354 /** Converts the passed address to a single cell address, without checking
357 @param orAddress (out-parameter) Returns the converted cell address.
358 @param rBinAddress Binary cell address struct.
359 @param nSheet Sheet index to be inserted into orAddress.
361 static void convertToCellAddressUnchecked(
362 css::table::CellAddress
& orAddress
,
363 const BinAddress
& rBinAddress
,
366 /** Converts the passed address to a single cell address, without checking
369 @param orAddress (out-parameter) Returns the converted cell address.
370 @param rBinAddress Binary cell address struct.
371 @param nSheet Sheet index to be inserted into orAddress.
373 static void convertToCellAddressUnchecked(
374 ScAddress
& orAddress
,
375 const BinAddress
& rBinAddress
,
378 /** Tries to convert the passed address to a single cell address.
380 @param orAddress (out-parameter) Returns the converted cell address.
381 @param rBinAddress Binary cell address struct.
382 @param nSheet Sheet index to be inserted into orAddress (will be checked).
383 @param bTrackOverflow true = Update the internal overflow flags, if
384 the address is outside of the supported sheet limits.
385 @return true = Converted address is valid (no index overflow).
387 bool convertToCellAddress(
388 ScAddress
& orAddress
,
389 const BinAddress
& rBinAddress
,
391 bool bTrackOverflow
);
393 /** Returns a valid cell address by moving it into allowed dimensions.
395 @param rBinAddress Binary cell address struct.
396 @param nSheet Sheet index for the returned address (will be checked).
397 @param bTrackOverflow true = Update the internal overflow flags, if
398 the address is outside of the supported sheet limits.
399 @return A valid API cell address struct. */
400 ScAddress
createValidCellAddress(
401 const BinAddress
& rBinAddress
,
403 bool bTrackOverflow
);
405 /** Checks the passed cell range if it fits into the spreadsheet limits.
407 @param rRange The cell range address to be checked.
408 @param bAllowOverflow true = Allow ranges that start inside the
409 supported sheet limits but may end outside of these limits.
410 false = Do not allow ranges that overflow the supported limits.
411 @param bTrackOverflow true = Update the internal overflow flags, if
412 the passed range contains cells outside of the supported sheet
414 @return true = Cell range is valid. This function returns also true,
415 if only parts of the range are outside the current sheet limits and
416 such an overflow is allowed via parameter bAllowOverflow. Returns
417 false, if the entire range is outside the sheet limits, or if
418 overflow is not allowed via parameter bAllowOverflow.
421 const css::table::CellRangeAddress
& rRange
,
422 bool bAllowOverflow
, bool bTrackOverflow
);
424 /** Checks the passed cell range, may try to fit it to current sheet limits.
426 First, this function reorders the column and row indexes so that the
427 starting indexes are less than or equal to the end indexes. Then,
428 depending on the parameter bAllowOverflow, the range is just checked or
429 cropped to the current sheet limits.
431 @param orRange (in-out-parameter) Converts the passed cell range
432 into a valid cell range address. If the passed range contains cells
433 outside the currently supported spreadsheet limits, it will be
434 cropped to these limits.
435 @param bAllowOverflow true = Allow ranges that start inside the
436 supported sheet limits but may end outside of these limits. The
437 cell range returned in orRange will be cropped to these limits.
438 false = Do not allow ranges that overflow the supported limits. The
439 function will return false when the range overflows the sheet limits.
440 @param bTrackOverflow true = Update the internal overflow flags, if
441 the original range contains cells outside of the supported sheet
443 @return true = Converted range address is valid. This function
444 returns also true, if overflowing ranges are allowed via parameter
445 bAllowOverflow and the range has been cropped, but still contains
446 cells inside the current sheet limits. Returns false, if the entire
447 range is outside the sheet limits or overflowing ranges are not
448 allowed via parameter bAllowOverflow.
450 bool validateCellRange(
451 css::table::CellRangeAddress
& orRange
,
452 bool bAllowOverflow
, bool bTrackOverflow
);
454 /** Converts the passed string to a cell range address, without checking
457 @param orRange (out-parameter) Returns the converted range address.
458 @param rString Cell range string in A1 notation.
459 @param nSheet Sheet index to be inserted into orRange.
460 @return true = Range address could be parsed from the passed string.
462 static bool convertToCellRangeUnchecked(
463 css::table::CellRangeAddress
& orRange
,
464 const OUString
& rString
,
467 /** Tries to convert the passed string to a cell range address.
469 @param orRange (out-parameter) Returns the converted cell range
470 address. If the original range in the passed string contains cells
471 outside the currently supported spreadsheet limits, and parameter
472 bAllowOverflow is set to true, the range will be cropped to these
473 limits. Example: the range string "A1:ZZ100000" may be converted to
474 the range A1:IV65536.
475 @param rString Cell range string in A1 notation.
476 @param nSheet Sheet index to be inserted into orRange (will be checked).
477 @param bAllowOverflow true = Allow ranges that start inside the
478 supported sheet limits but may end outside of these limits. The
479 cell range returned in orRange will be cropped to these limits.
480 false = Do not allow ranges that overflow the supported limits.
481 @param bTrackOverflow true = Update the internal overflow flags, if
482 the original range contains cells outside of the supported sheet
484 @return true = Converted and returned range is valid. This function
485 returns also true, if overflowing ranges are allowed via parameter
486 bAllowOverflow and the range has been cropped, but still contains
487 cells inside the current sheet limits. Returns false, if the entire
488 range is outside the sheet limits or overflowing ranges are not
489 allowed via parameter bAllowOverflow.
491 bool convertToCellRange(
492 css::table::CellRangeAddress
& orRange
,
493 const OUString
& rString
,
495 bool bAllowOverflow
, bool bTrackOverflow
);
497 /** Converts the passed range to a cell range address, without checking any
500 @param orRange (out-parameter) Returns the converted range address.
501 @param rBinRange Binary cell range struct.
502 @param nSheet Sheet index to be inserted into orRange.
504 static void convertToCellRangeUnchecked(
505 css::table::CellRangeAddress
& orRange
,
506 const BinRange
& rBinRange
,
509 /** Tries to convert the passed range to a cell range address.
511 @param orRange (out-parameter) Returns the converted cell range
512 address. If the passed original range contains cells outside the
513 currently supported spreadsheet limits, and parameter bAllowOverflow
514 is set to true, the range will be cropped to these limits.
515 @param rBinRange Binary cell range struct.
516 @param nSheet Sheet index to be inserted into orRange (will be checked).
517 @param bAllowOverflow true = Allow ranges that start inside the
518 supported sheet limits but may end outside of these limits. The
519 cell range returned in orRange will be cropped to these limits.
520 false = Do not allow ranges that overflow the supported limits.
521 @param bTrackOverflow true = Update the internal overflow flags, if
522 the original range contains cells outside of the supported sheet
524 @return true = Converted and returned range is valid. This function
525 returns also true, if overflowing ranges are allowed via parameter
526 bAllowOverflow and the range has been cropped, but still contains
527 cells inside the current sheet limits. Returns false, if the entire
528 range is outside the sheet limits or if overflowing ranges are not
529 allowed via parameter bAllowOverflow.
531 bool convertToCellRange(
532 css::table::CellRangeAddress
& orRange
,
533 const BinRange
& rBinRange
,
535 bool bAllowOverflow
, bool bTrackOverflow
);
537 /** Tries to restrict the passed cell range list to current sheet limits.
539 @param orRanges (in-out-parameter) Restricts the cell range addresses
540 in the passed list to the current sheet limits and removes invalid
541 ranges from the list.
542 @param bTrackOverflow true = Update the internal overflow flags, if
543 the original ranges contain cells outside of the supported sheet
546 void validateCellRangeList(
547 ApiCellRangeList
& orRanges
,
548 bool bTrackOverflow
);
550 /** Tries to convert the passed string to a cell range list.
552 @param orRanges (out-parameter) Returns the converted cell range
553 addresses. If a range in the passed string contains cells outside
554 the currently supported spreadsheet limits, it will be cropped to
555 these limits. Example: the range string "A1:ZZ100000" may be
556 converted to the range A1:IV65536. If a range is completely outside
557 the limits, it will be omitted.
558 @param rString Cell range list string in A1 notation, space separated.
559 @param nSheet Sheet index to be inserted into orRanges (will be checked).
560 @param bTrackOverflow true = Update the internal overflow flags, if
561 the original ranges contain cells outside of the supported sheet
564 void convertToCellRangeList(
565 ApiCellRangeList
& orRanges
,
566 const OUString
& rString
,
568 bool bTrackOverflow
);
570 /** Tries to convert the passed range list to a cell range list.
572 @param orRanges (out-parameter) Returns the converted cell range
573 addresses. If a range in the passed string contains cells outside
574 the currently supported spreadsheet limits, it will be cropped to
575 these limits. Example: the range string "A1:ZZ100000" may be
576 converted to the range A1:IV65536. If a range is completely outside
577 the limits, it will be omitted.
578 @param rBinRanges List of binary cell range objects.
579 @param nSheet Sheet index to be inserted into orRanges (will be checked).
580 @param bTrackOverflow true = Update the internal overflow flags, if
581 the original ranges contain cells outside of the supported sheet
584 void convertToCellRangeList(
585 ApiCellRangeList
& orRanges
,
586 const BinRangeList
& rBinRanges
,
588 bool bTrackOverflow
);
591 void initializeMaxPos(
592 sal_Int16 nMaxXlsTab
, sal_Int32 nMaxXlsCol
, sal_Int32 nMaxXlsRow
);
595 struct ControlCharacters
597 sal_Unicode mcThisWorkbook
; /// Control character: Link to current workbook.
598 sal_Unicode mcExternal
; /// Control character: Link to external workbook/sheet.
599 sal_Unicode mcThisSheet
; /// Control character: Link to current sheet.
600 sal_Unicode mcInternal
; /// Control character: Link to internal sheet.
601 sal_Unicode mcSameSheet
; /// Control character: Link to same sheet (special '!A1' syntax).
604 sal_Unicode cThisWorkbook
, sal_Unicode cExternal
,
605 sal_Unicode cThisSheet
, sal_Unicode cInternal
,
606 sal_Unicode cSameSheet
);
609 ScAddress maMaxApiPos
; /// Maximum valid cell address in Calc.
610 ScAddress maMaxXlsPos
; /// Maximum valid cell address in Excel.
611 ScAddress maMaxPos
; /// Maximum valid cell address in Calc/Excel.
612 ControlCharacters maLinkChars
; /// Control characters for external link import (BIFF).
613 ControlCharacters maDConChars
; /// Control characters for DCON* record import (BIFF).
614 bool mbColOverflow
; /// Flag for "columns overflow".
615 bool mbRowOverflow
; /// Flag for "rows overflow".
616 bool mbTabOverflow
; /// Flag for "tables overflow".
624 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */