xlsxcellformula.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 "xlsxcellformula.h"
  26. #include "xlsxcellformula_p.h"
  27. #include "xlsxutility_p.h"
  28. #include <QXmlStreamReader>
  29. #include <QXmlStreamWriter>
  30. QT_BEGIN_NAMESPACE_XLSX
  31. CellFormulaPrivate::CellFormulaPrivate(const QString &formula_, const CellRange &ref_, CellFormula::FormulaType type_)
  32. :formula(formula_), type(type_), reference(ref_), ca(false), si(0)
  33. {
  34. //Remove the formula '=' sign if exists
  35. if (formula.startsWith(QLatin1String("=")))
  36. formula.remove(0,1);
  37. else if (formula.startsWith(QLatin1String("{=")) && formula.endsWith(QLatin1String("}")))
  38. formula = formula.mid(2, formula.length()-3);
  39. }
  40. CellFormulaPrivate::CellFormulaPrivate(const CellFormulaPrivate &other)
  41. : QSharedData(other)
  42. , formula(other.formula), type(other.type), reference(other.reference)
  43. , ca(other.ca), si(other.si)
  44. {
  45. }
  46. CellFormulaPrivate::~CellFormulaPrivate()
  47. {
  48. }
  49. /*!
  50. \class CellFormula
  51. \inmodule QtXlsx
  52. \brief The CellFormula class provides a API that is used to handle the cell formula.
  53. */
  54. /*!
  55. \enum CellFormula::FormulaType
  56. \value NormalType
  57. \value ArrayType
  58. \value DataTableType
  59. \value SharedType
  60. */
  61. /*!
  62. * Creates a new formula.
  63. */
  64. CellFormula::CellFormula()
  65. {
  66. //The d pointer is initialized with a null pointer
  67. }
  68. /*!
  69. * Creates a new formula with the given \a formula and \a type.
  70. */
  71. CellFormula::CellFormula(const char *formula, FormulaType type)
  72. :d(new CellFormulaPrivate(QString::fromLatin1(formula), CellRange(), type))
  73. {
  74. }
  75. /*!
  76. * Creates a new formula with the given \a formula and \a type.
  77. */
  78. CellFormula::CellFormula(const QString &formula, FormulaType type)
  79. :d(new CellFormulaPrivate(formula, CellRange(), type))
  80. {
  81. }
  82. /*!
  83. * Creates a new formula with the given \a formula, \a ref and \a type.
  84. */
  85. CellFormula::CellFormula(const QString &formula, const CellRange &ref, FormulaType type)
  86. :d(new CellFormulaPrivate(formula, ref, type))
  87. {
  88. }
  89. /*!
  90. Creates a new formula with the same attributes as the \a other formula.
  91. */
  92. CellFormula::CellFormula(const CellFormula &other)
  93. :d(other.d)
  94. {
  95. }
  96. /*!
  97. Assigns the \a other formula to this formula, and returns a
  98. reference to this formula.
  99. */
  100. CellFormula &CellFormula::operator =(const CellFormula &other)
  101. {
  102. d = other.d;
  103. return *this;
  104. }
  105. /*!
  106. * Destroys this formula.
  107. */
  108. CellFormula::~CellFormula()
  109. {
  110. }
  111. /*!
  112. * Returns the type of the formula.
  113. */
  114. CellFormula::FormulaType CellFormula::formulaType() const
  115. {
  116. return d ? d->type : NormalType;
  117. }
  118. /*!
  119. * Returns the contents of the formula.
  120. */
  121. QString CellFormula::formulaText() const
  122. {
  123. return d ? d->formula : QString();
  124. }
  125. /*!
  126. * Returns the reference cells of the formula. For normal formula,
  127. * this will return an invalid CellRange object.
  128. */
  129. CellRange CellFormula::reference() const
  130. {
  131. return d ? d->reference : CellRange();
  132. }
  133. /*!
  134. * Returns whether the formula is valid.
  135. */
  136. bool CellFormula::isValid() const
  137. {
  138. return d;
  139. }
  140. /*!
  141. * Returns the shared index for shared formula.
  142. */
  143. int CellFormula::sharedIndex() const
  144. {
  145. return d && d->type == SharedType ? d->si : -1;
  146. }
  147. /*!
  148. * \internal
  149. */
  150. bool CellFormula::saveToXml(QXmlStreamWriter &writer) const
  151. {
  152. writer.writeStartElement(QStringLiteral("f"));
  153. QString t;
  154. switch (d->type) {
  155. case CellFormula::ArrayType:
  156. t = QStringLiteral("array");
  157. break;
  158. case CellFormula::SharedType:
  159. t = QStringLiteral("shared");
  160. break;
  161. default:
  162. break;
  163. }
  164. if (!t.isEmpty())
  165. writer.writeAttribute(QStringLiteral("t"), t);
  166. if (d->reference.isValid())
  167. writer.writeAttribute(QStringLiteral("ref"), d->reference.toString());
  168. if (d->ca)
  169. writer.writeAttribute(QStringLiteral("ca"), QStringLiteral("1"));
  170. if (d->type == CellFormula::SharedType)
  171. writer.writeAttribute(QStringLiteral("si"), QString::number(d->si));
  172. if (!d->formula.isEmpty())
  173. writer.writeCharacters(d->formula);
  174. writer.writeEndElement(); //f
  175. return true;
  176. }
  177. /*!
  178. * \internal
  179. */
  180. bool CellFormula::loadFromXml(QXmlStreamReader &reader)
  181. {
  182. Q_ASSERT(reader.name() == QLatin1String("f"));
  183. if (!d)
  184. d = new CellFormulaPrivate(QString(), CellRange(), NormalType);
  185. QXmlStreamAttributes attributes = reader.attributes();
  186. QString typeString = attributes.value(QLatin1String("t")).toString();
  187. if (typeString == QLatin1String("array"))
  188. d->type = ArrayType;
  189. else if (typeString == QLatin1String("shared"))
  190. d->type = SharedType;
  191. else
  192. d->type = NormalType;
  193. if (attributes.hasAttribute(QLatin1String("ref"))) {
  194. QString refString = attributes.value(QLatin1String("ref")).toString();
  195. d->reference = CellRange(refString);
  196. }
  197. QString ca = attributes.value(QLatin1String("si")).toString();
  198. d->ca = parseXsdBoolean(ca, false);
  199. if (attributes.hasAttribute(QLatin1String("si")))
  200. d->si = attributes.value(QLatin1String("si")).toString().toInt();
  201. d->formula = reader.readElementText();
  202. return true;
  203. }
  204. /*!
  205. * \internal
  206. */
  207. bool CellFormula::operator ==(const CellFormula &formula) const
  208. {
  209. return d->formula == formula.d->formula && d->type == formula.d->type
  210. && d->si ==formula.d->si;
  211. }
  212. /*!
  213. * \internal
  214. */
  215. bool CellFormula::operator !=(const CellFormula &formula) const
  216. {
  217. return d->formula != formula.d->formula || d->type != formula.d->type
  218. || d->si !=formula.d->si;
  219. }
  220. QT_END_NAMESPACE_XLSX