xlsxcellreference.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /****************************************************************************
  2. ** Copyright (c) 2013-2014 Debao Zhang <hello@debao.me>
  3. ** All right reserved.
  4. **
  5. ** Permission is hereby granted, free of charge, to any person obtaining
  6. ** a copy of this software and associated documentation files (the
  7. ** "Software"), to deal in the Software without restriction, including
  8. ** without limitation the rights to use, copy, modify, merge, publish,
  9. ** distribute, sublicense, and/or sell copies of the Software, and to
  10. ** permit persons to whom the Software is furnished to do so, subject to
  11. ** the following conditions:
  12. **
  13. ** The above copyright notice and this permission notice shall be
  14. ** included in all copies or substantial portions of the Software.
  15. **
  16. ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  20. ** LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  21. ** OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22. ** WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. **
  24. ****************************************************************************/
  25. #include "xlsxcellreference.h"
  26. #include <QStringList>
  27. #include <QMap>
  28. #include <QRegularExpression>
  29. QT_BEGIN_NAMESPACE_XLSX
  30. namespace {
  31. int intPow(int x, int p)
  32. {
  33. if (p == 0) return 1;
  34. if (p == 1) return x;
  35. int tmp = intPow(x, p/2);
  36. if (p%2 == 0) return tmp * tmp;
  37. else return x * tmp * tmp;
  38. }
  39. QString col_to_name(int col_num)
  40. {
  41. static QMap<int, QString> col_cache;
  42. if (!col_cache.contains(col_num)) {
  43. QString col_str;
  44. int remainder;
  45. while (col_num) {
  46. remainder = col_num % 26;
  47. if (remainder == 0)
  48. remainder = 26;
  49. col_str.prepend(QChar('A'+remainder-1));
  50. col_num = (col_num - 1) / 26;
  51. }
  52. col_cache.insert(col_num, col_str);
  53. }
  54. return col_cache[col_num];
  55. }
  56. int col_from_name(const QString &col_str)
  57. {
  58. int col = 0;
  59. int expn = 0;
  60. for (int i=col_str.size()-1; i>-1; --i) {
  61. col += (col_str[i].unicode() - 'A' + 1) * intPow(26, expn);
  62. expn++;
  63. }
  64. return col;
  65. }
  66. } //namespace
  67. /*!
  68. \class CellReference
  69. \brief For one single cell such as "A1"
  70. \inmodule QtXlsx
  71. The CellReference class stores the cell location in a worksheet.
  72. */
  73. /*!
  74. Constructs an invalid Cell Reference
  75. */
  76. CellReference::CellReference()
  77. : _row(-1), _column(-1)
  78. {
  79. }
  80. /*!
  81. Constructs the Reference from the given \a row, and \a column.
  82. */
  83. CellReference::CellReference(int row, int column)
  84. : _row(row), _column(column)
  85. {
  86. }
  87. /*!
  88. \overload
  89. Constructs the Reference form the given \a cell string.
  90. */
  91. CellReference::CellReference(const QString &cell)
  92. {
  93. init(cell);
  94. }
  95. /*!
  96. \overload
  97. Constructs the Reference form the given \a cell string.
  98. */
  99. CellReference::CellReference(const char *cell)
  100. {
  101. init(QString::fromLatin1(cell));
  102. }
  103. void CellReference::init(const QString &cell_str)
  104. {
  105. static QRegularExpression re(QStringLiteral("^\\$?([A-Z]{1,3})\\$?(\\d+)$"));
  106. QRegularExpressionMatch match = re.match(cell_str);
  107. if (match.hasMatch()) {
  108. const QString col_str = match.captured(1);
  109. const QString row_str = match.captured(2);
  110. _row = row_str.toInt();
  111. _column = col_from_name(col_str);
  112. }
  113. }
  114. /*!
  115. Constructs a Reference by copying the given \a
  116. other Reference.
  117. */
  118. CellReference::CellReference(const CellReference &other)
  119. : _row(other._row), _column(other._column)
  120. {
  121. }
  122. /*!
  123. Destroys the Reference.
  124. */
  125. CellReference::~CellReference()
  126. {
  127. }
  128. /*!
  129. Convert the Reference to string notation, such as "A1" or "$A$1".
  130. If current object is invalid, an empty string will be returned.
  131. */
  132. QString CellReference::toString(bool row_abs, bool col_abs) const
  133. {
  134. if (!isValid())
  135. return QString();
  136. QString cell_str;
  137. if (col_abs)
  138. cell_str.append(QLatin1Char('$'));
  139. cell_str.append(col_to_name(_column));
  140. if (row_abs)
  141. cell_str.append(QLatin1Char('$'));
  142. cell_str.append(QString::number(_row));
  143. return cell_str;
  144. }
  145. /*!
  146. * Returns true if the Reference is valid.
  147. */
  148. bool CellReference::isValid() const
  149. {
  150. return _row > 0 && _column > 0;
  151. }
  152. QT_END_NAMESPACE_XLSX