Browse Source

Code refactor for Worksheet::writeHyperlink()

master
Debao Zhang 11 years ago
parent
commit
987ca2dcdc
  1. 85
      src/xlsx/xlsxworksheet.cpp
  2. 2
      src/xlsx/xlsxworksheet.h
  3. 11
      src/xlsx/xlsxworksheet_p.h
  4. 25
      tests/auto/worksheet/tst_worksheet.cpp

85
src/xlsx/xlsxworksheet.cpp

@ -306,16 +306,14 @@ int Worksheet::write(int row, int column, const QVariant &value, Format *format)
ret = writeNumeric(row, column, value.toDouble(), format); ret = writeNumeric(row, column, value.toDouble(), format);
} }
} else if (value.type() == QMetaType::QUrl) { //url } else if (value.type() == QMetaType::QUrl) { //url
ret = writeUrl(row, column, value.toUrl(), format); ret = writeHyperlink(row, column, value.toUrl(), format);
} else if (value.type() == QMetaType::QString) { //string } else if (value.type() == QMetaType::QString) { //string
QString token = value.toString(); QString token = value.toString();
QRegularExpression urlPattern(QStringLiteral("^([fh]tt?ps?://)|(mailto:)|((in|ex)ternal:)")); QRegularExpression urlPattern(QStringLiteral("^([fh]tt?ps?://)|(mailto:)|(file://)"));
if (token.startsWith(QLatin1String("="))) { if (token.startsWith(QLatin1String("="))) {
ret = writeFormula(row, column, token, format); ret = writeFormula(row, column, token, format);
} else if (token.startsWith(QLatin1String("{")) && token.endsWith(QLatin1String("}"))) {
} else if (token.contains(urlPattern)) { } else if (token.contains(urlPattern)) {
ret = writeUrl(row, column, QUrl(token)); ret = writeHyperlink(row, column, QUrl(token));
} else { } else {
ret = writeString(row, column, token, format); ret = writeString(row, column, token, format);
} }
@ -469,67 +467,54 @@ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, Format *f
return 0; return 0;
} }
int Worksheet::writeUrl(int row, int column, const QUrl &url, Format *format, const QString &display, const QString &tip) int Worksheet::writeHyperlink(int row, int column, const QUrl &url, Format *format, const QString &display, const QString &tip)
{ {
Q_D(Worksheet); Q_D(Worksheet);
if (d->checkDimensions(row, column)) if (d->checkDimensions(row, column))
return -1; return -1;
int link_type = 1; int error = 0;
QString urlString = url.toString();
QString displayString = display;
if (urlString.startsWith(QLatin1String("internal:"))) {
urlString.replace(QLatin1String("internal:"), QString());
link_type = 2;
} else if (urlString.startsWith(QLatin1String("external:"))) {
urlString.replace(QLatin1String("external:"), QString());
link_type = 3;
}
if (display.isEmpty())
displayString = urlString;
//For external links, chagne the directory separator from Unix to Dos QString urlString = url.toString();
if (link_type == 3) {
urlString.replace(QLatin1Char('/'), QLatin1String("\\"));
displayString.replace(QLatin1Char('/'), QLatin1String("\\"));
}
//Generate proper display string
QString displayString = display.isEmpty() ? urlString : display;
if (displayString.startsWith(QLatin1String("mailto:")))
displayString.replace(QLatin1String("mailto:"), QString()); displayString.replace(QLatin1String("mailto:"), QString());
int error = 0;
if (displayString.size() > d->xls_strmax) { if (displayString.size() > d->xls_strmax) {
displayString = displayString.left(d->xls_strmax); displayString = displayString.left(d->xls_strmax);
error = -2; error = -2;
} }
QString locationString = displayString; /*
if (link_type == 1) { Location within target. If target is a workbook (or this workbook)
locationString = QString(); this shall refer to a sheet and cell or a defined name. Can also
} else if (link_type == 3) { be an HTML anchor if target is HTML file.
// External Workbook links need to be modified into correct format.
// The URL will look something like 'c:\temp\file.xlsx#Sheet!A1'. c:\temp\file.xlsx#Sheet!A1
// We need the part to the left of the # as the URL and the part to http://a.com/aaa.html#aaaaa
//the right as the "location" string (if it exists). */
if (urlString.contains(QLatin1Char('#'))) { QString locationString;
QStringList list = urlString.split(QLatin1Char('#')); if (url.hasFragment()) {
urlString = list[0]; locationString = url.fragment();
locationString = list[1]; urlString = url.toString(QUrl::RemoveFragment);
} else {
locationString = QString();
}
link_type = 1;
} }
//Given a default style for hyperlink
if (!format) {
format = d->workbook->createFormat();
format->setFontColor(Qt::blue);
format->setFontUnderline(Format::FontUnderlineSingle);
}
//Write the hyperlink string as normal string. //Write the hyperlink string as normal string.
d->sharedStrings()->addSharedString(urlString); d->sharedStrings()->addSharedString(displayString);
d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(urlString, Cell::String, format)); d->cellTable[row][column] = QSharedPointer<Cell>(new Cell(displayString, Cell::String, format));
//Store the hyperlink data in sa separate table
d->urlTable[row][column] = new XlsxUrlData(link_type, urlString, locationString, tip);
d->workbook->styles()->addFormat(format); d->workbook->styles()->addFormat(format);
//Store the hyperlink data in a separate table
d->urlTable[row][column] = new XlsxUrlData(XlsxUrlData::External, urlString, locationString, tip);
return error; return error;
} }
@ -821,14 +806,14 @@ void WorksheetPrivate::writeHyperlinks(XmlStreamWriter &writer)
QString ref = xl_rowcol_to_cell(row, col); QString ref = xl_rowcol_to_cell(row, col);
writer.writeEmptyElement(QStringLiteral("hyperlink")); writer.writeEmptyElement(QStringLiteral("hyperlink"));
writer.writeAttribute(QStringLiteral("ref"), ref); writer.writeAttribute(QStringLiteral("ref"), ref);
if (data->linkType == 1) { if (data->linkType == XlsxUrlData::External) {
rel_count += 1; rel_count += 1;
externUrlList.append(data->url); externUrlList.append(data->url);
writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(rel_count)); writer.writeAttribute(QStringLiteral("r:id"), QStringLiteral("rId%1").arg(rel_count));
if (!data->location.isEmpty()) if (!data->location.isEmpty())
writer.writeAttribute(QStringLiteral("location"), data->location); writer.writeAttribute(QStringLiteral("location"), data->location);
// if (!data->url.isEmpty()) if (!data->display.isEmpty())
// writer.writeAttribute(QStringLiteral("display"), data->url); writer.writeAttribute(QStringLiteral("display"), data->url);
if (!data->tip.isEmpty()) if (!data->tip.isEmpty())
writer.writeAttribute(QStringLiteral("tooltip"), data->tip); writer.writeAttribute(QStringLiteral("tooltip"), data->tip);
} else { } else {

2
src/xlsx/xlsxworksheet.h

@ -59,7 +59,7 @@ public:
int writeBlank(int row, int column, Format *format=0); int writeBlank(int row, int column, Format *format=0);
int writeBool(int row, int column, bool value, Format *format=0); int writeBool(int row, int column, bool value, Format *format=0);
int writeDateTime(int row, int column, const QDateTime& dt, Format *format=0); int writeDateTime(int row, int column, const QDateTime& dt, Format *format=0);
int writeUrl(int row, int column, const QUrl &url, Format *format=0, const QString &display=QString(), const QString &tip=QString()); int writeHyperlink(int row, int column, const QUrl &url, Format *format=0, const QString &display=QString(), const QString &tip=QString());
Cell *cellAt(const QString &row_column) const; Cell *cellAt(const QString &row_column) const;
Cell *cellAt(int row, int column) const; Cell *cellAt(int row, int column) const;

11
src/xlsx/xlsxworksheet_p.h

@ -39,15 +39,22 @@ class SharedStrings;
struct XlsxUrlData struct XlsxUrlData
{ {
XlsxUrlData(int linkType=1, const QString &url=QString(), const QString &location=QString(), const QString &tip=QString()) : enum LinkType
{
External,
Internal
};
XlsxUrlData(LinkType linkType=External, const QString &url=QString(), const QString &location=QString(), const QString &tip=QString()) :
linkType(linkType), url(url), location(location), tip(tip) linkType(linkType), url(url), location(location), tip(tip)
{ {
} }
int linkType; LinkType linkType;
QString url; QString url;
QString location; //location string QString location; //location string
QString display;
QString tip; QString tip;
}; };

25
tests/auto/worksheet/tst_worksheet.cpp

@ -18,6 +18,7 @@ private Q_SLOTS:
void testEmptySheet(); void testEmptySheet();
void testWriteCells(); void testWriteCells();
void testWriteHyperlinks();
void testMerge(); void testMerge();
void testUnMerge(); void testUnMerge();
@ -62,6 +63,30 @@ void WorksheetTest::testWriteCells()
QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(0), QStringLiteral("Hello")); QCOMPARE(sheet.d_ptr->sharedStrings()->getSharedString(0), QStringLiteral("Hello"));
} }
void WorksheetTest::testWriteHyperlinks()
{
QXlsx::Worksheet sheet("", 0);
sheet.write("A1", QUrl::fromUserInput("http://qt-project.org"));
sheet.write("B1", QUrl::fromUserInput("http://qt-project.org/abc"));
sheet.write("C1", QUrl::fromUserInput("http://qt-project.org/abc.html#test"));
sheet.write("D1", QUrl::fromUserInput("mailto:xyz@debao.me"));
sheet.write("E1", QUrl::fromUserInput("mailto:xyz@debao.me?subject=Test"));
QByteArray xmldata = sheet.saveToXmlData();
QVERIFY2(xmldata.contains("<hyperlink ref=\"A1\" r:id=\"rId1\"/>"), "simple");
QVERIFY2(xmldata.contains("<hyperlink ref=\"B1\" r:id=\"rId2\"/>"), "url with path");
QVERIFY2(xmldata.contains("<hyperlink ref=\"C1\" r:id=\"rId3\" location=\"test\"/>"), "url with location");
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"));
}
void WorksheetTest::testMerge() void WorksheetTest::testMerge()
{ {
QXlsx::Worksheet sheet("", 0); QXlsx::Worksheet sheet("", 0);

Loading…
Cancel
Save