|
|
@ -23,6 +23,7 @@ |
|
|
|
** |
|
|
|
****************************************************************************/ |
|
|
|
#include "xlsxutility_p.h" |
|
|
|
#include "xlsxcellreference.h" |
|
|
|
|
|
|
|
#include <QString> |
|
|
|
#include <QPoint> |
|
|
@ -145,4 +146,82 @@ bool isSpaceReserveNeeded(const QString &s) |
|
|
|
return !s.isEmpty() && (spaces.contains(s.at(0))||spaces.contains(s.at(s.length()-1))); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Convert shared formula for non-root cells. |
|
|
|
* |
|
|
|
* For example, if "B1:B10" have shared formula "=A1*A1", this function will return "=A2*A2" |
|
|
|
* for "B2" cell, "=A3*A3" for "B3" cell, etc. |
|
|
|
* |
|
|
|
* Note, the formula "=A1*A1" for B1 can also be written as "=RC[-1]*RC[-1]", which is the same |
|
|
|
* for all other cells. In other words, this formula is shared. |
|
|
|
* |
|
|
|
* For long run, we need a formula parser. |
|
|
|
*/ |
|
|
|
QString convertSharedFormula(const QString &rootFormula, const CellReference &rootCell, const CellReference &cell) |
|
|
|
{ |
|
|
|
//Find all the "[A-Z]+[0-9]+" patterns in the rootFormula.
|
|
|
|
QList<QPair<QString, bool> > segments; |
|
|
|
|
|
|
|
QString segment; |
|
|
|
bool inQuote = false; |
|
|
|
int cellFlag = 0; //-1, 0, 1, 2 ==> Invalid, Empty, A-Z ready, A1 ready
|
|
|
|
foreach (QChar ch, rootFormula) { |
|
|
|
if (inQuote) { |
|
|
|
segment.append(ch); |
|
|
|
if (ch == QLatin1Char('"')) { |
|
|
|
segments.append(qMakePair(segment, false)); |
|
|
|
segment = QString(); |
|
|
|
inQuote = false; |
|
|
|
cellFlag = 0; |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (ch == QLatin1Char('"')) { |
|
|
|
segments.append(qMakePair(segment, false)); |
|
|
|
segment = QString(ch); |
|
|
|
inQuote = true; |
|
|
|
} else if (ch >= QLatin1Char('A') && ch <=QLatin1Char('Z')) { |
|
|
|
if (cellFlag == 0 || cellFlag == 1) { |
|
|
|
segment.append(ch); |
|
|
|
} else { |
|
|
|
segments.append(qMakePair(segment, (cellFlag == 2))); |
|
|
|
segment = QString(ch); //start new "A1" segment
|
|
|
|
} |
|
|
|
cellFlag = 1; |
|
|
|
} else if (ch >= QLatin1Char('0') && ch <=QLatin1Char('9')) { |
|
|
|
segment.append(ch); |
|
|
|
if (cellFlag == 1) |
|
|
|
cellFlag = 2; |
|
|
|
} else { |
|
|
|
if (cellFlag == 2) { |
|
|
|
segments.append(qMakePair(segment, true)); //find one "A1" segment
|
|
|
|
segment = QString(ch); |
|
|
|
} else { |
|
|
|
segment.append(ch); |
|
|
|
} |
|
|
|
cellFlag = -1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!segment.isEmpty()) |
|
|
|
segments.append(qMakePair(segment, (cellFlag == 2))); |
|
|
|
|
|
|
|
//Replace "A1" segment with proper one.
|
|
|
|
QStringList result; |
|
|
|
typedef QPair<QString, bool> PairType; |
|
|
|
foreach (PairType p, segments) { |
|
|
|
if (p.second) { |
|
|
|
CellReference oldRef(p.first); |
|
|
|
CellReference newRef(oldRef.row()-rootCell.row()+cell.row(), |
|
|
|
oldRef.column()-rootCell.column()+cell.column()); |
|
|
|
result.append(newRef.toString()); |
|
|
|
} else { |
|
|
|
result.append(p.first); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//OK
|
|
|
|
return result.join(QString()); |
|
|
|
} |
|
|
|
|
|
|
|
} //namespace QXlsx
|
|
|
|