File indexing completed on 2025-03-23 03:32:46
0001 // xlsxcellreference.cpp 0002 0003 #include "xlsxcellreference.h" 0004 #include <QStringList> 0005 #include <QMap> 0006 0007 #include <QRegularExpression> 0008 0009 QT_BEGIN_NAMESPACE_XLSX 0010 0011 namespace { 0012 0013 int intPow(int x, int p) 0014 { 0015 if (p == 0) return 1; 0016 if (p == 1) return x; 0017 0018 int tmp = intPow(x, p/2); 0019 if (p%2 == 0) return tmp * tmp; 0020 else return x * tmp * tmp; 0021 } 0022 0023 QString col_to_name(int col_num) 0024 { 0025 static thread_local QMap<int, QString> col_cache; 0026 0027 auto it = col_cache.find(col_num); 0028 if (it == col_cache.end()) { 0029 QString col_str; 0030 int remainder; 0031 while (col_num) { 0032 remainder = col_num % 26; 0033 if (remainder == 0) 0034 remainder = 26; 0035 col_str.prepend(QChar('A'+remainder-1)); 0036 col_num = (col_num - 1) / 26; 0037 } 0038 it = col_cache.insert(col_num, col_str); 0039 } 0040 0041 return it.value(); 0042 } 0043 0044 int col_from_name(const QString &col_str) 0045 { 0046 int col = 0; 0047 int expn = 0; 0048 for (int i=col_str.size()-1; i>-1; --i) { 0049 col += (col_str[i].unicode() - 'A' + 1) * intPow(26, expn); 0050 expn++; 0051 } 0052 0053 return col; 0054 } 0055 } //namespace 0056 0057 /*! 0058 \class CellReference 0059 \brief For one single cell such as "A1" 0060 \inmodule QtXlsx 0061 0062 The CellReference class stores the cell location in a worksheet. 0063 */ 0064 0065 /*! 0066 Constructs an invalid Cell Reference 0067 */ 0068 CellReference::CellReference() 0069 : _row(-1), _column(-1) 0070 { 0071 } 0072 0073 /*! 0074 Constructs the Reference from the given \a row, and \a column. 0075 */ 0076 CellReference::CellReference(int row, int column) 0077 : _row(row), _column(column) 0078 { 0079 } 0080 0081 /*! 0082 \overload 0083 Constructs the Reference form the given \a cell string. 0084 */ 0085 CellReference::CellReference(const QString &cell) 0086 { 0087 init(cell); 0088 } 0089 0090 /*! 0091 \overload 0092 Constructs the Reference form the given \a cell string. 0093 */ 0094 CellReference::CellReference(const char *cell) 0095 { 0096 init(QString::fromLatin1(cell)); 0097 } 0098 0099 void CellReference::init(const QString &cell_str) 0100 { 0101 static thread_local QRegularExpression re(QStringLiteral("^\\$?([A-Z]{1,3})\\$?(\\d+)$")); 0102 QRegularExpressionMatch match = re.match(cell_str); 0103 if (match.hasMatch()) { 0104 const QString col_str = match.captured(1); 0105 const QString row_str = match.captured(2); 0106 _row = row_str.toInt(); 0107 _column = col_from_name(col_str); 0108 } 0109 } 0110 0111 /*! 0112 Constructs a Reference by copying the given \a 0113 other Reference. 0114 */ 0115 CellReference::CellReference(const CellReference &other) 0116 : _row(other._row), _column(other._column) 0117 { 0118 } 0119 0120 /*! 0121 Destroys the Reference. 0122 */ 0123 CellReference::~CellReference() 0124 { 0125 } 0126 0127 /*! 0128 Convert the Reference to string notation, such as "A1" or "$A$1". 0129 If current object is invalid, an empty string will be returned. 0130 */ 0131 QString CellReference::toString(bool row_abs, bool col_abs) const 0132 { 0133 if (!isValid()) 0134 return QString(); 0135 0136 QString cell_str; 0137 if (col_abs) 0138 cell_str.append(QLatin1Char('$')); 0139 cell_str.append(col_to_name(_column)); 0140 if (row_abs) 0141 cell_str.append(QLatin1Char('$')); 0142 cell_str.append(QString::number(_row)); 0143 return cell_str; 0144 } 0145 0146 /*! 0147 * Returns true if the Reference is valid. 0148 */ 0149 bool CellReference::isValid() const 0150 { 0151 return _row > 0 && _column > 0; 0152 } 0153 0154 QT_END_NAMESPACE_XLSX