diff --git a/src/xlsx/xlsxcellrange.cpp b/src/xlsx/xlsxcellrange.cpp index dc72baf..6251ab7 100644 --- a/src/xlsx/xlsxcellrange.cpp +++ b/src/xlsx/xlsxcellrange.cpp @@ -23,7 +23,7 @@ ** ****************************************************************************/ #include "xlsxcellrange.h" -#include "xlsxutility_p.h" +#include "xlsxcellreference.h" #include #include #include @@ -59,6 +59,12 @@ CellRange::CellRange(int top, int left, int bottom, int right) { } +CellRange::CellRange(const CellReference &topLeft, const CellReference &bottomRight) + : top(topLeft.row()), left(topLeft.column()) + , bottom(bottomRight.row()), right(bottomRight.column()) +{ +} + /*! \overload Constructs the range form the given \a range string. @@ -81,18 +87,18 @@ void CellRange::init(const QString &range) { QStringList rs = range.split(QLatin1Char(':')); if (rs.size() == 2) { - QPoint start = xl_cell_to_rowcol(rs[0]); - QPoint end = xl_cell_to_rowcol(rs[1]); - top = start.x(); - left = start.y(); - bottom = end.x(); - right = end.y(); + CellReference start(rs[0]); + CellReference end(rs[1]); + top = start.row(); + left = start.column(); + bottom = end.row(); + right = end.column(); } else { - QPoint p = xl_cell_to_rowcol(rs[0]); - top = p.x(); - left = p.y(); - bottom = p.x(); - right = p.y(); + CellReference p(rs[0]); + top = p.row(); + left = p.column(); + bottom = p.row(); + right = p.column(); } } @@ -115,18 +121,18 @@ CellRange::~CellRange() /*! Convert the range to string notation, such as "A1:B5". */ -QString CellRange::toString() const +QString CellRange::toString(bool row_abs, bool col_abs) const { - if (left == -1 || top == -1) + if (!isValid()) return QString(); if (left == right && top == bottom) { //Single cell - return xl_rowcol_to_cell(top, left); + return CellReference(top, left).toString(row_abs, col_abs); } - QString cell_1 = xl_rowcol_to_cell(top, left); - QString cell_2 = xl_rowcol_to_cell(bottom, right); + QString cell_1 = CellReference(top, left).toString(row_abs, col_abs); + QString cell_2 = CellReference(bottom, right).toString(row_abs, col_abs); return cell_1 + QLatin1String(":") + cell_2; } diff --git a/src/xlsx/xlsxcellrange.h b/src/xlsx/xlsxcellrange.h index 1ef2f0a..5a510b0 100644 --- a/src/xlsx/xlsxcellrange.h +++ b/src/xlsx/xlsxcellrange.h @@ -25,6 +25,7 @@ #ifndef QXLSX_XLSXCELLRANGE_H #define QXLSX_XLSXCELLRANGE_H #include "xlsxglobal.h" +#include "xlsxcellreference.h" QT_BEGIN_NAMESPACE_XLSX @@ -33,12 +34,13 @@ class Q_XLSX_EXPORT CellRange public: CellRange(); CellRange(int firstRow, int firstColumn, int lastRow, int lastColumn); + CellRange(const CellReference &topLeft, const CellReference &bottomRight); CellRange(const QString &range); CellRange(const char *range); CellRange(const CellRange &other); ~CellRange(); - QString toString() const; + QString toString(bool row_abs=false, bool col_abs=false) const; bool isValid() const; inline void setFirstRow(int row) { top = row; } inline void setLastRow(int row) { bottom = row; } @@ -50,6 +52,10 @@ public: inline int lastColumn() const { return right; } inline int rowCount() const { return bottom - top + 1; } inline int columnCount() const { return right - left + 1; } + inline CellReference topLeft() const { return CellReference(top, left); } + inline CellReference topRight() const { return CellReference(top, right); } + inline CellReference bottomLeft() const { return CellReference(bottom, left); } + inline CellReference bottomRight() const { return CellReference(bottom, right); } inline bool operator ==(const CellRange &other) const { diff --git a/src/xlsx/xlsxcellreference.cpp b/src/xlsx/xlsxcellreference.cpp index fcfe375..e7cf5da 100644 --- a/src/xlsx/xlsxcellreference.cpp +++ b/src/xlsx/xlsxcellreference.cpp @@ -163,14 +163,6 @@ QString CellReference::toString(bool row_abs, bool col_abs) const return cell_str; } -/*! - Returns a CellReference equivalent of the string \a cell -*/ -CellReference CellReference::fromString(const QString &cell) -{ - return CellReference(cell); -} - /*! * Returns true if the Reference is valid. */ diff --git a/src/xlsx/xlsxchart.cpp b/src/xlsx/xlsxchart.cpp index 86eae8d..c618f37 100644 --- a/src/xlsx/xlsxchart.cpp +++ b/src/xlsx/xlsxchart.cpp @@ -104,9 +104,7 @@ void Chart::addSeries(const CellRange &range, AbstractSheet *sheet) QString serRef = sheet ? sheet->sheetName() : d->sheet->sheetName(); serRef += QLatin1String("!"); - serRef += xl_rowcol_to_cell(range.firstRow(), range.firstColumn(), true, true); - serRef += QLatin1String(":"); - serRef += xl_rowcol_to_cell(range.lastRow(), range.lastColumn(), true, true); + serRef += range.toString(true, true); XlsxSeries *series = new XlsxSeries; series->numRef = serRef; diff --git a/src/xlsx/xlsxconditionalformatting.cpp b/src/xlsx/xlsxconditionalformatting.cpp index 397dae5..03561fe 100644 --- a/src/xlsx/xlsxconditionalformatting.cpp +++ b/src/xlsx/xlsxconditionalformatting.cpp @@ -419,9 +419,9 @@ QList ConditionalFormatting::ranges() const /*! Add the \a cell on which the conditional formatting will apply to. */ -void ConditionalFormatting::addCell(const QString &cell) +void ConditionalFormatting::addCell(const CellReference &cell) { - d->ranges.append(CellRange(cell)); + d->ranges.append(CellRange(cell, cell)); } /*! @@ -433,14 +433,6 @@ void ConditionalFormatting::addCell(int row, int col) d->ranges.append(CellRange(row, col, row, col)); } -/*! - Add the \a range on which the conditional formatting will apply to. - */ -void ConditionalFormatting::addRange(const QString &range) -{ - d->ranges.append(CellRange(range)); -} - /*! \overload Add the range(\a firstRow, \a firstCol, \a lastRow, \a lastCol) on @@ -452,7 +444,6 @@ void ConditionalFormatting::addRange(int firstRow, int firstCol, int lastRow, in } /*! - \overload Add the \a range on which the conditional formatting will apply to. */ void ConditionalFormatting::addRange(const CellRange &range) diff --git a/src/xlsx/xlsxconditionalformatting.h b/src/xlsx/xlsxconditionalformatting.h index 6ed0bd1..45378f7 100644 --- a/src/xlsx/xlsxconditionalformatting.h +++ b/src/xlsx/xlsxconditionalformatting.h @@ -26,6 +26,8 @@ #define QXLSX_XLSXCONDITIONALFORMATTING_H #include "xlsxglobal.h" +#include "xlsxcellrange.h" +#include "xlsxcellreference.h" #include #include #include @@ -37,7 +39,6 @@ class ConditionalFormattingTest; QT_BEGIN_NAMESPACE_XLSX -class CellRange; class Format; class Worksheet; class Styles; @@ -113,9 +114,8 @@ public: QList ranges() const; - void addCell(const QString &cell); + void addCell(const CellReference &cell); void addCell(int row, int col); - void addRange(const QString &range); void addRange(int firstRow, int firstCol, int lastRow, int lastCol); void addRange(const CellRange &range); diff --git a/src/xlsx/xlsxdatavalidation.cpp b/src/xlsx/xlsxdatavalidation.cpp index d4f5390..c538c72 100644 --- a/src/xlsx/xlsxdatavalidation.cpp +++ b/src/xlsx/xlsxdatavalidation.cpp @@ -353,9 +353,9 @@ void DataValidation::setErrorMessageVisible(bool visible) /*! Add the \a cell on which the DataValidation will apply to. */ -void DataValidation::addCell(const QString &cell) +void DataValidation::addCell(const CellReference &cell) { - d->ranges.append(CellRange(cell)); + d->ranges.append(CellRange(cell, cell)); } /*! @@ -367,14 +367,6 @@ void DataValidation::addCell(int row, int col) d->ranges.append(CellRange(row, col, row, col)); } -/*! - Add the \a range on which the DataValidation will apply to. - */ -void DataValidation::addRange(const QString &range) -{ - d->ranges.append(CellRange(range)); -} - /*! \overload Add the range(\a firstRow, \a firstCol, \a lastRow, \a lastCol) on @@ -386,7 +378,6 @@ void DataValidation::addRange(int firstRow, int firstCol, int lastRow, int lastC } /*! - \overload Add the \a range on which the DataValidation will apply to. */ void DataValidation::addRange(const CellRange &range) diff --git a/src/xlsx/xlsxdatavalidation.h b/src/xlsx/xlsxdatavalidation.h index 12597ca..3a19079 100644 --- a/src/xlsx/xlsxdatavalidation.h +++ b/src/xlsx/xlsxdatavalidation.h @@ -37,6 +37,7 @@ QT_BEGIN_NAMESPACE_XLSX class Worksheet; class CellRange; +class CellReference; class DataValidationPrivate; class Q_XLSX_EXPORT DataValidation @@ -104,9 +105,8 @@ public: void setPromptMessageVisible(bool visible); void setErrorMessageVisible(bool visible); - void addCell(const QString &cell); + void addCell(const CellReference &cell); void addCell(int row, int col); - void addRange(const QString &range); void addRange(int firstRow, int firstCol, int lastRow, int lastCol); void addRange(const CellRange &range); diff --git a/src/xlsx/xlsxdocument.cpp b/src/xlsx/xlsxdocument.cpp index b765188..0ec106d 100644 --- a/src/xlsx/xlsxdocument.cpp +++ b/src/xlsx/xlsxdocument.cpp @@ -406,7 +406,7 @@ Document::Document(QIODevice *device, QObject *parent) : Write \a value to cell \a row_column with the \a format. */ -bool Document::write(const QString &row_column, const QVariant &value, const Format &format) +bool Document::write(const CellReference &row_column, const QVariant &value, const Format &format) { if (Worksheet *sheet = currentWorksheet()) return sheet->write(row_column, value, format); @@ -427,7 +427,7 @@ bool Document::write(int row, int col, const QVariant &value, const Format &form \overload Returns the contents of the cell \a cell. */ -QVariant Document::read(const QString &cell) const +QVariant Document::read(const CellReference &cell) const { if (Worksheet *sheet = currentWorksheet()) return sheet->read(cell); @@ -760,7 +760,7 @@ bool Document::addConditionalFormatting(const ConditionalFormatting &cf) /*! * Returns a Cell object based on the given \a pos. 0 will be returned if the cell doesn't exist. */ -Cell *Document::cellAt(const QString &pos) const +Cell *Document::cellAt(const CellReference &pos) const { if (Worksheet *sheet = currentWorksheet()) return sheet->cellAt(pos); diff --git a/src/xlsx/xlsxdocument.h b/src/xlsx/xlsxdocument.h index 2d89684..7f1113d 100644 --- a/src/xlsx/xlsxdocument.h +++ b/src/xlsx/xlsxdocument.h @@ -42,6 +42,7 @@ class CellRange; class DataValidation; class ConditionalFormatting; class Chart; +class CellReference; class DocumentPrivate; class Q_XLSX_EXPORT Document : public QObject @@ -55,9 +56,9 @@ public: Document(QIODevice *device, QObject *parent=0); ~Document(); - bool write(const QString &cell, const QVariant &value, const Format &format=Format()); + bool write(const CellReference &cell, const QVariant &value, const Format &format=Format()); bool write(int row, int col, const QVariant &value, const Format &format=Format()); - QVariant read(const QString &cell) const; + QVariant read(const CellReference &cell) const; QVariant read(int row, int col) const; bool insertImage(int row, int col, const QImage &image); Chart *insertChart(int row, int col, const QSize &size); @@ -93,7 +94,7 @@ public: bool addDataValidation(const DataValidation &validation); bool addConditionalFormatting(const ConditionalFormatting &cf); - Cell *cellAt(const QString &cell) const; + Cell *cellAt(const CellReference &cell) const; Cell *cellAt(int row, int col) const; bool defineName(const QString &name, const QString &formula, const QString &comment=QString(), const QString &scope=QString()); diff --git a/src/xlsx/xlsxutility.cpp b/src/xlsx/xlsxutility.cpp index a432b58..f761d8b 100755 --- a/src/xlsx/xlsxutility.cpp +++ b/src/xlsx/xlsxutility.cpp @@ -35,16 +35,6 @@ namespace QXlsx { -int intPow(int x, int p) -{ - if (p == 0) return 1; - if (p == 1) return x; - - int tmp = intPow(x, p/2); - if (p%2 == 0) return tmp * tmp; - else return x * tmp * tmp; -} - QStringList splitPath(const QString &path) { int idx = path.lastIndexOf(QLatin1Char('/')); @@ -96,87 +86,6 @@ QDateTime datetimeFromNumber(double num, bool is1904) return epoch.addMSecs(msecs); } -QPoint xl_cell_to_rowcol(const QString &cell_str) -{ - if (cell_str.isEmpty()) - return QPoint(-1, -1); - QRegularExpression re(QStringLiteral("^([A-Z]{1,3})(\\d+)$")); - QRegularExpressionMatch match = re.match(cell_str); - if (match.hasMatch()) { - QString col_str = match.captured(1); - QString row_str = match.captured(2); - int col = 0; - int expn = 0; - for (int i=col_str.size()-1; i>-1; --i) { - col += (col_str[i].unicode() - 'A' + 1) * intPow(26, expn); - expn++; - } - - int row = row_str.toInt(); - return QPoint(row, col); - } else { - return QPoint(-1, -1); //... - } -} - -QString xl_col_to_name(int col_num) -{ - QString col_str; - - int remainder; - while (col_num) { - remainder = col_num % 26; - if (remainder == 0) - remainder = 26; - col_str.prepend(QChar('A'+remainder-1)); - col_num = (col_num - 1) / 26; - } - - return col_str; -} - -int xl_col_name_to_value(const QString &col_str) -{ - QRegularExpression re(QStringLiteral("^([A-Z]{1,3})$")); - QRegularExpressionMatch match = re.match(col_str); - if (match.hasMatch()) { - int col = 0; - int expn = 0; - for (int i=col_str.size()-1; i>-1; --i) { - col += (col_str[i].unicode() - 'A' + 1) * intPow(26, expn); - expn++; - } - - return col; - } - return -1; -} - -QString xl_rowcol_to_cell(int row, int col, bool row_abs, bool col_abs) -{ - QString cell_str; - if (col_abs) - cell_str.append(QLatin1Char('$')); - cell_str.append(xl_col_to_name(col)); - if (row_abs) - cell_str.append(QLatin1Char('$')); - cell_str.append(QString::number(row)); - return cell_str; -} - -QString xl_rowcol_to_cell_fast(int row, int col) -{ - static QMap col_cache; - QString col_str; - if (col_cache.contains(col)) { - col_str = col_cache[col]; - } else { - col_str = xl_col_to_name(col); - col_cache[col] = col_str; - } - return col_str + QString::number(row); -} - /* Creates a valid sheet name minimum length is 1 diff --git a/src/xlsx/xlsxutility_p.h b/src/xlsx/xlsxutility_p.h index 7c1c5e5..f40d63d 100755 --- a/src/xlsx/xlsxutility_p.h +++ b/src/xlsx/xlsxutility_p.h @@ -46,7 +46,6 @@ class QTime; namespace QXlsx { -XLSX_AUTOTEST_EXPORT int intPow(int x, int p); XLSX_AUTOTEST_EXPORT QStringList splitPath(const QString &path); XLSX_AUTOTEST_EXPORT QString getRelFilePath(const QString &filePath); @@ -54,12 +53,6 @@ XLSX_AUTOTEST_EXPORT double datetimeToNumber(const QDateTime &dt, bool is1904=fa XLSX_AUTOTEST_EXPORT QDateTime datetimeFromNumber(double num, bool is1904=false); XLSX_AUTOTEST_EXPORT double timeToNumber(const QTime &t); -XLSX_AUTOTEST_EXPORT QPoint xl_cell_to_rowcol(const QString &cell_str); -XLSX_AUTOTEST_EXPORT QString xl_col_to_name(int col_num); -XLSX_AUTOTEST_EXPORT int xl_col_name_to_value(const QString &col_str); -XLSX_AUTOTEST_EXPORT QString xl_rowcol_to_cell(int row, int col, bool row_abs=false, bool col_abs=false); -XLSX_AUTOTEST_EXPORT QString xl_rowcol_to_cell_fast(int row, int col); - XLSX_AUTOTEST_EXPORT QString createSafeSheetName(const QString &nameProposal); XLSX_AUTOTEST_EXPORT bool isSpaceReserveNeeded(const QString &string); diff --git a/src/xlsx/xlsxworksheet.cpp b/src/xlsx/xlsxworksheet.cpp index 6718fb2..7d5ce8f 100755 --- a/src/xlsx/xlsxworksheet.cpp +++ b/src/xlsx/xlsxworksheet.cpp @@ -23,6 +23,7 @@ ** ****************************************************************************/ #include "xlsxrichstring.h" +#include "xlsxcellreference.h" #include "xlsxworksheet.h" #include "xlsxworksheet_p.h" #include "xlsxworkbook.h" @@ -484,28 +485,24 @@ bool Worksheet::write(int row, int column, const QVariant &value, const Format & * Write \a value to cell \a row_column with the \a format. * Both row and column are all 1-indexed value. */ -bool Worksheet::write(const QString &row_column, const QVariant &value, const Format &format) +bool Worksheet::write(const CellReference &row_column, const QVariant &value, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return write(pos.x(), pos.y(), value, format); + return write(row_column.row(), row_column.column(), value, format); } /*! \overload Return the contents of the cell \a row_column. */ -QVariant Worksheet::read(const QString &row_column) const +QVariant Worksheet::read(const CellReference &row_column) const { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return QVariant(); - return read(pos.x(), pos.y()); + return read(row_column.row(), row_column.column()); } /*! @@ -535,13 +532,12 @@ QVariant Worksheet::read(int row, int column) const * 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 +Cell *Worksheet::cellAt(const CellReference &row_column) const { - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return 0; - return cellAt(pos.x(), pos.y()); + return cellAt(row_column.row(), row_column.column()); } /*! @@ -572,14 +568,12 @@ Format WorksheetPrivate::cellFormat(int row, int col) const \overload Write string \a value to the cell \a row_column with the \a format */ -bool Worksheet::writeString(const QString &row_column, const RichString &value, const Format &format) +bool Worksheet::writeString(const CellReference &row_column, const RichString &value, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeString(pos.x(), pos.y(), value, format); + return writeString(row_column.row(), row_column.column(), value, format); } /*! @@ -612,14 +606,12 @@ bool Worksheet::writeString(int row, int column, const RichString &value, const \overload Write string \a value to the cell \a row_column with the \a format */ -bool Worksheet::writeString(const QString &row_column, const QString &value, const Format &format) +bool Worksheet::writeString(const CellReference &row_column, const QString &value, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeString(pos.x(), pos.y(), value, format); + return writeString(row_column.row(), row_column.column(), value, format); } /*! @@ -646,14 +638,12 @@ bool Worksheet::writeString(int row, int column, const QString &value, const For \overload Write string \a value to the cell \a row_column with the \a format */ -bool Worksheet::writeInlineString(const QString &row_column, const QString &value, const Format &format) +bool Worksheet::writeInlineString(const CellReference &row_column, const QString &value, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeInlineString(pos.x(), pos.y(), value, format); + return writeInlineString(row_column.row(), row_column.column(), value, format); } /*! @@ -682,14 +672,12 @@ bool Worksheet::writeInlineString(int row, int column, const QString &value, con \overload Write numeric \a value to the cell \a row_column with the \a format */ -bool Worksheet::writeNumeric(const QString &row_column, double value, const Format &format) +bool Worksheet::writeNumeric(const CellReference &row_column, double value, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeNumeric(pos.x(), pos.y(), value, format); + return writeNumeric(row_column.row(), row_column.column(), value, format); } /*! @@ -711,14 +699,12 @@ bool Worksheet::writeNumeric(int row, int column, double value, const Format &fo \overload Write \a formula to the cell \a row_column with the \a format and \a result. */ -bool Worksheet::writeFormula(const QString &row_column, const QString &formula, const Format &format, double result) +bool Worksheet::writeFormula(const CellReference &row_column, const QString &formula, const Format &format, double result) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeFormula(pos.x(), pos.y(), formula, format, result); + return writeFormula(row_column.row(), row_column.column(), formula, format, result); } /*! @@ -780,27 +766,16 @@ bool Worksheet::writeArrayFormula(const CellRange &range, const QString &formula return true; } -/*! - \overload - Write \a formula to the \a range with the \a format - */ -bool Worksheet::writeArrayFormula(const QString &range, const QString &formula, const Format &format) -{ - return writeArrayFormula(CellRange(range), formula, format); -} - /*! \overload Write a empty cell \a row_column with the \a format */ -bool Worksheet::writeBlank(const QString &row_column, const Format &format) +bool Worksheet::writeBlank(const CellReference &row_column, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeBlank(pos.x(), pos.y(), format); + return writeBlank(row_column.row(), row_column.column(), format); } /*! @@ -823,14 +798,12 @@ bool 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 */ -bool Worksheet::writeBool(const QString &row_column, bool value, const Format &format) +bool Worksheet::writeBool(const CellReference &row_column, bool value, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeBool(pos.x(), pos.y(), value, format); + return writeBool(row_column.row(), row_column.column(), value, format); } /*! @@ -852,14 +825,12 @@ bool 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 */ -bool Worksheet::writeDateTime(const QString &row_column, const QDateTime &dt, const Format &format) +bool Worksheet::writeDateTime(const CellReference &row_column, const QDateTime &dt, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeDateTime(pos.x(), pos.y(), dt, format); + return writeDateTime(row_column.row(), row_column.column(), dt, format); } /*! @@ -887,14 +858,12 @@ bool Worksheet::writeDateTime(int row, int column, const QDateTime &dt, const Fo \overload Write a QTime \a t to the cell \a row_column with the \a format */ -bool Worksheet::writeTime(const QString &row_column, const QTime &t, const Format &format) +bool Worksheet::writeTime(const CellReference &row_column, const QTime &t, const Format &format) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeTime(pos.x(), pos.y(), t, format); + return writeTime(row_column.row(), row_column.column(), t, format); } /*! @@ -920,14 +889,12 @@ bool Worksheet::writeTime(int row, int column, const QTime &t, const Format &for \overload Write a QUrl \a url to the cell \a row_column with the given \a format \a display and \a tip */ -bool Worksheet::writeHyperlink(const QString &row_column, const QUrl &url, const Format &format, const QString &display, const QString &tip) +bool Worksheet::writeHyperlink(const CellReference &row_column, const QUrl &url, const Format &format, const QString &display, const QString &tip) { - //convert the "A1" notation to row/column notation - QPoint pos = xl_cell_to_rowcol(row_column); - if (pos == QPoint(-1, -1)) + if (!row_column.isValid()) return false; - return writeHyperlink(pos.x(), pos.y(), url, format, display, tip); + return writeHyperlink(row_column.row(), row_column.column(), url, format, display, tip); } /*! @@ -1295,7 +1262,7 @@ void WorksheetPrivate::saveXmlSheetData(QXmlStreamWriter &writer) const void WorksheetPrivate::saveXmlCellData(QXmlStreamWriter &writer, int row, int col, QSharedPointer cell) const { //This is the innermost loop so efficiency is important. - QString cell_pos = xl_rowcol_to_cell_fast(row, col); + QString cell_pos = CellReference(row, col).toString(); writer.writeStartElement(QStringLiteral("c")); writer.writeAttribute(QStringLiteral("r"), cell_pos); @@ -1381,10 +1348,8 @@ void WorksheetPrivate::saveXmlMergeCells(QXmlStreamWriter &writer) const writer.writeAttribute(QStringLiteral("count"), QString::number(merges.size())); foreach (CellRange range, merges) { - QString cell1 = xl_rowcol_to_cell(range.firstRow(), range.firstColumn()); - QString cell2 = xl_rowcol_to_cell(range.lastRow(), range.lastColumn()); writer.writeEmptyElement(QStringLiteral("mergeCell")); - writer.writeAttribute(QStringLiteral("ref"), cell1+QLatin1Char(':')+cell2); + writer.writeAttribute(QStringLiteral("ref"), range.toString()); } writer.writeEndElement(); //mergeCells @@ -1419,7 +1384,7 @@ void WorksheetPrivate::saveXmlHyperlinks(QXmlStreamWriter &writer) const it2.next(); int col = it2.key(); QSharedPointer data = it2.value(); - QString ref = xl_rowcol_to_cell(row, col); + QString ref = CellReference(row, col).toString(); writer.writeEmptyElement(QStringLiteral("hyperlink")); writer.writeAttribute(QStringLiteral("ref"), ref); if (data->linkType == XlsxHyperlinkData::External) { @@ -1802,15 +1767,12 @@ bool Worksheet::groupRows(int rowFirst, int rowLast, bool collapsed) /*! \overload */ -bool Worksheet::groupColumns(const QString &colFirst, const QString &colLast, bool collapsed) +bool Worksheet::groupColumns(const CellRange &range, bool collapsed) { - int col1 = xl_col_name_to_value(colFirst); - int col2 = xl_col_name_to_value(colLast); - - if (col1 == -1 || col2 == -1) + if (!range.isValid()) return false; - return groupColumns(col1, col2, collapsed); + return groupColumns(range.firstColumn(), range.lastColumn(), collapsed); } /*! @@ -2007,7 +1969,7 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader) } else if (reader.name() == QLatin1String("c")) { QXmlStreamAttributes attributes = reader.attributes(); QString r = attributes.value(QLatin1String("r")).toString(); - QPoint pos = xl_cell_to_rowcol(r); + CellReference pos(r); //get format Format format; @@ -2031,7 +1993,7 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader) QSharedPointer data(new Cell(rs.toPlainString() ,Cell::String, format, q)); if (rs.isRichString()) data->d_ptr->richString = rs; - cellTable[pos.x()][pos.y()] = QSharedPointer(data); + cellTable[pos.row()][pos.column()] = QSharedPointer(data); } } } else if (type == QLatin1String("inlineStr")) { @@ -2043,7 +2005,7 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader) if (reader.name() == QLatin1String("t")) { QString value = reader.readElementText(); QSharedPointer data(new Cell(value, Cell::InlineString, format, q)); - cellTable[pos.x()][pos.y()] = data; + cellTable[pos.row()][pos.column()] = data; } } } @@ -2053,14 +2015,14 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader) if (reader.name() == QLatin1String("v")) { QString value = reader.readElementText(); QSharedPointer data(new Cell(value.toInt() ? true : false, Cell::Boolean, format, q)); - cellTable[pos.x()][pos.y()] = data; + cellTable[pos.row()][pos.column()] = data; } } else if (type == QLatin1String("str")) { //formula type QSharedPointer data = loadXmlNumericCellData(reader); data->d_ptr->format = format; data->d_ptr->parent = q; - cellTable[pos.x()][pos.y()] = data; + cellTable[pos.row()][pos.column()] = data; } else if (type == QLatin1String("e")) { //error type, such as #DIV/0! #NULL! #REF! etc QString v_str, f_str; @@ -2076,19 +2038,19 @@ void WorksheetPrivate::loadXmlSheetData(QXmlStreamReader &reader) QSharedPointer data(new Cell(v_str, Cell::Error, format, q)); if (!f_str.isEmpty()) data->d_ptr->formula = f_str; - cellTable[pos.x()][pos.y()] = data; + cellTable[pos.row()][pos.column()] = data; } else if (type == QLatin1String("n")) { QSharedPointer data = loadXmlNumericCellData(reader); data->d_ptr->format = format; data->d_ptr->parent = q; - cellTable[pos.x()][pos.y()] = data; + cellTable[pos.row()][pos.column()] = data; } } else { //default is "n" QSharedPointer data = loadXmlNumericCellData(reader); data->d_ptr->format = format; data->d_ptr->parent = q; - cellTable[pos.x()][pos.y()] = data; + cellTable[pos.row()][pos.column()] = data; } } } @@ -2153,15 +2115,7 @@ void WorksheetPrivate::loadXmlMergeCells(QXmlStreamReader &reader) if (reader.name() == QLatin1String("mergeCell")) { QXmlStreamAttributes attrs = reader.attributes(); QString rangeStr = attrs.value(QLatin1String("ref")).toString(); - QStringList items = rangeStr.split(QLatin1Char(':')); - if (items.size() != 2) { - //Error - } else { - QPoint p0 = xl_cell_to_rowcol(items[0]); - QPoint p1 = xl_cell_to_rowcol(items[1]); - - merges.append(CellRange(p0.x(), p0.y(), p1.x(), p1.y())); - } + merges.append(CellRange(rangeStr)); } } } @@ -2264,8 +2218,8 @@ void WorksheetPrivate::loadXmlHyperlinks(QXmlStreamReader &reader) reader.readNextStartElement(); if (reader.tokenType() == QXmlStreamReader::StartElement && reader.name() == QLatin1String("hyperlink")) { QXmlStreamAttributes attrs = reader.attributes(); - QPoint pos = xl_cell_to_rowcol(attrs.value(QLatin1String("ref")).toString()); - if (pos.x() != -1) { //Valid + CellReference pos(attrs.value(QLatin1String("ref")).toString()); + if (pos.isValid()) { //Valid QSharedPointer link(new XlsxHyperlinkData); link->display = attrs.value(QLatin1String("display")).toString(); link->tooltip = attrs.value(QLatin1String("tooltip")).toString(); @@ -2279,7 +2233,7 @@ void WorksheetPrivate::loadXmlHyperlinks(QXmlStreamReader &reader) link->linkType = XlsxHyperlinkData::Internal; } - urlTable[pos.x()][pos.y()] = link; + urlTable[pos.row()][pos.column()] = link; } } } diff --git a/src/xlsx/xlsxworksheet.h b/src/xlsx/xlsxworksheet.h index d6c248d..6d5bc74 100755 --- a/src/xlsx/xlsxworksheet.h +++ b/src/xlsx/xlsxworksheet.h @@ -28,6 +28,7 @@ #include "xlsxabstractsheet.h" #include "xlsxcell.h" #include "xlsxcellrange.h" +#include "xlsxcellreference.h" #include #include #include @@ -56,38 +57,37 @@ class Q_XLSX_EXPORT Worksheet : public AbstractSheet { Q_DECLARE_PRIVATE(Worksheet) public: - bool write(const QString &row_column, const QVariant &value, const Format &format=Format()); + bool write(const CellReference &row_column, const QVariant &value, const Format &format=Format()); bool write(int row, int column, const QVariant &value, const Format &format=Format()); - QVariant read(const QString &row_column) const; + QVariant read(const CellReference &row_column) const; QVariant read(int row, int column) const; - bool writeString(const QString &row_column, const QString &value, const Format &format=Format()); + bool writeString(const CellReference &row_column, const QString &value, const Format &format=Format()); bool writeString(int row, int column, const QString &value, const Format &format=Format()); - bool writeString(const QString &row_column, const RichString &value, const Format &format=Format()); + bool writeString(const CellReference &row_column, const RichString &value, const Format &format=Format()); bool writeString(int row, int column, const RichString &value, const Format &format=Format()); - bool writeInlineString(const QString &row_column, const QString &value, const Format &format=Format()); + bool writeInlineString(const CellReference &row_column, const QString &value, const Format &format=Format()); bool writeInlineString(int row, int column, const QString &value, const Format &format=Format()); - bool writeNumeric(const QString &row_column, double value, const Format &format=Format()); + bool writeNumeric(const CellReference &row_column, double value, const Format &format=Format()); bool writeNumeric(int row, int column, double value, const Format &format=Format()); - bool writeFormula(const QString &row_column, const QString &formula, const Format &format=Format(), double result=0); + bool writeFormula(const CellReference &row_column, const QString &formula, const Format &format=Format(), double result=0); bool writeFormula(int row, int column, const QString &formula, const Format &format=Format(), double result=0); - bool writeArrayFormula(const QString &range, const QString &formula, const Format &format=Format()); bool writeArrayFormula(const CellRange &range, const QString &formula, const Format &format=Format()); - bool writeBlank(const QString &row_column, const Format &format=Format()); + bool writeBlank(const CellReference &row_column, const Format &format=Format()); bool writeBlank(int row, int column, const Format &format=Format()); - bool writeBool(const QString &row_column, bool value, const Format &format=Format()); + bool writeBool(const CellReference &row_column, bool value, const Format &format=Format()); bool writeBool(int row, int column, bool value, const Format &format=Format()); - bool writeDateTime(const QString &row_column, const QDateTime& dt, const Format &format=Format()); + bool writeDateTime(const CellReference &row_column, const QDateTime& dt, const Format &format=Format()); bool writeDateTime(int row, int column, const QDateTime& dt, const Format &format=Format()); - bool writeTime(const QString &row_column, const QTime& t, const Format &format=Format()); + bool writeTime(const CellReference &row_column, const QTime& t, const Format &format=Format()); bool writeTime(int row, int column, const QTime& t, const Format &format=Format()); - bool writeHyperlink(const QString &row_column, const QUrl &url, const Format &format=Format(), const QString &display=QString(), const QString &tip=QString()); + bool writeHyperlink(const CellReference &row_column, const QUrl &url, const Format &format=Format(), const QString &display=QString(), const QString &tip=QString()); bool writeHyperlink(int row, int column, const QUrl &url, const Format &format=Format(), const QString &display=QString(), const QString &tip=QString()); bool addDataValidation(const DataValidation &validation); bool addConditionalFormatting(const ConditionalFormatting &cf); - Cell *cellAt(const QString &row_column) const; + Cell *cellAt(const CellReference &row_column) const; Cell *cellAt(int row, int column) const; bool insertImage(int row, int column, const QImage &image); @@ -117,7 +117,7 @@ public: bool groupRows(int rowFirst, int rowLast, bool collapsed = true); bool groupColumns(int colFirst, int colLast, bool collapsed = true); - bool groupColumns(const QString &colFirst, const QString &colLast, bool collapsed = true); + bool groupColumns(const CellRange &range, bool collapsed = true); CellRange dimension() const; bool isWindowProtected() const; diff --git a/tests/auto/cellreference/tst_cellreferencetest.cpp b/tests/auto/cellreference/tst_cellreferencetest.cpp index 7a979bb..860f885 100644 --- a/tests/auto/cellreference/tst_cellreferencetest.cpp +++ b/tests/auto/cellreference/tst_cellreferencetest.cpp @@ -27,7 +27,7 @@ void CellReferenceTest::test_fromString() QFETCH(QString, cell); QFETCH(int, row); QFETCH(int, col); - CellReference pos = CellReference::fromString(cell); + CellReference pos(cell); QCOMPARE(pos.row(), row); QCOMPARE(pos.column(), col); } diff --git a/tests/auto/utility/tst_utilitytest.cpp b/tests/auto/utility/tst_utilitytest.cpp index 52222eb..a53f745 100644 --- a/tests/auto/utility/tst_utilitytest.cpp +++ b/tests/auto/utility/tst_utilitytest.cpp @@ -35,12 +35,6 @@ public: UtilityTest(); private Q_SLOTS: - void test_cell_to_rowcol(); - void test_cell_to_rowcol_data(); - - void test_rowcol_to_cell(); - void test_rowcol_to_cell_data(); - void test_datetimeToNumber_data(); void test_datetimeToNumber(); @@ -58,62 +52,6 @@ UtilityTest::UtilityTest() { } -void UtilityTest::test_cell_to_rowcol() -{ - QFETCH(QString, cell); - QFETCH(int, row); - QFETCH(int, col); - QPoint pos = QXlsx::xl_cell_to_rowcol(cell); - QCOMPARE(pos.x(), row); - QCOMPARE(pos.y(), col); -} - -void UtilityTest::test_cell_to_rowcol_data() -{ - QTest::addColumn("cell"); - QTest::addColumn("row"); - QTest::addColumn("col"); - - QTest::newRow("A1") << "A1" << 1 << 1; - QTest::newRow("B1") << "B1" << 1 << 2; - QTest::newRow("C1") << "C1" << 1 << 3; - QTest::newRow("J1") << "J1" << 1 << 10; - QTest::newRow("A2") << "A2" << 2 << 1; - QTest::newRow("A3") << "A3" << 3 << 1; - QTest::newRow("A10") << "A10" << 10 << 1; - QTest::newRow("Z8") << "Z8" << 8 << 26; - QTest::newRow("AA10") << "AA10" << 10 << 27; - QTest::newRow("IU2") << "IU2" << 2 << 255; - QTest::newRow("XFD1") << "XFD1" << 1 << 16384; - QTest::newRow("XFE1048577") << "XFE1048577" << 1048577 << 16385; -} - -void UtilityTest::test_rowcol_to_cell() -{ - QFETCH(int, row); - QFETCH(int, col); - QFETCH(bool, row_abs); - QFETCH(bool, col_abs); - QFETCH(QString, cell); - - QCOMPARE(QXlsx::xl_rowcol_to_cell(row, col, row_abs, col_abs), cell); -} - -void UtilityTest::test_rowcol_to_cell_data() -{ - QTest::addColumn("row"); - QTest::addColumn("col"); - QTest::addColumn("row_abs"); - QTest::addColumn("col_abs"); - QTest::addColumn("cell"); - - QTest::newRow("simple") << 1 << 1 << false << false << "A1"; - QTest::newRow("rowabs") << 1 << 1 << true << false << "A$1"; - QTest::newRow("colabs") << 1 << 1 << false << true << "$A1"; - QTest::newRow("bothabs") << 1 << 1 << true << true << "$A$1"; - QTest::newRow("...") << 1048577 << 16385 << false << false << "XFE1048577"; -} - void UtilityTest::test_datetimeToNumber_data() { QTest::addColumn("dt");