From 2e2a4ff9bc41a48eef3d6b76feb24b1720575277 Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Sat, 2 Nov 2013 14:26:59 +0800 Subject: [PATCH] Add read support for indexedColors Some old .xlsx files use indexed colors --- src/xlsx/xlsxstyles.cpp | 106 ++++++++++++++++++++++++++++++++++------ src/xlsx/xlsxstyles_p.h | 7 +++ 2 files changed, 98 insertions(+), 15 deletions(-) diff --git a/src/xlsx/xlsxstyles.cpp b/src/xlsx/xlsxstyles.cpp index a44ae87..ff9a406 100755 --- a/src/xlsx/xlsxstyles.cpp +++ b/src/xlsx/xlsxstyles.cpp @@ -620,7 +620,7 @@ bool Styles::readFonts(XmlStreamReader &reader) QString colorString = attributes.value(QLatin1String("rgb")).toString(); font->color = fromARGBString(colorString); } else if (attributes.hasAttribute(QLatin1String("indexed"))) { - + font->color = getColorByIndex(attributes.value(QLatin1String("indexed")).toInt()); } else if (attributes.hasAttribute(QLatin1String("theme"))) { } @@ -693,22 +693,26 @@ bool Styles::readFill(XmlStreamReader &reader) fill->pattern = patternValues.contains(pattern) ? patternValues[pattern] : Format::PatternNone; } else if (reader.name() == QLatin1String("fgColor")) { QXmlStreamAttributes attributes = reader.attributes(); - if (attributes.hasAttribute(QLatin1String("rgb"))) { - QColor c = fromARGBString(attributes.value(QLatin1String("rgb")).toString()); - if (fill->pattern == Format::PatternSolid) - fill->bgColor = c; - else - fill->fgColor = c; - } + QColor c; + if (attributes.hasAttribute(QLatin1String("rgb"))) + c = fromARGBString(attributes.value(QLatin1String("rgb")).toString()); + else if (attributes.hasAttribute(QLatin1String("indexed"))) + c = getColorByIndex(attributes.value(QLatin1String("indexed")).toInt()); + if (fill->pattern == Format::PatternSolid) + fill->bgColor = c; + else + fill->fgColor = c; } else if (reader.name() == QLatin1String("bgColor")) { QXmlStreamAttributes attributes = reader.attributes(); - if (attributes.hasAttribute(QLatin1String("rgb"))) { - QColor c = fromARGBString(attributes.value(QLatin1String("rgb")).toString()); - if (fill->pattern == Format::PatternSolid) - fill->fgColor = c; - else - fill->bgColor = c; - } + QColor c; + if (attributes.hasAttribute(QLatin1String("rgb"))) + c = fromARGBString(attributes.value(QLatin1String("rgb")).toString()); + else if (attributes.hasAttribute(QLatin1String("indexed"))) + c = getColorByIndex(attributes.value(QLatin1String("indexed")).toInt()); + if (fill->pattern == Format::PatternSolid) + fill->fgColor = c; + else + fill->bgColor = c; } } @@ -814,6 +818,8 @@ bool Styles::readSubBorder(XmlStreamReader &reader, const QString &name, Format: QString colorString = colorAttrs.value(QLatin1String("rgb")).toString(); //get color color = fromARGBString(colorString); + } else if (colorAttrs.hasAttribute(QLatin1String("indexed"))) { + color = getColorByIndex(colorAttrs.value(QLatin1String("indexed")).toInt()); } } @@ -940,8 +946,53 @@ bool Styles::readCellXfs(XmlStreamReader &reader) return true; } +bool Styles::readColors(XmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("colors")); + while (!(reader.name() == QLatin1String("colors") && reader.tokenType() == QXmlStreamReader::EndElement)) { + reader.readNextStartElement(); + if (reader.tokenType() == QXmlStreamReader::StartElement) { + if (reader.name() == QLatin1String("indexedColors")) { + readIndexedColors(reader); + } else if (reader.name() == QLatin1String("mruColors")) { + + } + } + } + return true; +} + +bool Styles::readIndexedColors(XmlStreamReader &reader) +{ + Q_ASSERT(reader.name() == QLatin1String("indexedColors")); + while (!(reader.name() == QLatin1String("indexedColors") && reader.tokenType() == QXmlStreamReader::EndElement)) { + reader.readNextStartElement(); + if (reader.tokenType() == QXmlStreamReader::StartElement) { + if (reader.name() == QLatin1String("rgbColor")) { + QString color = reader.attributes().value(QLatin1String("rgb")).toString(); + m_indexedColors.append(fromARGBString(color)); + } + } + } + return true; +} + bool Styles::loadFromXmlFile(QIODevice *device) { + { + //Try load colors part first! + XmlStreamReader reader(device); + while(!reader.atEnd()) { + QXmlStreamReader::TokenType token = reader.readNext(); + if (token == QXmlStreamReader::StartElement) { + if (reader.name() == QLatin1String("colors")) { + readColors(reader); + } + } + } + device->seek(0); + } + XmlStreamReader reader(device); while(!reader.atEnd()) { QXmlStreamReader::TokenType token = reader.readNext(); @@ -979,4 +1030,29 @@ bool Styles::loadFromXmlData(const QByteArray &data) return loadFromXmlFile(&buffer); } +QColor Styles::getColorByIndex(int idx) +{ + if (m_indexedColors.isEmpty()) { + m_indexedColors<= m_indexedColors.size()) + return QColor(); + return m_indexedColors[idx]; +} + } //namespace QXlsx diff --git a/src/xlsx/xlsxstyles_p.h b/src/xlsx/xlsxstyles_p.h index f985894..8f55f6e 100755 --- a/src/xlsx/xlsxstyles_p.h +++ b/src/xlsx/xlsxstyles_p.h @@ -32,6 +32,7 @@ #include #include #include +#include class QIODevice; class StylesTest; @@ -81,6 +82,10 @@ private: bool readBorder(XmlStreamReader &reader); bool readSubBorder(XmlStreamReader &reader, const QString &name, Format::BorderStyle &style, QColor &color); bool readCellXfs(XmlStreamReader &reader); + bool readColors(XmlStreamReader &reader); + bool readIndexedColors(XmlStreamReader &reader); + + QColor getColorByIndex(int idx); QHash m_builtinNumFmtsHash; QMap > m_customNumFmtIdMap; @@ -93,6 +98,8 @@ private: QHash > m_fillsHash; QHash > m_bordersHash; + QVector m_indexedColors; + QList > m_createdFormatsList; //All created formats QList m_xf_formatsList;