From e2752e4da865d8a0528d360b70acf5a59154441f Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Tue, 14 Jan 2014 10:24:03 +0800 Subject: [PATCH 1/2] Don't do too smart thing for Worksheet::write() Implictly convert QString to other types is danger. Such as QVariant("12345").toTime() will generate a valid QTime Object. --- src/xlsx/xlsxworksheet.cpp | 46 +++++++++++++++--------- tests/auto/document/tst_documenttest.cpp | 29 +++++++++------ 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index c5a7c67..47694b5 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -467,45 +467,59 @@ QList > Worksheet::drawingLinks() const int Worksheet::write(int row, int column, const QVariant &value, const Format &format) { Q_D(Worksheet); - bool ok; int ret = 0; if (d->checkDimensions(row, column)) return -1; - if (value.isNull()) { //blank + if (value.isNull()) { + //Blank ret = writeBlank(row, column, format); } else if (value.userType() == qMetaTypeId()) { ret = writeString(row, column, value.value(), format); - } else if (value.userType() == QMetaType::Bool) { //Bool + } else if (value.userType() == QMetaType::Bool) { + //Bool ret = writeBool(row,column, value.toBool(), format); - } else if (value.toDateTime().isValid()) { //DateTime + } else if (value.userType() == QMetaType::QDateTime || value.userType() == QMetaType::QDate) { + //DateTime, Date + // note that, QTime cann't convert to QDateTime ret = writeDateTime(row, column, value.toDateTime(), format); - } else if (value.toTime().isValid()) { //Time + } else if (value.userType() == QMetaType::QTime) { + //Time ret = writeTime(row, column, value.toTime(), format); - } else if (value.toDouble(&ok), ok) { //Number - if (!d->workbook->isStringsToNumbersEnabled() && value.userType() == QMetaType::QString) { - //Don't convert string to number if the flag not enabled. - ret = writeString(row, column, value.toString(), format); - } else { - ret = writeNumeric(row, column, value.toDouble(), format); - } - } else if (value.userType() == QMetaType::QUrl) { //url + } else if (value.userType() == QMetaType::Int || value.userType() == QMetaType::UInt + || value.userType() == QMetaType::LongLong || value.userType() == QMetaType::ULongLong + || value.userType() == QMetaType::Double || value.userType() == QMetaType::Float) { + //Number + + ret = writeNumeric(row, column, value.toDouble(), format); + } else if (value.userType() == QMetaType::QUrl) { + //Url ret = writeHyperlink(row, column, value.toUrl(), format); - } else if (value.userType() == QMetaType::QString) { //string + } else if (value.userType() == QMetaType::QString) { + //String QString token = value.toString(); + bool ok; QRegularExpression urlPattern(QStringLiteral("^([fh]tt?ps?://)|(mailto:)|(file://)")); + if (token.startsWith(QLatin1String("="))) { + //convert to formula ret = writeFormula(row, column, token, format); } else if (token.startsWith(QLatin1String("{=")) && token.endsWith(QLatin1Char('}'))) { + //convert to array formula ret = writeArrayFormula(CellRange(row, column, row, column), token, format); } else if (token.contains(urlPattern)) { + //convert to url ret = writeHyperlink(row, column, QUrl(token)); + } else if (d->workbook->isStringsToNumbersEnabled() && (value.toDouble(&ok), ok)) { + //Try convert string to number if the flag enabled. + ret = writeString(row, column, value.toString(), format); } else { + //normal string now ret = writeString(row, column, token, format); } - } else { //Wrong type - + } else { + //Wrong type return -1; } diff --git a/tests/auto/document/tst_documenttest.cpp b/tests/auto/document/tst_documenttest.cpp index f83436c..6de637e 100644 --- a/tests/auto/document/tst_documenttest.cpp +++ b/tests/auto/document/tst_documenttest.cpp @@ -56,11 +56,15 @@ void DocumentTest::testReadWriteString() Document xlsx1; xlsx1.write("A1", "Hello Qt!"); + Format format; format.setFontColor(Qt::blue); format.setBorderStyle(Format::BorderDashDotDot); format.setFillPattern(Format::PatternSolid); xlsx1.write("A2", "Hello Qt again!", format); + + xlsx1.write("A3", "12345"); + xlsx1.saveAs(&device); device.open(QIODevice::ReadOnly); @@ -74,6 +78,9 @@ void DocumentTest::testReadWriteString() // qDebug()<dataType(), Cell::String); + QCOMPARE(xlsx2.cellAt("A3")->value().toString(), QString("12345")); } void DocumentTest::testReadWriteNumeric() @@ -198,7 +205,7 @@ void DocumentTest::testReadWriteDateTime() format3.setNumberFormat("dd/mm/yyyy"); xlsx1.write("A3", dt, format3); - xlsx1.write("A4", "2013-12-14T12:30"); //Auto convert to QDateTime, by QVariant +// xlsx1.write("A4", "2013-12-14T12:30"); //Auto convert to QDateTime, by QVariant xlsx1.saveAs(&device); @@ -220,10 +227,10 @@ void DocumentTest::testReadWriteDateTime() QCOMPARE(xlsx2.cellAt("A3")->dateTime(), dt); QCOMPARE(xlsx2.cellAt("A3")->format().numberFormat(), QString("dd/mm/yyyy")); - QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); - QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); - QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14), QTime(12, 30))); - QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDateTime); +// QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); +// QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); +// QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14), QTime(12, 30))); +// QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDateTime); } void DocumentTest::testReadWriteDate() @@ -246,7 +253,7 @@ void DocumentTest::testReadWriteDate() format3.setNumberFormat("dd/mm/yyyy"); xlsx1.write("A3", d, format3); - xlsx1.write("A4", "2013-12-14"); //Auto convert to QDateTime, by QVariant +// xlsx1.write("A4", "2013-12-14"); //Auto convert to QDateTime, by QVariant xlsx1.saveAs(&device); @@ -268,11 +275,11 @@ void DocumentTest::testReadWriteDate() QVERIFY(xlsx2.read("A3").userType() == QMetaType::QDate); QCOMPARE(xlsx2.read("A3").toDate(), d); - QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); - QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); - QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14))); - QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDate); - QCOMPARE(xlsx2.read("A4").toDate(), QDate(2013,12,14)); +// QCOMPARE(xlsx2.cellAt("A4")->dataType(), Cell::Numeric); +// QCOMPARE(xlsx2.cellAt("A4")->isDateTime(), true); +// QCOMPARE(xlsx2.cellAt("A4")->dateTime(), QDateTime(QDate(2013,12,14))); +// QVERIFY(xlsx2.read("A4").userType() == QMetaType::QDate); +// QCOMPARE(xlsx2.read("A4").toDate(), QDate(2013,12,14)); } void DocumentTest::testReadWriteTime() From 536f3926b24300bffa8066d80519a28a97f4d4ab Mon Sep 17 00:00:00 2001 From: Debao Zhang Date: Mon, 20 Jan 2014 10:37:26 +0800 Subject: [PATCH 2/2] Update documentation --- src/xlsx/xlsxconditionalformatting.cpp | 16 ++++ src/xlsx/xlsxdocument.cpp | 4 +- src/xlsx/xlsxformat.cpp | 4 + src/xlsx/xlsxworksheet.cpp | 111 ++++++++++++++++++++----- 4 files changed, 113 insertions(+), 22 deletions(-) diff --git a/src/xlsx/xlsxconditionalformatting.cpp b/src/xlsx/xlsxconditionalformatting.cpp index 63df48c..397dae5 100644 --- a/src/xlsx/xlsxconditionalformatting.cpp +++ b/src/xlsx/xlsxconditionalformatting.cpp @@ -125,6 +125,17 @@ void ConditionalFormattingPrivate::writeCfVo(QXmlStreamWriter &writer, const Xls \value Highlight_Expression */ +/*! + \enum ConditionalFormatting::ValueObjectType + + \value VOT_Formula + \value VOT_Max + \value VOT_Min + \value VOT_Num + \value VOT_Percent + \value VOT_Percentile +*/ + /*! Construct a conditional formatting object */ @@ -164,6 +175,7 @@ ConditionalFormatting::~ConditionalFormatting() /*! * Add a hightlight rule with the given \a type, \a formula1, \a formula2, * \a format and \a stopIfTrue. + * Return false if failed. */ bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula1, const QString &formula2, const Format &format, bool stopIfTrue) { @@ -290,6 +302,7 @@ bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const * \overload * * Add a hightlight rule with the given \a type, \a formula, \a format and \a stopIfTrue. + * Return false if failed. */ bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula, const Format &format, bool stopIfTrue) { @@ -302,6 +315,7 @@ bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const /*! * Add a dataBar rule with the given \a color, \a type1, \a val1 * , \a type2, \a val2, \a showData and \a stopIfTrue. + * Return false if failed. */ bool ConditionalFormatting::addDataBarRule(const QColor &color, ValueObjectType type1, const QString &val1, ValueObjectType type2, const QString &val2, bool showData, bool stopIfTrue) { @@ -334,6 +348,7 @@ bool ConditionalFormatting::addDataBarRule(const QColor &color, bool showData, b /*! * Add a colorScale rule with the given \a minColor, \a maxColor and \a stopIfTrue. + * Return false if failed. */ bool ConditionalFormatting::add2ColorScaleRule(const QColor &minColor, const QColor &maxColor, bool stopIfTrue) { @@ -361,6 +376,7 @@ bool ConditionalFormatting::add2ColorScaleRule(const QColor &minColor, const QCo /*! * Add a colorScale rule with the given \a minColor, \a midColor, \a maxColor and \a stopIfTrue. + * Return false if failed. */ bool ConditionalFormatting::add3ColorScaleRule(const QColor &minColor, const QColor &midColor, const QColor &maxColor, bool stopIfTrue) { diff --git a/src/xlsx/xlsxdocument.cpp b/src/xlsx/xlsxdocument.cpp index f39b2ba..131a538 100644 --- a/src/xlsx/xlsxdocument.cpp +++ b/src/xlsx/xlsxdocument.cpp @@ -657,6 +657,7 @@ bool Document::moveWorksheet(const QString &srcName, int distIndex) /*! Delete the worksheet \a name. + Returns true if current sheet was deleted successfully. */ bool Document::deleteWorksheet(const QString &name) { @@ -703,7 +704,8 @@ void Document::setCurrentWorksheet(const QString &name) } /*! - * \brief Set current selected worksheet to be the sheet named \a name. + * \brief Set worksheet named \a name to be active sheet. + * Returns true if success. */ bool Document::selectWorksheet(const QString &name) { diff --git a/src/xlsx/xlsxformat.cpp b/src/xlsx/xlsxformat.cpp index 0690723..c7c1197 100755 --- a/src/xlsx/xlsxformat.cpp +++ b/src/xlsx/xlsxformat.cpp @@ -1124,6 +1124,10 @@ void Format::setLocked(bool locked) setProperty(FormatPrivate::P_Protection_Locked, locked); } +/*! + \internal + Return true if the format has protection data, otherwise return false. + */ bool Format::hasProtectionData() const { if (!d) diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index 47694b5..417bd28 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -165,11 +165,13 @@ int WorksheetPrivate::checkDimensions(int row, int col, bool ignore_row, bool ig } /*! - * \brief Worksheet::Worksheet - * \param name Name of the worksheet - * \param id : An integer representing the internal id of the - * sheet which is used by .xlsx revision part. - * (Note: id is not the index of the sheet in workbook) + \class Worksheet + \inmodule QtXlsx + \brief Represent one worksheet in the workbook. +*/ + +/*! + * \internal */ Worksheet::Worksheet(const QString &name, int id, Workbook *workbook) : d_ptr(new WorksheetPrivate(this)) @@ -181,6 +183,12 @@ Worksheet::Worksheet(const QString &name, int id, Workbook *workbook) : d_ptr->workbook = workbook; } +/*! + * \internal + * + * Make a copy of this sheet. + */ + QSharedPointer Worksheet::copy(const QString &distName, int distId) const { Q_D(const Worksheet); @@ -219,16 +227,25 @@ QSharedPointer Worksheet::copy(const QString &distName, int distId) c return sheet; } +/*! + * Destroys this workssheet. + */ Worksheet::~Worksheet() { delete d_ptr; } +/*! + * \internal + */ bool Worksheet::isChartsheet() const { return false; } +/*! + * Returns the name of the sheet. + */ QString Worksheet::sheetName() const { Q_D(const Worksheet); @@ -253,18 +270,27 @@ Relationships &Worksheet::relationships() return d->relationships; } +/*! + * \internal + */ bool Worksheet::isHidden() const { Q_D(const Worksheet); return d->hidden; } +/*! + * \internal + */ void Worksheet::setHidden(bool hidden) { Q_D(Worksheet); d->hidden = hidden; } +/*! + * \internal + */ int Worksheet::sheetId() const { Q_D(const Worksheet); @@ -281,7 +307,7 @@ bool Worksheet::isWindowProtected() const } /*! - * Protects/unprotects the sheet. + * Protects/unprotects the sheet based on \a protect. */ void Worksheet::setWindowProtected(bool protect) { @@ -299,7 +325,7 @@ bool Worksheet::isFormulasVisible() const } /*! - * Show formulas in cells instead of their calculated results + * Show formulas in cells instead of their calculated results when \a visible is true. */ void Worksheet::setFormulasVisible(bool visible) { @@ -354,7 +380,7 @@ bool Worksheet::isRightToLeft() const } /*! - * Enable or disable the right-to-left. + * Enable or disable the right-to-left based on \a enable. */ void Worksheet::setRightToLeft(bool enable) { @@ -372,7 +398,7 @@ bool Worksheet::isZerosVisible() const } /*! - * Show a zero in cells that have zero value. + * Show a zero in cells that have zero value if \a visible is true. */ void Worksheet::setZerosVisible(bool visible) { @@ -390,7 +416,7 @@ bool Worksheet::isSelected() const } /*! - * Set + * Select this sheet if \a select is true. */ void Worksheet::setSelected(bool select) { @@ -409,7 +435,7 @@ bool Worksheet::isRulerVisible() const } /*! - * Show or hide the ruler. + * Show or hide the ruler based on \a visible. */ void Worksheet::setRulerVisible(bool visible) { @@ -428,7 +454,7 @@ bool Worksheet::isOutlineSymbolsVisible() const } /*! - * Show or hide the outline symbols. + * Show or hide the outline symbols based ib \a visible. */ void Worksheet::setOutlineSymbolsVisible(bool visible) { @@ -446,7 +472,7 @@ bool Worksheet::isWhiteSpaceVisible() const } /*! - * Show or hide the white space. + * Show or hide the white space based on \a visible. */ void Worksheet::setWhiteSpaceVisible(bool visible) { @@ -527,7 +553,9 @@ int Worksheet::write(int row, int column, const QVariant &value, const Format &f } /*! - \overload + * \overload + * Write \a value to cell \a row_column with the \a format. + * Both row and column are all 1-indexed value. */ int Worksheet::write(const QString &row_column, const QVariant &value, const Format &format) { @@ -541,6 +569,7 @@ int Worksheet::write(const QString &row_column, const QVariant &value, const For /*! \overload + Return the contents of the cell \a row_column. */ QVariant Worksheet::read(const QString &row_column) const { @@ -574,6 +603,11 @@ QVariant Worksheet::read(int row, int column) const return cell->value(); } +/*! + * \overload + * Returns the cell at the position \a row_column. + * 0 will be returned if the cell doesn't exist. + */ Cell *Worksheet::cellAt(const QString &row_column) const { QPoint pos = xl_cell_to_rowcol(row_column); @@ -583,6 +617,10 @@ Cell *Worksheet::cellAt(const QString &row_column) const return cellAt(pos.x(), pos.y()); } +/*! + * Returns the cell at the position (\a row \a column). + * 0 will be returned if the cell doesn't exist. + */ Cell *Worksheet::cellAt(int row, int column) const { Q_D(const Worksheet); @@ -605,6 +643,7 @@ Format WorksheetPrivate::cellFormat(int row, int col) const /*! \overload + Write string \a value to the cell \a row_column with the \a format */ int Worksheet::writeString(const QString &row_column, const RichString &value, const Format &format) { @@ -643,6 +682,7 @@ int Worksheet::writeString(int row, int column, const RichString &value, const F /*! \overload + Write string \a value to the cell \a row_column with the \a format */ int Worksheet::writeString(const QString &row_column, const QString &value, const Format &format) { @@ -679,6 +719,7 @@ int Worksheet::writeString(int row, int column, const QString &value, const Form /*! \overload + Write string \a value to the cell \a row_column with the \a format */ int Worksheet::writeInlineString(const QString &row_column, const QString &value, const Format &format) { @@ -714,6 +755,7 @@ int Worksheet::writeInlineString(int row, int column, const QString &value, cons /*! \overload + Write numeric \a value to the cell \a row_column with the \a format */ int Worksheet::writeNumeric(const QString &row_column, double value, const Format &format) { @@ -742,6 +784,7 @@ int Worksheet::writeNumeric(int row, int column, double value, const Format &for /*! \overload + Write \a formula to the cell \a row_column with the \a format and \a result. */ int Worksheet::writeFormula(const QString &row_column, const QString &formula, const Format &format, double result) { @@ -754,7 +797,7 @@ int Worksheet::writeFormula(const QString &row_column, const QString &formula, c } /*! - Write \a formula to the cell (\a row, \a column) with the \a format + Write \a formula to the cell (\a row, \a column) with the \a format and \a result. */ int Worksheet::writeFormula(int row, int column, const QString &formula, const Format &format, double result) { @@ -816,6 +859,7 @@ int Worksheet::writeArrayFormula(const CellRange &range, const QString &formula, /*! \overload + Write \a formula to the \a range with the \a format */ int Worksheet::writeArrayFormula(const QString &range, const QString &formula, const Format &format) { @@ -824,6 +868,7 @@ int Worksheet::writeArrayFormula(const QString &range, const QString &formula, c /*! \overload + Write a empty cell \a row_column with the \a format */ int Worksheet::writeBlank(const QString &row_column, const Format &format) { @@ -853,6 +898,7 @@ int Worksheet::writeBlank(int row, int column, const Format &format) } /*! \overload + Write a bool \a value to the cell \a row_column with the \a format */ int Worksheet::writeBool(const QString &row_column, bool value, const Format &format) { @@ -881,6 +927,7 @@ int Worksheet::writeBool(int row, int column, bool value, const Format &format) } /*! \overload + Write a QDateTime \a dt to the cell \a row_column with the \a format */ int Worksheet::writeDateTime(const QString &row_column, const QDateTime &dt, const Format &format) { @@ -893,7 +940,7 @@ int Worksheet::writeDateTime(const QString &row_column, const QDateTime &dt, con } /*! - Write a QDateTime \a value to the cell (\a row, \a column) with the \a format + Write a QDateTime \a dt to the cell (\a row, \a column) with the \a format */ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const Format &format) { @@ -915,6 +962,7 @@ int Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const For /*! \overload + Write a QTime \a t to the cell \a row_column with the \a format */ int Worksheet::writeTime(const QString &row_column, const QTime &t, const Format &format) { @@ -927,7 +975,7 @@ int Worksheet::writeTime(const QString &row_column, const QTime &t, const Format } /*! - Write a QTime \a value to the cell (\a row, \a column) with the \a format + Write a QTime \a t to the cell (\a row, \a column) with the \a format */ int Worksheet::writeTime(int row, int column, const QTime &t, const Format &format) { @@ -947,6 +995,7 @@ int Worksheet::writeTime(int row, int column, const QTime &t, const Format &form /*! \overload + Write a QUrl \a url to the cell \a row_column with the given \a format \a display and \a tip */ int Worksheet::writeHyperlink(const QString &row_column, const QUrl &url, const Format &format, const QString &display, const QString &tip) { @@ -959,7 +1008,7 @@ int Worksheet::writeHyperlink(const QString &row_column, const QUrl &url, const } /*! - Write a QUrl \a url to the cell (\a row, \a column) with the given \a format + Write a QUrl \a url to the cell (\a row, \a column) with the given \a format \a display and \a tip. */ int Worksheet::writeHyperlink(int row, int column, const QUrl &url, const Format &format, const QString &display, const QString &tip) { @@ -1012,6 +1061,10 @@ int Worksheet::writeHyperlink(int row, int column, const QUrl &url, const Format return error; } +/*! + * Add one DataValidation \a validation to the sheet. + * Return true if it's successful. + */ bool Worksheet::addDataValidation(const DataValidation &validation) { Q_D(Worksheet); @@ -1022,6 +1075,10 @@ bool Worksheet::addDataValidation(const DataValidation &validation) return true; } +/*! + * Add one ConditionalFormatting \a cf to the sheet. + * Return true if it's successful. + */ bool Worksheet::addConditionalFormatting(const ConditionalFormatting &cf) { Q_D(Worksheet); @@ -1038,6 +1095,9 @@ bool Worksheet::addConditionalFormatting(const ConditionalFormatting &cf) return true; } +/*! + * \internal + */ int Worksheet::insertImage(int row, int column, const QImage &image, const QPointF &offset, double xScale, double yScale) { Q_D(Worksheet); @@ -1458,8 +1518,11 @@ void WorksheetPrivate::saveXmlDrawings(QXmlStreamWriter &writer) const } /*! - Sets row \a height and \a format. Row height measured in point size. If format + Sets the \a height and \a format of the row \a row. Row height measured in point size. If format equals 0 then format is ignored. \a row is 1-indexed. + Hides the row if \a hidden is true. + + Returns true if success. */ bool Worksheet::setRow(int row, double height, const Format &format, bool hidden) { @@ -1521,6 +1584,9 @@ void WorksheetPrivate::splitColsInfo(int colFirst, int colLast) width measured as the number of characters of the maximum digit width of the numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. If format equals 0 then format is ignored. Both \a colFirst and \a colLast are all 1-indexed. + Hides the column if \a hidden is true. + + Return true if success. */ bool Worksheet::setColumn(int colFirst, int colLast, double width, const Format &format, bool hidden) { @@ -1588,7 +1654,9 @@ bool Worksheet::setColumn(const QString &colFirst, const QString &colLast, doubl } /*! - Groups rows from rowFirst to rowLast. Returns false if error occurs. + Groups rows from \a rowFirst to \a rowLast with the given \a collapsed. + + Returns false if error occurs. */ bool Worksheet::groupRows(int rowFirst, int rowLast, bool collapsed) { @@ -1628,7 +1696,8 @@ bool Worksheet::groupColumns(const QString &colFirst, const QString &colLast, bo } /*! - Groups columns from colFirst to colLast. Returns false if error occurs. + Groups columns from \a colFirst to \a colLast with the given \a collapsed. + Returns false if error occurs. */ bool Worksheet::groupColumns(int colFirst, int colLast, bool collapsed) {