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 #ifndef INCLUDED_SC_SOURCE_FILTER_INC_XESTYLE_HXX
21 #define INCLUDED_SC_SOURCE_FILTER_INC_XESTYLE_HXX
22 
23 #include <map>
24 #include <svl/zforlist.hxx>
25 #include <svl/nfkeytab.hxx>
26 #include <editeng/svxfont.hxx>
27 #include "xerecord.hxx"
28 #include "xlstyle.hxx"
29 #include "xeroot.hxx"
30 #include <fonthelper.hxx>
31 #include <memory>
32 #include <vector>
33 #include <o3tl/sorted_vector.hxx>
34 
35 /* ============================================================================
36 - Buffers for style records (PALETTE, FONT, FORMAT, XF, STYLE).
37 ============================================================================ */
38 
39 const sal_uInt16 EXC_ID_FONTLIST    = 0x8031;   /// For internal use only.
40 const sal_uInt16 EXC_ID_FORMATLIST  = 0x801E;   /// For internal use only.
41 const sal_uInt16 EXC_ID_XFLIST      = 0x8043;   /// For internal use only.
42 const sal_uInt16 EXC_ID_DXFS        = 0x9999;   /// For internal use only. TODO:moggi: find a better/correct value
43 
44 // PALETTE record - color information =========================================
45 
46 /** Different types of colors in a document. */
47 enum XclExpColorType
48 {
49     EXC_COLOR_CELLTEXT,         /// Text in a cell.
50     EXC_COLOR_CELLBORDER,       /// Border of a cell.
51     EXC_COLOR_CELLAREA,         /// Background area of a cell.
52     EXC_COLOR_CHARTTEXT,        /// Text color in a chart.
53     EXC_COLOR_CHARTLINE,        /// Line in a chart.
54     EXC_COLOR_CHARTAREA,        /// Area in a chart.
55     EXC_COLOR_CTRLTEXT,         /// Text color in a form control.
56     EXC_COLOR_GRID,              /// Spreadsheet grid color.
57     EXC_COLOR_TABBG             /// Spreadsheet tab bg color.
58 };
59 
60 class XclExpPaletteImpl;
61 
62 /** Stores all used colors in the document.
63 
64     Supports color reduction to the maximum count of the current BIFF version.
65     An instance of this class collects all colors in the conversion phase of
66     the export, using the InsertColor() function. It returns a unique
67     identifier for each passed color.
68 
69     After the entire document is converted, the Finalize() function will reduce
70     the palette to the  number of colors supported by the current BIFF version.
71 
72     Then, in the streaming phase, the functions GetColorIndex() and
73     GetMixedColors() return the real Excel palette index for all color
74     identifiers.
75  */
76 class XclExpPalette : public XclDefaultPalette, public XclExpRecord
77 {
78 public:
79     explicit            XclExpPalette( const XclExpRoot& rRoot );
80     virtual             ~XclExpPalette() override;
81 
82     /** Inserts the color into the list and updates weighting.
83         @param nAutoDefault  The Excel palette index for automatic color.
84         @return  A unique ID for this color. */
85     sal_uInt32          InsertColor( const Color& rColor, XclExpColorType eType, sal_uInt16 nAutoDefault = 0 );
86     /** Returns the color ID representing a fixed Excel palette index (i.e. for auto colors). */
87     static sal_uInt32   GetColorIdFromIndex( sal_uInt16 nIndex );
88 
89     /** Reduces the color list to the maximum count of the current BIFF version. */
90     void                Finalize();
91 
92     /** Returns the Excel palette index of the color with passed color ID. */
93     sal_uInt16          GetColorIndex( sal_uInt32 nColorId ) const;
94 
95     /** Returns a foreground and background color for the two passed color IDs.
96         @descr  If rnXclPattern contains a solid pattern, this function tries to find
97         the two best fitting colors and a mix pattern (25%, 50% or 75%) for nForeColorId.
98         This will result in a better approximation to the passed foreground color. */
99     void                GetMixedColors(
100                             sal_uInt16& rnXclForeIx, sal_uInt16& rnXclBackIx, sal_uInt8& rnXclPattern,
101                             sal_uInt32 nForeColorId, sal_uInt32 nBackColorId ) const;
102 
103     /** Returns the color for a (non-zero-based) Excel palette entry.
104         @return  The color from current or default palette or COL_AUTO, if nothing else found. */
105     Color               GetColor( sal_uInt16 nXclIndex ) const;
106 
107     /** Saves the PALETTE record, if it differs from the default palette. */
108     virtual void        Save( XclExpStream& rStrm ) override;
109     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
110 
111 private:
112     /** Writes the contents of the PALETTE record. */
113     virtual void        WriteBody( XclExpStream& rStrm ) override;
114 
115 private:
116     typedef std::shared_ptr< XclExpPaletteImpl > XclExpPaletteImplRef;
117     XclExpPaletteImplRef mxImpl;
118 };
119 
120 // FONT record - font information =============================================
121 
122 const size_t EXC_FONTLIST_NOTFOUND = static_cast< size_t >( -1 );
123 
124 /** Helper functions for font export. */
125 namespace XclExpFontHelper
126 {
127     /** Returns the script type of the first font item found in the item set and its parents. */
128     sal_Int16    GetFirstUsedScript(
129                             const XclExpRoot& rRoot,
130                             const SfxItemSet& rItemSet );
131 
132     /** Returns a VCL font object filled from the passed item set. */
133     vcl::Font    GetFontFromItemSet(
134                             const XclExpRoot& rRoot,
135                             const SfxItemSet& rItemSet,
136                             sal_Int16 nScript );
137 
138     /**
139      * Get a dxf related font object from the item set.
140      * Only items that are explicitly set in the item set
141      * are also set in the returned object.
142      */
143     ScDxfFont GetDxfFontFromItemSet(const XclExpRoot& rRoot, const SfxItemSet& rSet);
144 
145     /** Returns true, if at least one font related item is set in the passed item set.
146         @param bDeep  true = Searches in parent item sets too. */
147     bool         CheckItems(
148                             const XclExpRoot& rRoot,
149                             const SfxItemSet& rItemSet,
150                             sal_Int16 nScript,
151                             bool bDeep );
152 }
153 
154 /** Stores all data of an Excel font and provides export of FONT records. */
155 class XclExpFont : public XclExpRecord, protected XclExpRoot
156 {
157 public:
158     explicit            XclExpFont( const XclExpRoot& rRoot,
159                             const XclFontData& rFontData, XclExpColorType eColorType );
160 
161     /** Returns read-only access to font data. */
GetFontData() const162     const XclFontData& GetFontData() const { return maData; }
163     /** Returns the font color identifier. */
GetFontColorId() const164     sal_uInt32   GetFontColorId() const { return mnColorId; }
165     /** Compares this font with the passed font data.
166         @param nHash  The hash value calculated from the font data. */
167     virtual bool        Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const;
168 
169     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
170 
171 private:
172     /** Writes the contents of the FONT record. */
173     virtual void        WriteBody( XclExpStream& rStrm ) override;
174 
175 private:
176     XclFontData         maData;         /// All font attributes.
177     sal_uInt32          mnColorId;      /// Unique color ID for text color.
178     sal_uInt32          mnHash;         /// Hash value for fast comparison.
179 };
180 
181 class XclExpDxfFont : public XclExpRecordBase, protected XclExpRoot
182 {
183 public:
184     XclExpDxfFont(const XclExpRoot& rRoot, const SfxItemSet& rItemSet);
185 
186     virtual void SaveXml(XclExpXmlStream& rStrm) override;
187 private:
188 
189     ScDxfFont maDxfData;
190 };
191 
192 /** Used as placeholder for font index 4, which is not used in Excel. */
193 class XclExpBlindFont : public XclExpFont
194 {
195 public:
196     explicit            XclExpBlindFont( const XclExpRoot& rRoot );
197 
198     /** Returns always false to never find this font while searching the font list. */
199     virtual bool        Equals( const XclFontData& rFontData, sal_uInt32 nHash ) const override;
200 
201     /** Skips writing this record. */
202     virtual void        Save( XclExpStream& rStrm ) override;
203 };
204 
205 class ScPatternAttr;
206 
207 /** Stores the data of all fonts used in the document. */
208 class XclExpFontBuffer : public XclExpRecordBase, protected XclExpRoot
209 {
210 public:
211     explicit            XclExpFontBuffer( const XclExpRoot& rRoot );
212 
213     /** Returns the specified font from font list. */
214     const XclExpFont*   GetFont( sal_uInt16 nXclFont ) const;
215     /** Returns the application font data of this file, needed e.g. for column width. */
216     const XclFontData&  GetAppFontData() const;
217 
218     /** Inserts a new font with the passed font data into the buffer if not present.
219         @param bAppFont  true = Sets the application font; false = Inserts a new font.
220         @return  The resulting Excel font index. */
221     sal_uInt16          Insert( const XclFontData& rFontData,
222                             XclExpColorType eColorType, bool bAppFont = false );
223     /** Inserts the SvxFont into the buffer if not present, e.g. where escapements are used.
224         @return  The resulting Excel font index. */
225     sal_uInt16          Insert( const SvxFont& rFont,
226                             XclExpColorType eColorType );
227     /** Inserts the font contained in the passed item set into the buffer, if not present.
228         @param nScript  The script type of the font properties to be used.
229         @param bAppFont  true = Sets the application font; false = Inserts a new font.
230         @return  The resulting Excel font index. */
231     sal_uInt16          Insert( const SfxItemSet& rItemSet, sal_Int16 nScript,
232                             XclExpColorType eColorType, bool bAppFont );
233 
234     /** Writes all FONT records contained in this buffer. */
235     virtual void        Save( XclExpStream& rStrm ) override;
236     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
237 
238 private:
239     /** Initializes the default fonts for the current BIFF version. */
240     void                InitDefaultFonts();
241     /** Tries to find the passed font and returns the current list index. */
242     size_t              Find( const XclFontData& rFontData );
243 
244 private:
245     typedef XclExpRecordList< XclExpFont >  XclExpFontList;
246     typedef XclExpFontList::RecordRefType   XclExpFontRef;
247 
248     XclExpFontList      maFontList;     /// List of all FONT records.
249     size_t              mnXclMaxSize;   /// Maximum number of fonts.
250 };
251 
252 // FORMAT record - number formats =============================================
253 
254 /** Stores a core number format index with corresponding Excel format index. */
255 struct XclExpNumFmt
256 {
257     sal_uInt32 const   mnScNumFmt;     /// Core index of the number format.
258     sal_uInt16 const   mnXclNumFmt;    /// Resulting Excel format index.
259     OUString const     maNumFmtString; /// format string
260 
XclExpNumFmtXclExpNumFmt261     explicit     XclExpNumFmt( sal_uInt32 nScNumFmt, sal_uInt16 nXclNumFmt, const OUString& rFrmt ) :
262                             mnScNumFmt( nScNumFmt ), mnXclNumFmt( nXclNumFmt ), maNumFmtString( rFrmt ) {}
263 
264     void SaveXml( XclExpXmlStream& rStrm );
265 };
266 
267 typedef ::std::unique_ptr< SvNumberFormatter >    SvNumberFormatterPtr;
268 
269 /** Stores all number formats used in the document. */
270 class XclExpNumFmtBuffer : public XclExpRecordBase, protected XclExpRoot
271 {
272 public:
273     explicit            XclExpNumFmtBuffer( const XclExpRoot& rRoot );
274     virtual             ~XclExpNumFmtBuffer() override;
275 
276     /** Returns the core index of the current standard number format. */
GetStandardFormat() const277     sal_uInt32   GetStandardFormat() const { return mnStdFmt; }
278 
279     /** Inserts a number format into the format buffer.
280         @param nScNumFmt  The core index of the number format.
281         @return  The resulting Excel format index. */
282     sal_uInt16          Insert( sal_uInt32 nScNumFmt );
283 
284     /** Writes all FORMAT records contained in this buffer. */
285     virtual void        Save( XclExpStream& rStrm ) override;
286     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
287 
288     OUString            GetFormatCode ( sal_uInt32 nScNumFmt );
289 
290 private:
291     /** Writes the FORMAT record with index nXclIx and format string rFormatStr. */
292     void                WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const OUString& rFormatStr );
293     /** Writes the FORMAT record represented by rFormat. */
294     void                WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat );
295 
296 private:
297     typedef ::std::vector< XclExpNumFmt >           XclExpNumFmtVec;
298 
299     SvNumberFormatterPtr mxFormatter;   /// Special number formatter for conversion.
300     XclExpNumFmtVec     maFormatMap;    /// Maps core formats to Excel indexes.
301     std::unique_ptr<NfKeywordTable>   mpKeywordTable; /// Replacement table.
302     sal_uInt32 const    mnStdFmt;       /// Key for standard number format.
303     sal_uInt16          mnXclOffset;    /// Offset to first user defined format.
304 };
305 
306 // XF, STYLE record - Cell formatting =========================================
307 
308 /** Extends the XclCellProt struct for export.
309     @descr  Provides functions to fill from item sets and to fill to Excel record data. */
310 struct XclExpCellProt : public XclCellProt
311 {
312     /** Fills the protection attributes from the passed item set.
313         @return  true = At least one protection item is set. */
314     bool                FillFromItemSet( const SfxItemSet& rItemSet, bool bStyle = false );
315 
316     /** Fills the data to the passed fields of a BIFF3-BIFF8 XF record. */
317     void                FillToXF3( sal_uInt16& rnProt ) const;
318 
319     void                SaveXml( XclExpXmlStream& rStrm ) const;
320 };
321 
322 /** Extends the XclCellAlign struct for export.
323     @descr  Provides functions to fill from item sets and to fill to Excel record data. */
324 struct XclExpCellAlign : public XclCellAlign
325 {
326     /** Fills the alignment attributes from the passed item set.
327         @descr  Fills only the attributes exported in the passed BIFF version.
328         @param bForceLineBreak  true = Set line break flag unconditionally.
329         @return  true = At least one alignment item is set. */
330     bool                FillFromItemSet( const SfxItemSet& rItemSet,
331                             bool bForceLineBreak, XclBiff eBiff, bool bStyle = false );
332 
333     /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
334     void                FillToXF5( sal_uInt16& rnAlign ) const;
335     /** Fills the data to the passed fields of a BIFF8 XF record. */
336     void                FillToXF8( sal_uInt16& rnAlign, sal_uInt16& rnMiscAttrib ) const;
337 
338     void                SaveXml( XclExpXmlStream& rStrm ) const;
339 };
340 
341 /** Extends the XclCellBorder struct for export.
342     @descr  Provides functions to fill from item sets and to fill to Excel record data. */
343 struct XclExpCellBorder : public XclCellBorder
344 {
345     sal_uInt32          mnLeftColorId;      /// Color ID for left line.
346     sal_uInt32          mnRightColorId;     /// Color ID for right line.
347     sal_uInt32          mnTopColorId;       /// Color ID for top line.
348     sal_uInt32          mnBottomColorId;    /// Color ID for bottom line.
349     sal_uInt32          mnDiagColorId;      /// Color ID for diagonal line(s).
350 
351     explicit            XclExpCellBorder();
352 
353     /** Fills the border attributes from the passed item set.
354         @descr  Fills only the attributes exported in the passed BIFF version.
355         @return  true = At least one border item is set. */
356     bool                FillFromItemSet( const SfxItemSet& rItemSet,
357                             XclExpPalette& rPalette, XclBiff eBiff, bool bStyle = false );
358     /** Fills the mn***Color base members from the mn***ColorId members. */
359     void                SetFinalColors( const XclExpPalette& rPalette );
360 
361     /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
362     void                FillToXF5( sal_uInt32& rnBorder, sal_uInt32& rnArea ) const;
363     /** Fills the data to the passed fields of a BIFF8 XF record. */
364     void                FillToXF8( sal_uInt32& rnBorder1, sal_uInt32& rnBorder2 ) const;
365 
366     /** Fills the data to the passed fields of a BIFF8 CF (conditional format) record. */
367     void                FillToCF8( sal_uInt16& rnLine, sal_uInt32& rnColor ) const;
368 
369     void                SaveXml( XclExpXmlStream& rStrm ) const;
370 };
371 
372 /** Extends the XclCellArea struct for export.
373     @descr  Provides functions to fill from item sets and to fill to Excel record data. */
374 struct XclExpCellArea : public XclCellArea
375 {
376     sal_uInt32          mnForeColorId;  /// Foreground color ID.
377     sal_uInt32          mnBackColorId;  /// Background color ID.
378 
379     explicit            XclExpCellArea();
380 
381     /** Fills the area attributes from the passed item set.
382         @return  true = At least one area item is set. */
383     bool                FillFromItemSet(
384                             const SfxItemSet& rItemSet, XclExpPalette& rPalette,
385                             bool bStyle );
386     /** Fills the mn***Color base members from the mn***ColorId members. */
387     void                SetFinalColors( const XclExpPalette& rPalette );
388 
389     /** Fills the data to the passed fields of a BIFF5/BIFF7 XF record. */
390     void                FillToXF5( sal_uInt32& rnArea ) const;
391     /** Fills the data to the passed fields of a BIFF8 XF record. */
392     void                FillToXF8( sal_uInt32& rnBorder2, sal_uInt16& rnArea ) const;
393 
394     /** Fills the data to the passed fields of a BIFF8 CF (conditional format) record. */
395     void                FillToCF8( sal_uInt16& rnPattern, sal_uInt16& rnColor ) const;
396 
397     void                SaveXml( XclExpXmlStream& rStrm ) const;
398 };
399 
400 struct XclExpColor
401 {
402     Color maColor;
403 
404     bool FillFromItemSet( const SfxItemSet& rItemSet );
405 
406     void SaveXml( XclExpXmlStream& rStrm ) const;
407 };
408 
409 /** A combination of unique XF identifier with real Excel XF index. */
410 struct XclExpXFId
411 {
412     sal_uInt32          mnXFId;         /// Temporary XF identifier.
413     sal_uInt16          mnXFIndex;      /// Real Excel XF index.
414 
415     explicit            XclExpXFId();
416     explicit            XclExpXFId( sal_uInt32 nXFId );
417 
418     /** Converts the XF identifier in mnXFId to an Excel XF index and stores it in mnXFIndex. */
419     void                ConvertXFIndex( const XclExpRoot& rRoot );
420 };
421 
422 class SfxStyleSheetBase;
423 
424 /** Represents an XF record which contains all formatting data of a cell or cell style. */
425 class XclExpXF : public XclXFBase, public XclExpRecord, protected XclExpRoot
426 {
427 public:
428     /** Constructs a cell XF record from the passed Calc cell formatting. */
429     explicit            XclExpXF(
430                             const XclExpRoot& rRoot,
431                             const ScPatternAttr& rPattern,
432                             sal_Int16 nScript,
433                             sal_uInt32 nScForceNumFmt = NUMBERFORMAT_ENTRY_NOT_FOUND,
434                             sal_uInt16 nForceXclFont = EXC_FONT_NOTFOUND,
435                             bool bForceLineBreak = false );
436     /** Constructs a style XF record from the passed cell style sheet. */
437     explicit            XclExpXF(
438                             const XclExpRoot& rRoot,
439                             const SfxStyleSheetBase& rStyleSheet );
440 
441     /** Returns the cell protection settings of this XF. */
GetProtectionData() const442     const XclExpCellProt& GetProtectionData() const { return maProtection; }
443     /** Returns the alignment settings of this XF. */
GetAlignmentData() const444     const XclExpCellAlign& GetAlignmentData() const { return maAlignment; }
445     /** Returns the cell border settings of this XF. */
GetBorderData() const446     const XclExpCellBorder& GetBorderData() const { return maBorder; }
447     /** Returns the cell fill settings of this XF. */
GetAreaData() const448     const XclExpCellArea& GetAreaData() const { return maArea; }
449 
450     /** Returns true, if this XF record represents the passed cell formatting.
451         @descr  Searches for cell XFs only. */
452     bool                Equals(
453                             const ScPatternAttr& rPattern,
454                             sal_uInt32 nScForceNumFmt,
455                             sal_uInt16 nForceXclFont,
456                             bool bForceLineBreak ) const;
457 
458     /** Returns true, if this XF record represents the passed style.
459         @descr  Searches for style XFs only. */
460     bool                Equals( const SfxStyleSheetBase& rStyleSheet ) const;
461 
462     /** Sets the resulting Excel palette index from all used color IDs (border and area). */
463     void                SetFinalColors();
464 
465     /** Returns true, if this XF record is completely equal to the passed. */
466     bool                Equals( const XclExpXF& rCmpXF ) const;
467 
468     void                SetXmlIds( sal_uInt32 nBorderId, sal_uInt32 nFillId );
469 
470     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
471 
GetItemSet() const472     const SfxItemSet*   GetItemSet() const { return mpItemSet; }
473 
GetScNumFmt() const474     sal_uInt32          GetScNumFmt() const { return mnScNumFmt; }
GetXclFont() const475     sal_uInt16          GetXclFont() const { return mnXclFont; }
476 
477 protected:
478     explicit            XclExpXF( const XclExpRoot& rRoot, bool bCellXF );
479 
480 protected:  // access for XclExpDefaultXF
481     const SfxItemSet*   mpItemSet;          /// Pointer to the item set (we do not own it).
482 
483     XclExpCellProt      maProtection;       /// Cell protection flags.
484     XclExpCellAlign     maAlignment;        /// All alignment attributes.
485     XclExpCellBorder    maBorder;           /// Border line style.
486     XclExpCellArea      maArea;             /// Background area style.
487     sal_uInt32          mnParentXFId;       /// XF ID of parent XF record.
488     sal_uInt32          mnScNumFmt;         /// Calc number format index.
489     sal_uInt16          mnXclFont;          /// Excel font index.
490     sal_uInt16          mnXclNumFmt;        /// Excel number format index.
491     sal_Int32           mnBorderId;         /// OOXML Border Index
492     sal_Int32           mnFillId;           /// OOXML Fill Index
493 
494 private:
495     using               XclXFBase::Equals;
496 
497     /** Initializes with default values. */
498     void                InitDefault();
499     /** Fills all members from the passed item set.
500         @param bDefStyle  true = This is the "Default"/"Normal" style - needs special handling. */
501     void                Init(
502                             const SfxItemSet& rItemSet,
503                             sal_Int16 nScript,
504                             sal_uInt32 nForceScNumFmt,
505                             sal_uInt16 nForceXclFont,
506                             bool bForceLineBreak,
507                             bool bDefStyle );
508 
509     /** Returns the bits specifying the used attributes.
510         @descr  In cell XFs a set bit means a used attribute, in style XF a cleared
511         bit means a used attribute. This method regards the cell/style state.
512         @return  The mask based on bit 0 (not yet bit-shifted as needed for export). */
513     sal_uInt8           GetUsedFlags() const;
514 
515     void                WriteBody5( XclExpStream& rStrm );
516     void                WriteBody8( XclExpStream& rStrm );
517 
518     /** Writes the contents of the XF record. */
519     virtual void        WriteBody( XclExpStream& rStrm ) override;
520 };
521 
522 /** Represents a default XF record. Supports methods to set attributes directly. */
523 class XclExpDefaultXF : public XclExpXF
524 {
525 public:
526     explicit            XclExpDefaultXF( const XclExpRoot& rRoot, bool bCellXF );
527 
528     /** Sets the Excel font index. */
529     void                SetFont( sal_uInt16 nXclFont );
530     /** Sets the Excel number format index. */
531     void                SetNumFmt( sal_uInt16 nXclNumFmt );
532 };
533 
534 /** Represents a STYLE record containing the data of a cell style.
535     @descr  The class is able to store built-in and user-defined styles. */
536 class XclExpStyle : public XclExpRecord
537 {
538 public:
539     explicit            XclExpStyle( sal_uInt32 nXFId, const OUString& rStyleName );
540     explicit            XclExpStyle( sal_uInt32 nXFId, sal_uInt8 nStyleId, sal_uInt8 nLevel );
541 
542     /** Returns true, if this record represents an Excel built-in style. */
IsBuiltIn() const543     bool         IsBuiltIn() const { return mnStyleId != EXC_STYLE_USERDEF; }
544 
545     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
546 
547 private:
548     /** Writes the contents of the STYLE record. */
549     virtual void        WriteBody( XclExpStream& rStrm ) override;
550 
551 private:
552     OUString const      maName;         /// Name of the cell style.
553     XclExpXFId          maXFId;         /// XF identifier for style formatting.
554     sal_uInt8           mnStyleId;      /// Built-in style identifier.
555     sal_uInt8 const     mnLevel;        /// Outline level for RowLevel and ColLevel styles.
556 };
557 
558 /** Stores all XF records (cell formats and cell styles) in the document.
559 
560     Stores also the names of user defined cell styles (STYLE records). Supports
561     reduction to the maximum count of XF records of the current BIFF version.
562 
563     An instance of this class collects all XF records in the conversion phase
564     of the export, using the Insert() and InsertStyle() functions. It returns a
565     unique identifier for each XF record.
566 
567     After the entire document is converted, the Finalize() function will reduce
568     the list to the number of XF records supported by the current BIFF version.
569 
570     Then, in the streaming phase, the function GetXFIndex() returns the real
571     Excel XF index for all XF identifiers.
572  */
573 class XclExpXFBuffer : public XclExpRecordBase, protected XclExpRoot
574 {
575 public:
576     explicit            XclExpXFBuffer( const XclExpRoot& rRoot );
577 
578     /** Inserts predefined built-in styles and user-defined styles. */
579     void                Initialize();
580 
581     /** Finds or creates a cell XF record for the passed item set.
582         @return  A unique XF record ID. */
583     sal_uInt32          Insert( const ScPatternAttr* pPattern, sal_Int16 nScript );
584     /** Finds or creates a cell XF record for the passed item set.
585         @param nForceXclFont  The font to be exported. If not equal to EXC_FONT_NOTFOUND,
586             this font index will be used unconditionally and the cell font will be ignored.
587         @param bForceLineBreak  true = Set line break flag unconditionally.
588             This is required for cells that contain multi-line text.
589         @return  A unique XF record ID. */
590     sal_uInt32          InsertWithFont(
591                             const ScPatternAttr* pPattern, sal_Int16 nScript,
592                             sal_uInt16 nForceXclFont,
593                             bool bForceLineBreak );
594     /** Finds or creates a cell XF record for the passed item set, with custom number format.
595         @param nXFFlags  Additional flags allowing to control the creation of an XF.
596         @param nForceScNumFmt  The number format to be exported, e.g. formula
597             result type. This format will always overwrite the cell's number format.
598         @param bForceLineBreak  true = Set line break flag unconditionally.
599             This is required for cells that contain multi-line text.
600         @return  A unique XF record ID. */
601     sal_uInt32          InsertWithNumFmt(
602                             const ScPatternAttr* pPattern, sal_Int16 nScript,
603                             sal_uInt32 nForceScNumFmt,
604                             bool bForceLineBreak );
605     /** Inserts the passed cell style. Creates a style XF record and a STYLE record.
606         @return  A unique XF record ID. */
607     sal_uInt32          InsertStyle( const SfxStyleSheetBase* pStyleSheet );
608     /** Returns the XF identifier representing a fixed Excel XF index (e.g. for built-in XFs). */
609     static sal_uInt32   GetXFIdFromIndex( sal_uInt16 nXFIndex );
610     /** Returns the XF identifier representing the default cell XF. */
611     static sal_uInt32   GetDefCellXFId();
612 
613     /** Returns an XF record by its unique identifier. */
614     const XclExpXF*     GetXFById( sal_uInt32 nXFId ) const;
615 
616     /** Reduces the XF record list to the maximum allowed number of records. */
617     void                Finalize();
618 
619     /** Returns the Excel XF index of the XF record with passed XF ID. */
620     sal_uInt16          GetXFIndex( sal_uInt32 nXFId ) const;
621 
622     sal_Int32           GetXmlStyleIndex( sal_uInt32 nXFId ) const;
623     sal_Int32           GetXmlCellIndex( sal_uInt32 nXFId ) const;
624 
625     /** Writes all XF records contained in this buffer. */
626     virtual void        Save( XclExpStream& rStrm ) override;
627     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
628 
629 private:
630     typedef XclExpRecordList< XclExpXF >    XclExpXFList;
631     typedef XclExpXFList::RecordRefType     XclExpXFRef;
632     typedef XclExpRecordList< XclExpStyle > XclExpStyleList;
633 
634 private:
635     /** Returns the XF ID of the cell XF containing the passed format. */
636     sal_uInt32          FindXF( const ScPatternAttr& rPattern, sal_uInt32 nForceScNumFmt,
637                             sal_uInt16 nForceXclFont, bool bForceLineBreak ) const;
638     /** Returns the XF ID of the style XF containing the passed style. */
639     sal_uInt32          FindXF( const SfxStyleSheetBase& rStyleSheet ) const;
640 
641     /** Returns the XF ID of a built-in style XF, searches by style identifier. */
642     sal_uInt32          FindBuiltInXF( sal_uInt8 nStyleId, sal_uInt8 nLevel ) const;
643 
644     /** Tries to find the XF record containing the passed format or inserts a new record.
645         @return  The XF record ID. */
646     sal_uInt32          InsertCellXF( const ScPatternAttr* pPattern, sal_Int16 nScript,
647                             sal_uInt32 nForceScNumFmt,
648                             sal_uInt16 nForceXclFont, bool bForceLineBreak );
649     /** Inserts the passed cell style. Creates a style XF record and a STYLE record.
650         @return  The XF record ID. */
651     sal_uInt32          InsertStyleXF( const SfxStyleSheetBase& rStyleSheet );
652 
653     /** Inserts an XF and a STYLE record for all user defined style sheets. */
654     void                InsertUserStyles();
655 
656     /** Inserts a built-in XF record without a STYLE record and returns the XF ID.
657         @param bCreateStyleRec  true = Creates the related STYLE record. */
658     sal_uInt32          AppendBuiltInXF( XclExpXFRef const & xXF,
659                             sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
660     /** Inserts a built-in XF and STYLE record and returns the XF ID.
661         @param bCreateStyleRec  true = Creates the related STYLE record. */
662     sal_uInt32          AppendBuiltInXFWithStyle( XclExpXFRef const & xXF,
663                             sal_uInt8 nStyleId, sal_uInt8 nLevel = EXC_STYLE_NOLEVEL );
664 
665     /** Inserts all default XF and STYLE records. */
666     void                InsertDefaultRecords();
667 
668     /** Appends a XF index to the internal ID<->index maps. */
669     void                AppendXFIndex( sal_uInt32 nXFId );
670 
671     void                AddBorderAndFill( const XclExpXF& rXF );
672     void                SaveXFXml( XclExpXmlStream& rStrm, XclExpXF& rXF );
673 
674 private:
675     /** Extended info about a built-in XF. */
676     struct XclExpBuiltInInfo
677     {
678         sal_uInt8           mnStyleId;          /// Built-in style identifier.
679         sal_uInt8           mnLevel;            /// Level for RowLevel/ColLevel styles.
680         bool                mbPredefined;       /// true = XF still predefined.
681         bool                mbHasStyleRec;      /// true = STYLE record created.
682         explicit            XclExpBuiltInInfo();
683     };
684     typedef ::std::map< sal_uInt32, XclExpBuiltInInfo > XclExpBuiltInMap;
685     typedef ::std::vector< XclExpCellBorder >           XclExpBorderList;
686     typedef ::std::vector< XclExpCellArea >             XclExpFillList;
687 
688     /** composite key for the find-map, so we can do partial key searching */
689     struct FindKey
690     {
691         bool mbCellXF; // is this a hard cell format, or a cell style
692         const SfxItemSet* mpItemSet;
693         sal_uInt32 mnScNumFmt;
694         sal_uInt16 mnXclFont;
695 
operator <XclExpXFBuffer::FindKey696         bool operator<(const FindKey& other) const
697         {
698             if (mbCellXF != other.mbCellXF)
699                 return mbCellXF < other.mbCellXF;
700             if (mpItemSet != other.mpItemSet)
701                 return mpItemSet < other.mpItemSet;
702             if (mnScNumFmt != other.mnScNumFmt)
703                 return mnScNumFmt < other.mnScNumFmt;
704             return mnXclFont < other.mnXclFont;
705         }
706     };
707     static FindKey ToFindKey(XclExpXF const &);
708 
709     XclExpXFList        maXFList;           /// List of all XF records.
710     std::map<FindKey, std::vector<sal_uInt32>>
711                         maXFFindMap;        /// map of itemset to vector of positions, to speed up find
712     XclExpStyleList     maStyleList;        /// List of all STYLE records.
713     XclExpBuiltInMap    maBuiltInMap;       /// Contained elements describe built-in XFs.
714     ScfUInt16Vec        maXFIndexVec;       /// Maps XF IDs to XF indexes.
715     ScfUInt16Vec        maStyleIndexes;     /// Maps XF IDs to OOXML Style indexes
716     ScfUInt16Vec        maCellIndexes;      /// Maps XF IDs to OOXML Cell indexes
717     XclExpXFList        maSortedXFList;     /// List of XF records in XF index order.
718     XclExpBorderList    maBorders;          /// List of borders used by XF records
719     XclExpFillList      maFills;            /// List of fills used by XF records
720 
721 };
722 
723 class XclExpDxf : public XclExpRecordBase, protected XclExpRoot
724 {
725 public:
726     XclExpDxf( const XclExpRoot& rRoot, std::unique_ptr<XclExpCellAlign> pAlign, std::unique_ptr<XclExpCellBorder> pBorder,
727             std::unique_ptr<XclExpDxfFont> pFont, std::unique_ptr<XclExpNumFmt> pNumberFmt,
728             std::unique_ptr<XclExpCellProt> pProt, std::unique_ptr<XclExpColor> pColor);
729     virtual ~XclExpDxf() override;
730 
731     virtual void SaveXml( XclExpXmlStream& rStrm ) override;
732     void SaveXmlExt( XclExpXmlStream& rStrm);
733 
734 private:
735     std::unique_ptr<XclExpCellAlign> mpAlign;
736     std::unique_ptr<XclExpCellBorder> mpBorder;
737     std::unique_ptr<XclExpDxfFont> mpFont;
738     std::unique_ptr<XclExpNumFmt> mpNumberFmt;
739     std::unique_ptr<XclExpCellProt> mpProt;
740     std::unique_ptr<XclExpColor> mpColor;
741 };
742 
743 class XclExpDxfs : public XclExpRecordBase, protected XclExpRoot
744 {
745 public:
746     XclExpDxfs( const XclExpRoot& rRoot );
747 
748     sal_Int32 GetDxfId(const OUString& rName);
749 
750     virtual void SaveXml( XclExpXmlStream& rStrm) override;
751 private:
752     typedef std::vector< std::unique_ptr<XclExpDxf> > DxfContainer;
753     std::map<OUString, sal_Int32> maStyleNameToDxfId;
754     DxfContainer maDxf;
755     std::unique_ptr<NfKeywordTable>   mpKeywordTable; /// Replacement table.
756 };
757 
758 class XclExpXmlStyleSheet : public XclExpRecordBase, protected XclExpRoot
759 {
760 public:
761     explicit            XclExpXmlStyleSheet( const XclExpRoot& rRoot );
762 
763     virtual void        SaveXml( XclExpXmlStream& rStrm ) override;
764 };
765 
766 #endif
767 
768 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
769