File indexing completed on 2025-01-19 13:27:36

0001 /*
0002  * This file is part of Office 2007 Filters for Calligra
0003  *
0004  * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
0005  *
0006  * Contact: Suresh Chande suresh.chande@nokia.com
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Lesser General Public License
0010  * version 2.1 as published by the Free Software Foundation.
0011  *
0012  * This library is distributed in the hope that it will be useful, but
0013  * WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library; if not, write to the Free Software
0019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020  * 02110-1301 USA
0021  *
0022  */
0023 
0024 #ifndef XLSXXMLSTYLESREADER_H
0025 #define XLSXXMLSTYLESREADER_H
0026 
0027 #include <MsooXmlTheme.h>
0028 #include <QFlags>
0029 #include <QColor>
0030 
0031 #include "XlsxXmlCommonReader.h"
0032 
0033 class KoGenStyle;
0034 class XlsxImport;
0035 class XlsxStyles;
0036 class XlsxCellFormat;
0037 class XlsxXmlStylesReader;
0038 
0039 //! Single XLSX cell format definition as specified in ECMA-376, 18.8.10 (Cell Formats), p. 1956.
0040 /*! @see XlsxXmlStylesReader::read_cellXfs() */
0041 class XlsxCellFormat
0042 {
0043 public:
0044     XlsxCellFormat();
0045 
0046     ~XlsxCellFormat();
0047 
0048     //! 18.18.40 ST_HorizontalAlignment (Horizontal Alignment Type), p. 2698
0049     /*! The enumeration value indicating the portion of Cell Alignment in a cell format (XF)
0050         that is horizontal alignment, i.e., whether it is aligned general, left, right,
0051         horizontally centered, filled (replicated), justified, centered across multiple cells,
0052         or distributed. */
0053     enum ST_HorizontalAlignment {
0054         GeneralHorizontalAlignment,
0055         CenterHorizontalAlignment,
0056         CenterContinuousHorizontalAlignment,
0057         DistributedHorizontalAlignment,
0058         FillHorizontalAlignment,
0059         JustifyHorizontalAlignment,
0060         LeftHorizontalAlignment,
0061         RightHorizontalAlignment
0062     };
0063 
0064     //! 18.18.88 ST_VerticalAlignment (Vertical Alignment Types), p. 2755
0065     /*! This enumeration value indicates the type of vertical alignment for a cell,
0066         i.e., whether it is aligned top, bottom, vertically centered, justified or distributed. */
0067     enum ST_VerticalAlignment {
0068         NoVerticalAlignment,
0069         BottomVerticalAlignment,
0070         CenterVerticalAlignment,
0071         DistributedVerticalAlignment,
0072         JustifyVerticalAlignment,
0073         TopVerticalAlignment
0074     };
0075 
0076     //! Indicates whether the alignment formatting specified for this xf should be applied
0077 //! @todo should be saved as metadata in ODF
0078     bool applyAlignment;
0079 
0080     //! Indicates whether the border formatting specified for this xf should be applied.
0081 //! @todo should be saved as metadata in ODF
0082     bool applyBorder;
0083 
0084     //! Indicates whether the fill formatting specified for this xf should be applied.
0085 //! @todo should be saved as metadata in ODF
0086     bool applyFill;
0087 
0088     //! Indicates whether the font formatting specified for this xf should be applied.
0089 //! @todo should be saved as metadata in ODF
0090     bool applyFont;
0091 
0092     //! Indicates whether the number formatting specified for this xf should be applied.
0093     bool applyNumberFormat;
0094 
0095     //! Indicates whether the protection formatting specified for this xf should be applied.
0096     bool applyProtection;
0097 
0098     //! Zero-based index of the border record used by this cell format. Can be -1.
0099 //! @todo set pointer directly here for optimization?
0100     int borderId;
0101 
0102     //! Zero-based index of the fill record used by this cell format. Can be -1.
0103 //! @todo set pointer directly here for optimization?
0104     int fillId;
0105 
0106     //! Font id used in XlsXStyles::fontStyle(). Can be -1.
0107 //! @todo set pointer directly here for optimization?
0108     int fontId;
0109 
0110     //! Id of the number format (numFmt) record used by this cell format. Can be -1.
0111 //! @todo set pointer directly here for optimization?
0112     int numFmtId;
0113 
0114     //! Indicates whether the cell rendering includes a pivot table dropdown button.
0115     bool pivotButton;
0116 
0117     //! Indicates whether the text string in a cell should be prefixed by a single quote mark
0118     //! (e.g., 'text). In these cases, the quote is not stored in the Shared Strings Part.
0119     bool quotePrefix;
0120 
0121     //! For xf records contained in cellXfs this is the zero-based index of an xf record
0122     //! contained in cellStyleXfs corresponding to the cell style applied to the cell.
0123     //! Not present for xf records contained in cellStyleXfs. Can be -1.
0124 //! @todo set pointer directly here for optimization?
0125     int xfId;
0126 
0127 //! @todo should be saved as metadata in ODF if applyAlignment false
0128     ST_HorizontalAlignment horizontalAlignment;
0129 //! @todo should be saved as metadata in ODF if applyAlignment false
0130     ST_VerticalAlignment verticalAlignment;
0131 
0132     //! Indicates whether if the text in the cell should be line-wrapped with the cell.
0133     bool wrapText;
0134 
0135     //! Indicates whether the displayed text in a cell should be shrunk to fit the cell width.
0136     bool shrinkToFit;
0137 
0138     //! Text rotation in cells, expressed in degrees. (Undocumented? special case: 255 means
0139     //! vertical top-to-bottom-text without rotated characters
0140     uint textRotation;
0141 
0142     void setHorizontalAlignment(const QString& alignment);
0143     void setVerticalAlignment(const QString& alignment);
0144 
0145     //! Sets up @a cellStyle to match this cell style.
0146     //! @todo implement more styling
0147     bool setupCellStyle(const XlsxStyles *styles, KoGenStyle* cellStyle) const;
0148 
0149     //! Used by setupCellStyle() & read_dxf
0150     void setupCellStyleAlignment(KoGenStyle* cellStyle) const;
0151 };
0152 
0153 class XlsxStyles
0154 {
0155 public:
0156     XlsxStyles();
0157     ~XlsxStyles();
0158 
0159     //! @return font style for id @a id (counted from 0)
0160     KoGenStyle* fontStyle(int id) const {
0161         if (id < 0 || id >= fontStyles.size())
0162             return 0;
0163         return fontStyles[id];
0164     }
0165 
0166     //! @return fill style for id @a id (counted from 0)
0167     KoGenStyle* fillStyle(int id) const {
0168         if (id < 0 || id >= fillStyles.size())
0169             return 0;
0170         return fillStyles[id];
0171     }
0172 
0173     //! @return border style for id @a id (counted from 0)
0174     KoGenStyle* borderStyle(int id) const {
0175         if (id < 0 || id >= borderStyles.size())
0176             return 0;
0177         return borderStyles[id];
0178     }
0179 
0180     //! @return cell format for id @a id (counted from 0)
0181     XlsxCellFormat* cellFormat(int id) const {
0182         if (id < 0 || id >= cellFormats.size())
0183             return 0;
0184         return cellFormats[id];
0185     }
0186 
0187     //! @return number format string for id @a (counted from 0)
0188     QString numberFormatString( int id ) const
0189     {
0190         return numberFormatStrings[ id ];
0191     }
0192 
0193 //     //! @return the KoGenStyle the number-formatting style has
0194 //     KoGenStyle numberFormatStyle( int id ) const {
0195 //         return numberFormatStyles[ id ];
0196 //     }
0197 
0198     //! @return the KoGenStyle styleName the number-formatting style has
0199     QString numberFormatStyleName( int id ) const {
0200         return numberFormatStyleNames[ id ];
0201     }
0202 
0203     //! @return conditional style name for the given index
0204     QString conditionalStyle( int index ) const
0205     {
0206         return conditionalStyles[ index ];
0207     }
0208 
0209 protected:
0210     void setCellFormat(XlsxCellFormat *format, int cellFormatIndex);
0211 
0212     QVector<KoGenStyle*> fontStyles;
0213     QVector<KoGenStyle*> fillStyles;
0214     QVector<KoGenStyle*> borderStyles;
0215     QVector<XlsxCellFormat*> cellFormats;
0216     QMap< int, QString > numberFormatStrings;
0217 //     QMap< int, KoGenStyle > numberFormatStyles;
0218     QMap< int, QString > numberFormatStyleNames;
0219     QMap< int, QString > conditionalStyles;
0220 
0221     friend class XlsxXmlStylesReader;
0222 };
0223 
0224 class XlsxXmlStylesReaderContext : public MSOOXML::MsooXmlReaderContext
0225 {
0226 public:
0227     XlsxXmlStylesReaderContext(XlsxStyles& _styles, bool _skipFirstPart,
0228                                XlsxImport* _import,
0229                                MSOOXML::DrawingMLTheme* _themes);
0230     XlsxStyles* styles;
0231     bool skipFirstPart;
0232     XlsxImport* import;
0233     MSOOXML::DrawingMLTheme* themes;
0234     QVector<QString> colorIndices;
0235 };
0236 
0237 //! A class reading MSOOXML XLSX markup - styles.xml part.
0238 //! See ECMA-376, 12.3.20: Styles Part, p. 104
0239 class XlsxXmlStylesReader : public XlsxXmlCommonReader
0240 {
0241 public:
0242     explicit XlsxXmlStylesReader(KoOdfWriters *writers);
0243 
0244     ~XlsxXmlStylesReader() override;
0245 
0246     //! Reads/parses the file of format document.xml.
0247     //! The output goes mainly to KoXmlWriter* KoOdfWriters::body
0248     KoFilter::ConversionStatus read(MSOOXML::MsooXmlReaderContext* context = 0) override;
0249 
0250     enum DiagonalDirection {
0251         DiagonalUp = 1,
0252         DiagonalDown = 2
0253     };
0254     Q_DECLARE_FLAGS(DiagonalDirections, DiagonalDirection)
0255     DiagonalDirections diagonalDirections;
0256 
0257 protected:
0258     KoFilter::ConversionStatus readInternal();
0259     KoFilter::ConversionStatus read_styleSheet();
0260     KoFilter::ConversionStatus read_numFmts();
0261     KoFilter::ConversionStatus read_numFmt();
0262     KoFilter::ConversionStatus read_fonts();
0263     KoFilter::ConversionStatus read_font();
0264     KoFilter::ConversionStatus read_name();
0265     KoFilter::ConversionStatus read_cellXfs();
0266     KoFilter::ConversionStatus read_dxfs();
0267     KoFilter::ConversionStatus read_dxf();
0268     KoFilter::ConversionStatus read_xf();
0269     KoFilter::ConversionStatus read_alignment();
0270     KoFilter::ConversionStatus read_fills();
0271     KoFilter::ConversionStatus read_fill();
0272 //! @todo implement read_patternFill
0273     KoFilter::ConversionStatus read_patternFill();
0274     KoFilter::ConversionStatus read_bgColor();
0275     KoFilter::ConversionStatus read_fgColor();
0276 //! @todo implement read_gradientFill
0277     KoFilter::ConversionStatus read_gradientFill();
0278 //! @todo implement read_stop()
0279     KoFilter::ConversionStatus read_borders();
0280     KoFilter::ConversionStatus read_border();
0281     KoFilter::ConversionStatus read_top();
0282     KoFilter::ConversionStatus read_bottom();
0283     KoFilter::ConversionStatus read_left();
0284     KoFilter::ConversionStatus read_right();
0285     KoFilter::ConversionStatus read_diagonal();
0286     KoFilter::ConversionStatus read_colors();
0287     KoFilter::ConversionStatus read_indexedColors();
0288     KoFilter::ConversionStatus read_rgbColor();
0289 
0290     uint m_cellFormatIndex;
0291 
0292     XlsxXmlStylesReaderContext* m_context;
0293 
0294     QColor m_currentFgColor;
0295     QColor m_currentBgColor;
0296 
0297     KoGenStyle *m_currentFontStyle;
0298     KoGenStyle *m_currentFillStyle;
0299     XlsxCellFormat *m_currentCellFormat;
0300     KoGenStyle *m_currentBorderStyle;
0301 
0302     int m_colorIndex;
0303 
0304     KoFilter::ConversionStatus readAttributes(const QXmlStreamAttributes& attrs, QString& borderStyle);
0305 
0306 private:
0307     void init();
0308 
0309     class Private;
0310     Private* const d;
0311 };
0312 
0313 Q_DECLARE_OPERATORS_FOR_FLAGS(XlsxXmlStylesReader::DiagonalDirections)
0314 
0315 #endif //XLSXXMLSTYLESREADER_H