Browse Source

Add internal support for dxf format

test needed.
master
Debao Zhang 12 years ago
parent
commit
2273a967a9
  1. 21
      src/xlsx/xlsxformat.cpp
  2. 5
      src/xlsx/xlsxformat.h
  3. 289
      src/xlsx/xlsxstyles.cpp
  4. 18
      src/xlsx/xlsxstyles_p.h
  5. 26
      src/xlsx/xlsxworksheet.cpp
  6. 18
      tests/auto/styles/tst_stylestest.cpp

21
src/xlsx/xlsxformat.cpp

@ -283,6 +283,16 @@ void Format::setNumberFormat(int id, const QString &format)
setProperty(FormatPrivate::P_NumFmt_FormatCode, format); 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, false);
setProperty(FormatPrivate::P_NumFmt_FormatCode, format, false);
}
/*! /*!
\internal \internal
Return true if the format has number format. Return true if the format has number format.
@ -1170,13 +1180,6 @@ bool Format::operator !=(const Format &format) const
return this->formatKey() != format.formatKey(); return this->formatKey() != format.formatKey();
} }
bool Format::isDxfFormat() const
{
if (!d)
return false;
return d->is_dxf_fomat;
}
int Format::theme() const int Format::theme() const
{ {
return d->theme; return d->theme;
@ -1195,7 +1198,7 @@ QVariant Format::property(int propertyId) const
/*! /*!
* \internal * \internal
*/ */
void Format::setProperty(int propertyId, const QVariant &value) void Format::setProperty(int propertyId, const QVariant &value, bool detach)
{ {
if (!d) if (!d)
d = new FormatPrivate; d = new FormatPrivate;
@ -1203,11 +1206,13 @@ void Format::setProperty(int propertyId, const QVariant &value)
if (value.isValid()) { if (value.isValid()) {
if (d->property.contains(propertyId) && d->property[propertyId] == value) if (d->property.contains(propertyId) && d->property[propertyId] == value)
return; return;
if (detach)
d.detach(); d.detach();
d->property[propertyId] = value; d->property[propertyId] = value;
} else { } else {
if (!d->property.contains(propertyId)) if (!d->property.contains(propertyId))
return; return;
if (detach)
d.detach(); d.detach();
d->property.remove(propertyId); d->property.remove(propertyId);
} }

5
src/xlsx/xlsxformat.h

@ -220,7 +220,7 @@ public:
bool operator != (const Format &format) const; bool operator != (const Format &format) const;
QVariant property(int propertyId) const; QVariant property(int propertyId) const;
void setProperty(int propertyId, const QVariant &value); void setProperty(int propertyId, const QVariant &value, bool detach=true);
void clearProperty(int propertyId); void clearProperty(int propertyId);
bool hasProperty(int propertyId) const; bool hasProperty(int propertyId) const;
@ -239,6 +239,8 @@ private:
friend class ::FormatTest; friend class ::FormatTest;
friend Q_XLSX_EXPORT QDebug operator<<(QDebug, const Format &f); friend Q_XLSX_EXPORT QDebug operator<<(QDebug, const Format &f);
void fixNumberFormat(int id, const QString &format);
bool fontIndexValid() const; bool fontIndexValid() const;
int fontIndex() const; int fontIndex() const;
void setFontIndex(int index); void setFontIndex(int index);
@ -265,7 +267,6 @@ private:
bool xfIndexValid() const; bool xfIndexValid() const;
int xfIndex() const; int xfIndex() const;
void setXfIndex(int index); void setXfIndex(int index);
bool isDxfFormat() const;
bool dxfIndexValid() const; bool dxfIndexValid() const;
int dxfIndex() const; int dxfIndex() const;
void setDxfIndex(int index); void setDxfIndex(int index);

289
src/xlsx/xlsxstyles.cpp

@ -48,7 +48,7 @@ Styles::Styles(bool createEmpty)
if (!createEmpty) { if (!createEmpty) {
//Add default Format //Add default Format
Format defaultFmt; Format defaultFmt;
addFormat(defaultFmt); addXfFormat(defaultFmt);
//Add another fill format //Add another fill format
Format fillFmt; Format fillFmt;
@ -70,24 +70,24 @@ Format Styles::xfFormat(int idx) const
return m_xf_formatsList[idx]; return m_xf_formatsList[idx];
} }
/* Format Styles::dxfFormat(int idx) const
Assign index to Font/Fill/Border and Format {
if (idx <0 || idx >= m_dxf_formatsList.size())
return Format();
When \a force is true, add the format to the format list, even other format has return m_dxf_formatsList[idx];
the same key have been in. }
This is useful when reading existing .xlsx files which may contains duplicated formats.
*/ void Styles::fixNumFmt(const Format &format)
void Styles::addFormat(const Format &format, bool force)
{ {
if (format.isEmpty()) { if (!format.hasNumFmtData())
//Try do something for empty Format. return;
if (m_emptyFormatAdded)
if (format.hasProperty(FormatPrivate::P_NumFmt_Id)
&& !format.stringProperty(FormatPrivate::P_NumFmt_FormatCode).isEmpty()) {
return; return;
m_emptyFormatAdded = true;
} }
//numFmt
if (format.hasNumFmtData() && !format.hasProperty(FormatPrivate::P_NumFmt_Id)) {
if (m_builtinNumFmtsHash.isEmpty()) { if (m_builtinNumFmtsHash.isEmpty()) {
m_builtinNumFmtsHash.insert(QStringLiteral("General"), 0); m_builtinNumFmtsHash.insert(QStringLiteral("General"), 0);
m_builtinNumFmtsHash.insert(QStringLiteral("0"), 1); m_builtinNumFmtsHash.insert(QStringLiteral("0"), 1);
@ -127,15 +127,17 @@ void Styles::addFormat(const Format &format, bool force)
m_builtinNumFmtsHash.insert(QStringLiteral("##0.0E+0"), 48); m_builtinNumFmtsHash.insert(QStringLiteral("##0.0E+0"), 48);
m_builtinNumFmtsHash.insert(QStringLiteral("@"), 49); m_builtinNumFmtsHash.insert(QStringLiteral("@"), 49);
} }
const QString str = format.numberFormat(); const QString str = format.numberFormat();
if (!str.isEmpty()) {
//Assign proper number format index //Assign proper number format index
if (m_builtinNumFmtsHash.contains(str)) { if (m_builtinNumFmtsHash.contains(str)) {
const_cast<Format *>(&format)->setNumberFormat(m_builtinNumFmtsHash[str], str); const_cast<Format *>(&format)->fixNumberFormat(m_builtinNumFmtsHash[str], str);
} else if (m_customNumFmtsHash.contains(str)) { } else if (m_customNumFmtsHash.contains(str)) {
const_cast<Format *>(&format)->setNumberFormat(m_customNumFmtsHash[str]->formatIndex, str); const_cast<Format *>(&format)->fixNumberFormat(m_customNumFmtsHash[str]->formatIndex, str);
} else { } else {
//Assign a new fmt Id. //Assign a new fmt Id.
const_cast<Format *>(&format)->setNumberFormat(m_nextCustomNumFmtId, str); const_cast<Format *>(&format)->fixNumberFormat(m_nextCustomNumFmtId, str);
QSharedPointer<XlsxFormatNumberData> fmt(new XlsxFormatNumberData); QSharedPointer<XlsxFormatNumberData> fmt(new XlsxFormatNumberData);
fmt->formatIndex = m_nextCustomNumFmtId; fmt->formatIndex = m_nextCustomNumFmtId;
@ -145,8 +147,50 @@ void Styles::addFormat(const Format &format, bool force)
m_nextCustomNumFmtId += 1; m_nextCustomNumFmtId += 1;
} }
} else {
int id = format.numberFormatIndex();
//Assign proper format code, this is needed by dxf format
if (m_customNumFmtIdMap.contains(id)) {
const_cast<Format *>(&format)->fixNumberFormat(id, m_customNumFmtIdMap[id]->formatString);
} else {
QHashIterator<QString, int> it(m_builtinNumFmtsHash);
bool find=false;
while(it.hasNext()) {
it.next();
if (it.value() == id)
const_cast<Format *>(&format)->fixNumberFormat(id, it.key());
find = true;
break;
}
if (!find) {
//Wrong numFmt
const_cast<Format *>(&format)->fixNumberFormat(id, QStringLiteral("General"));
}
}
}
}
/*
Assign index to Font/Fill/Border and Format
When \a force is true, add the format to the format list, even other format has
the same key have been in.
This is useful when reading existing .xlsx files which may contains duplicated formats.
*/
void Styles::addXfFormat(const Format &format, bool force)
{
if (format.isEmpty()) {
//Try do something for empty Format.
if (m_emptyFormatAdded)
return;
m_emptyFormatAdded = true;
} }
//numFmt
if (format.hasNumFmtData() && !format.hasProperty(FormatPrivate::P_NumFmt_Id))
fixNumFmt(format);
//Font //Font
if (format.hasFontData() && !format.fontIndexValid()) { if (format.hasFontData() && !format.fontIndexValid()) {
//Assign proper font index, if has font data. //Assign proper font index, if has font data.
@ -190,17 +234,6 @@ void Styles::addFormat(const Format &format, bool force)
} }
//Format //Format
// if (format.isDxfFormat()) {
// if (!format.dxfIndexValid()) {
// if (!m_dxf_formatsHash.contains(format.formatKey())) {
// const_cast<Format *>(&format)->setDxfIndex(m_dxf_formatsList.size());
// m_dxf_formatsList.append(format);
// m_dxf_formatsHash[format.formatKey()] = format;
// } else {
// const_cast<Format *>(&format)->setDxfIndex(m_dxf_formatsHash[format.formatKey()].dxfIndex());
// }
// }
// } else {
if (!format.isEmpty() && !format.xfIndexValid()) { if (!format.isEmpty() && !format.xfIndexValid()) {
if (m_xf_formatsHash.contains(format.formatKey())) if (m_xf_formatsHash.contains(format.formatKey()))
const_cast<Format *>(&format)->setXfIndex(m_xf_formatsHash[format.formatKey()].xfIndex()); const_cast<Format *>(&format)->setXfIndex(m_xf_formatsHash[format.formatKey()].xfIndex());
@ -211,7 +244,24 @@ void Styles::addFormat(const Format &format, bool force)
m_xf_formatsList.append(format); m_xf_formatsList.append(format);
m_xf_formatsHash[format.formatKey()] = format; m_xf_formatsHash[format.formatKey()] = format;
} }
// } }
void Styles::addDxfFormat(const Format &format, bool force)
{
//numFmt
if (format.hasNumFmtData())
fixNumFmt(format);
if (!format.isEmpty() && !format.dxfIndexValid()) {
if (m_dxf_formatsHash.contains(format.formatKey()))
const_cast<Format *>(&format)->setDxfIndex(m_dxf_formatsHash[format.formatKey()].dxfIndex());
else
const_cast<Format *>(&format)->setDxfIndex(m_dxf_formatsList.size());
}
if (!m_dxf_formatsHash.contains(format.formatKey()) || force) {
m_dxf_formatsList.append(format);
m_dxf_formatsHash[format.formatKey()] = format;
}
} }
QByteArray Styles::saveToXmlData() QByteArray Styles::saveToXmlData()
@ -289,16 +339,32 @@ void Styles::writeNumFmts(XmlStreamWriter &writer)
} }
/* /*
not consider dxf format.
*/ */
void Styles::writeFonts(XmlStreamWriter &writer) void Styles::writeFonts(XmlStreamWriter &writer)
{ {
writer.writeStartElement(QStringLiteral("fonts")); writer.writeStartElement(QStringLiteral("fonts"));
writer.writeAttribute(QStringLiteral("count"), QString::number(m_fontsList.count())); writer.writeAttribute(QStringLiteral("count"), QString::number(m_fontsList.count()));
for (int i=0; i<m_fontsList.size(); ++i) { for (int i=0; i<m_fontsList.size(); ++i)
const Format &format = m_fontsList[i]; writeFont(writer, m_fontsList[i], false);
writer.writeEndElement();//fonts
}
void Styles::writeFont(XmlStreamWriter &writer, const Format &format, bool isDxf)
{
writer.writeStartElement(QStringLiteral("font")); writer.writeStartElement(QStringLiteral("font"));
//The condense and extend elements are mainly used in dxf format
if (format.hasProperty(FormatPrivate::P_Font_Condense)
&& !format.boolProperty(FormatPrivate::P_Font_Condense)) {
writer.writeEmptyElement(QStringLiteral("condense"));
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0"));
}
if (format.hasProperty(FormatPrivate::P_Font_Extend)
&& !format.boolProperty(FormatPrivate::P_Font_Extend)) {
writer.writeEmptyElement(QStringLiteral("extend"));
writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0"));
}
if (format.fontBold()) if (format.fontBold())
writer.writeEmptyElement(QStringLiteral("b")); writer.writeEmptyElement(QStringLiteral("b"));
if (format.fontItalic()) if (format.fontItalic())
@ -332,7 +398,7 @@ void Styles::writeFonts(XmlStreamWriter &writer)
} }
} }
if (format.hasProperty(FormatPrivate::P_Font_Size)) { if (!isDxf && format.hasProperty(FormatPrivate::P_Font_Size)) {
writer.writeEmptyElement(QStringLiteral("sz")); writer.writeEmptyElement(QStringLiteral("sz"));
writer.writeAttribute(QStringLiteral("val"), QString::number(format.fontSize())); writer.writeAttribute(QStringLiteral("val"), QString::number(format.fontSize()));
} }
@ -349,6 +415,7 @@ void Styles::writeFonts(XmlStreamWriter &writer)
writer.writeAttribute(QStringLiteral("tint"), themes[1]); writer.writeAttribute(QStringLiteral("tint"), themes[1]);
} }
if (!isDxf) {
if (!format.fontName().isEmpty()) { if (!format.fontName().isEmpty()) {
writer.writeEmptyElement(QStringLiteral("name")); writer.writeEmptyElement(QStringLiteral("name"));
writer.writeAttribute(QStringLiteral("val"), format.fontName()); writer.writeAttribute(QStringLiteral("val"), format.fontName());
@ -362,24 +429,8 @@ void Styles::writeFonts(XmlStreamWriter &writer)
writer.writeEmptyElement(QStringLiteral("scheme")); writer.writeEmptyElement(QStringLiteral("scheme"));
writer.writeAttribute(QStringLiteral("val"), format.stringProperty(FormatPrivate::P_Font_Scheme)); writer.writeAttribute(QStringLiteral("val"), format.stringProperty(FormatPrivate::P_Font_Scheme));
} }
// if (!format.isDxfFormat()) {
// writer.writeEmptyElement(QStringLiteral("sz"));
// writer.writeAttribute(QStringLiteral("val"), QString::number(format.fontSize()));
// }
// if (!format.isDxfFormat()) {
// writer.writeEmptyElement(QStringLiteral("name"));
// writer.writeAttribute(QStringLiteral("val"), format.fontName());
// writer.writeEmptyElement(QStringLiteral("family"));
// writer.writeAttribute(QStringLiteral("val"), QString::number(format.fontFamily()));
// if (format.fontName() == QLatin1String("Calibri")) {
// writer.writeEmptyElement(QStringLiteral("scheme"));
// writer.writeAttribute(QStringLiteral("val"), format.fontScheme());
// }
// }
writer.writeEndElement(); //font
} }
writer.writeEndElement();//fonts writer.writeEndElement(); //font
} }
void Styles::writeFills(XmlStreamWriter &writer) void Styles::writeFills(XmlStreamWriter &writer)
@ -393,7 +444,7 @@ void Styles::writeFills(XmlStreamWriter &writer)
writer.writeEndElement(); //fills writer.writeEndElement(); //fills
} }
void Styles::writeFill(XmlStreamWriter &writer, const Format &fill) void Styles::writeFill(XmlStreamWriter &writer, const Format &fill, bool /*isDxf*/)
{ {
static QMap<int, QString> patternStrings; static QMap<int, QString> patternStrings;
if (patternStrings.isEmpty()) { if (patternStrings.isEmpty()) {
@ -451,9 +502,13 @@ void Styles::writeBorders(XmlStreamWriter &writer)
{ {
writer.writeStartElement(QStringLiteral("borders")); writer.writeStartElement(QStringLiteral("borders"));
writer.writeAttribute(QStringLiteral("count"), QString::number(m_bordersList.count())); writer.writeAttribute(QStringLiteral("count"), QString::number(m_bordersList.count()));
for (int i=0; i<m_bordersList.size(); ++i) { for (int i=0; i<m_bordersList.size(); ++i)
const Format &border = m_bordersList[i]; writeBorder(writer, m_bordersList[i]);
writer.writeEndElement();//borders
}
void Styles::writeBorder(XmlStreamWriter &writer, const Format &border, bool isDxf)
{
writer.writeStartElement(QStringLiteral("border")); writer.writeStartElement(QStringLiteral("border"));
if (border.hasProperty(FormatPrivate::P_Border_DiagonalType)) { if (border.hasProperty(FormatPrivate::P_Border_DiagonalType)) {
Format::DiagonalBorderType t = border.diagonalBorderType(); Format::DiagonalBorderType t = border.diagonalBorderType();
@ -475,13 +530,16 @@ void Styles::writeBorders(XmlStreamWriter &writer)
if (border.hasProperty(FormatPrivate::P_Border_BottomStyle)) if (border.hasProperty(FormatPrivate::P_Border_BottomStyle))
writeSubBorder(writer, QStringLiteral("bottom"), border.bottomBorderStyle(), border.bottomBorderColor(), border.stringProperty(FormatPrivate::P_Border_ThemeBottomColor)); writeSubBorder(writer, QStringLiteral("bottom"), border.bottomBorderStyle(), border.bottomBorderColor(), border.stringProperty(FormatPrivate::P_Border_ThemeBottomColor));
// if (!format.isDxfFormat()) { //Condition DXF formats don't allow diagonal style
if (border.hasProperty(FormatPrivate::P_Border_DiagonalStyle)) if (!isDxf && border.hasProperty(FormatPrivate::P_Border_DiagonalStyle))
writeSubBorder(writer, QStringLiteral("diagonal"), border.diagonalBorderStyle(), border.diagonalBorderColor(), border.stringProperty(FormatPrivate::P_Border_ThemeDiagonalColor)); writeSubBorder(writer, QStringLiteral("diagonal"), border.diagonalBorderStyle(), border.diagonalBorderColor(), border.stringProperty(FormatPrivate::P_Border_ThemeDiagonalColor));
// }
writer.writeEndElement();//border if (isDxf) {
// writeSubBorder(wirter, QStringLiteral("vertical"), );
// writeSubBorder(writer, QStringLiteral("horizontal"), );
} }
writer.writeEndElement();//borders
writer.writeEndElement();//border
} }
void Styles::writeSubBorder(XmlStreamWriter &writer, const QString &type, int style, const QColor &color, const QString &themeColor) void Styles::writeSubBorder(XmlStreamWriter &writer, const QString &type, int style, const QColor &color, const QString &themeColor)
@ -619,12 +677,31 @@ void Styles::writeDxfs(XmlStreamWriter &writer)
{ {
writer.writeStartElement(QStringLiteral("dxfs")); writer.writeStartElement(QStringLiteral("dxfs"));
writer.writeAttribute(QStringLiteral("count"), QString::number(m_dxf_formatsList.size())); writer.writeAttribute(QStringLiteral("count"), QString::number(m_dxf_formatsList.size()));
foreach (const Format &format, m_dxf_formatsList) { foreach (const Format &format, m_dxf_formatsList)
writeDxf(writer, format);
writer.writeEndElement(); //dxfs
}
void Styles::writeDxf(XmlStreamWriter &writer, const Format &format)
{
writer.writeStartElement(QStringLiteral("dxf")); writer.writeStartElement(QStringLiteral("dxf"));
Q_UNUSED(format)
writer.writeEndElement();//dxf if (format.hasFontData())
writeFont(writer, format, true);
if (format.hasNumFmtData()) {
writer.writeEmptyElement(QStringLiteral("numFmt"));
writer.writeAttribute(QStringLiteral("numFmtId"), QString::number(format.numberFormatIndex()));
writer.writeAttribute(QStringLiteral("formatCode"), format.numberFormat());
} }
writer.writeEndElement(); //dxfs
if (format.hasFillData())
writeFill(writer, format, true);
if (format.hasBorderData())
writeBorder(writer, format, true);
writer.writeEndElement();//dxf
} }
bool Styles::readNumFmts(XmlStreamReader &reader) bool Styles::readNumFmts(XmlStreamReader &reader)
@ -661,6 +738,18 @@ bool Styles::readFonts(XmlStreamReader &reader)
if (reader.name() != QLatin1String("font")) if (reader.name() != QLatin1String("font"))
return false; return false;
Format format; Format format;
readFont(reader, format);
m_fontsList.append(format);
m_fontsHash.insert(format.fontKey(), format);
if (format.isValid())
format.setFontIndex(m_fontsList.size()-1);
}
return true;
}
bool Styles::readFont(XmlStreamReader &reader, Format &format)
{
Q_ASSERT(reader.name() == QLatin1String("font"));
while((reader.readNextStartElement(), true)) { //read until font endelement. while((reader.readNextStartElement(), true)) { //read until font endelement.
if (reader.tokenType() == QXmlStreamReader::StartElement) { if (reader.tokenType() == QXmlStreamReader::StartElement) {
QXmlStreamAttributes attributes = reader.attributes(); QXmlStreamAttributes attributes = reader.attributes();
@ -723,11 +812,6 @@ bool Styles::readFonts(XmlStreamReader &reader)
if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("font")) if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("font"))
break; break;
} }
m_fontsList.append(format);
m_fontsHash.insert(format.fontKey(), format);
if (format.isValid())
format.setFontIndex(m_fontsList.size()-1);
}
return true; return true;
} }
@ -741,12 +825,17 @@ bool Styles::readFills(XmlStreamReader &reader)
reader.readNextStartElement(); reader.readNextStartElement();
if (reader.name() != QLatin1String("fill") || reader.tokenType() != QXmlStreamReader::StartElement) if (reader.name() != QLatin1String("fill") || reader.tokenType() != QXmlStreamReader::StartElement)
return false; return false;
readFill(reader); Format fill;
readFill(reader, fill);
m_fillsList.append(fill);
m_fillsHash.insert(fill.fillKey(), fill);
if (fill.isValid())
fill.setFillIndex(m_fillsList.size()-1);
} }
return true; return true;
} }
bool Styles::readFill(XmlStreamReader &reader) bool Styles::readFill(XmlStreamReader &reader, Format &fill)
{ {
Q_ASSERT(reader.name() == QLatin1String("fill")); Q_ASSERT(reader.name() == QLatin1String("fill"));
@ -773,7 +862,6 @@ bool Styles::readFill(XmlStreamReader &reader)
patternValues[QStringLiteral("lightGrid")] = Format::PatternLightGrid; patternValues[QStringLiteral("lightGrid")] = Format::PatternLightGrid;
} }
Format fill;
while((reader.readNextStartElement(), true)) { //read until fill endelement while((reader.readNextStartElement(), true)) { //read until fill endelement
if (reader.tokenType() == QXmlStreamReader::StartElement) { if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("patternFill")) { if (reader.name() == QLatin1String("patternFill")) {
@ -821,11 +909,6 @@ bool Styles::readFill(XmlStreamReader &reader)
break; break;
} }
m_fillsList.append(fill);
m_fillsHash.insert(fill.fillKey(), fill);
if (fill.isValid())
fill.setFillIndex(m_fillsList.size()-1);
return true; return true;
} }
@ -839,15 +922,19 @@ bool Styles::readBorders(XmlStreamReader &reader)
reader.readNextStartElement(); reader.readNextStartElement();
if (reader.name() != QLatin1String("border") || reader.tokenType() != QXmlStreamReader::StartElement) if (reader.name() != QLatin1String("border") || reader.tokenType() != QXmlStreamReader::StartElement)
return false; return false;
readBorder(reader); Format border;
readBorder(reader, border);
m_bordersList.append(border);
m_bordersHash.insert(border.borderKey(), border);
if (border.isValid())
border.setBorderIndex(m_bordersList.size()-1);
} }
return true; return true;
} }
bool Styles::readBorder(XmlStreamReader &reader) bool Styles::readBorder(XmlStreamReader &reader, Format &border)
{ {
Q_ASSERT(reader.name() == QLatin1String("border")); Q_ASSERT(reader.name() == QLatin1String("border"));
Format border;
QXmlStreamAttributes attributes = reader.attributes(); QXmlStreamAttributes attributes = reader.attributes();
bool isUp = attributes.hasAttribute(QLatin1String("diagonalUp")); bool isUp = attributes.hasAttribute(QLatin1String("diagonalUp"));
@ -907,11 +994,6 @@ bool Styles::readBorder(XmlStreamReader &reader)
break; break;
} }
m_bordersList.append(border);
m_bordersHash.insert(border.borderKey(), border);
if (border.isValid())
border.setBorderIndex(m_bordersList.size()-1);
return true; return true;
} }
@ -1085,7 +1167,7 @@ bool Styles::readCellXfs(XmlStreamReader &reader)
} }
} }
addFormat(format, true); addXfFormat(format, true);
//Find the endElement of xf //Find the endElement of xf
while (!(reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("xf"))) while (!(reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == QLatin1String("xf")))
@ -1095,6 +1177,45 @@ bool Styles::readCellXfs(XmlStreamReader &reader)
return true; return true;
} }
bool Styles::readDxfs(XmlStreamReader &reader)
{
Q_ASSERT(reader.name() == QLatin1String("dxfs"));
QXmlStreamAttributes attributes = reader.attributes();
int count = attributes.value(QLatin1String("count")).toString().toInt();
for (int i=0; i<count; ++i) {
reader.readNextStartElement();
if (reader.name() != QLatin1String("dxf"))
return false;
readDxf(reader);
}
return true;
}
bool Styles::readDxf(XmlStreamReader &reader)
{
Q_ASSERT(reader.name() == QLatin1String("dxf"));
Format format;
while (!(reader.name() == QLatin1String("dxf") && reader.tokenType() == QXmlStreamReader::EndElement)) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("numFmt")) {
QXmlStreamAttributes attributes = reader.attributes();
int id = attributes.value(QLatin1String("numFmtId")).toString().toInt();
QString code = attributes.value(QLatin1String("formatCode")).toString();
format.setNumberFormat(id, code);
} else if (reader.name() == QLatin1String("font")) {
readFont(reader, format);
} else if (reader.name() == QLatin1String("fill")) {
readFill(reader, format);
} else if (reader.name() == QLatin1String("border")) {
readBorder(reader, format);
}
}
}
addDxfFormat(format, true);
return true;
}
bool Styles::readColors(XmlStreamReader &reader) bool Styles::readColors(XmlStreamReader &reader)
{ {
Q_ASSERT(reader.name() == QLatin1String("colors")); Q_ASSERT(reader.name() == QLatin1String("colors"));

18
src/xlsx/xlsxstyles_p.h

@ -56,8 +56,10 @@ class XLSX_AUTOTEST_EXPORT Styles
public: public:
Styles(bool createEmpty=false); Styles(bool createEmpty=false);
~Styles(); ~Styles();
void addFormat(const Format &format, bool force=false); void addXfFormat(const Format &format, bool force=false);
Format xfFormat(int idx) const; Format xfFormat(int idx) const;
void addDxfFormat(const Format &format, bool force=false);
Format dxfFormat(int idx) const;
QByteArray saveToXmlData(); QByteArray saveToXmlData();
void saveToXmlFile(QIODevice *device); void saveToXmlFile(QIODevice *device);
@ -68,23 +70,31 @@ private:
friend class Format; friend class Format;
friend class ::StylesTest; friend class ::StylesTest;
void fixNumFmt(const Format &format);
void writeNumFmts(XmlStreamWriter &writer); void writeNumFmts(XmlStreamWriter &writer);
void writeFonts(XmlStreamWriter &writer); void writeFonts(XmlStreamWriter &writer);
void writeFont(XmlStreamWriter &writer, const Format &font, bool isDxf = false);
void writeFills(XmlStreamWriter &writer); void writeFills(XmlStreamWriter &writer);
void writeFill(XmlStreamWriter &writer, const Format &fill); void writeFill(XmlStreamWriter &writer, const Format &fill, bool isDxf = false);
void writeBorders(XmlStreamWriter &writer); void writeBorders(XmlStreamWriter &writer);
void writeBorder(XmlStreamWriter &writer, const Format &border, bool isDxf = false);
void writeSubBorder(XmlStreamWriter &writer, const QString &type, int style, const QColor &color, const QString &themeColor); void writeSubBorder(XmlStreamWriter &writer, const QString &type, int style, const QColor &color, const QString &themeColor);
void writeCellXfs(XmlStreamWriter &writer); void writeCellXfs(XmlStreamWriter &writer);
void writeDxfs(XmlStreamWriter &writer); void writeDxfs(XmlStreamWriter &writer);
void writeDxf(XmlStreamWriter &writer, const Format &format);
bool readNumFmts(XmlStreamReader &reader); bool readNumFmts(XmlStreamReader &reader);
bool readFonts(XmlStreamReader &reader); bool readFonts(XmlStreamReader &reader);
bool readFont(XmlStreamReader &reader, Format &format);
bool readFills(XmlStreamReader &reader); bool readFills(XmlStreamReader &reader);
bool readFill(XmlStreamReader &reader); bool readFill(XmlStreamReader &reader, Format &format);
bool readBorders(XmlStreamReader &reader); bool readBorders(XmlStreamReader &reader);
bool readBorder(XmlStreamReader &reader); bool readBorder(XmlStreamReader &reader, Format &format);
bool readSubBorder(XmlStreamReader &reader, const QString &name, Format::BorderStyle &style, QColor &color, QString &themeColor); bool readSubBorder(XmlStreamReader &reader, const QString &name, Format::BorderStyle &style, QColor &color, QString &themeColor);
bool readCellXfs(XmlStreamReader &reader); bool readCellXfs(XmlStreamReader &reader);
bool readDxfs(XmlStreamReader &reader);
bool readDxf(XmlStreamReader &reader);
bool readColors(XmlStreamReader &reader); bool readColors(XmlStreamReader &reader);
bool readIndexedColors(XmlStreamReader &reader); bool readIndexedColors(XmlStreamReader &reader);

26
src/xlsx/xlsxworksheet.cpp

@ -575,7 +575,7 @@ int Worksheet::writeString(int row, int column, const RichString &value, const F
d->sharedStrings()->addSharedString(value); d->sharedStrings()->addSharedString(value);
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
QSharedPointer<Cell> cell = QSharedPointer<Cell>(new Cell(QString(), Cell::String, fmt, this)); QSharedPointer<Cell> cell = QSharedPointer<Cell>(new Cell(QString(), Cell::String, fmt, this));
cell->d_ptr->richString = value; cell->d_ptr->richString = value;
d->cellTable[row][column] = cell; d->cellTable[row][column] = cell;
@ -613,7 +613,7 @@ int Worksheet::writeString(int row, int column, const QString &value, const Form
d->sharedStrings()->addSharedString(content); d->sharedStrings()->addSharedString(content);
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(content, Cell::String, fmt, this)); d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(content, Cell::String, fmt, this));
return error; return error;
} }
@ -648,7 +648,7 @@ int Worksheet::writeInlineString(int row, int column, const QString &value, cons
} }
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::InlineString, fmt, this)); d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::InlineString, fmt, this));
return error; return error;
} }
@ -676,7 +676,7 @@ int Worksheet::writeNumeric(int row, int column, double value, const Format &for
return -1; return -1;
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Numeric, fmt, this)); d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Numeric, fmt, this));
return 0; return 0;
} }
@ -710,7 +710,7 @@ int Worksheet::writeFormula(int row, int column, const QString &formula, const F
_formula.remove(0,1); _formula.remove(0,1);
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
Cell *data = new Cell(result, Cell::Formula, fmt, this); Cell *data = new Cell(result, Cell::Formula, fmt, this);
data->d_ptr->formula = _formula; data->d_ptr->formula = _formula;
d->cellTable[row][column] = QSharedPointer<Cell>(data); d->cellTable[row][column] = QSharedPointer<Cell>(data);
@ -740,7 +740,7 @@ int Worksheet::writeArrayFormula(const CellRange &range, const QString &formula,
for (int row=range.firstRow(); row<=range.lastRow(); ++row) { for (int row=range.firstRow(); row<=range.lastRow(); ++row) {
for (int column=range.firstColumn(); column<=range.lastColumn(); ++column) { for (int column=range.firstColumn(); column<=range.lastColumn(); ++column) {
Format _format = format.isValid() ? format : d->cellFormat(row, column); Format _format = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(_format); d->workbook->styles()->addXfFormat(_format);
if (row == range.firstRow() && column == range.firstColumn()) { if (row == range.firstRow() && column == range.firstColumn()) {
QSharedPointer<Cell> data(new Cell(0, Cell::ArrayFormula, _format, this)); QSharedPointer<Cell> data(new Cell(0, Cell::ArrayFormula, _format, this));
data->d_ptr->formula = _formula; data->d_ptr->formula = _formula;
@ -786,7 +786,7 @@ int Worksheet::writeBlank(int row, int column, const Format &format)
return -1; return -1;
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(QVariant(), Cell::Blank, fmt, this)); d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(QVariant(), Cell::Blank, fmt, this));
@ -815,7 +815,7 @@ int Worksheet::writeBool(int row, int column, bool value, const Format &format)
return -1; return -1;
Format fmt = format.isValid() ? format : d->cellFormat(row, column); Format fmt = format.isValid() ? format : d->cellFormat(row, column);
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Boolean, fmt, this)); d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(value, Cell::Boolean, fmt, this));
return 0; return 0;
@ -845,7 +845,7 @@ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const For
Format fmt = format; Format fmt = format;
if (!fmt.isValid()) if (!fmt.isValid())
fmt.setNumberFormat(d->workbook->defaultDateFormat()); fmt.setNumberFormat(d->workbook->defaultDateFormat());
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
double value = datetimeToNumber(dt, d->workbook->isDate1904()); double value = datetimeToNumber(dt, d->workbook->isDate1904());
@ -909,7 +909,7 @@ int Worksheet::writeHyperlink(int row, int column, const QUrl &url, const Format
fmt.setFontColor(Qt::blue); fmt.setFontColor(Qt::blue);
fmt.setFontUnderline(Format::FontUnderlineSingle); fmt.setFontUnderline(Format::FontUnderlineSingle);
} }
d->workbook->styles()->addFormat(fmt); d->workbook->styles()->addXfFormat(fmt);
//Write the hyperlink string as normal string. //Write the hyperlink string as normal string.
d->sharedStrings()->addSharedString(displayString); d->sharedStrings()->addSharedString(displayString);
@ -955,7 +955,7 @@ int Worksheet::mergeCells(const CellRange &range, const Format &format)
return -1; return -1;
if (format.isValid()) if (format.isValid())
d->workbook->styles()->addFormat(format); d->workbook->styles()->addXfFormat(format);
for (int row = range.firstRow(); row <= range.lastRow(); ++row) { for (int row = range.firstRow(); row <= range.lastRow(); ++row) {
for (int col = range.firstColumn(); col <= range.lastColumn(); ++col) { for (int col = range.firstColumn(); col <= range.lastColumn(); ++col) {
@ -1415,7 +1415,7 @@ bool Worksheet::setRow(int row, double height, const Format &format, bool hidden
return false; return false;
d->rowsInfo[row] = QSharedPointer<XlsxRowInfo>(new XlsxRowInfo(height, format, hidden)); d->rowsInfo[row] = QSharedPointer<XlsxRowInfo>(new XlsxRowInfo(height, format, hidden));
d->workbook->styles()->addFormat(format); d->workbook->styles()->addXfFormat(format);
return true; return true;
} }
@ -1510,7 +1510,7 @@ bool Worksheet::setColumn(int colFirst, int colLast, double width, const Format
d->colsInfoHelper[c] = info; d->colsInfoHelper[c] = info;
} }
} }
d->workbook->styles()->addFormat(format); d->workbook->styles()->addXfFormat(format);
return true; return true;
} }

18
tests/auto/styles/tst_stylestest.cpp

@ -14,8 +14,8 @@ public:
private Q_SLOTS: private Q_SLOTS:
void testEmptyStyle(); void testEmptyStyle();
void testAddFormat(); void testAddXfFormat();
void testAddFormat2(); void testAddXfFormat2();
void testSolidFillBackgroundColor(); void testSolidFillBackgroundColor();
void testWriteBorders(); void testWriteBorders();
@ -39,33 +39,33 @@ void StylesTest::testEmptyStyle()
QVERIFY2(xmlData.contains("<cellXfs count=\"1\"><xf xfId=\"0\"/></cellXfs>"), "Must have one cell style"); QVERIFY2(xmlData.contains("<cellXfs count=\"1\"><xf xfId=\"0\"/></cellXfs>"), "Must have one cell style");
} }
void StylesTest::testAddFormat() void StylesTest::testAddXfFormat()
{ {
QXlsx::Styles styles; QXlsx::Styles styles;
for (int i=0; i<10; ++i) { for (int i=0; i<10; ++i) {
QXlsx::Format format; QXlsx::Format format;
format.setFontBold(true); format.setFontBold(true);
styles.addFormat(format); styles.addXfFormat(format);
} }
QByteArray xmlData = styles.saveToXmlData(); QByteArray xmlData = styles.saveToXmlData();
QVERIFY2(xmlData.contains("<cellXfs count=\"2\">"), ""); //Note we have a default one QVERIFY2(xmlData.contains("<cellXfs count=\"2\">"), ""); //Note we have a default one
} }
void StylesTest::testAddFormat2() void StylesTest::testAddXfFormat2()
{ {
QXlsx::Styles styles; QXlsx::Styles styles;
QXlsx::Format format; QXlsx::Format format;
format.setNumberFormat("h:mm:ss AM/PM"); //builtin 19 format.setNumberFormat("h:mm:ss AM/PM"); //builtin 19
styles.addFormat(format); styles.addXfFormat(format);
QCOMPARE(format.numberFormatIndex(), 19); QCOMPARE(format.numberFormatIndex(), 19);
QXlsx::Format format2; QXlsx::Format format2;
format2.setNumberFormat("aaaaa h:mm:ss AM/PM"); //custom format2.setNumberFormat("aaaaa h:mm:ss AM/PM"); //custom
styles.addFormat(format2); styles.addXfFormat(format2);
QCOMPARE(format2.numberFormatIndex(), 176); QCOMPARE(format2.numberFormatIndex(), 176);
} }
@ -76,7 +76,7 @@ void StylesTest::testSolidFillBackgroundColor()
QXlsx::Styles styles; QXlsx::Styles styles;
QXlsx::Format format; QXlsx::Format format;
format.setPatternBackgroundColor(QColor(Qt::red)); format.setPatternBackgroundColor(QColor(Qt::red));
styles.addFormat(format); styles.addXfFormat(format);
QByteArray xmlData = styles.saveToXmlData(); QByteArray xmlData = styles.saveToXmlData();
@ -88,7 +88,7 @@ void StylesTest::testWriteBorders()
QXlsx::Styles styles; QXlsx::Styles styles;
QXlsx::Format format; QXlsx::Format format;
format.setRightBorderStyle(QXlsx::Format::BorderThin); format.setRightBorderStyle(QXlsx::Format::BorderThin);
styles.addFormat(format); styles.addXfFormat(format);
QByteArray xmlData = styles.saveToXmlData(); QByteArray xmlData = styles.saveToXmlData();

Loading…
Cancel
Save