Browse Source

Make use of the new CellReference class

master
Debao Zhang 11 years ago
parent
commit
76e0bd4e54
  1. 40
      src/xlsx/xlsxcellrange.cpp
  2. 8
      src/xlsx/xlsxcellrange.h
  3. 8
      src/xlsx/xlsxcellreference.cpp
  4. 4
      src/xlsx/xlsxchart.cpp
  5. 13
      src/xlsx/xlsxconditionalformatting.cpp
  6. 6
      src/xlsx/xlsxconditionalformatting.h
  7. 13
      src/xlsx/xlsxdatavalidation.cpp
  8. 4
      src/xlsx/xlsxdatavalidation.h
  9. 6
      src/xlsx/xlsxdocument.cpp
  10. 7
      src/xlsx/xlsxdocument.h
  11. 91
      src/xlsx/xlsxutility.cpp
  12. 7
      src/xlsx/xlsxutility_p.h
  13. 162
      src/xlsx/xlsxworksheet.cpp
  14. 30
      src/xlsx/xlsxworksheet.h
  15. 2
      tests/auto/cellreference/tst_cellreferencetest.cpp
  16. 62
      tests/auto/utility/tst_utilitytest.cpp

40
src/xlsx/xlsxcellrange.cpp

@ -23,7 +23,7 @@
**
****************************************************************************/
#include "xlsxcellrange.h"
#include "xlsxutility_p.h"
#include "xlsxcellreference.h"
#include <QString>
#include <QPoint>
#include <QStringList>
@ -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;
}

8
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
{

8
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.
*/

4
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;

13
src/xlsx/xlsxconditionalformatting.cpp

@ -419,9 +419,9 @@ QList<CellRange> 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)

6
src/xlsx/xlsxconditionalformatting.h

@ -26,6 +26,8 @@
#define QXLSX_XLSXCONDITIONALFORMATTING_H
#include "xlsxglobal.h"
#include "xlsxcellrange.h"
#include "xlsxcellreference.h"
#include <QSharedDataPointer>
#include <QString>
#include <QList>
@ -37,7 +39,6 @@ class ConditionalFormattingTest;
QT_BEGIN_NAMESPACE_XLSX
class CellRange;
class Format;
class Worksheet;
class Styles;
@ -113,9 +114,8 @@ public:
QList<CellRange> 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);

13
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)

4
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);

6
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);

7
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());

91
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<int, QString> 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

7
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);

162
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> 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<XlsxHyperlinkData> 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<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);
cellTable[pos.row()][pos.column()] = QSharedPointer<Cell>(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<Cell> 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<Cell> 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<Cell> 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<Cell> 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<Cell> 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<Cell> 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<XlsxHyperlinkData> 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;
}
}
}

30
src/xlsx/xlsxworksheet.h

@ -28,6 +28,7 @@
#include "xlsxabstractsheet.h"
#include "xlsxcell.h"
#include "xlsxcellrange.h"
#include "xlsxcellreference.h"
#include <QStringList>
#include <QMap>
#include <QVariant>
@ -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;

2
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);
}

62
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<QString>("cell");
QTest::addColumn<int>("row");
QTest::addColumn<int>("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<int>("row");
QTest::addColumn<int>("col");
QTest::addColumn<bool>("row_abs");
QTest::addColumn<bool>("col_abs");
QTest::addColumn<QString>("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<QDateTime>("dt");

Loading…
Cancel
Save