123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747 |
- // xlsxconditionalformatting.cpp
- #include <QtGlobal>
- #include <QXmlStreamReader>
- #include <QXmlStreamWriter>
- #include <QDebug>
- #include "xlsxconditionalformatting.h"
- #include "xlsxconditionalformatting_p.h"
- #include "xlsxworksheet.h"
- #include "xlsxcellrange.h"
- #include "xlsxstyles_p.h"
- QT_BEGIN_NAMESPACE_XLSX
- ConditionalFormattingPrivate::ConditionalFormattingPrivate()
- {
- }
- ConditionalFormattingPrivate::ConditionalFormattingPrivate(const ConditionalFormattingPrivate &other)
- :QSharedData(other)
- {
- }
- ConditionalFormattingPrivate::~ConditionalFormattingPrivate()
- {
- }
- void ConditionalFormattingPrivate::writeCfVo(QXmlStreamWriter &writer, const XlsxCfVoData &cfvo) const
- {
- writer.writeEmptyElement(QStringLiteral("cfvo"));
- QString type;
- switch(cfvo.type) {
- case ConditionalFormatting::VOT_Formula: type=QStringLiteral("formula"); break;
- case ConditionalFormatting::VOT_Max: type=QStringLiteral("max"); break;
- case ConditionalFormatting::VOT_Min: type=QStringLiteral("min"); break;
- case ConditionalFormatting::VOT_Num: type=QStringLiteral("num"); break;
- case ConditionalFormatting::VOT_Percent: type=QStringLiteral("percent"); break;
- case ConditionalFormatting::VOT_Percentile: type=QStringLiteral("percentile"); break;
- default: break;
- }
- writer.writeAttribute(QStringLiteral("type"), type);
- writer.writeAttribute(QStringLiteral("val"), cfvo.value);
- if (!cfvo.gte)
- writer.writeAttribute(QStringLiteral("gte"), QStringLiteral("0"));
- }
- /*!
- * \class ConditionalFormatting
- * \brief Conditional formatting for single cell or ranges
- * \inmodule QtXlsx
- *
- * The conditional formatting can be applied to a single cell or ranges of cells.
- */
- /*!
- \enum ConditionalFormatting::HighlightRuleType
- \value Highlight_LessThan
- \value Highlight_LessThanOrEqual
- \value Highlight_Equal
- \value Highlight_NotEqual
- \value Highlight_GreaterThanOrEqual
- \value Highlight_GreaterThan
- \value Highlight_Between
- \value Highlight_NotBetween
- \value Highlight_ContainsText
- \value Highlight_NotContainsText
- \value Highlight_BeginsWith
- \value Highlight_EndsWith
- \value Highlight_TimePeriod
- \value Highlight_Duplicate
- \value Highlight_Unique
- \value Highlight_Blanks
- \value Highlight_NoBlanks
- \value Highlight_Errors
- \value Highlight_NoErrors
- \value Highlight_Top
- \value Highlight_TopPercent
- \value Highlight_Bottom
- \value Highlight_BottomPercent
- \value Highlight_AboveAverage
- \value Highlight_AboveOrEqualAverage
- \value Highlight_BelowAverage
- \value Highlight_BelowOrEqualAverage
- \value Highlight_AboveStdDev1
- \value Highlight_AboveStdDev2
- \value Highlight_AboveStdDev3
- \value Highlight_BelowStdDev1
- \value Highlight_BelowStdDev2
- \value Highlight_BelowStdDev3
- \value Highlight_Expression
- */
- /*!
- \enum ConditionalFormatting::ValueObjectType
- \value VOT_Formula
- \value VOT_Max
- \value VOT_Min
- \value VOT_Num
- \value VOT_Percent
- \value VOT_Percentile
- */
- /*!
- Construct a conditional formatting object
- */
- ConditionalFormatting::ConditionalFormatting()
- :d(new ConditionalFormattingPrivate())
- {
- }
- /*!
- Constructs a copy of \a other.
- */
- ConditionalFormatting::ConditionalFormatting(const ConditionalFormatting &other)
- :d(other.d)
- {
- }
- /*!
- Assigns \a other to this conditional formatting and returns a reference to
- this conditional formatting.
- */
- ConditionalFormatting &ConditionalFormatting::operator=(const ConditionalFormatting &other)
- {
- this->d = other.d;
- return *this;
- }
- /*!
- * Destroy the object.
- */
- ConditionalFormatting::~ConditionalFormatting()
- {
- }
- /*!
- * Add a hightlight rule with the given \a type, \a formula1, \a formula2,
- * \a format and \a stopIfTrue.
- * Return false if failed.
- */
- bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula1, const QString &formula2, const Format &format, bool stopIfTrue)
- {
- if (format.isEmpty())
- return false;
- bool skipFormula = false;
- QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
- if (type >= Highlight_LessThan && type <= Highlight_NotBetween) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("cellIs");
- QString op;
- switch (type) {
- case Highlight_Between: op = QStringLiteral("between"); break;
- case Highlight_Equal: op = QStringLiteral("equal"); break;
- case Highlight_GreaterThan: op = QStringLiteral("greaterThan"); break;
- case Highlight_GreaterThanOrEqual: op = QStringLiteral("greaterThanOrEqual"); break;
- case Highlight_LessThan: op = QStringLiteral("lessThan"); break;
- case Highlight_LessThanOrEqual: op = QStringLiteral("lessThanOrEqual"); break;
- case Highlight_NotBetween: op = QStringLiteral("notBetween"); break;
- case Highlight_NotEqual: op = QStringLiteral("notEqual"); break;
- default: break;
- }
- cfRule->attrs[XlsxCfRuleData::A_operator] = op;
- } else if (type >= Highlight_ContainsText && type <= Highlight_EndsWith) {
- if (type == Highlight_ContainsText) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsText");
- cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("containsText");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("NOT(ISERROR(SEARCH(\"%1\",%2)))").arg(formula1);
- } else if (type == Highlight_NotContainsText) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsText");
- cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("notContains");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("ISERROR(SEARCH(\"%2\",%1))").arg(formula1);
- } else if (type == Highlight_BeginsWith) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("beginsWith");
- cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("beginsWith");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEFT(%2,LEN(\"%1\"))=\"%1\"").arg(formula1);
- } else {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("endsWith");
- cfRule->attrs[XlsxCfRuleData::A_operator] = QStringLiteral("endsWith");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("RIGHT(%2,LEN(\"%1\"))=\"%1\"").arg(formula1);
- }
- cfRule->attrs[XlsxCfRuleData::A_text] = formula1;
- skipFormula = true;
- } else if (type == Highlight_TimePeriod) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("timePeriod");
- //:Todo
- return false;
- } else if (type == Highlight_Duplicate) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("duplicateValues");
- } else if (type == Highlight_Unique) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("uniqueValues");
- } else if (type == Highlight_Errors) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsErrors");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("ISERROR(%1)");
- skipFormula = true;
- } else if (type == Highlight_NoErrors) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsErrors");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("NOT(ISERROR(%1))");
- skipFormula = true;
- } else if (type == Highlight_Blanks) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("containsBlanks");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEN(TRIM(%1))=0");
- skipFormula = true;
- } else if (type == Highlight_NoBlanks) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("notContainsBlanks");
- cfRule->attrs[XlsxCfRuleData::A_formula1_temp] = QStringLiteral("LEN(TRIM(%1))>0");
- skipFormula = true;
- } else if (type >= Highlight_Top && type <= Highlight_BottomPercent) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("top10");
- if (type == Highlight_Bottom || type == Highlight_BottomPercent)
- cfRule->attrs[XlsxCfRuleData::A_bottom] = QStringLiteral("1");
- if (type == Highlight_TopPercent || type == Highlight_BottomPercent)
- cfRule->attrs[XlsxCfRuleData::A_percent] = QStringLiteral("1");
- cfRule->attrs[XlsxCfRuleData::A_rank] = !formula1.isEmpty() ? formula1 : QStringLiteral("10");
- skipFormula = true;
- } else if (type >= Highlight_AboveAverage && type <= Highlight_BelowStdDev3) {
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("aboveAverage");
- if (type >= Highlight_BelowAverage && type <= Highlight_BelowStdDev3)
- cfRule->attrs[XlsxCfRuleData::A_aboveAverage] = QStringLiteral("0");
- if (type == Highlight_AboveOrEqualAverage || type == Highlight_BelowOrEqualAverage)
- cfRule->attrs[XlsxCfRuleData::A_equalAverage] = QStringLiteral("1");
- if (type == Highlight_AboveStdDev1 || type == Highlight_BelowStdDev1)
- cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("1");
- else if (type == Highlight_AboveStdDev2 || type == Highlight_BelowStdDev2)
- cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("2");
- else if (type == Highlight_AboveStdDev3 || type == Highlight_BelowStdDev3)
- cfRule->attrs[XlsxCfRuleData::A_stdDev] = QStringLiteral("3");
- } else if (type == Highlight_Expression){
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("expression");
- } else {
- return false;
- }
- cfRule->dxfFormat = format;
- if (stopIfTrue)
- cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
- if (!skipFormula) {
- if (!formula1.isEmpty())
- cfRule->attrs[XlsxCfRuleData::A_formula1] = formula1.startsWith(QLatin1String("=")) ? formula1.mid(1) : formula1;
- if (!formula2.isEmpty())
- cfRule->attrs[XlsxCfRuleData::A_formula2] = formula2.startsWith(QLatin1String("=")) ? formula2.mid(1) : formula2;
- }
- d->cfRules.append(cfRule);
- return true;
- }
- /*!
- * \overload
- *
- * Add a hightlight rule with the given \a type \a format and \a stopIfTrue.
- */
- bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const Format &format, bool stopIfTrue)
- {
- if ((type >= Highlight_AboveAverage && type <= Highlight_BelowStdDev3)
- || (type >= Highlight_Duplicate && type <= Highlight_NoErrors)) {
- return addHighlightCellsRule(type, QString(), QString(), format, stopIfTrue);
- }
- return false;
- }
- /*!
- * \overload
- *
- * Add a hightlight rule with the given \a type, \a formula, \a format and \a stopIfTrue.
- * Return false if failed.
- */
- bool ConditionalFormatting::addHighlightCellsRule(HighlightRuleType type, const QString &formula, const Format &format, bool stopIfTrue)
- {
- if (type == Highlight_Between || type == Highlight_NotBetween)
- return false;
- return addHighlightCellsRule(type, formula, QString(), format, stopIfTrue);
- }
- /*!
- * Add a dataBar rule with the given \a color, \a type1, \a val1
- * , \a type2, \a val2, \a showData and \a stopIfTrue.
- * Return false if failed.
- */
- bool ConditionalFormatting::addDataBarRule(const QColor &color, ValueObjectType type1, const QString &val1, ValueObjectType type2, const QString &val2, bool showData, bool stopIfTrue)
- {
- QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("dataBar");
- cfRule->attrs[XlsxCfRuleData::A_color1] = XlsxColor(color);
- if (stopIfTrue)
- cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
- if (!showData)
- cfRule->attrs[XlsxCfRuleData::A_hideData] = true;
- XlsxCfVoData cfvo1(type1, val1);
- XlsxCfVoData cfvo2(type2, val2);
- cfRule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(cfvo1);
- cfRule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(cfvo2);
- d->cfRules.append(cfRule);
- return true;
- }
- /*!
- * \overload
- * Add a dataBar rule with the given \a color, \a showData and \a stopIfTrue.
- */
- bool ConditionalFormatting::addDataBarRule(const QColor &color, bool showData, bool stopIfTrue)
- {
- return addDataBarRule(color, VOT_Min, QStringLiteral("0"), VOT_Max, QStringLiteral("0"), showData, stopIfTrue);
- }
- /*!
- * Add a colorScale rule with the given \a minColor, \a maxColor and \a stopIfTrue.
- * Return false if failed.
- */
- bool ConditionalFormatting::add2ColorScaleRule(const QColor &minColor, const QColor &maxColor, bool stopIfTrue)
- {
- ValueObjectType type1 = VOT_Min;
- ValueObjectType type2 = VOT_Max;
- QString val1 = QStringLiteral("0");
- QString val2 = QStringLiteral("0");
- QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("colorScale");
- cfRule->attrs[XlsxCfRuleData::A_color1] = XlsxColor(minColor);
- cfRule->attrs[XlsxCfRuleData::A_color2] = XlsxColor(maxColor);
- if (stopIfTrue)
- cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
- XlsxCfVoData cfvo1(type1, val1);
- XlsxCfVoData cfvo2(type2, val2);
- cfRule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(cfvo1);
- cfRule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(cfvo2);
- d->cfRules.append(cfRule);
- return true;
- }
- /*!
- * Add a colorScale rule with the given \a minColor, \a midColor, \a maxColor and \a stopIfTrue.
- * Return false if failed.
- */
- bool ConditionalFormatting::add3ColorScaleRule(const QColor &minColor, const QColor &midColor, const QColor &maxColor, bool stopIfTrue)
- {
- ValueObjectType type1 = VOT_Min;
- ValueObjectType type2 = VOT_Percent;
- ValueObjectType type3 = VOT_Max;
- QString val1 = QStringLiteral("0");
- QString val2 = QStringLiteral("50");
- QString val3 = QStringLiteral("0");
- QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
- cfRule->attrs[XlsxCfRuleData::A_type] = QStringLiteral("colorScale");
- cfRule->attrs[XlsxCfRuleData::A_color1] = XlsxColor(minColor);
- cfRule->attrs[XlsxCfRuleData::A_color2] = XlsxColor(midColor);
- cfRule->attrs[XlsxCfRuleData::A_color3] = XlsxColor(maxColor);
- if (stopIfTrue)
- cfRule->attrs[XlsxCfRuleData::A_stopIfTrue] = true;
- XlsxCfVoData cfvo1(type1, val1);
- XlsxCfVoData cfvo2(type2, val2);
- XlsxCfVoData cfvo3(type3, val3);
- cfRule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(cfvo1);
- cfRule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(cfvo2);
- cfRule->attrs[XlsxCfRuleData::A_cfvo3] = QVariant::fromValue(cfvo3);
- d->cfRules.append(cfRule);
- return true;
- }
- /*!
- Returns the ranges on which the validation will be applied.
- */
- QList<CellRange> ConditionalFormatting::ranges() const
- {
- return d->ranges;
- }
- /*!
- Add the \a cell on which the conditional formatting will apply to.
- */
- void ConditionalFormatting::addCell(const CellReference &cell)
- {
- d->ranges.append(CellRange(cell, cell));
- }
- /*!
- \overload
- Add the cell(\a row, \a col) on which the conditional formatting will apply to.
- */
- void ConditionalFormatting::addCell(int row, int col)
- {
- d->ranges.append(CellRange(row, col, row, col));
- }
- /*!
- \overload
- Add the range(\a firstRow, \a firstCol, \a lastRow, \a lastCol) on
- which the conditional formatting will apply to.
- */
- void ConditionalFormatting::addRange(int firstRow, int firstCol, int lastRow, int lastCol)
- {
- d->ranges.append(CellRange(firstRow, firstCol, lastRow, lastCol));
- }
- /*!
- Add the \a range on which the conditional formatting will apply to.
- */
- void ConditionalFormatting::addRange(const CellRange &range)
- {
- d->ranges.append(range);
- }
- bool ConditionalFormattingPrivate::readCfRule(QXmlStreamReader &reader, XlsxCfRuleData *rule, Styles *styles)
- {
- Q_ASSERT(reader.name() == QLatin1String("cfRule"));
- QXmlStreamAttributes attrs = reader.attributes();
- if (attrs.hasAttribute(QLatin1String("type")))
- rule->attrs[XlsxCfRuleData::A_type] = attrs.value(QLatin1String("type")).toString();
- if (attrs.hasAttribute(QLatin1String("dxfId"))) {
- int id = attrs.value(QLatin1String("dxfId")).toString().toInt();
- if (styles)
- rule->dxfFormat = styles->dxfFormat(id);
- else
- rule->dxfFormat.setDxfIndex(id);
- }
- rule->priority = attrs.value(QLatin1String("priority")).toString().toInt();
- if (attrs.value(QLatin1String("stopIfTrue")) == QLatin1String("1")) {
- //default is false
- rule->attrs[XlsxCfRuleData::A_stopIfTrue] = QLatin1String("1");
- }
- if (attrs.value(QLatin1String("aboveAverage")) == QLatin1String("0")) {
- //default is true
- rule->attrs[XlsxCfRuleData::A_aboveAverage] = QLatin1String("0");
- }
- if (attrs.value(QLatin1String("percent")) == QLatin1String("1")) {
- //default is false
- rule->attrs[XlsxCfRuleData::A_percent] = QLatin1String("1");
- }
- if (attrs.value(QLatin1String("bottom")) == QLatin1String("1")) {
- //default is false
- rule->attrs[XlsxCfRuleData::A_bottom] = QLatin1String("1");
- }
- if (attrs.hasAttribute(QLatin1String("operator")))
- rule->attrs[XlsxCfRuleData::A_operator] = attrs.value(QLatin1String("operator")).toString();
- if (attrs.hasAttribute(QLatin1String("text")))
- rule->attrs[XlsxCfRuleData::A_text] = attrs.value(QLatin1String("text")).toString();
- if (attrs.hasAttribute(QLatin1String("timePeriod")))
- rule->attrs[XlsxCfRuleData::A_timePeriod] = attrs.value(QLatin1String("timePeriod")).toString();
- if (attrs.hasAttribute(QLatin1String("rank")))
- rule->attrs[XlsxCfRuleData::A_rank] = attrs.value(QLatin1String("rank")).toString();
- if (attrs.hasAttribute(QLatin1String("stdDev")))
- rule->attrs[XlsxCfRuleData::A_stdDev] = attrs.value(QLatin1String("stdDev")).toString();
- if (attrs.value(QLatin1String("equalAverage")) == QLatin1String("1")) {
- //default is false
- rule->attrs[XlsxCfRuleData::A_equalAverage] = QLatin1String("1");
- }
- while (!reader.atEnd()) {
- reader.readNextStartElement();
- if (reader.tokenType() == QXmlStreamReader::StartElement) {
- if (reader.name() == QLatin1String("formula")) {
- const QString f = reader.readElementText();
- if (!rule->attrs.contains(XlsxCfRuleData::A_formula1))
- rule->attrs[XlsxCfRuleData::A_formula1] = f;
- else if (!rule->attrs.contains(XlsxCfRuleData::A_formula2))
- rule->attrs[XlsxCfRuleData::A_formula2] = f;
- else if (!rule->attrs.contains(XlsxCfRuleData::A_formula3))
- rule->attrs[XlsxCfRuleData::A_formula3] = f;
- } else if (reader.name() == QLatin1String("dataBar")) {
- readCfDataBar(reader, rule);
- } else if (reader.name() == QLatin1String("colorScale")) {
- readCfColorScale(reader, rule);
- }
- }
- if (reader.tokenType() == QXmlStreamReader::EndElement
- && reader.name() == QStringLiteral("conditionalFormatting")) {
- break;
- }
- }
- return true;
- }
- bool ConditionalFormattingPrivate::readCfDataBar(QXmlStreamReader &reader, XlsxCfRuleData *rule)
- {
- Q_ASSERT(reader.name() == QLatin1String("dataBar"));
- QXmlStreamAttributes attrs = reader.attributes();
- if (attrs.value(QLatin1String("showValue")) == QLatin1String("0"))
- rule->attrs[XlsxCfRuleData::A_hideData] = QStringLiteral("1");
- while (!reader.atEnd()) {
- reader.readNextStartElement();
- if (reader.tokenType() == QXmlStreamReader::StartElement) {
- if (reader.name() == QLatin1String("cfvo")) {
- XlsxCfVoData data;
- readCfVo(reader, data);
- if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo1))
- rule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(data);
- else
- rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
- } else if (reader.name() == QLatin1String("color")) {
- XlsxColor color;
- color.loadFromXml(reader);
- rule->attrs[XlsxCfRuleData::A_color1] = color;
- }
- }
- if (reader.tokenType() == QXmlStreamReader::EndElement
- && reader.name() == QStringLiteral("dataBar")) {
- break;
- }
- }
- return true;
- }
- bool ConditionalFormattingPrivate::readCfColorScale(QXmlStreamReader &reader, XlsxCfRuleData *rule)
- {
- Q_ASSERT(reader.name() == QLatin1String("colorScale"));
- while (!reader.atEnd()) {
- reader.readNextStartElement();
- if (reader.tokenType() == QXmlStreamReader::StartElement) {
- if (reader.name() == QLatin1String("cfvo")) {
- XlsxCfVoData data;
- readCfVo(reader, data);
- if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo1))
- rule->attrs[XlsxCfRuleData::A_cfvo1] = QVariant::fromValue(data);
- else if (!rule->attrs.contains(XlsxCfRuleData::A_cfvo2))
- rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
- else
- rule->attrs[XlsxCfRuleData::A_cfvo2] = QVariant::fromValue(data);
- } else if (reader.name() == QLatin1String("color")) {
- XlsxColor color;
- color.loadFromXml(reader);
- if (!rule->attrs.contains(XlsxCfRuleData::A_color1))
- rule->attrs[XlsxCfRuleData::A_color1] = color;
- else if (!rule->attrs.contains(XlsxCfRuleData::A_color2))
- rule->attrs[XlsxCfRuleData::A_color2] = color;
- else
- rule->attrs[XlsxCfRuleData::A_color3] = color;
- }
- }
- if (reader.tokenType() == QXmlStreamReader::EndElement
- && reader.name() == QStringLiteral("colorScale")) {
- break;
- }
- }
- return true;
- }
- bool ConditionalFormattingPrivate::readCfVo(QXmlStreamReader &reader, XlsxCfVoData &cfvo)
- {
- Q_ASSERT(reader.name() == QStringLiteral("cfvo"));
- QXmlStreamAttributes attrs = reader.attributes();
- QString type = attrs.value(QLatin1String("type")).toString();
- ConditionalFormatting::ValueObjectType t;
- if (type == QLatin1String("formula"))
- t = ConditionalFormatting::VOT_Formula;
- else if (type == QLatin1String("max"))
- t = ConditionalFormatting::VOT_Max;
- else if (type == QLatin1String("min"))
- t = ConditionalFormatting::VOT_Min;
- else if (type == QLatin1String("num"))
- t = ConditionalFormatting::VOT_Num;
- else if (type == QLatin1String("percent"))
- t = ConditionalFormatting::VOT_Percent;
- else //if (type == QLatin1String("percentile"))
- t = ConditionalFormatting::VOT_Percentile;
- cfvo.type = t;
- cfvo.value = attrs.value(QLatin1String("val")).toString();
- if (attrs.value(QLatin1String("gte")) == QLatin1String("0")) {
- //default is true
- cfvo.gte = false;
- }
- return true;
- }
- bool ConditionalFormatting::loadFromXml(QXmlStreamReader &reader, Styles *styles)
- {
- Q_ASSERT(reader.name() == QStringLiteral("conditionalFormatting"));
- d->ranges.clear();
- d->cfRules.clear();
- QXmlStreamAttributes attrs = reader.attributes();
- const QString sqref = attrs.value(QLatin1String("sqref")).toString();
- const auto sqrefParts = sqref.split(QLatin1Char(' '));
- for (const QString &range : sqrefParts) {
- this->addRange(range);
- }
- while (!reader.atEnd()) {
- reader.readNextStartElement();
- if (reader.tokenType() == QXmlStreamReader::StartElement) {
- if (reader.name() == QLatin1String("cfRule")) {
- QSharedPointer<XlsxCfRuleData> cfRule(new XlsxCfRuleData);
- d->readCfRule(reader, cfRule.data(), styles);
- d->cfRules.append(cfRule);
- }
- }
- if (reader.tokenType() == QXmlStreamReader::EndElement
- && reader.name() == QStringLiteral("conditionalFormatting")) {
- break;
- }
- }
- return true;
- }
- bool ConditionalFormatting::saveToXml(QXmlStreamWriter &writer) const
- {
- writer.writeStartElement(QStringLiteral("conditionalFormatting"));
- QStringList sqref;
- const auto rangeList = ranges();
- for (const CellRange &range : rangeList) {
- sqref.append(range.toString());
- }
- writer.writeAttribute(QStringLiteral("sqref"), sqref.join(QLatin1String(" ")));
- for (int i=0; i<d->cfRules.size(); ++i) {
- const QSharedPointer<XlsxCfRuleData> &rule = d->cfRules[i];
- writer.writeStartElement(QStringLiteral("cfRule"));
- writer.writeAttribute(QStringLiteral("type"), rule->attrs[XlsxCfRuleData::A_type].toString());
- if (rule->dxfFormat.dxfIndexValid())
- writer.writeAttribute(QStringLiteral("dxfId"), QString::number(rule->dxfFormat.dxfIndex()));
- writer.writeAttribute(QStringLiteral("priority"), QString::number(rule->priority));
- auto it = rule->attrs.constFind(XlsxCfRuleData::A_stopIfTrue);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("stopIfTrue"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_aboveAverage);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("aboveAverage"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_percent);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("percent"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_bottom);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("bottom"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_operator);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("operator"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_text);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("text"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_timePeriod);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("timePeriod"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_rank);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("rank"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_stdDev);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("stdDev"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_equalAverage);
- if (it != rule->attrs.constEnd())
- writer.writeAttribute(QStringLiteral("equalAverage"), it.value().toString());
- if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("dataBar")) {
- writer.writeStartElement(QStringLiteral("dataBar"));
- if (rule->attrs.contains(XlsxCfRuleData::A_hideData))
- writer.writeAttribute(QStringLiteral("showValue"), QStringLiteral("0"));
- d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
- d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
- rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
- writer.writeEndElement();//dataBar
- } else if (rule->attrs[XlsxCfRuleData::A_type] == QLatin1String("colorScale")) {
- writer.writeStartElement(QStringLiteral("colorScale"));
- d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo1].value<XlsxCfVoData>());
- d->writeCfVo(writer, rule->attrs[XlsxCfRuleData::A_cfvo2].value<XlsxCfVoData>());
- it = rule->attrs.constFind(XlsxCfRuleData::A_cfvo3);
- if (it != rule->attrs.constEnd())
- d->writeCfVo(writer, it.value().value<XlsxCfVoData>());
- rule->attrs[XlsxCfRuleData::A_color1].value<XlsxColor>().saveToXml(writer);
- rule->attrs[XlsxCfRuleData::A_color2].value<XlsxColor>().saveToXml(writer);
- it = rule->attrs.constFind(XlsxCfRuleData::A_color3);
- if (it != rule->attrs.constEnd())
- it.value().value<XlsxColor>().saveToXml(writer);
- writer.writeEndElement();//colorScale
- }
- it = rule->attrs.constFind(XlsxCfRuleData::A_formula1_temp);
- if (it != rule->attrs.constEnd()) {
- QString str = ( ranges().begin() )->toString();
- QString startCell = *( str.split(QLatin1Char(':')).begin() );
- writer.writeTextElement(QStringLiteral("formula"), it.value().toString().arg(startCell));
- } else if ((it = rule->attrs.constFind(XlsxCfRuleData::A_formula1)) != rule->attrs.constEnd()) {
- writer.writeTextElement(QStringLiteral("formula"), it.value().toString());
- }
- it = rule->attrs.constFind(XlsxCfRuleData::A_formula2);
- if (it != rule->attrs.constEnd())
- writer.writeTextElement(QStringLiteral("formula"), it.value().toString());
- it = rule->attrs.constFind(XlsxCfRuleData::A_formula3);
- if (it != rule->attrs.constEnd())
- writer.writeTextElement(QStringLiteral("formula"), it.value().toString());
- writer.writeEndElement(); //cfRule
- }
- writer.writeEndElement(); //conditionalFormatting
- return true;
- }
- QT_END_NAMESPACE_XLSX
|