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_XETABLE_HXX
21 #define INCLUDED_SC_SOURCE_FILTER_INC_XETABLE_HXX
23 #include "xltable.hxx"
26 #include "xladdress.hxx"
27 #include "xerecord.hxx"
28 #include "xestyle.hxx"
29 #include "xlformula.hxx"
33 #include <unordered_map>
34 #include <unordered_set>
38 /* ============================================================================
39 Export of cell tables including row and column description.
40 - Managing all used and formatted cells in a sheet.
41 - Row and column properties, i.e. width/height, visibility.
42 - Find default row formatting and default column formatting.
44 ============================================================================ */
46 // Helper records for cell records
48 /** Represents a STRING record that contains the result of a string formula. */
49 class XclExpStringRec
: public XclExpRecord
52 explicit XclExpStringRec( const XclExpRoot
& rRoot
, const OUString
& rResult
);
55 virtual void WriteBody( XclExpStream
& rStrm
) override
;
58 XclExpStringRef
const mxResult
;
61 // Additional records for special formula ranges
63 /** Base record for additional range formula records (i.e. ARRAY, SHRFMLA). */
64 class XclExpRangeFmlaBase
: public XclExpRecord
67 /** Returns true, if the passed cell position is equal to own base position. */
68 bool IsBasePos( sal_uInt16 nXclCol
, sal_uInt32 nXclRow
) const;
70 /** Derived classes create the token array for a corresponding FORMULA cell record. */
71 virtual XclTokenArrayRef
CreateCellTokenArray( const XclExpRoot
& rRoot
) const = 0;
72 /** Derived classes return true, if the own formula contains volatile functions. */
73 virtual bool IsVolatile() const = 0;
76 /** Constructs the record with a single cell. */
77 explicit XclExpRangeFmlaBase(
78 sal_uInt16 nRecId
, sal_uInt32 nRecSize
, const ScAddress
& rScPos
);
79 /** Constructs the record with a cell range. */
80 explicit XclExpRangeFmlaBase(
81 sal_uInt16 nRecId
, sal_uInt32 nRecSize
, const ScRange
& rScRange
);
83 /** Extends the cell range to include the passed cell address. */
84 void Extend( const ScAddress
& rScPos
);
86 /** Writes the range address covered by this record. */
87 void WriteRangeAddress( XclExpStream
& rStrm
) const;
90 XclRange maXclRange
; /// Range described by this record.
91 XclAddress maBaseXclPos
; /// Address of base cell (first FORMULA record).
94 typedef std::shared_ptr
< XclExpRangeFmlaBase
> XclExpRangeFmlaRef
;
96 // Array formulas =============================================================
100 /** Represents an ARRAY record that contains the token array of a matrix formula.
102 An ARRAY record is stored following the first FORMULA record that is part
103 of a matrix formula. All FORMULA records of a matrix formula contain a
104 reference to the ARRAY record, while the ARRAY record contains the formula
105 token array used by all formulas.
107 class XclExpArray
: public XclExpRangeFmlaBase
110 explicit XclExpArray( const XclTokenArrayRef
& xTokArr
, const ScRange
& rScRange
);
112 /** Creates and returns the token array for a corresponding FORMULA cell record. */
113 virtual XclTokenArrayRef
CreateCellTokenArray( const XclExpRoot
& rRoot
) const override
;
114 /** Returns true, if the array formula contains volatile functions. */
115 virtual bool IsVolatile() const override
;
118 virtual void WriteBody( XclExpStream
& rStrm
) override
;
121 XclTokenArrayRef
const mxTokArr
; /// The token array of a matrix formula.
124 typedef std::shared_ptr
< XclExpArray
> XclExpArrayRef
;
126 /** Caches all ARRAY records. */
127 class XclExpArrayBuffer
: protected XclExpRoot
130 explicit XclExpArrayBuffer( const XclExpRoot
& rRoot
);
132 /** Inserts a new ARRAY record into the buffer and returns it. */
133 XclExpArrayRef
CreateArray( const ScTokenArray
& rScTokArr
, const ScRange
& rScRange
);
134 /** Tries to find an ARRAY record that corresponds to an ocMatRef token. */
135 XclExpArrayRef
FindArray( const ScTokenArray
& rScTokArr
, const ScAddress
& rBasePos
) const;
138 typedef ::std::map
< ScAddress
, XclExpArrayRef
> XclExpArrayMap
;
139 XclExpArrayMap maRecMap
; /// Map containing the ARRAY records.
142 // Shared formulas ============================================================
144 /** Represents a SHRFMLA record that contains the token array of a shared formula.
146 A SHRFMLA record is stored following the first FORMULA record that is part
147 of a shared formula. All FORMULA records of a shared formula contain a
148 reference to the SHRFMLA record, while the SHRFMLA record contains the
149 formula token array used by all formulas.
151 class XclExpShrfmla
: public XclExpRangeFmlaBase
154 /** Creates a SHRFMLA record that consists of the passed cell address only. */
155 explicit XclExpShrfmla( const XclTokenArrayRef
& xTokArr
, const ScAddress
& rScPos
);
157 /** Extends the cell range to include the passed cell address. */
158 void ExtendRange( const ScAddress
& rScPos
);
160 /** Creates and returns the token array for a corresponding FORMULA cell record. */
161 virtual XclTokenArrayRef
CreateCellTokenArray( const XclExpRoot
& rRoot
) const override
;
162 /** Returns true, if the shared formula contains volatile functions. */
163 virtual bool IsVolatile() const override
;
166 virtual void WriteBody( XclExpStream
& rStrm
) override
;
169 XclTokenArrayRef
const mxTokArr
; /// The token array of a shared formula.
170 sal_uInt8 mnUsedCount
; /// Number of FORMULA records referring to this record.
173 typedef std::shared_ptr
< XclExpShrfmla
> XclExpShrfmlaRef
;
175 /** Caches all SHRFMLA records and provides functions to update their ranges. */
176 class XclExpShrfmlaBuffer
: protected XclExpRoot
179 explicit XclExpShrfmlaBuffer( const XclExpRoot
& rRoot
);
181 /** Tries to create a new or to update an existing SHRFMLA record.
182 @return An empty reference, if the passed token array does not contain
183 a shared formula. If the token array is a shared formula, this
184 function updates its cell range to include the passed cell position,
185 if there is a SHRFMLA record for the passed token array; otherwise
186 this function creates and returns a new SHRFMLA record. */
187 XclExpShrfmlaRef
CreateOrExtendShrfmla( const ScFormulaCell
& rScCell
, const ScAddress
& rScPos
);
191 * Check for presence of token that's not allowed in Excel's shared
192 * formula. Refer to the "SharedParsedFormula" section of [MS-XLS] spec
195 bool IsValidTokenArray( const ScTokenArray
& rArray
) const;
197 typedef std::unordered_map
<const ScTokenArray
*, XclExpShrfmlaRef
> TokensType
;
198 typedef std::unordered_set
<const ScTokenArray
*> BadTokenArraysType
;
200 TokensType maRecMap
; /// Map containing the SHRFMLA records.
201 BadTokenArraysType maBadTokens
; /// shared tokens we should *not* export as SHRFMLA
204 // Multiple operations ========================================================
206 /** Represents a TABLEOP record for a multiple operations range. */
207 class XclExpTableop
: public XclExpRangeFmlaBase
210 explicit XclExpTableop( const ScAddress
& rScPos
,
211 const XclMultipleOpRefs
& rRefs
, sal_uInt8 nScMode
);
213 /** Returns true, if the cell range has been extended to the passed position.
214 @descr All references passed in rRefs must fit the ranges passed in the constructor. */
215 bool TryExtend( const ScAddress
& rScPos
, const XclMultipleOpRefs
& rRefs
);
217 /** Finalizes the record. Tests on valid cell range and reference addresses. */
220 /** Creates and returns the token array for a corresponding FORMULA cell record. */
221 virtual XclTokenArrayRef
CreateCellTokenArray( const XclExpRoot
& rRoot
) const override
;
222 /** Returns true, if the multiple operations range is volatile. */
223 virtual bool IsVolatile() const override
;
224 /** Writes the record if it is valid. */
225 virtual void Save( XclExpStream
& rStrm
) override
;
228 /** Returns true, if the passed cell position can be appended to this record. */
229 bool IsAppendable( sal_uInt16 nXclCol
, sal_uInt16 nXclRow
) const;
231 /** Writes the contents of the TABLEOP record. */
232 virtual void WriteBody( XclExpStream
& rStrm
) override
;
235 sal_uInt16 mnLastAppXclCol
;/// Column index of last appended cell.
236 sal_uInt16 mnColInpXclCol
; /// Column index of column input cell.
237 sal_uInt32 mnColInpXclRow
; /// Row index of column input cell.
238 sal_uInt16 mnRowInpXclCol
; /// Column index of row input cell.
239 sal_uInt32 mnRowInpXclRow
; /// Row index of row input cell.
240 sal_uInt8
const mnScMode
; /// Type of the multiple operation (Calc constant).
241 bool mbValid
; /// true = Contains valid references.
244 typedef std::shared_ptr
< XclExpTableop
> XclExpTableopRef
;
246 /** Contains all created TABLEOP records and supports creating or updating them. */
247 class XclExpTableopBuffer
: protected XclExpRoot
250 explicit XclExpTableopBuffer( const XclExpRoot
& rRoot
);
252 /** Tries to update an existing or to create a new TABLEOP record.
253 @return Reference to the TABLEOP record for this cell (existing or new),
254 or an empty reference, if rScTokArr does not contain a multiple
255 operations formula. */
256 XclExpTableopRef
CreateOrExtendTableop(
257 const ScTokenArray
& rScTokArr
, const ScAddress
& rScPos
);
259 /** Finalizes all contained TABLEOP records. */
263 /** Tries to create a new TABLEOP record, if rRefs contains valid references. */
264 XclExpTableopRef
TryCreate( const ScAddress
& rScPos
, const XclMultipleOpRefs
& rRefs
);
267 typedef XclExpRecordList
< XclExpTableop
> XclExpTableopList
;
268 XclExpTableopList maTableopList
; /// List of all TABLEOP records.
273 /** The base class of all cell records. */
274 class XclExpCellBase
: public XclExpRecord
277 /** Returns the (first) address of the cell(s). */
278 const XclAddress
& GetXclPos() const { return maXclPos
; }
279 /** Returns the (first) Excel column index of the cell(s). */
280 sal_uInt16
GetXclCol() const { return maXclPos
.mnCol
; }
281 /** Returns the Excel row index of the cell. */
282 sal_uInt32
GetXclRow() const { return maXclPos
.mnRow
; }
284 /** Derived classes return the column index of the last contained cell. */
285 virtual sal_uInt16
GetLastXclCol() const = 0;
286 /** Derived classes return the XF identifier of the first contained cell. */
287 virtual sal_uInt32
GetFirstXFId() const = 0;
288 /** Derived classes return true, if this record does not contain at least one valid cell. */
289 virtual bool IsEmpty() const = 0;
290 /** Derived classes return whether the cell contains multi-line text. */
291 virtual bool IsMultiLineText() const;
293 /** Derived classes try to merge the contents of the passed cell to own data. */
294 virtual bool TryMerge( const XclExpCellBase
& rCell
);
295 /** Derived classes convert the XF identifier(s) into the Excel XF index(es).
296 @param rXFIndexes The converted XF index(es) are inserted here. */
297 virtual void ConvertXFIndexes( const XclExpRoot
& rRoot
) = 0;
298 /** Derived classes for blank cells insert the Excel XF index(es) into the passed vector. */
299 virtual void GetBlankXFIndexes( ScfUInt16Vec
& rXFIndexes
) const;
300 /** Derived classes for blank cells remove unused Excel XF index(es). */
301 virtual void RemoveUnusedBlankCells( const ScfUInt16Vec
& rXFIndexes
);
304 explicit XclExpCellBase(
305 sal_uInt16 nRecId
, std::size_t nContSize
, const XclAddress
& rXclPos
);
307 /** Sets this record to a new column position. */
308 void SetXclCol( sal_uInt16 nXclCol
) { maXclPos
.mnCol
= nXclCol
; }
311 XclAddress maXclPos
; /// Address of the cell.
314 typedef std::shared_ptr
< XclExpCellBase
> XclExpCellRef
;
316 // Single cell records ========================================================
318 /** Base class for all cell records not supporting multiple contents. */
319 class XclExpSingleCellBase
: public XclExpCellBase
322 /** Returns the last column, which is equal to the first column for single cells. */
323 virtual sal_uInt16
GetLastXclCol() const override
;
324 /** Return the XF identifier of the cell. */
325 virtual sal_uInt32
GetFirstXFId() const override
;
326 /** Returns true, if this record does not contain at least one valid cell. */
327 virtual bool IsEmpty() const override
;
328 /** Converts the XF identifier into the Excel XF index. */
329 virtual void ConvertXFIndexes( const XclExpRoot
& rRoot
) override
;
330 /** Writes cell address, XF index, and calls WriteContents() for each cell. */
331 virtual void Save( XclExpStream
& rStrm
) override
;
334 explicit XclExpSingleCellBase( sal_uInt16 nRecId
, std::size_t nContSize
,
335 const XclAddress
& rXclPos
, sal_uInt32 nXFId
);
337 explicit XclExpSingleCellBase( const XclExpRoot
& rRoot
,
338 sal_uInt16 nRecId
, std::size_t nContSize
, const XclAddress
& rXclPos
,
339 const ScPatternAttr
* pPattern
, sal_Int16 nScript
, sal_uInt32 nForcedXFId
);
341 void SetContSize( std::size_t nContSize
) { mnContSize
= nContSize
; }
342 std::size_t GetContSize() const { return mnContSize
; }
344 void SetXFId( sal_uInt32 nXFId
) { maXFId
.mnXFId
= nXFId
; }
345 sal_uInt32
GetXFId() const { return maXFId
.mnXFId
; }
348 /** Writes cell address, XF index, and calls WriteContents() for each cell. */
349 virtual void WriteBody( XclExpStream
& rStrm
) override
;
350 /** Derived classes write the contents of the specified cell (without XF index). */
351 virtual void WriteContents( XclExpStream
& rStrm
) = 0;
354 XclExpXFId maXFId
; /// The XF identifier of the cell formatting.
355 std::size_t mnContSize
; /// The size of the cell contents.
358 /** Represents a NUMBER record that describes a cell with a double value. */
359 class XclExpNumberCell
: public XclExpSingleCellBase
362 explicit XclExpNumberCell( const XclExpRoot
& rRoot
, const XclAddress
& rXclPos
,
363 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
,
366 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
368 virtual void WriteContents( XclExpStream
& rStrm
) override
;
371 double const mfValue
; /// The cell value.
374 /** Represents a BOOLERR record that describes a cell with a Boolean value. */
375 class XclExpBooleanCell
: public XclExpSingleCellBase
378 explicit XclExpBooleanCell( const XclExpRoot
& rRoot
, const XclAddress
& rXclPos
,
379 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
,
382 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
384 virtual void WriteContents( XclExpStream
& rStrm
) override
;
387 bool mbValue
; /// The cell value.
390 class XclExpHyperlinkHelper
;
391 class EditTextObject
;
393 /** Represents a text cell record.
395 May contain a BIFF2-BIFF7 LABEL record for a simple string, or a BIFF2-BIFF7
396 RSTRING record for a formatted string, or a BIFF8 LABELSST string for any
397 string (simply stores a reference to the Shared String Table).
399 class XclExpLabelCell
: public XclExpSingleCellBase
402 /** Constructs the record from an unformatted Calc string cell. */
403 explicit XclExpLabelCell( const XclExpRoot
& rRoot
, const XclAddress
& rXclPos
,
404 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
,
405 const OUString
& rStr
);
407 /** Constructs the record from a formatted Calc edit cell. */
408 explicit XclExpLabelCell( const XclExpRoot
& rRoot
, const XclAddress
& rXclPos
,
409 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
,
410 const EditTextObject
* pEditText
, XclExpHyperlinkHelper
& rHlinkHelper
);
412 /** Returns true if the cell contains multi-line text. */
413 virtual bool IsMultiLineText() const override
;
415 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
417 /** Initializes the record contents. Called from constructors. */
418 void Init( const XclExpRoot
& rRoot
,
419 const ScPatternAttr
* pPattern
, XclExpStringRef
const & xText
);
421 virtual void WriteContents( XclExpStream
& rStrm
) override
;
424 XclExpStringRef mxText
; /// The cell text.
425 sal_uInt32 mnSstIndex
; /// Index into Shared String Table (only used for BIFF8).
426 bool mbLineBreak
; /// True = cell has automatic linebreaks enabled.
431 /** Represents a FORMULA record that describes a cell with a formula. */
432 class XclExpFormulaCell
: public XclExpSingleCellBase
435 explicit XclExpFormulaCell( const XclExpRoot
& rRoot
, const XclAddress
& rXclPos
,
436 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
,
437 const ScFormulaCell
& rScFmlaCell
,
438 XclExpArrayBuffer
& rArrayBfr
,
439 XclExpShrfmlaBuffer
& rShrfmlaBfr
,
440 XclExpTableopBuffer
& rTableopBfr
);
442 /** Writes the FORMULA record and additional records related to the formula. */
443 virtual void Save( XclExpStream
& rStrm
) override
;
444 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
447 virtual void WriteContents( XclExpStream
& rStrm
) override
;
450 ScFormulaCell
& mrScFmlaCell
; /// The Calc formula cell.
451 XclTokenArrayRef mxTokArr
; /// The token array of the formula.
452 XclExpRangeFmlaRef mxAddRec
; /// Additional record for matrix/shared formulas.
453 XclExpRecordRef mxStringRec
; /// STRING record for string result.
456 // Multiple cell records ======================================================
458 struct XclExpMultiXFId
: public XclExpXFId
460 sal_uInt16 mnCount
; /// Number of XF identifiers.
462 explicit XclExpMultiXFId( sal_uInt32 nXFId
, sal_uInt16 nCount
= 1 ) :
463 XclExpXFId( nXFId
), mnCount( nCount
) {}
466 /** Base class for all cell records supporting multiple contents. */
467 class XclExpMultiCellBase
: public XclExpCellBase
470 /** Returns the column index of the last cell this record describes. */
471 virtual sal_uInt16
GetLastXclCol() const override
;
472 /** Return the XF identifier of the first contained cell. */
473 virtual sal_uInt32
GetFirstXFId() const override
;
474 /** Returns true, if this record does not contain at least one valid cell. */
475 virtual bool IsEmpty() const override
;
477 /** Convert all XF identifiers into the Excel XF indexes. */
478 virtual void ConvertXFIndexes( const XclExpRoot
& rRoot
) override
;
479 /** Writes the record, calls WriteContents() for each contained cell.
480 @descr May write several records, if unused XF indexes are contained. */
481 virtual void Save( XclExpStream
& rStrm
) override
;
482 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
485 explicit XclExpMultiCellBase( sal_uInt16 nRecId
, sal_uInt16 nMulRecId
,
486 std::size_t nContSize
, const XclAddress
& rXclPos
);
488 /** Returns the number of cells this record represents. */
489 sal_uInt16
GetCellCount() const;
491 /** Appends the passed XF identifier nCount times to the list of XF identifiers. */
492 void AppendXFId( const XclExpMultiXFId
& rXFId
);
493 /** Appends the passed cell format nCount times to the list of XF identifiers. */
494 void AppendXFId( const XclExpRoot
& rRoot
,
495 const ScPatternAttr
* pPattern
, sal_uInt16 nScript
,
496 sal_uInt32 nForcedXFId
, sal_uInt16 nCount
= 1 );
498 /** Tries to merge the XF ID list of the passed cell with the own list. */
499 bool TryMergeXFIds( const XclExpMultiCellBase
& rCell
);
500 /** Inserts the Excel XF index(es) into the passed vector. */
501 void GetXFIndexes( ScfUInt16Vec
& rXFIndexes
) const;
503 /** Removes unused Excel XF index(es).
504 @param rXFIndexes Specifies which XF indexes are used. */
505 void RemoveUnusedXFIndexes( const ScfUInt16Vec
& rXFIndexes
);
508 /** Derived classes write the remaining contents of the specified cell (without XF index).
509 @param nRelCol Relative column index (starts with 0 for first cell of this record). */
510 virtual void WriteContents( XclExpStream
& rStrm
, sal_uInt16 nRelCol
) = 0;
511 virtual void WriteXmlContents( XclExpXmlStream
& rStrm
, const XclAddress
& rAddress
, sal_uInt32 nXFId
, sal_uInt16 nRelCol
) = 0;
514 typedef ::std::vector
< XclExpMultiXFId
> XclExpMultiXFIdDeq
;
516 sal_uInt16
const mnMulRecId
; /// Record ID for multiple record variant.
517 std::size_t const mnContSize
; /// Data size of contents for one cell
518 XclExpMultiXFIdDeq maXFIds
; /// The XF identifiers of the cell formatting.
521 /** Represents a BLANK or MULBLANK record that describes empty but formatted cells. */
522 class XclExpBlankCell
: public XclExpMultiCellBase
525 explicit XclExpBlankCell( const XclAddress
& rXclPos
, const XclExpMultiXFId
& rXFId
);
527 explicit XclExpBlankCell( const XclExpRoot
& rRoot
,
528 const XclAddress
& rXclPos
, sal_uInt16 nLastXclCol
,
529 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
);
531 /** Tries to merge the contents of the passed cell to own data. */
532 virtual bool TryMerge( const XclExpCellBase
& rCell
) override
;
533 /** Inserts the Excel XF index(es) into the passed vector. */
534 virtual void GetBlankXFIndexes( ScfUInt16Vec
& rXFIndexes
) const override
;
535 /** Tries to remove unused Excel XF index(es). */
536 virtual void RemoveUnusedBlankCells( const ScfUInt16Vec
& rXFIndexes
) override
;
539 /** Writes the remaining contents of the specified cell (without XF index). */
540 virtual void WriteContents( XclExpStream
& rStrm
, sal_uInt16 nRelCol
) override
;
541 virtual void WriteXmlContents( XclExpXmlStream
& rStrm
, const XclAddress
& rAddress
, sal_uInt32 nXFId
, sal_uInt16 nRelCol
) override
;
544 /** Represents an RK or MULRK record that describes cells with a compressed double values. */
545 class XclExpRkCell
: public XclExpMultiCellBase
548 explicit XclExpRkCell( const XclExpRoot
& rRoot
, const XclAddress
& rXclPos
,
549 const ScPatternAttr
* pPattern
, sal_uInt32 nForcedXFId
,
550 sal_Int32 nRkValue
);
552 /** Tries to merge the contents of the passed cell to own data. */
553 virtual bool TryMerge( const XclExpCellBase
& rCell
) override
;
556 /** Writes the remaining contents of the specified cell (without XF index). */
557 virtual void WriteContents( XclExpStream
& rStrm
, sal_uInt16 nRelCol
) override
;
558 virtual void WriteXmlContents( XclExpXmlStream
& rStrm
, const XclAddress
& rAddress
, sal_uInt32 nXFId
, sal_uInt16 nRelCol
) override
;
561 ScfInt32Vec maRkValues
; /// The cell values.
566 class ScOutlineArray
;
568 /** Base class for buffers containing row or column outline data. */
569 class XclExpOutlineBuffer
572 /** Returns true, if a collapsed group ends at the last processed position. */
573 bool IsCollapsed() const { return mbCurrCollapse
; }
574 /** Returns the highest level of an open group at the last processed position. */
575 sal_uInt8
GetLevel() const { return ::std::min( mnCurrLevel
, EXC_OUTLINE_MAX
); }
578 /** Constructs the outline buffer.
579 @param bRows true = Process row outline array; false = Process column outline array. */
580 explicit XclExpOutlineBuffer( const XclExpRoot
& rRoot
, bool bRows
);
582 /** Updates the current state by processing the settings at the passed Calc position. */
583 void UpdateColRow( SCCOLROW nScPos
);
586 /** Data about an outline level. */
587 struct XclExpLevelInfo
589 SCCOLROW mnScEndPos
; /// The end position of a group in a level.
590 bool mbHidden
; /// true = Group in this level is hidden.
591 explicit XclExpLevelInfo() : mnScEndPos( 0 ), mbHidden( false ) {}
593 typedef ::std::vector
< XclExpLevelInfo
> XclExpLevelInfoVec
;
595 const ScOutlineArray
* mpScOLArray
; /// Pointer to Calc outline array.
596 XclExpLevelInfoVec maLevelInfos
; /// Info for current row and all levels.
597 sal_uInt8 mnCurrLevel
; /// Highest level of an open group for current position.
598 bool mbCurrCollapse
; /// true = Collapsed group ends at current position.
601 /** The outline buffer for column outlines. */
602 class XclExpColOutlineBuffer
: public XclExpOutlineBuffer
605 explicit XclExpColOutlineBuffer( const XclExpRoot
& rRoot
) :
606 XclExpOutlineBuffer( rRoot
, false ) {}
608 /** Updates the current state by processing the settings of the passed Calc column. */
609 void Update( SCCOL nScCol
)
610 { UpdateColRow( static_cast< SCCOLROW
>( nScCol
) ); }
613 /** The outline buffer for row outlines. */
614 class XclExpRowOutlineBuffer
: public XclExpOutlineBuffer
617 explicit XclExpRowOutlineBuffer( const XclExpRoot
& rRoot
) :
618 XclExpOutlineBuffer( rRoot
, true ) {}
620 /** Updates the current state by processing the settings of the passed Calc row. */
621 void Update( SCROW nScRow
)
622 { UpdateColRow( static_cast< SCCOLROW
>( nScRow
) ); }
625 /** Represents a GUTS record containing the level count of row and column outlines. */
626 class XclExpGuts
: public XclExpRecord
629 explicit XclExpGuts( const XclExpRoot
& rRoot
);
632 virtual void WriteBody( XclExpStream
& rStrm
) override
;
635 sal_uInt16 mnColLevels
; /// Number of visible column outline levels.
636 sal_uInt16 mnColWidth
; /// Width of column outline area (pixels).
637 sal_uInt16 mnRowLevels
; /// Number of visible row outline levels.
638 sal_uInt16 mnRowWidth
; /// Width of row outline area (pixels).
641 /** Represents a DIMENSIONS record containing the used area of a sheet. */
642 class XclExpDimensions
: public XclExpRecord
645 explicit XclExpDimensions( const XclExpRoot
& rRoot
);
647 /** Sets the used area to the record. */
649 sal_uInt16 nFirstUsedXclCol
, sal_uInt32 nFirstUsedXclRow
,
650 sal_uInt16 nFirstFreeXclCol
, sal_uInt32 nFirstFreeXclRow
);
652 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
654 /** Writes the contents of the DIMENSIONS record. */
655 virtual void WriteBody( XclExpStream
& rStrm
) override
;
658 const XclExpRoot
& mrRoot
;
659 sal_uInt32 mnFirstUsedXclRow
; /// First used row.
660 sal_uInt32 mnFirstFreeXclRow
; /// First unused row after used area.
661 sal_uInt16 mnFirstUsedXclCol
; /// First used column.
662 sal_uInt16 mnFirstFreeXclCol
; /// First free column after used area.
665 /** Represents the DEFCOLWIDTH record containing the default column width of a sheet.
667 Excel stores the default column width in entire character widths of the '0'
668 character using the application default font (i.e. the default width is 10,
669 if the '0' character fits 10 times into a cell in a column with default
672 Half of character width is reserved for non character display.
673 It is margin padding (two on each side) and padding for the gridlines.
675 The IsDefWidth() function returns true, if the passed width (measured in
676 1/256 of the width of the '0' character) could be converted exactly to the
677 default width. If the passed width is rounded up or down to get the default
678 width, the function returns false.
680 class XclExpDefcolwidth
: public XclExpDoubleRecord
, protected XclExpRoot
683 explicit XclExpDefcolwidth( const XclExpRoot
& rRoot
);
685 /** Returns true, if the own default width exactly matches the passed width. */
686 bool IsDefWidth( sal_uInt16 nXclColWidth
) const;
688 /** Sets the passed column width (in 1/256 character width) as default width. */
689 void SetDefWidth( sal_uInt16 nXclColWidth
, bool bXLS
);
691 virtual void Save(XclExpStream
& rStrm
) override
;
694 /** Contains the column settings for a range of columns.
696 After construction the record contains a temporary XF identifier returned
697 from the XF buffer. After creating the entire Excel document in memory, the
698 ConvertXFIndexes() function converts it into the real Excel XF index.
700 class XclExpColinfo
: public XclExpRecord
, protected XclExpRoot
703 /** Constructs the record with the settings in the Calc document. */
704 explicit XclExpColinfo( const XclExpRoot
& rRoot
,
705 SCCOL nScCol
, SCROW nLastScRow
,
706 XclExpColOutlineBuffer
& rOutlineBfr
);
708 /** Converts the XF identifier into the Excel XF index. */
709 void ConvertXFIndexes();
711 /** Tries to merge this record with the passed record.
712 @descr Possible, if passed record directly follows this record and has equal contents.
713 @return true = This record is equal to passed record and has been updated. */
714 bool TryMerge( const XclExpColinfo
& rColInfo
);
716 /** Returns the Excel width of the column(s). */
717 sal_uInt16
GetColWidth() const { return mnWidth
; }
718 /** Returns the final Excel XF index of the column(s). */
719 sal_uInt16
GetXFIndex() const { return maXFId
.mnXFIndex
; }
720 /** Returns the number of columns represented by this record. */
721 sal_uInt16
GetColCount() const { return mnLastXclCol
- mnFirstXclCol
+ 1; }
723 /** Returns true, if the column has default format and width. Also sets mbCustomWidth */
724 bool IsDefault( const XclExpDefcolwidth
& rDefColWidth
);
726 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
729 /** Writes the contents of this COLINFO record. */
730 virtual void WriteBody( XclExpStream
& rStrm
) override
;
733 XclExpXFId maXFId
; /// The XF identifier for column default format.
734 bool mbCustomWidth
; /// True = Column width is different from default width
735 sal_uInt16 mnWidth
; /// Excel width of the column.
736 sal_uInt16 mnScWidth
; /// Calc width of the column.
737 sal_uInt16 mnFlags
; /// Additional column flags.
738 sal_uInt8 mnOutlineLevel
; /// Outline Level of column (for OOXML)
739 sal_uInt16 mnFirstXclCol
; /// Index to first column.
740 sal_uInt16 mnLastXclCol
; /// Index to last column.
743 /** Contains COLINFO records for all columns of a Calc sheet.
745 On construction one COLINFO record per column is created. After creating
746 the entire Excel document in memory, the ConvertXFIndexes() function converts
747 all temporary XF identifiers into real Excel XF indexes and merges all equal
748 COLINFO records together.
750 class XclExpColinfoBuffer
: public XclExpRecordBase
, protected XclExpRoot
753 explicit XclExpColinfoBuffer( const XclExpRoot
& rRoot
);
755 /** Initializes the buffer: finds settings and formatting of all columns.
756 @param nLastScRow Last row used to find default formatting. */
757 void Initialize( SCROW nLastScRow
);
758 /** Converts the XF identifiers into the Excel XF indexes and merges equal columns.
759 @param rXFIndexes Returns the final XF indexes of all columns. */
760 void Finalize( ScfUInt16Vec
& rXFIndexes
, bool bXLS
);
762 /** Writes all COLINFO records of this buffer. */
763 virtual void Save( XclExpStream
& rStrm
) override
;
764 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
765 sal_uInt8
GetHighestOutlineLevel() const { return mnHighestOutlineLevel
; }
766 double GetDefColWidth() const { return maDefcolwidth
.GetValue(); }
769 typedef XclExpRecordList
< XclExpColinfo
> XclExpColinfoList
;
770 typedef XclExpColinfoList::RecordRefType XclExpColinfoRef
;
772 XclExpColinfoList maColInfos
; /// List of COLINFO records.
773 XclExpDefcolwidth maDefcolwidth
; /// The DEFCOLWIDTH record.
774 XclExpColOutlineBuffer maOutlineBfr
; /// Buffer for column outline groups.
775 sal_uInt8 mnHighestOutlineLevel
; /// Highest number of outline levels for columns in sheet.
780 /** Contains all possible default row settings. */
781 struct XclExpDefaultRowData
783 sal_uInt16 mnFlags
; /// Default flags for unspecified rows.
784 sal_uInt16 mnHeight
; /// Default height for unspecified rows.
786 explicit XclExpDefaultRowData();
787 explicit XclExpDefaultRowData( const XclExpRow
& rRow
);
789 /** Returns true, if rows are hidden by default. */
790 bool IsHidden() const { return ::get_flag( mnFlags
, EXC_DEFROW_HIDDEN
); }
791 /** Returns true, if the rows have a manually set height by default. */
792 bool IsUnsynced() const { return ::get_flag( mnFlags
, EXC_DEFROW_UNSYNCED
); }
795 /** Represents a DEFROWHEIGHT record containing default format for unused rows. */
796 class XclExpDefrowheight
: public XclExpRecord
799 explicit XclExpDefrowheight();
801 /** Sets the passed default data as current record contents. */
802 void SetDefaultData( const XclExpDefaultRowData
& rDefData
);
803 XclExpDefaultRowData
& GetDefaultData() { return maDefData
; }
805 /** Writes the contents of the record. */
806 virtual void WriteBody( XclExpStream
& rStrm
) override
;
809 XclExpDefaultRowData maDefData
; /// Record data.
812 /** Represents a ROW record and additionally contains all cells records of a row.
814 This class contains all cell records of a row in a spreadsheet. There are 2
815 cell records in Excel that support storing a range of cells in one record
816 (MULBLANK for multiple blank cells, and MULRK for multiple RK values). The
817 insertion functions try to merge a new inserted cell with existing
818 neighbors, if this is supported by the current type of cell record.
820 The Finalize() function converts the XF identifiers of all cell records to
821 the final Excel XF indexes. Then a default
823 class XclExpRow
: public XclExpRecord
, protected XclExpRoot
826 /** Constructs the ROW record and converts the Calc row settings.
827 @param bAlwaysEmpty true = This row will not be filled with blank cells
828 in the Finalize() function. */
829 explicit XclExpRow( const XclExpRoot
& rRoot
, sal_uInt32 nXclRow
,
830 XclExpRowOutlineBuffer
& rOutlineBfr
, bool bAlwaysEmpty
, bool bHidden
, sal_uInt16 nHeight
);
832 /** Returns the excel row index of this ROW record. */
833 sal_uInt32
GetXclRow() const { return mnXclRow
; }
834 /** Returns the height of the row in twips. */
835 sal_uInt16
GetHeight() const { return mnHeight
; }
836 /** Returns true, if this row does not contain at least one valid cell. */
837 bool IsEmpty() const { return maCellList
.IsEmpty(); }
838 /** Returns true, if this row is hidden. */
839 bool IsHidden() const { return ::get_flag( mnFlags
, EXC_ROW_HIDDEN
); }
840 /** Returns true, if this row contains a manually set height. */
841 bool IsUnsynced() const { return ::get_flag( mnFlags
, EXC_ROW_UNSYNCED
); }
842 /** Returns true, if this row is enabled (will be exported). */
843 bool IsEnabled() const { return mbEnabled
; }
845 /** Appends the passed cell object to this row. */
846 void AppendCell( XclExpCellRef
const & xCell
, bool bIsMergedBase
);
848 /** Converts all XF identifiers into the Excel XF indexes. */
849 void Finalize( const ScfUInt16Vec
& rColXFIndexes
,
850 bool bUpdateProgress
);
852 /** Returns the column index of the first used cell in this row.
853 @descr This function can only be called after Finalize(). */
854 sal_uInt16
GetFirstUsedXclCol() const;
855 /** Returns the column index of the first unused cell following all used cells in this row.
856 @descr This function can only be called after Finalize(). */
857 sal_uInt16
GetFirstFreeXclCol() const;
859 /** Returns true, if this row may be omitted by using the DEFROWHEIGHT record.
860 @descr A row may be omitted, if it does not contain any cell or
861 explicit default cell formatting, and is not part of an outline.
862 This function can only be called after Finalize(). */
863 bool IsDefaultable() const;
864 /** Disables this row, if it is defaultable and has the passed default format.
865 @descr Disabled rows will not be saved.
866 This function can only be called after Finalize(). */
867 void DisableIfDefault( const XclExpDefaultRowData
& rDefRowData
);
869 /** Writes all cell records of this row. */
870 void WriteCellList( XclExpStream
& rStrm
);
872 /** Writes the ROW record if the row is not disabled (see DisableIfDefault() function). */
873 virtual void Save( XclExpStream
& rStrm
) override
;
874 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
876 sal_uInt32
GetXclRowRpt() const { return mnXclRowRpt
; }
877 void SetXclRowRpt( sal_uInt32 nRpt
){ mnXclRowRpt
= nRpt
; }
879 /** Inserts a cell at the specified list position, tries to merge with neighbors. */
880 void InsertCell( XclExpCellRef xCell
, size_t nPos
, bool bIsMergedBase
);
882 /** Writes the contents of the ROW record. */
883 virtual void WriteBody( XclExpStream
& rStrm
) override
;
886 typedef XclExpRecordList
< XclExpCellBase
> XclExpCellList
;
888 XclExpCellList maCellList
; /// List of cell records for this row.
889 sal_uInt32
const mnXclRow
; /// Excel row index of this row.
890 sal_uInt16 mnHeight
; /// Row height in twips.
891 sal_uInt16 mnFlags
; /// Flags for the ROW record.
892 sal_uInt16 mnXFIndex
; /// Default row formatting.
893 sal_uInt8 mnOutlineLevel
; /// Outline Level of row (for OOXML)
894 sal_uInt32 mnXclRowRpt
;
895 sal_uInt32 mnCurrentRow
;
896 bool const mbAlwaysEmpty
; /// true = Do not add blank cells in Finalize().
897 bool mbEnabled
; /// true = Write this ROW record.
900 /** Collects all rows which contain all cells of a sheet.
902 This row buffer automatically creates ROW records when cells are inserted
903 with the AppendCell() function. It is possible to force creation of more
904 ROW records with the CreateRows() function. In both cases, all preceding
905 missing ROW records are inserted too.
907 class XclExpRowBuffer
: public XclExpRecordBase
, protected XclExpRoot
910 explicit XclExpRowBuffer( const XclExpRoot
& rRoot
);
912 /** Appends the passed cell object to the row that the cell specifies. */
913 void AppendCell( XclExpCellRef
const & xCell
, bool bIsMergedBase
);
914 /** Forces insertion of all ROW records before the passed row. */
915 void CreateRows( SCROW nFirstFreeScRow
);
917 /** Converts all XF identifiers into the Excel XF indexes and calculates default formats.
918 @param rDefRowData (out-param) The default row format is returned here.
919 @param rColXFIndexes The column default XF indexes. */
920 void Finalize( XclExpDefaultRowData
& rDefRowData
, const ScfUInt16Vec
& rColXFIndexes
);
922 /** Writes the DIMENSIONS record, all ROW records and all cell records. */
923 virtual void Save( XclExpStream
& rStrm
) override
;
924 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
926 XclExpDimensions
& GetDimensions() { return maDimensions
; }
927 sal_uInt8
GetHighestOutlineLevel() const { return mnHighestOutlineLevel
; }
930 /** Returns access to the specified ROW record. Inserts preceding missing ROW records.
931 @param bRowAlwaysEmpty true = Created rows will not be filled with blank cells
932 in the XclExpRow::Finalize() function. */
933 XclExpRow
& GetOrCreateRow( sal_uInt32 nXclRow
, bool bRowAlwaysEmpty
);
936 typedef std::shared_ptr
<XclExpRow
> RowRef
;
937 typedef ::std::map
<sal_uInt32
, RowRef
> RowMap
;
940 XclExpRowOutlineBuffer maOutlineBfr
; /// Buffer for row outline groups.
941 XclExpDimensions maDimensions
; /// DIMENSIONS record for used area.
942 sal_uInt8 mnHighestOutlineLevel
; /// Highest number of outline levels for rows in sheet.
948 class XclExpMergedcells
;
949 class XclExpHyperlink
;
952 /** This class contains the cell contents and more of an entire sheet.
954 The cell table includes the settings and default formatting of all columns,
955 the settings and default formatting of all used rows, and the contents of
956 all cells of one sheet in a spreadsheet document.
958 The constructor does all the work creating the cell table. It reads the
959 Calc sheet and converts all columns, rows, and cells to Excel record data.
960 Additionally, hyperlink records, note records, additional records for
961 formula cells, data validation records, and outline records are created.
963 The Finalize() function does even more work. It calculates default column
964 settings and removes column records that are equal to this default. The
965 same happens with rows: A default format is calculated for each row, and
966 all blank cells in this row that have the same format are removed. Then,
967 the most used row settings are calculated, and all empty rows that have the
968 same settings are removed too.
970 Records that are not stored inside the cell table area in an Excel file
971 (i.e. DEFROWHEIGHT record, NOTE records, MERGEDCELLS record, HLINK records,
972 DVAL and DV records for data validation) can be accessed with the function
973 CreateRecord(). It returns the reference to the respective record (or
974 record list) which can be inserted into a record list.
976 class XclExpCellTable
: public XclExpRecordBase
, protected XclExpRoot
979 explicit XclExpCellTable( const XclExpRoot
& rRoot
);
981 /** Converts all XF identifiers into the Excel XF indexes and calculates default formats. */
982 void Finalize(bool bXLS
);
984 /** Returns the reference to an internal record specified by the passed record id.
985 @param nRecId The record identifier that specifies which record is
986 returned. Possible values are: EXC_ID_DEFROWHEIGHT, EXC_ID_NOTE,
987 EXC_ID_MERGEDCELLS, EXC_ID_HLINK, EXC_ID_DVAL. */
988 XclExpRecordRef
CreateRecord( sal_uInt16 nRecId
) const;
989 /** Saves the entire cell table. */
990 virtual void Save( XclExpStream
& rStrm
) override
;
991 virtual void SaveXml( XclExpXmlStream
& rStrm
) override
;
994 typedef XclExpRecordList
< XclExpNote
> XclExpNoteList
;
995 typedef XclExpRecordList
< XclExpHyperlink
> XclExpHyperlinkList
;
997 typedef std::shared_ptr
< XclExpDefrowheight
> XclExpDefrowhRef
;
998 typedef std::shared_ptr
< XclExpNoteList
> XclExpNoteListRef
;
999 typedef std::shared_ptr
< XclExpMergedcells
> XclExpMergedcellsRef
;
1000 typedef std::shared_ptr
< XclExpHyperlinkList
> XclExpHyperlinkRef
;
1001 typedef std::shared_ptr
< XclExpDval
> XclExpDvalRef
;
1002 typedef std::shared_ptr
< XclExtLst
> XclExtLstRef
;
1004 XclExpColinfoBuffer maColInfoBfr
; /// Buffer for column formatting.
1005 XclExpRowBuffer maRowBfr
; /// Rows and cell records.
1006 XclExpArrayBuffer maArrayBfr
; /// Buffer for ARRAY records.
1007 XclExpShrfmlaBuffer maShrfmlaBfr
; /// Buffer for SHRFMLA records.
1008 XclExpTableopBuffer maTableopBfr
; /// Buffer for TABLEOP records.
1009 XclExpDefrowhRef mxDefrowheight
; /// DEFROWHEIGHT record for default row format.
1010 XclExpRecordRef
const mxGuts
; /// GUTS record for outline areas.
1011 XclExpNoteListRef mxNoteList
; /// List of NOTE records.
1012 XclExpMergedcellsRef mxMergedcells
; /// MERGEDCELLS record for merged cell ranges.
1013 XclExpHyperlinkRef mxHyperlinkList
; /// List of HLINK records.
1014 XclExpDvalRef mxDval
; /// Data validation with DVAL and DV records.
1015 XclExtLstRef mxExtLst
;
1020 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */