Mercurial > clickerconvert
view src/xlsx/xlsxformat.cpp @ 43:f9a0b2b6832e
Sanitize input and unify Lineendings
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Thu, 12 May 2016 17:35:49 +0200 |
parents | 93d3106bb9a4 |
children |
line wrap: on
line source
/**************************************************************************** ** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me> ** All right reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining ** a copy of this software and associated documentation files (the ** "Software"), to deal in the Software without restriction, including ** without limitation the rights to use, copy, modify, merge, publish, ** distribute, sublicense, and/or sell copies of the Software, and to ** permit persons to whom the Software is furnished to do so, subject to ** the following conditions: ** ** The above copyright notice and this permission notice shall be ** included in all copies or substantial portions of the Software. ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ** ****************************************************************************/ #include "xlsxformat.h" #include "xlsxformat_p.h" #include "xlsxcolor_p.h" #include "xlsxnumformatparser_p.h" #include <QDataStream> #include <QDebug> QT_BEGIN_NAMESPACE_XLSX FormatPrivate::FormatPrivate() : dirty(true) , font_dirty(true), font_index_valid(false), font_index(0) , fill_dirty(true), fill_index_valid(false), fill_index(0) , border_dirty(true), border_index_valid(false), border_index(0) , xf_index(-1), xf_indexValid(false) , is_dxf_fomat(false), dxf_index(-1), dxf_indexValid(false) , theme(0) { } FormatPrivate::FormatPrivate(const FormatPrivate &other) : QSharedData(other) , dirty(other.dirty), formatKey(other.formatKey) , font_dirty(other.font_dirty), font_index_valid(other.font_index_valid), font_key(other.font_key), font_index(other.font_index) , fill_dirty(other.fill_dirty), fill_index_valid(other.fill_index_valid), fill_key(other.fill_key), fill_index(other.fill_index) , border_dirty(other.border_dirty), border_index_valid(other.border_index_valid), border_key(other.border_key), border_index(other.border_index) , xf_index(other.xf_index), xf_indexValid(other.xf_indexValid) , is_dxf_fomat(other.is_dxf_fomat), dxf_index(other.dxf_index), dxf_indexValid(other.dxf_indexValid) , theme(other.theme) , properties(other.properties) { } FormatPrivate::~FormatPrivate() { } /*! * \class Format * \inmodule QtXlsx * \brief Providing the methods and properties that are available for formatting cells in Excel. */ /*! * \enum Format::FontScript * * The enum type defines the type of font script. * * \value FontScriptNormal normal * \value FontScriptSuper super script * \value FontScriptSub sub script */ /*! * \enum Format::FontUnderline * * The enum type defines the type of font underline. * * \value FontUnderlineNone * \value FontUnderlineSingle * \value FontUnderlineDouble * \value FontUnderlineSingleAccounting * \value FontUnderlineDoubleAccounting */ /*! * \enum Format::HorizontalAlignment * * The enum type defines the type of horizontal alignment. * * \value AlignHGeneral * \value AlignLeft * \value AlignHCenter * \value AlignRight * \value AlignHFill * \value AlignHJustify * \value AlignHMerge * \value AlignHDistributed */ /*! * \enum Format::VerticalAlignment * * The enum type defines the type of vertical alignment. * * \value AlignTop, * \value AlignVCenter, * \value AlignBottom, * \value AlignVJustify, * \value AlignVDistributed */ /*! * \enum Format::BorderStyle * * The enum type defines the type of font underline. * * \value BorderNone * \value BorderThin * \value BorderMedium * \value BorderDashed * \value BorderDotted * \value BorderThick * \value BorderDouble * \value BorderHair * \value BorderMediumDashed * \value BorderDashDot * \value BorderMediumDashDot * \value BorderDashDotDot * \value BorderMediumDashDotDot * \value BorderSlantDashDot */ /*! * \enum Format::DiagonalBorderType * * The enum type defines the type of diagonal border. * * \value DiagonalBorderNone * \value DiagonalBorderDown * \value DiagonalBorderUp * \value DiagnoalBorderBoth */ /*! * \enum Format::FillPattern * * The enum type defines the type of fill. * * \value PatternNone * \value PatternSolid * \value PatternMediumGray * \value PatternDarkGray * \value PatternLightGray * \value PatternDarkHorizontal * \value PatternDarkVertical * \value PatternDarkDown * \value PatternDarkUp * \value PatternDarkGrid * \value PatternDarkTrellis * \value PatternLightHorizontal * \value PatternLightVertical * \value PatternLightDown * \value PatternLightUp * \value PatternLightTrellis * \value PatternGray125 * \value PatternGray0625 * \value PatternLightGrid */ /*! * Creates a new invalid format. */ Format::Format() { //The d pointer is initialized with a null pointer } /*! Creates a new format with the same attributes as the \a other format. */ Format::Format(const Format &other) :d(other.d) { } /*! Assigns the \a other format to this format, and returns a reference to this format. */ Format &Format::operator =(const Format &other) { d = other.d; return *this; } /*! * Destroys this format. */ Format::~Format() { } /*! * Returns the number format identifier. */ int Format::numberFormatIndex() const { return intProperty(FormatPrivate::P_NumFmt_Id, 0); } /*! * Set the number format identifier. The \a format * must be a valid built-in number format identifier * or the identifier of a custom number format. */ void Format::setNumberFormatIndex(int format) { setProperty(FormatPrivate::P_NumFmt_Id, format); clearProperty(FormatPrivate::P_NumFmt_FormatCode); } /*! * Returns the number format string. * \note for built-in number formats, this may * return an empty string. */ QString Format::numberFormat() const { return stringProperty(FormatPrivate::P_NumFmt_FormatCode); } /*! * Set number \a format. * http://office.microsoft.com/en-001/excel-help/create-a-custom-number-format-HP010342372.aspx */ void Format::setNumberFormat(const QString &format) { if (format.isEmpty()) return; setProperty(FormatPrivate::P_NumFmt_FormatCode, format); clearProperty(FormatPrivate::P_NumFmt_Id); //numFmt id must be re-generated. } /*! * Returns whether the number format is probably a dateTime or not */ bool Format::isDateTimeFormat() const { if (hasProperty(FormatPrivate::P_NumFmt_FormatCode)) { //Custom numFmt, so //Gauss from the number string return NumFormatParser::isDateTime(numberFormat()); } else if (hasProperty(FormatPrivate::P_NumFmt_Id)){ //Non-custom numFmt int idx = numberFormatIndex(); //Is built-in date time number id? if ((idx >= 14 && idx <= 22) || (idx >= 45 && idx <= 47)) return true; if ((idx >= 27 && idx <= 36) || (idx >= 50 && idx <= 58)) //Used in CHS\CHT\JPN\KOR return true; } return false; } /*! \internal Set a custom num \a format with the given \a id. */ void Format::setNumberFormat(int id, const QString &format) { setProperty(FormatPrivate::P_NumFmt_Id, id); setProperty(FormatPrivate::P_NumFmt_FormatCode, format); } /*! \internal Called by styles to fix the numFmt */ void Format::fixNumberFormat(int id, const QString &format) { setProperty(FormatPrivate::P_NumFmt_Id, id, 0, false); setProperty(FormatPrivate::P_NumFmt_FormatCode, format, QString(), false); } /*! \internal Return true if the format has number format. */ bool Format::hasNumFmtData() const { if (!d) return false; if (hasProperty(FormatPrivate::P_NumFmt_Id) || hasProperty(FormatPrivate::P_NumFmt_FormatCode)) { return true; } return false; } /*! * Return the size of the font in points. */ int Format::fontSize() const { return intProperty(FormatPrivate::P_Font_Size); } /*! * Set the \a size of the font in points. */ void Format::setFontSize(int size) { setProperty(FormatPrivate::P_Font_Size, size, 0); } /*! * Return whether the font is italic. */ bool Format::fontItalic() const { return boolProperty(FormatPrivate::P_Font_Italic); } /*! * Turn on/off the italic font based on \a italic. */ void Format::setFontItalic(bool italic) { setProperty(FormatPrivate::P_Font_Italic, italic, false); } /*! * Return whether the font is strikeout. */ bool Format::fontStrikeOut() const { return boolProperty(FormatPrivate::P_Font_StrikeOut); } /*! * Turn on/off the strikeOut font based on \a strikeOut. */ void Format::setFontStrikeOut(bool strikeOut) { setProperty(FormatPrivate::P_Font_StrikeOut, strikeOut, false); } /*! * Return the color of the font. */ QColor Format::fontColor() const { if (hasProperty(FormatPrivate::P_Font_Color)) return colorProperty(FormatPrivate::P_Font_Color); return QColor(); } /*! * Set the \a color of the font. */ void Format::setFontColor(const QColor &color) { setProperty(FormatPrivate::P_Font_Color, XlsxColor(color), XlsxColor()); } /*! * Return whether the font is bold. */ bool Format::fontBold() const { return boolProperty(FormatPrivate::P_Font_Bold); } /*! * Turn on/off the bold font based on the given \a bold. */ void Format::setFontBold(bool bold) { setProperty(FormatPrivate::P_Font_Bold, bold, false); } /*! * Return the script style of the font. */ Format::FontScript Format::fontScript() const { return static_cast<Format::FontScript>(intProperty(FormatPrivate::P_Font_Script)); } /*! * Set the script style of the font to \a script. */ void Format::setFontScript(FontScript script) { setProperty(FormatPrivate::P_Font_Script, script, FontScriptNormal); } /*! * Return the underline style of the font. */ Format::FontUnderline Format::fontUnderline() const { return static_cast<Format::FontUnderline>(intProperty(FormatPrivate::P_Font_Underline)); } /*! * Set the underline style of the font to \a underline. */ void Format::setFontUnderline(FontUnderline underline) { setProperty(FormatPrivate::P_Font_Underline, underline, FontUnderlineNone); } /*! * Return whether the font is outline. */ bool Format::fontOutline() const { return boolProperty(FormatPrivate::P_Font_Outline); } /*! * Turn on/off the outline font based on \a outline. */ void Format::setFontOutline(bool outline) { setProperty(FormatPrivate::P_Font_Outline, outline, false); } /*! * Return the name of the font. */ QString Format::fontName() const { return stringProperty(FormatPrivate::P_Font_Name, QStringLiteral("Calibri")); } /*! * Set the name of the font to \a name. */ void Format::setFontName(const QString &name) { setProperty(FormatPrivate::P_Font_Name, name, QStringLiteral("Calibri")); } /*! * Returns a QFont object based on font data contained in the format. */ QFont Format::font() const { QFont font; font.setFamily(fontName()); if (fontSize() > 0) font.setPointSize(fontSize()); font.setBold(fontBold()); font.setItalic(fontItalic()); font.setUnderline(fontUnderline()!=FontUnderlineNone); font.setStrikeOut(fontStrikeOut()); return font; } /*! * Set the format properties from the given \a font. */ void Format::setFont(const QFont &font) { setFontName(font.family()); if (font.pointSize() > 0) setFontSize(font.pointSize()); setFontBold(font.bold()); setFontItalic(font.italic()); setFontUnderline(font.underline() ? FontUnderlineSingle : FontUnderlineNone); setFontStrikeOut(font.strikeOut()); } /*! * \internal * When the format has font data, when need to assign a valid index for it. * The index value is depend on the order <fonts > in styles.xml */ bool Format::fontIndexValid() const { if (!hasFontData()) return false; return d->font_index_valid; } /*! * \internal */ int Format::fontIndex() const { if (fontIndexValid()) return d->font_index; return 0; } /*! * \internal */ void Format::setFontIndex(int index) { d->font_index = index; d->font_index_valid = true; } /*! * \internal */ QByteArray Format::fontKey() const { if (isEmpty()) return QByteArray(); if (d->font_dirty) { QByteArray key; QDataStream stream(&key, QIODevice::WriteOnly); for (int i=FormatPrivate::P_Font_STARTID; i<FormatPrivate::P_Font_ENDID; ++i) { if (d->properties.contains(i)) stream << i << d->properties[i]; }; const_cast<Format*>(this)->d->font_key = key; const_cast<Format*>(this)->d->font_dirty = false; } return d->font_key; } /*! \internal Return true if the format has font format, otherwise return false. */ bool Format::hasFontData() const { if (!d) return false; for (int i=FormatPrivate::P_Font_STARTID; i<FormatPrivate::P_Font_ENDID; ++i) { if (hasProperty(i)) return true; } return false; } /*! * Return the horizontal alignment. */ Format::HorizontalAlignment Format::horizontalAlignment() const { return static_cast<Format::HorizontalAlignment>(intProperty(FormatPrivate::P_Alignment_AlignH, AlignHGeneral)); } /*! * Set the horizontal alignment with the given \a align. */ void Format::setHorizontalAlignment(HorizontalAlignment align) { if (hasProperty(FormatPrivate::P_Alignment_Indent) &&(align != AlignHGeneral && align != AlignLeft && align != AlignRight && align != AlignHDistributed)) { clearProperty(FormatPrivate::P_Alignment_Indent); } if (hasProperty(FormatPrivate::P_Alignment_ShinkToFit) && (align == AlignHFill || align == AlignHJustify || align == AlignHDistributed)) { clearProperty(FormatPrivate::P_Alignment_ShinkToFit); } setProperty(FormatPrivate::P_Alignment_AlignH, align, AlignHGeneral); } /*! * Return the vertical alignment. */ Format::VerticalAlignment Format::verticalAlignment() const { return static_cast<Format::VerticalAlignment>(intProperty(FormatPrivate::P_Alignment_AlignV, AlignBottom)); } /*! * Set the vertical alignment with the given \a align. */ void Format::setVerticalAlignment(VerticalAlignment align) { setProperty(FormatPrivate::P_Alignment_AlignV, align, AlignBottom); } /*! * Return whether the cell text is wrapped. */ bool Format::textWrap() const { return boolProperty(FormatPrivate::P_Alignment_Wrap); } /*! * Enable the text wrap if \a wrap is true. */ void Format::setTextWarp(bool wrap) { if (wrap && hasProperty(FormatPrivate::P_Alignment_ShinkToFit)) clearProperty(FormatPrivate::P_Alignment_ShinkToFit); setProperty(FormatPrivate::P_Alignment_Wrap, wrap, false); } /*! * Return the text rotation. */ int Format::rotation() const { return intProperty(FormatPrivate::P_Alignment_Rotation); } /*! * Set the text roation with the given \a rotation. Must be in the range [0, 180] or 255. */ void Format::setRotation(int rotation) { setProperty(FormatPrivate::P_Alignment_Rotation, rotation, 0); } /*! * Return the text indentation level. */ int Format::indent() const { return intProperty(FormatPrivate::P_Alignment_Indent); } /*! * Set the text indentation level with the given \a indent. Must be less than or equal to 15. */ void Format::setIndent(int indent) { if (indent && hasProperty(FormatPrivate::P_Alignment_AlignH)) { HorizontalAlignment hl = horizontalAlignment(); if (hl != AlignHGeneral && hl != AlignLeft && hl!= AlignRight && hl!= AlignHJustify) { setHorizontalAlignment(AlignLeft); } } setProperty(FormatPrivate::P_Alignment_Indent, indent, 0); } /*! * Return whether the cell is shrink to fit. */ bool Format::shrinkToFit() const { return boolProperty(FormatPrivate::P_Alignment_ShinkToFit); } /*! * Turn on/off shrink to fit base on \a shink. */ void Format::setShrinkToFit(bool shink) { if (shink && hasProperty(FormatPrivate::P_Alignment_Wrap)) clearProperty(FormatPrivate::P_Alignment_Wrap); if (shink && hasProperty(FormatPrivate::P_Alignment_AlignH)) { HorizontalAlignment hl = horizontalAlignment(); if (hl == AlignHFill || hl == AlignHJustify || hl == AlignHDistributed) setHorizontalAlignment(AlignLeft); } setProperty(FormatPrivate::P_Alignment_ShinkToFit, shink, false); } /*! * \internal */ bool Format::hasAlignmentData() const { if (!d) return false; for (int i=FormatPrivate::P_Alignment_STARTID; i<FormatPrivate::P_Alignment_ENDID; ++i) { if (hasProperty(i)) return true; } return false; } /*! * Set the border style with the given \a style. */ void Format::setBorderStyle(BorderStyle style) { setLeftBorderStyle(style); setRightBorderStyle(style); setBottomBorderStyle(style); setTopBorderStyle(style); } /*! * Sets the border color with the given \a color. */ void Format::setBorderColor(const QColor &color) { setLeftBorderColor(color); setRightBorderColor(color); setTopBorderColor(color); setBottomBorderColor(color); } /*! * Returns the left border style */ Format::BorderStyle Format::leftBorderStyle() const { return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_LeftStyle)); } /*! * Sets the left border style to \a style */ void Format::setLeftBorderStyle(BorderStyle style) { setProperty(FormatPrivate::P_Border_LeftStyle, style, BorderNone); } /*! * Returns the left border color */ QColor Format::leftBorderColor() const { return colorProperty(FormatPrivate::P_Border_LeftColor); } /*! Sets the left border color to the given \a color */ void Format::setLeftBorderColor(const QColor &color) { setProperty(FormatPrivate::P_Border_LeftColor, XlsxColor(color), XlsxColor()); } /*! Returns the right border style. */ Format::BorderStyle Format::rightBorderStyle() const { return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_RightStyle)); } /*! Sets the right border style to the given \a style. */ void Format::setRightBorderStyle(BorderStyle style) { setProperty(FormatPrivate::P_Border_RightStyle, style, BorderNone); } /*! Returns the right border color. */ QColor Format::rightBorderColor() const { return colorProperty(FormatPrivate::P_Border_RightColor); } /*! Sets the right border color to the given \a color */ void Format::setRightBorderColor(const QColor &color) { setProperty(FormatPrivate::P_Border_RightColor, XlsxColor(color), XlsxColor()); } /*! Returns the top border style. */ Format::BorderStyle Format::topBorderStyle() const { return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_TopStyle)); } /*! Sets the top border style to the given \a style. */ void Format::setTopBorderStyle(BorderStyle style) { setProperty(FormatPrivate::P_Border_TopStyle, style, BorderNone); } /*! Returns the top border color. */ QColor Format::topBorderColor() const { return colorProperty(FormatPrivate::P_Border_TopColor); } /*! Sets the top border color to the given \a color. */ void Format::setTopBorderColor(const QColor &color) { setProperty(FormatPrivate::P_Border_TopColor, XlsxColor(color), XlsxColor()); } /*! Returns the bottom border style. */ Format::BorderStyle Format::bottomBorderStyle() const { return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_BottomStyle)); } /*! Sets the bottom border style to the given \a style. */ void Format::setBottomBorderStyle(BorderStyle style) { setProperty(FormatPrivate::P_Border_BottomStyle, style, BorderNone); } /*! Returns the bottom border color. */ QColor Format::bottomBorderColor() const { return colorProperty(FormatPrivate::P_Border_BottomColor); } /*! Sets the bottom border color to the given \a color. */ void Format::setBottomBorderColor(const QColor &color) { setProperty(FormatPrivate::P_Border_BottomColor, XlsxColor(color), XlsxColor()); } /*! Return the diagonla border style. */ Format::BorderStyle Format::diagonalBorderStyle() const { return static_cast<BorderStyle>(intProperty(FormatPrivate::P_Border_DiagonalStyle)); } /*! Sets the diagonal border style to the given \a style. */ void Format::setDiagonalBorderStyle(BorderStyle style) { setProperty(FormatPrivate::P_Border_DiagonalStyle, style, BorderNone); } /*! Returns the diagonal border type. */ Format::DiagonalBorderType Format::diagonalBorderType() const { return static_cast<DiagonalBorderType>(intProperty(FormatPrivate::P_Border_DiagonalType)); } /*! Sets the diagonal border type to the given \a style */ void Format::setDiagonalBorderType(DiagonalBorderType style) { setProperty(FormatPrivate::P_Border_DiagonalType, style, DiagonalBorderNone); } /*! Returns the diagonal border color. */ QColor Format::diagonalBorderColor() const { return colorProperty(FormatPrivate::P_Border_DiagonalColor); } /*! Sets the diagonal border color to the given \a color */ void Format::setDiagonalBorderColor(const QColor &color) { setProperty(FormatPrivate::P_Border_DiagonalColor, XlsxColor(color), XlsxColor()); } /*! \internal Returns whether this format has been set valid border index. */ bool Format::borderIndexValid() const { if (!hasBorderData()) return false; return d->border_index_valid; } /*! \internal Returns the border index. */ int Format::borderIndex() const { if (borderIndexValid()) return d->border_index; return 0; } /*! * \internal */ void Format::setBorderIndex(int index) { d->border_index = index; d->border_index_valid = true; } /*! \internal */ QByteArray Format::borderKey() const { if (isEmpty()) return QByteArray(); if (d->border_dirty) { QByteArray key; QDataStream stream(&key, QIODevice::WriteOnly); for (int i=FormatPrivate::P_Border_STARTID; i<FormatPrivate::P_Border_ENDID; ++i) { if (d->properties.contains(i)) stream << i << d->properties[i]; }; const_cast<Format*>(this)->d->border_key = key; const_cast<Format*>(this)->d->border_dirty = false; } return d->border_key; } /*! \internal Return true if the format has border format, otherwise return false. */ bool Format::hasBorderData() const { if (!d) return false; for (int i=FormatPrivate::P_Border_STARTID; i<FormatPrivate::P_Border_ENDID; ++i) { if (hasProperty(i)) return true; } return false; } /*! Return the fill pattern. */ Format::FillPattern Format::fillPattern() const { return static_cast<FillPattern>(intProperty(FormatPrivate::P_Fill_Pattern, PatternNone)); } /*! Sets the fill pattern to the given \a pattern. */ void Format::setFillPattern(FillPattern pattern) { setProperty(FormatPrivate::P_Fill_Pattern, pattern, PatternNone); } /*! Returns the foreground color of the pattern. */ QColor Format::patternForegroundColor() const { return colorProperty(FormatPrivate::P_Fill_FgColor); } /*! Sets the foreground color of the pattern with the given \a color. */ void Format::setPatternForegroundColor(const QColor &color) { if (color.isValid() && !hasProperty(FormatPrivate::P_Fill_Pattern)) setFillPattern(PatternSolid); setProperty(FormatPrivate::P_Fill_FgColor, XlsxColor(color), XlsxColor()); } /*! Returns the background color of the pattern. */ QColor Format::patternBackgroundColor() const { return colorProperty(FormatPrivate::P_Fill_BgColor); } /*! Sets the background color of the pattern with the given \a color. */ void Format::setPatternBackgroundColor(const QColor &color) { if (color.isValid() && !hasProperty(FormatPrivate::P_Fill_Pattern)) setFillPattern(PatternSolid); setProperty(FormatPrivate::P_Fill_BgColor, XlsxColor(color), XlsxColor()); } /*! * \internal */ bool Format::fillIndexValid() const { if (!hasFillData()) return false; return d->fill_index_valid; } /*! * \internal */ int Format::fillIndex() const { if (fillIndexValid()) return d->fill_index; return 0; } /*! * \internal */ void Format::setFillIndex(int index) { d->fill_index = index; d->fill_index_valid = true; } /*! * \internal */ QByteArray Format::fillKey() const { if (isEmpty()) return QByteArray(); if (d->fill_dirty) { QByteArray key; QDataStream stream(&key, QIODevice::WriteOnly); for (int i=FormatPrivate::P_Fill_STARTID; i<FormatPrivate::P_Fill_ENDID; ++i) { if (d->properties.contains(i)) stream << i << d->properties[i]; }; const_cast<Format*>(this)->d->fill_key = key; const_cast<Format*>(this)->d->fill_dirty = false; } return d->fill_key; } /*! \internal Return true if the format has fill format, otherwise return false. */ bool Format::hasFillData() const { if (!d) return false; for (int i=FormatPrivate::P_Fill_STARTID; i<FormatPrivate::P_Fill_ENDID; ++i) { if (hasProperty(i)) return true; } return false; } /*! Returns whether the hidden protection property is set to true. */ bool Format::hidden() const { return boolProperty(FormatPrivate::P_Protection_Hidden); } /*! Sets the hidden protection property with the given \a hidden. */ void Format::setHidden(bool hidden) { setProperty(FormatPrivate::P_Protection_Hidden, hidden); } /*! Returns whether the locked protection property is set to true. */ bool Format::locked() const { return boolProperty(FormatPrivate::P_Protection_Locked); } /*! Sets the locked protection property with the given \a locked. */ void Format::setLocked(bool locked) { setProperty(FormatPrivate::P_Protection_Locked, locked); } /*! \internal Return true if the format has protection data, otherwise return false. */ bool Format::hasProtectionData() const { if (!d) return false; if (hasProperty(FormatPrivate::P_Protection_Hidden || FormatPrivate::P_Protection_Locked)) { return true; } return false; } /*! Merges the current format with the properties described by format \a modifier. */ void Format::mergeFormat(const Format &modifier) { if (!modifier.isValid()) return; if (!isValid()) { d = modifier.d; return; } QMapIterator<int, QVariant> it(modifier.d->properties); while(it.hasNext()) { it.next(); setProperty(it.key(), it.value()); } } /*! Returns true if the format is valid; otherwise returns false. */ bool Format::isValid() const { if (d) return true; return false; } /*! Returns true if the format is empty; otherwise returns false. */ bool Format::isEmpty() const { if (!d) return true; return d->properties.isEmpty(); } /*! * \internal */ QByteArray Format::formatKey() const { if (isEmpty()) return QByteArray(); if (d->dirty) { QByteArray key; QDataStream stream(&key, QIODevice::WriteOnly); QMapIterator<int, QVariant> i(d->properties); while (i.hasNext()) { i.next(); stream<<i.key()<<i.value(); } d->formatKey = key; d->dirty = false; } return d->formatKey; } /*! * \internal * Called by QXlsx::Styles or some unittests. */ void Format::setXfIndex(int index) { if (!d) d = new FormatPrivate; d->xf_index = index; d->xf_indexValid = true; } /*! * \internal */ int Format::xfIndex() const { if (!d) return -1; return d->xf_index; } /*! * \internal */ bool Format::xfIndexValid() const { if (!d) return false; return d->xf_indexValid; } /*! * \internal * Called by QXlsx::Styles or some unittests. */ void Format::setDxfIndex(int index) { if (!d) d = new FormatPrivate; d->dxf_index = index; d->dxf_indexValid = true; } /*! * \internal * Returns the index in the styles dxfs. */ int Format::dxfIndex() const { if (!d) return -1; return d->dxf_index; } /*! * \internal * Returns whether the dxf index is valid or not. */ bool Format::dxfIndexValid() const { if (!d) return false; return d->dxf_indexValid; } /*! Returns ture if the \a format is equal to this format. */ bool Format::operator ==(const Format &format) const { return this->formatKey() == format.formatKey(); } /*! Returns ture if the \a format is not equal to this format. */ bool Format::operator !=(const Format &format) const { return this->formatKey() != format.formatKey(); } int Format::theme() const { return d->theme; } /*! * \internal */ QVariant Format::property(int propertyId, const QVariant &defaultValue) const { if (d && d->properties.contains(propertyId)) return d->properties[propertyId]; return defaultValue; } /*! * \internal */ void Format::setProperty(int propertyId, const QVariant &value, const QVariant &clearValue, bool detach) { if (!d) d = new FormatPrivate; if (value != clearValue) { if (d->properties.contains(propertyId) && d->properties[propertyId] == value) return; if (detach) d.detach(); d->properties[propertyId] = value; } else { if (!d->properties.contains(propertyId)) return; if (detach) d.detach(); d->properties.remove(propertyId); } d->dirty = true; d->xf_indexValid = false; d->dxf_indexValid = false; if (propertyId >= FormatPrivate::P_Font_STARTID && propertyId < FormatPrivate::P_Font_ENDID) { d->font_dirty = true; d->font_index_valid = false; } else if (propertyId >= FormatPrivate::P_Border_STARTID && propertyId < FormatPrivate::P_Border_ENDID) { d->border_dirty = true; d->border_index_valid = false; } else if (propertyId >= FormatPrivate::P_Fill_STARTID && propertyId < FormatPrivate::P_Fill_ENDID) { d->fill_dirty = true; d->fill_index_valid = false; } } /*! * \internal */ void Format::clearProperty(int propertyId) { setProperty(propertyId, QVariant()); } /*! * \internal */ bool Format::hasProperty(int propertyId) const { if (!d) return false; return d->properties.contains(propertyId); } /*! * \internal */ bool Format::boolProperty(int propertyId, bool defaultValue) const { if (!hasProperty(propertyId)) return defaultValue; const QVariant prop = d->properties[propertyId]; if (prop.userType() != QMetaType::Bool) return defaultValue; return prop.toBool(); } /*! * \internal */ int Format::intProperty(int propertyId, int defaultValue) const { if (!hasProperty(propertyId)) return defaultValue; const QVariant prop = d->properties[propertyId]; if (prop.userType() != QMetaType::Int) return defaultValue; return prop.toInt(); } /*! * \internal */ double Format::doubleProperty(int propertyId, double defaultValue) const { if (!hasProperty(propertyId)) return defaultValue; const QVariant prop = d->properties[propertyId]; if (prop.userType() != QMetaType::Double && prop.userType() != QMetaType::Float) return defaultValue; return prop.toDouble(); } /*! * \internal */ QString Format::stringProperty(int propertyId, const QString &defaultValue) const { if (!hasProperty(propertyId)) return defaultValue; const QVariant prop = d->properties[propertyId]; if (prop.userType() != QMetaType::QString) return defaultValue; return prop.toString(); } /*! * \internal */ QColor Format::colorProperty(int propertyId, const QColor &defaultValue) const { if (!hasProperty(propertyId)) return defaultValue; const QVariant prop = d->properties[propertyId]; if (prop.userType() != qMetaTypeId<XlsxColor>()) return defaultValue; return qvariant_cast<XlsxColor>(prop).rgbColor(); } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const Format &f) { dbg.nospace() << "QXlsx::Format(" << f.d->properties << ")"; return dbg.space(); } #endif QT_END_NAMESPACE_XLSX