Browse Source

Fix Issue 7: Cell string misplacement when rich text exist

A private class RichString has been added. More work is needed
master
Debao Zhang 11 years ago
parent
commit
00350d4251
  1. 6
      src/xlsx/qtxlsx.pri
  2. 12
      src/xlsx/xlsxcell.cpp
  3. 2
      src/xlsx/xlsxcell.h
  4. 5
      src/xlsx/xlsxcell_p.h
  5. 2
      src/xlsx/xlsxformat.h
  6. 3
      src/xlsx/xlsxpackage.cpp
  7. 173
      src/xlsx/xlsxrichstring.cpp
  8. 79
      src/xlsx/xlsxrichstring_p.h
  9. 107
      src/xlsx/xlsxsharedstrings.cpp
  10. 19
      src/xlsx/xlsxsharedstrings_p.h
  11. 24
      src/xlsx/xlsxworksheet.cpp
  12. 3
      tests/auto/auto.pro
  13. 12
      tests/auto/richstring/richstring.pro
  14. 41
      tests/auto/richstring/tst_richstringtest.cpp
  15. 36
      tests/auto/sharedstrings/tst_sharedstringstest.cpp
  16. 13
      tests/auto/worksheet/tst_worksheet.cpp

6
src/xlsx/qtxlsx.pri

@ -31,7 +31,8 @@ HEADERS += $$PWD/xlsxdocpropscore_p.h \
$$PWD/xlsxcell_p.h \
$$PWD/xlsxdatavalidation.h \
$$PWD/xlsxdatavalidation_p.h \
$$PWD/xlsxcellrange.h
$$PWD/xlsxcellrange.h \
$$PWD/xlsxrichstring_p.h
SOURCES += $$PWD/xlsxdocpropscore.cpp \
$$PWD/xlsxdocpropsapp.cpp \
@ -53,4 +54,5 @@ SOURCES += $$PWD/xlsxdocpropscore.cpp \
$$PWD/xlsxdocument.cpp \
$$PWD/xlsxcell.cpp \
$$PWD/xlsxdatavalidation.cpp \
$$PWD/xlsxcellrange.cpp
$$PWD/xlsxcellrange.cpp \
$$PWD/xlsxrichstring.cpp

12
src/xlsx/xlsxcell.cpp

@ -121,4 +121,16 @@ QDateTime Cell::dateTime() const
return datetimeFromNumber(d->value.toDouble(), d->parent->workbook()->isDate1904());
}
/*!
* Returns whether the cell is probably a rich string or not
*/
bool Cell::isRichString() const
{
Q_D(const Cell);
if (d->dataType != String && d->dataType != InlineString)
return false;
return d->richString.isRichString();
}
QT_END_NAMESPACE_XLSX

2
src/xlsx/xlsxcell.h

@ -58,6 +58,8 @@ public:
bool isDateTime() const;
QDateTime dateTime() const;
bool isRichString() const;
~Cell();
private:
friend class Worksheet;

5
src/xlsx/xlsxcell_p.h

@ -28,6 +28,9 @@
#include "xlsxglobal.h"
#include "xlsxcell.h"
#include "xlsxcellrange.h"
#include "xlsxrichstring_p.h"
#include <QList>
#include <QSharedPointer>
QT_BEGIN_NAMESPACE_XLSX
@ -43,6 +46,8 @@ public:
Format *format;
CellRange range; //used for arrayFormula
RichString richString;
Worksheet *parent;
Cell *q_ptr;
};

2
src/xlsx/xlsxformat.h

@ -38,6 +38,7 @@ QT_BEGIN_NAMESPACE_XLSX
class Styles;
class Worksheet;
class WorksheetPrivate;
class RichString;
class FormatPrivate;
class Q_XLSX_EXPORT Format
@ -214,6 +215,7 @@ private:
friend class Styles;
friend class Worksheet;
friend class WorksheetPrivate;
friend class RichString;
friend class ::FormatTest;
Format();

3
src/xlsx/xlsxpackage.cpp

@ -160,8 +160,7 @@ bool Package::parsePackage(QIODevice *packageDevice)
//In normal case this should be sharedStrings.xml which in xl
QString name = rels_sharedStrings[0].target;
QString path = xlworkbook_Dir + QLatin1String("/") + name;
QSharedPointer<SharedStrings> sst= SharedStrings::loadFromXmlData(zipReader.fileData(path));
m_document->workbook()->d_ptr->sharedStrings = sst;
m_document->workbook()->d_ptr->sharedStrings->loadFromXmlData(zipReader.fileData(path));
}
//load theme

173
src/xlsx/xlsxrichstring.cpp

@ -0,0 +1,173 @@
/****************************************************************************
** Copyright (c) 2013 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 "xlsxrichstring_p.h"
QT_BEGIN_NAMESPACE_XLSX
RichString::RichString()
:m_dirty(true)
{
}
RichString::RichString(const QString text)
:m_dirty(true)
{
addFragment(text, 0);
}
bool RichString::isRichString() const
{
if (fragmentCount() > 1) //Is this enough??
return true;
return false;
}
bool RichString::isEmtpy() const
{
return m_fragmentTexts.size() == 0;
}
QString RichString::toPlainString() const
{
if (isEmtpy())
return QString();
if (m_fragmentTexts.size() == 1)
return m_fragmentTexts[0];
return m_fragmentTexts.join(QString());
}
int RichString::fragmentCount() const
{
return m_fragmentTexts.size();
}
void RichString::addFragment(const QString &text, Format *format)
{
m_fragmentTexts.append(text);
m_fragmentFormats.append(format);
m_dirty = true;
}
QString RichString::fragmentText(int index) const
{
if (index < 0 || index >= fragmentCount())
return QString();
return m_fragmentTexts[index];
}
Format *RichString::fragmentFormat(int index) const
{
if (index < 0 || index >= fragmentCount())
return 0;
return m_fragmentFormats[index];
}
/*!
* \internal
*/
QByteArray RichString::idKey() const
{
if (m_dirty) {
RichString *rs = const_cast<RichString *>(this);
QByteArray bytes;
if (!isRichString()) {
bytes = toPlainString().toUtf8();
} else {
//Generate a hash value base on QByteArray ?
bytes.append("@@QtXlsxRichString=");
for (int i=0; i<fragmentCount(); ++i) {
bytes.append("@Text");
bytes.append(m_fragmentTexts[i].toUtf8());
bytes.append("@Format");
if (m_fragmentFormats[i])
bytes.append(m_fragmentFormats[i]->fontKey());
}
}
rs->m_idKey = bytes;
rs->m_dirty = false;
}
return m_idKey;
}
bool operator==(const RichString &rs1, const RichString &rs2)
{
if (rs1.fragmentCount() != rs2.fragmentCount())
return false;
return rs1.idKey() == rs2.idKey();
}
bool operator!=(const RichString &rs1, const RichString &rs2)
{
if (rs1.fragmentCount() != rs2.fragmentCount())
return true;
return rs1.idKey() != rs2.idKey();
}
/*!
* \internal
*/
bool operator<(const RichString &rs1, const RichString &rs2)
{
return rs1.idKey() < rs2.idKey();
}
bool operator ==(const RichString &rs1, const QString &rs2)
{
if (rs1.fragmentCount() == 1 && rs1.fragmentText(0) == rs2) //format == 0
return true;
return false;
}
bool operator !=(const RichString &rs1, const QString &rs2)
{
if (rs1.fragmentCount() == 1 && rs1.fragmentText(0) == rs2) //format == 0
return false;
return true;
}
bool operator ==(const QString &rs1, const RichString &rs2)
{
return rs2 == rs1;
}
bool operator !=(const QString &rs1, const RichString &rs2)
{
return rs2 != rs1;
}
uint qHash(const RichString &rs, uint seed) Q_DECL_NOTHROW
{
return qHash(rs.idKey(), seed);
}
QT_END_NAMESPACE_XLSX

79
src/xlsx/xlsxrichstring_p.h

@ -0,0 +1,79 @@
/****************************************************************************
** Copyright (c) 2013 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.
**
****************************************************************************/
#ifndef XLSXRICHSTRING_P_H
#define XLSXRICHSTRING_P_H
#include "xlsxglobal.h"
#include "xlsxformat.h"
#include <QStringList>
QT_BEGIN_NAMESPACE_XLSX
class RichString;
// qHash is a friend, but we can't use default arguments for friends (§8.3.6.4)
XLSX_AUTOTEST_EXPORT uint qHash(const RichString &rs, uint seed = 0) Q_DECL_NOTHROW;
class XLSX_AUTOTEST_EXPORT RichString
{
public:
RichString();
explicit RichString(const QString text);
bool isRichString() const;
bool isEmtpy() const;
QString toPlainString() const;
int fragmentCount() const;
void addFragment(const QString &text, Format *format);
QString fragmentText(int index) const;
Format *fragmentFormat(int index) const;
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);
friend XLSX_AUTOTEST_EXPORT bool operator!=(const RichString &rs1, const RichString &rs2);
friend XLSX_AUTOTEST_EXPORT bool operator<(const RichString &rs1, const RichString &rs2);
QByteArray idKey() const;
QStringList m_fragmentTexts;
QList<Format *> m_fragmentFormats;
QByteArray m_idKey;
bool m_dirty;
};
XLSX_AUTOTEST_EXPORT bool operator==(const RichString &rs1, const RichString &rs2);
XLSX_AUTOTEST_EXPORT bool operator!=(const RichString &rs1, const RichString &rs2);
XLSX_AUTOTEST_EXPORT bool operator<(const RichString &rs1, const RichString &rs2);
XLSX_AUTOTEST_EXPORT bool operator==(const RichString &rs1, const QString &rs2);
XLSX_AUTOTEST_EXPORT bool operator==(const QString &rs1, const RichString &rs2);
XLSX_AUTOTEST_EXPORT bool operator!=(const RichString &rs1, const QString &rs2);
XLSX_AUTOTEST_EXPORT bool operator!=(const QString &rs1, const RichString &rs2);
QT_END_NAMESPACE_XLSX
Q_DECLARE_METATYPE(QXlsx::RichString);
#endif // XLSXRICHSTRING_P_H

107
src/xlsx/xlsxsharedstrings.cpp

@ -22,6 +22,7 @@
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxrichstring_p.h"
#include "xlsxsharedstrings_p.h"
#include "xlsxxmlwriter_p.h"
#include "xlsxxmlreader_p.h"
@ -44,6 +45,11 @@ int SharedStrings::count() const
}
int SharedStrings::addSharedString(const QString &string)
{
return addSharedString(RichString(string));
}
int SharedStrings::addSharedString(const RichString &string)
{
m_stringCount += 1;
@ -70,6 +76,11 @@ void SharedStrings::incRefByStringIndex(int idx)
}
void SharedStrings::removeSharedString(const QString &string)
{
removeSharedString(RichString(string));
}
void SharedStrings::removeSharedString(const RichString &string)
{
if (!m_stringTable.contains(string))
return;
@ -89,20 +100,25 @@ void SharedStrings::removeSharedString(const QString &string)
}
int SharedStrings::getSharedStringIndex(const QString &string) const
{
return getSharedStringIndex(RichString(string));
}
int SharedStrings::getSharedStringIndex(const RichString &string) const
{
if (m_stringTable.contains(string))
return m_stringTable[string].index;
return -1;
}
QString SharedStrings::getSharedString(int index) const
RichString SharedStrings::getSharedString(int index) const
{
if (index < m_stringList.count() && index >= 0)
return m_stringList[index];
return QString();
return RichString();
}
QStringList SharedStrings::getSharedStrings() const
QList<RichString> SharedStrings::getSharedStrings() const
{
return m_stringList;
}
@ -117,16 +133,29 @@ void SharedStrings::saveToXmlFile(QIODevice *device) const
writer.writeAttribute(QStringLiteral("count"), QString::number(m_stringCount));
writer.writeAttribute(QStringLiteral("uniqueCount"), QString::number(m_stringTable.size()));
foreach (QString string, m_stringList) {
foreach (RichString string, m_stringList) {
writer.writeStartElement(QStringLiteral("si"));
if (string.contains(QRegularExpression(QStringLiteral("^<r>"))) || string.contains(QRegularExpression(QStringLiteral("</r>$")))) {
//Rich text string,
// writer.writeCharacters(string);
if (string.isRichString()) {
//Rich text string
for (int i=0; i<string.fragmentCount(); ++i) {
if (string.fragmentFormat(i)) {
writer.writeStartElement(QStringLiteral("rPr"));
//:Todo
writer.writeEndElement();// rPr
}
writer.writeStartElement(QStringLiteral("t"));
writer.writeAttribute(QStringLiteral("xml:space"), QStringLiteral("preserve"));
writer.writeCharacters(string.fragmentText(i));
writer.writeEndElement();// t
}
} else {
writer.writeStartElement(QStringLiteral("t"));
if (string.contains(QRegularExpression(QStringLiteral("^\\s"))) || string.contains(QRegularExpression(QStringLiteral("\\s$"))))
QString pString = string.toPlainString();
if (pString.contains(QRegularExpression(QStringLiteral("^\\s")))
|| pString.contains(QRegularExpression(QStringLiteral("\\s$")))) {
writer.writeAttribute(QStringLiteral("xml:space"), QStringLiteral("preserve"));
writer.writeCharacters(string);
}
writer.writeCharacters(pString);
writer.writeEndElement();//t
}
writer.writeEndElement();//si
@ -146,6 +175,56 @@ QByteArray SharedStrings::saveToXmlData() const
return data;
}
void SharedStrings::readString(XmlStreamReader &reader)
{
Q_ASSERT(reader.name() == QLatin1String("si"));
RichString richString;
while (!(reader.name() == QLatin1String("si") && reader.tokenType() == QXmlStreamReader::EndElement)) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("r"))
readRichStringPart(reader, richString);
else if (reader.name() == QLatin1String("t"))
readPlainStringPart(reader, richString);
}
}
int idx = m_stringList.size();
m_stringTable[richString] = XlsxSharedStringInfo(idx, 0);
m_stringList.append(richString);
}
void SharedStrings::readRichStringPart(XmlStreamReader &reader, RichString &richString)
{
Q_ASSERT(reader.name() == QLatin1String("r"));
QString text;
Format *format=0;
while (!(reader.name() == QLatin1String("r") && reader.tokenType() == QXmlStreamReader::EndElement)) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
if (reader.name() == QLatin1String("rPr")) {
//:Todo
} else if (reader.name() == QLatin1String("t")) {
text = reader.readElementText();
}
}
}
richString.addFragment(text, format);
}
void SharedStrings::readPlainStringPart(XmlStreamReader &reader, RichString &richString)
{
Q_ASSERT(reader.name() == QLatin1String("t"));
//QXmlStreamAttributes attributes = reader.attributes();
QString text = reader.readElementText();
richString.addFragment(text, 0);
}
bool SharedStrings::loadFromXmlFile(QIODevice *device)
{
XmlStreamReader reader(device);
@ -157,15 +236,7 @@ bool SharedStrings::loadFromXmlFile(QIODevice *device)
QXmlStreamAttributes attributes = reader.attributes();
count = attributes.value(QLatin1String("uniqueCount")).toString().toInt();
} else if (reader.name() == QLatin1String("si")) {
if (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("t")) {
// QXmlStreamAttributes attributes = reader.attributes();
QString string = reader.readElementText();
int idx = m_stringList.size();
m_stringTable[string] = XlsxSharedStringInfo(idx, 0);
m_stringList.append(string);
}
}
readString(reader);
}
}
}

19
src/xlsx/xlsxsharedstrings_p.h

@ -26,6 +26,7 @@
#define XLSXSHAREDSTRINGS_H
#include "xlsxglobal.h"
#include "xlsxrichstring_p.h"
#include <QHash>
#include <QStringList>
#include <QSharedPointer>
@ -34,6 +35,9 @@ class QIODevice;
namespace QXlsx {
class XmlStreamReader;
class RichString;
class XlsxSharedStringInfo
{
public:
@ -53,12 +57,15 @@ public:
int count() const;
int addSharedString(const QString &string);
int addSharedString(const RichString &string);
void removeSharedString(const QString &string);
void removeSharedString(const RichString &string);
void incRefByStringIndex(int idx);
int getSharedStringIndex(const QString &string) const;
QString getSharedString(int index) const;
QStringList getSharedStrings() const;
int getSharedStringIndex(const RichString &string) const;
RichString getSharedString(int index) const;
QList<RichString> getSharedStrings() const;
void saveToXmlFile(QIODevice *device) const;
QByteArray saveToXmlData() const;
@ -66,8 +73,12 @@ public:
bool loadFromXmlData(const QByteArray &data);
private:
QHash<QString, XlsxSharedStringInfo> m_stringTable; //for fast lookup
QStringList m_stringList;
void readString(XmlStreamReader &reader); // <si>
void readRichStringPart(XmlStreamReader &reader, RichString &rich); // <r>
void readPlainStringPart(XmlStreamReader &reader, RichString &rich); // <v>
QHash<RichString, XlsxSharedStringInfo> m_stringTable; //for fast lookup
QList<RichString> m_stringList;
int m_stringCount;
};

24
src/xlsx/xlsxworksheet.cpp

@ -22,6 +22,7 @@
** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**
****************************************************************************/
#include "xlsxrichstring_p.h"
#include "xlsxworksheet.h"
#include "xlsxworksheet_p.h"
#include "xlsxworkbook.h"
@ -1163,7 +1164,21 @@ void WorksheetPrivate::writeCellData(XmlStreamWriter &writer, int row, int col,
} else if (cell->dataType() == Cell::InlineString) {
writer.writeAttribute(QStringLiteral("t"), QStringLiteral("inlineStr"));
writer.writeStartElement(QStringLiteral("is"));
writer.writeTextElement(QStringLiteral("t"), cell->value().toString());
if (cell->isRichString()) {
//Rich text string
RichString string = cell->d_ptr->richString;
for (int i=0; i<string.fragmentCount(); ++i) {
writer.writeStartElement(QStringLiteral("rPr"));
//:Todo
writer.writeEndElement();// rPr
writer.writeStartElement(QStringLiteral("t"));
writer.writeAttribute(QStringLiteral("xml:space"), QStringLiteral("preserve"));
writer.writeCharacters(string.fragmentText(i));
writer.writeEndElement();// t
}
} else {
writer.writeTextElement(QStringLiteral("t"), cell->value().toString());
}
writer.writeEndElement();//is
} else if (cell->dataType() == Cell::Numeric){
double value = cell->value().toDouble();
@ -1874,8 +1889,10 @@ void WorksheetPrivate::readSheetData(XmlStreamReader &reader)
if (reader.name() == QLatin1String("v")) {
int sst_idx = reader.readElementText().toInt();
sharedStrings()->incRefByStringIndex(sst_idx);
QString value = sharedStrings()->getSharedString(sst_idx);
QSharedPointer<Cell> data(new Cell(value ,Cell::String, format, q));
RichString rs = sharedStrings()->getSharedString(sst_idx);
QSharedPointer<Cell> data(new Cell(rs.toPlainString() ,Cell::String, format, q));
if (rs.isRichString())
data->d_ptr->richString = rs;
cellTable[pos.x()][pos.y()] = QSharedPointer<Cell>(data);
}
}
@ -1884,6 +1901,7 @@ void WorksheetPrivate::readSheetData(XmlStreamReader &reader)
while (!(reader.name() == QLatin1String("c") && reader.tokenType() == QXmlStreamReader::EndElement)) {
reader.readNextStartElement();
if (reader.tokenType() == QXmlStreamReader::StartElement) {
//:Todo, add rich text read support
if (reader.name() == QLatin1String("t")) {
QString value = reader.readElementText();
QSharedPointer<Cell> data(new Cell(value, Cell::InlineString, format, q));

3
tests/auto/auto.pro

@ -9,4 +9,5 @@ SUBDIRS=\
document \
sharedstrings \
styles \
format
format \
richstring

12
tests/auto/richstring/richstring.pro

@ -0,0 +1,12 @@
QT += testlib xlsx xlsx-private
CONFIG += testcase
DEFINES += XLSX_TEST
TARGET = tst_richstringtest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += tst_richstringtest.cpp
DEFINES += SRCDIR=\\\"$$PWD/\\\"

41
tests/auto/richstring/tst_richstringtest.cpp

@ -0,0 +1,41 @@
#include "private/xlsxrichstring_p.h"
#include <QtTest>
#include <QDebug>
class RichstringTest : public QObject
{
Q_OBJECT
public:
RichstringTest();
private Q_SLOTS:
void testEqual();
};
RichstringTest::RichstringTest()
{
}
void RichstringTest::testEqual()
{
QXlsx::RichString rs;
rs.addFragment("Hello", 0);
rs.addFragment(" RichText", 0);
QXlsx::RichString rs2;
rs2.addFragment("Hello", 0);
rs2.addFragment(" Qt!", 0);
QXlsx::RichString rs3;
rs3.addFragment("Hello", 0);
rs3.addFragment(" Qt!", 0);
QVERIFY2(rs2 != rs, "Failure");
QVERIFY2(rs2 == rs3, "Failure");
QVERIFY2(rs2 != QStringLiteral("Hello Qt!"), "Failure");
}
QTEST_APPLESS_MAIN(RichstringTest)
#include "tst_richstringtest.moc"

36
tests/auto/sharedstrings/tst_sharedstringstest.cpp

@ -1,4 +1,5 @@
#include "private/xlsxsharedstrings_p.h"
#include "private/xlsxrichstring_p.h"
#include <QString>
#include <QtTest>
#include <QXmlStreamReader>
@ -27,6 +28,19 @@ void SharedStringsTest::testAddSharedString()
QXlsx::SharedStrings sst;
sst.addSharedString("Hello Qt!");
sst.addSharedString("Xlsx Writer");
QXlsx::RichString rs;
rs.addFragment("Hello", 0);
rs.addFragment(" RichText", 0);
sst.addSharedString(rs);
for (int i=0; i<3; ++i) {
QXlsx::RichString rs2;
rs2.addFragment("Hello", 0);
rs2.addFragment(" Qt!", 0);
sst.addSharedString(rs2);
}
sst.addSharedString("Hello World");
sst.addSharedString("Hello Qt!");
@ -46,8 +60,8 @@ void SharedStringsTest::testAddSharedString()
}
}
QCOMPARE(count, 4);
QCOMPARE(uniqueCount, 3);
QCOMPARE(count, 8);
QCOMPARE(uniqueCount, 5);
}
void SharedStringsTest::testRemoveSharedString()
@ -88,6 +102,17 @@ void SharedStringsTest::testLoadXmlData()
QXlsx::SharedStrings sst;
sst.addSharedString("Hello Qt!");
sst.addSharedString("Xlsx Writer");
QXlsx::RichString rs;
rs.addFragment("Hello", 0);
rs.addFragment(" RichText", 0);
sst.addSharedString(rs);
for (int i=0; i<3; ++i) {
QXlsx::RichString rs2;
rs2.addFragment("Hello", 0);
rs2.addFragment(" Qt!", 0);
sst.addSharedString(rs2);
}
sst.addSharedString("Hello World");
sst.addSharedString("Hello Qt!");
QByteArray xmlData = sst.saveToXmlData();
@ -95,10 +120,11 @@ void SharedStringsTest::testLoadXmlData()
QSharedPointer<QXlsx::SharedStrings> sst2(new QXlsx::SharedStrings);
sst2->loadFromXmlData(xmlData);
QCOMPARE(sst2->getSharedString(0), QStringLiteral("Hello Qt!"));
QCOMPARE(sst2->getSharedString(2), QStringLiteral("Hello World"));
QCOMPARE(sst2->getSharedString(0).toPlainString(), QStringLiteral("Hello Qt!"));
QCOMPARE(sst2->getSharedString(2), rs);
QCOMPARE(sst2->getSharedString(4).toPlainString(), QStringLiteral("Hello World"));
QCOMPARE(sst2->getSharedStringIndex("Hello Qt!"), 0);
QCOMPARE(sst2->getSharedStringIndex("Hello World"), 2);
QCOMPARE(sst2->getSharedStringIndex("Hello World"), 4);
}
QTEST_APPLESS_MAIN(SharedStringsTest)

13
tests/auto/worksheet/tst_worksheet.cpp

@ -8,6 +8,7 @@
#include "private/xlsxworksheet_p.h"
#include "private/xlsxxmlreader_p.h"
#include "private/xlsxsharedstrings_p.h"
#include "private/xlsxrichstring_p.h"
class WorksheetTest : public QObject
{
@ -116,7 +117,7 @@ void WorksheetTest::testWriteCells()
QVERIFY2(xmldata.contains("<c r=\"A5\" t=\"str\"><f>44+33</f><v>0</v></c>"), "formula");
QVERIFY2(xmldata.contains("<c r=\"B5\" t=\"str\"><f>44+33</f><v>77</v></c>"), "formula");
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(0), QStringLiteral("Hello"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(0).toPlainString(), QStringLiteral("Hello"));
}
void WorksheetTest::testWriteHyperlinks()
@ -136,11 +137,11 @@ void WorksheetTest::testWriteHyperlinks()
QVERIFY2(xmldata.contains("<hyperlink ref=\"D1\" r:id=\"rId4\"/>"), "mail");
QVERIFY2(xmldata.contains("<hyperlink ref=\"E1\" r:id=\"rId5\"/>"), "mail with subject");
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(0), QStringLiteral("http://qt-project.org"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(1), QStringLiteral("http://qt-project.org/abc"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(2), QStringLiteral("http://qt-project.org/abc.html#test"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(3), QStringLiteral("xyz@debao.me"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(4), QStringLiteral("xyz@debao.me?subject=Test"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(0).toPlainString(), QStringLiteral("http://qt-project.org"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(1).toPlainString(), QStringLiteral("http://qt-project.org/abc"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(2).toPlainString(), QStringLiteral("http://qt-project.org/abc.html#test"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(3).toPlainString(), QStringLiteral("xyz@debao.me"));
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(4).toPlainString(), QStringLiteral("xyz@debao.me?subject=Test"));
}
void WorksheetTest::testWriteDataValidations()

Loading…
Cancel
Save