diff --git a/src/xlsx/xlsxformat.h b/src/xlsx/xlsxformat.h index 40f73ce..2f214e8 100755 --- a/src/xlsx/xlsxformat.h +++ b/src/xlsx/xlsxformat.h @@ -39,6 +39,7 @@ class Styles; class Worksheet; class WorksheetPrivate; class RichString; +class SharedStrings; class FormatPrivate; class Q_XLSX_EXPORT Format @@ -216,6 +217,7 @@ private: friend class Worksheet; friend class WorksheetPrivate; friend class RichString; + friend class SharedStrings; friend class ::FormatTest; Format(); diff --git a/src/xlsx/xlsxrichstring.cpp b/src/xlsx/xlsxrichstring.cpp index 1212854..cd98e09 100644 --- a/src/xlsx/xlsxrichstring.cpp +++ b/src/xlsx/xlsxrichstring.cpp @@ -87,6 +87,17 @@ Format *RichString::fragmentFormat(int index) const return m_fragmentFormats[index]; } +/*! + * \internal + */ +Format *RichString::createFormat() +{ + Format *format = new Format(); + m_createdFormats.append(QSharedPointer(format)); + + return format; +} + /*! * \internal */ diff --git a/src/xlsx/xlsxrichstring_p.h b/src/xlsx/xlsxrichstring_p.h index 7f24246..b985a39 100644 --- a/src/xlsx/xlsxrichstring_p.h +++ b/src/xlsx/xlsxrichstring_p.h @@ -28,6 +28,7 @@ #include "xlsxglobal.h" #include "xlsxformat.h" #include +#include QT_BEGIN_NAMESPACE_XLSX @@ -49,6 +50,7 @@ public: QString fragmentText(int index) const; Format *fragmentFormat(int index) const; + Format *createFormat(); private: friend XLSX_AUTOTEST_EXPORT uint qHash(const RichString &rs, uint seed) Q_DECL_NOTHROW; friend XLSX_AUTOTEST_EXPORT bool operator==(const RichString &rs1, const RichString &rs2); @@ -61,6 +63,7 @@ private: QList m_fragmentFormats; QByteArray m_idKey; bool m_dirty; + QList > m_createdFormats; }; diff --git a/src/xlsx/xlsxsharedstrings.cpp b/src/xlsx/xlsxsharedstrings.cpp index 247f4e4..046746d 100755 --- a/src/xlsx/xlsxsharedstrings.cpp +++ b/src/xlsx/xlsxsharedstrings.cpp @@ -26,6 +26,8 @@ #include "xlsxsharedstrings_p.h" #include "xlsxxmlwriter_p.h" #include "xlsxxmlreader_p.h" +#include "xlsxutility_p.h" +#include "xlsxformat_p.h" #include #include #include @@ -123,6 +125,65 @@ QList SharedStrings::getSharedStrings() const return m_stringList; } +void SharedStrings::writeRichStringPart_rPr(XmlStreamWriter &writer, Format *format) const +{ + if (!format) + return; + + FontData *font = &format->d_ptr->fontData; + + if (font->bold) + writer.writeEmptyElement(QStringLiteral("b")); + if (font->italic) + writer.writeEmptyElement(QStringLiteral("i")); + if (font->strikeOut) + writer.writeEmptyElement(QStringLiteral("strike")); + if (font->outline) + writer.writeEmptyElement(QStringLiteral("outline")); + if (font->shadow) + writer.writeEmptyElement(QStringLiteral("shadow")); + if (font->underline != Format::FontUnderlineNone) { + writer.writeEmptyElement(QStringLiteral("u")); + if (font->underline == Format::FontUnderlineDouble) + writer.writeAttribute(QStringLiteral("val"), QStringLiteral("double")); + else if (font->underline == Format::FontUnderlineSingleAccounting) + writer.writeAttribute(QStringLiteral("val"), QStringLiteral("singleAccounting")); + else if (font->underline == Format::FontUnderlineDoubleAccounting) + writer.writeAttribute(QStringLiteral("val"), QStringLiteral("doubleAccounting")); + } + if (font->scirpt != Format::FontScriptNormal) { + writer.writeEmptyElement(QStringLiteral("vertAlign")); + if (font->scirpt == Format::FontScriptSuper) + writer.writeAttribute(QStringLiteral("val"), QStringLiteral("superscript")); + else + writer.writeAttribute(QStringLiteral("val"), QStringLiteral("subscript")); + } + + writer.writeEmptyElement(QStringLiteral("sz")); + writer.writeAttribute(QStringLiteral("val"), QString::number(font->size)); + + if (font->color.isValid()) { + writer.writeEmptyElement(QStringLiteral("color")); + QString color = font->color.name(); + writer.writeAttribute(QStringLiteral("rgb"), QStringLiteral("FF")+color.mid(1));//remove # + } else if (!font->themeColor.isEmpty()) { + writer.writeEmptyElement(QStringLiteral("color")); + QStringList themes = font->themeColor.split(QLatin1Char(':')); + writer.writeAttribute(QStringLiteral("theme"), themes[0]); + if (!themes[1].isEmpty()) + writer.writeAttribute(QStringLiteral("tint"), themes[1]); + } + + writer.writeEmptyElement(QStringLiteral("rFont")); + writer.writeAttribute(QStringLiteral("val"), font->name); + writer.writeEmptyElement(QStringLiteral("family")); + writer.writeAttribute(QStringLiteral("val"), QString::number(font->family)); + if (font->name == QLatin1String("Calibri")) { + writer.writeEmptyElement(QStringLiteral("scheme")); + writer.writeAttribute(QStringLiteral("val"), font->scheme); + } +} + void SharedStrings::saveToXmlFile(QIODevice *device) const { XmlStreamWriter writer(device); @@ -138,15 +199,21 @@ void SharedStrings::saveToXmlFile(QIODevice *device) const if (string.isRichString()) { //Rich text string for (int i=0; isetFontName(attributes.value(QLatin1String("val")).toString()); + } else if (reader.name() == QLatin1String("charset")) { + format->d_ptr->fontData.charset = attributes.value(QLatin1String("val")).toString().toInt(); + } else if (reader.name() == QLatin1String("family")) { + format->d_ptr->fontData.family = attributes.value(QLatin1String("val")).toString().toInt(); + } else if (reader.name() == QLatin1String("b")) { + format->setFontBold(true); + } else if (reader.name() == QLatin1String("i")) { + format->setFontItalic(true); + } else if (reader.name() == QLatin1String("strike")) { + format->setFontStrikeOut(true); + } else if (reader.name() == QLatin1String("outline")) { + format->setFontOutline(true); + } else if (reader.name() == QLatin1String("shadow")) { + format->d_ptr->fontData.shadow = true; + } else if (reader.name() == QLatin1String("condense")) { + format->d_ptr->fontData.condense = attributes.value(QLatin1String("val")).toString().toInt(); + } else if (reader.name() == QLatin1String("extend")) { + format->d_ptr->fontData.extend = attributes.value(QLatin1String("val")).toString().toInt(); + } else if (reader.name() == QLatin1String("color")) { + if (attributes.hasAttribute(QLatin1String("rgb"))) { + QString colorString = attributes.value(QLatin1String("rgb")).toString(); + format->setFontColor(fromARGBString(colorString)); + } else if (attributes.hasAttribute(QLatin1String("indexed"))) { +// color = getColorByIndex(attributes.value(QLatin1String("indexed")).toString().toInt()); + } else if (attributes.hasAttribute(QLatin1String("theme"))) { + QString theme = attributes.value(QLatin1String("theme")).toString(); + QString tint = attributes.value(QLatin1String("tint")).toString(); + format->d_ptr->fontData.themeColor = theme + QLatin1Char(':') + tint; + } + } else if (reader.name() == QLatin1String("sz")) { + format->setFontSize(attributes.value(QLatin1String("val")).toString().toInt()); + } else if (reader.name() == QLatin1String("u")) { + QString value = attributes.value(QLatin1String("val")).toString(); + if (value == QLatin1String("double")) + format->setFontUnderline(Format::FontUnderlineDouble); + else if (value == QLatin1String("doubleAccounting")) + format->setFontUnderline(Format::FontUnderlineDoubleAccounting); + else if (value == QLatin1String("singleAccounting")) + format->setFontUnderline(Format::FontUnderlineSingleAccounting); + else + format->setFontUnderline(Format::FontUnderlineSingle); + } else if (reader.name() == QLatin1String("vertAlign")) { + QString value = attributes.value(QLatin1String("val")).toString(); + if (value == QLatin1String("superscript")) + format->setFontScript(Format::FontScriptSuper); + else if (value == QLatin1String("subscript")) + format->setFontScript(Format::FontScriptSub); + } else if (reader.name() == QLatin1String("scheme")) { + format->d_ptr->fontData.scheme = attributes.value(QLatin1String("val")).toString(); + } + } + } + return format; +} + bool SharedStrings::loadFromXmlFile(QIODevice *device) { XmlStreamReader reader(device); diff --git a/src/xlsx/xlsxsharedstrings_p.h b/src/xlsx/xlsxsharedstrings_p.h index 26af890..dec9031 100755 --- a/src/xlsx/xlsxsharedstrings_p.h +++ b/src/xlsx/xlsxsharedstrings_p.h @@ -36,6 +36,7 @@ class QIODevice; namespace QXlsx { class XmlStreamReader; +class XmlStreamWriter; class RichString; class XlsxSharedStringInfo @@ -76,6 +77,8 @@ private: void readString(XmlStreamReader &reader); // void readRichStringPart(XmlStreamReader &reader, RichString &rich); // void readPlainStringPart(XmlStreamReader &reader, RichString &rich); // + Format *readRichStringPart_rPr(XmlStreamReader &reader, RichString &richString); + void writeRichStringPart_rPr(XmlStreamWriter &writer, Format *format) const; QHash m_stringTable; //for fast lookup QList m_stringList; diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index fc5db89..0bc005f 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -1158,7 +1158,12 @@ void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col, writer.writeAttribute(QStringLiteral("s"), QString::number(colsInfoHelper[col]->format->xfIndex())); if (cell->dataType() == Cell::String) { - int sst_idx = sharedStrings()->getSharedStringIndex(cell->value().toString()); + int sst_idx; + if (cell->isRichString()) + sst_idx = sharedStrings()->getSharedStringIndex(cell->d_ptr->richString); + else + sst_idx = sharedStrings()->getSharedStringIndex(cell->value().toString()); + writer.writeAttribute(QStringLiteral("t"), QStringLiteral("s")); writer.writeTextElement(QStringLiteral("v"), QString::number(sst_idx)); } else if (cell->dataType() == Cell::InlineString) { @@ -1168,13 +1173,17 @@ void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col, //Rich text string RichString string = cell->d_ptr->richString; for (int i=0; ivalue().toString()); diff --git a/tests/auto/sharedstrings/tst_sharedstringstest.cpp b/tests/auto/sharedstrings/tst_sharedstringstest.cpp index 12316ec..ed9bf1b 100644 --- a/tests/auto/sharedstrings/tst_sharedstringstest.cpp +++ b/tests/auto/sharedstrings/tst_sharedstringstest.cpp @@ -1,5 +1,6 @@ #include "private/xlsxsharedstrings_p.h" #include "private/xlsxrichstring_p.h" +#include "xlsxformat.h" #include #include #include @@ -16,6 +17,7 @@ private Q_SLOTS: void testRemoveSharedString(); void testLoadXmlData(); + void testLoadRichStringXmlData(); }; @@ -127,6 +129,37 @@ void SharedStringsTest::testLoadXmlData() QCOMPARE(sst2->getSharedStringIndex("Hello World"), 4); } +void SharedStringsTest::testLoadRichStringXmlData() +{ + QByteArray xmlData = "" + "" + "" + "e=mc" + "" + "" + "" + "" + "" + "" + "" + "" + "2" + "" + ""; + + QSharedPointer sst(new QXlsx::SharedStrings); + sst->loadFromXmlData(xmlData); + QXlsx::RichString rs = sst->getSharedString(0); + QVERIFY(rs.fragmentText(0) == "e=mc"); + QVERIFY(rs.fragmentText(1) == "2"); + QVERIFY(rs.fragmentFormat(0) == 0); + QXlsx::Format *format = rs.fragmentFormat(1); + QCOMPARE(format->fontName(), QString("MyFontName")); +// QCOMPARE(format->fontFamily(), 3); + QCOMPARE(format->fontScript(), QXlsx::Format::FontScriptSuper); + QCOMPARE(format->fontSize(), 11); +} + QTEST_APPLESS_MAIN(SharedStringsTest) #include "tst_sharedstringstest.moc"