File indexing completed on 2025-01-19 13:27:35

0001 /*
0002  * This file is part of Office 2007 Filters for Calligra
0003  *
0004  * Copyright (C) 2010 Sebastian Sauer <sebsauer@kdab.com>
0005  * Copyright (c) 2010 Carlos Licea <carlos@kdab.com>
0006  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
0007  *
0008  * Contact: Suresh Chande suresh.chande@nokia.com
0009  *
0010  * This library is free software; you can redistribute it and/or
0011  * modify it under the terms of the GNU Lesser General Public License
0012  * version 2.1 as published by the Free Software Foundation.
0013  *
0014  * This library is distributed in the hope that it will be useful, but
0015  * WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0017  * Lesser General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Lesser General Public
0020  * License along with this library; if not, write to the Free Software
0021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0022  * 02110-1301 USA
0023  *
0024  */
0025 
0026 // Own
0027 #include "XlsxXmlChartReader.h"
0028 
0029 // libodf2
0030 #include "Charting.h"
0031 
0032 // libmso
0033 #include "XlsUtils.h"
0034 #include "NumberFormatParser.h"
0035 
0036 // The Xlsx import filter
0037 #include "XlsxChartOdfWriter.h"
0038 
0039 
0040 #define MSOOXML_CURRENT_NS "c"
0041 #define MSOOXML_CURRENT_CLASS XlsxXmlChartReader
0042 #define BIND_READ_CLASS MSOOXML_CURRENT_CLASS
0043 
0044 #include <MsooXmlReader_p.h>
0045 #include <MsooXmlUtils.h>
0046 
0047 // QT5TODO: shared debug definition for all filters using this source file
0048 #include <QDebug>
0049 #include <QFontMetricsF>
0050 #include <QDateTime>
0051 
0052 class SpPr {
0053 public:
0054     SpPr() {}
0055 };
0056 
0057 class NumCache {
0058 public:
0059     int m_ptCount;
0060     QVector< QString > m_cache;
0061     QString formatCode;
0062     NumCache() : m_ptCount(0) {}
0063 };
0064 
0065 class StrCache {
0066 public:
0067     int m_ptCount;
0068     QVector< QString >  m_cache;
0069     StrCache() : m_ptCount(0) {}
0070 };
0071 
0072 class NumRef {
0073 public:
0074     QString m_f;
0075     NumCache m_numCache;
0076 };
0077 
0078 class NumLit {
0079 public:
0080     int m_ptCount;
0081     QVector< QString > m_cache;
0082     NumLit() : m_ptCount(0) {}
0083 };
0084 
0085 class StrLit {
0086 public:
0087     int m_ptCount;
0088     QVector< QString > m_cache;
0089     StrLit() : m_ptCount(0) {}
0090 };
0091 
0092 class StrRef {
0093 public:
0094     QString m_f;
0095     StrCache m_strCache;
0096 };
0097 
0098 class Tx {
0099 public:
0100     StrRef m_strRef;
0101 
0102     QString writeRefToInternalTable(XlsxXmlChartReader *chartReader);
0103 };
0104 
0105 QString Tx::writeRefToInternalTable(XlsxXmlChartReader *chartReader)
0106 {
0107     chartReader->WriteIntoInternalTable(m_strRef.m_f,m_strRef.m_strCache.m_cache,KoGenStyle::NumericTextStyle);
0108     return m_strRef.m_f;
0109 }
0110 
0111 class Cat {
0112 public:
0113     NumRef m_numRef;
0114     StrRef m_strRef;
0115     NumLit m_numLit;
0116     StrLit m_strLit;
0117 
0118     QString writeRefToInternalTable(XlsxXmlChartReader *chartReader);
0119     QString writeLitToInternalTable(XlsxXmlChartReader *chartReader);
0120 };
0121 
0122 QString Cat::writeRefToInternalTable(XlsxXmlChartReader *chartReader)
0123 {
0124     if (m_numRef.m_numCache.m_ptCount != 0) {
0125         KoGenStyle::Type formatType = KoGenStyle::NumericNumberStyle;
0126         if (!m_numRef.m_numCache.formatCode.isEmpty() && m_numRef.m_numCache.formatCode != "General") {
0127             KoGenStyle style = NumberFormatParser::parse(m_numRef.m_numCache.formatCode);
0128             formatType = style.type();
0129         }
0130         chartReader->WriteIntoInternalTable(m_numRef.m_f,m_numRef.m_numCache.m_cache, formatType, m_numRef.m_numCache.formatCode );
0131         return m_numRef.m_f;
0132     }
0133 
0134     chartReader->WriteIntoInternalTable(m_strRef.m_f,m_strRef.m_strCache.m_cache,KoGenStyle::NumericTextStyle);
0135     return m_strRef.m_f;
0136 }
0137 
0138 QString Cat::writeLitToInternalTable(XlsxXmlChartReader *chartReader)
0139 {
0140     if (m_numLit.m_ptCount != 0) {
0141         return chartReader->AlocateAndWriteIntoInternalTable(m_numLit.m_cache,KoGenStyle::NumericNumberStyle);
0142     }
0143 
0144     return chartReader->AlocateAndWriteIntoInternalTable(m_strLit.m_cache,KoGenStyle::NumericTextStyle);
0145 }
0146 
0147 class Val {
0148 public:
0149     NumRef m_numRef;
0150     NumLit m_numLit;
0151 
0152     QString writeRefToInternalTable(XlsxXmlChartReader *chartReader);
0153     QString writeLitToInternalTable(XlsxXmlChartReader *chartReader);
0154 };
0155 
0156 QString Val::writeRefToInternalTable(XlsxXmlChartReader *chartReader)
0157 {
0158     chartReader->WriteIntoInternalTable(m_numRef.m_f,m_numRef.m_numCache.m_cache,KoGenStyle::NumericNumberStyle);
0159     return m_numRef.m_f;
0160 }
0161 
0162 QString Val::writeLitToInternalTable(XlsxXmlChartReader *chartReader)
0163 {
0164     return chartReader->AlocateAndWriteIntoInternalTable(m_numLit.m_cache,KoGenStyle::NumericNumberStyle);
0165 }
0166 
0167 class XVal {
0168 public:
0169     NumRef m_numRef;
0170     StrRef m_strRef;
0171     NumLit m_numLit;
0172     StrLit m_strLit;
0173 
0174     QString writeRefToInternalTable(XlsxXmlChartReader *chartReader);
0175     QString writeLitToInternalTable(XlsxXmlChartReader *chartReader);
0176 };
0177 
0178 QString XVal::writeRefToInternalTable(XlsxXmlChartReader *chartReader)
0179 {
0180     if (m_numRef.m_numCache.m_ptCount != 0) {
0181         chartReader->WriteIntoInternalTable(m_numRef.m_f,m_numRef.m_numCache.m_cache,KoGenStyle::NumericNumberStyle);
0182         return m_numRef.m_f;
0183     }
0184 
0185     chartReader->WriteIntoInternalTable(m_strRef.m_f,m_strRef.m_strCache.m_cache,KoGenStyle::NumericTextStyle);
0186     return m_strRef.m_f;
0187 }
0188 
0189 QString XVal::writeLitToInternalTable(XlsxXmlChartReader *chartReader)
0190 {
0191     if (m_numLit.m_ptCount != 0) {
0192         return chartReader->AlocateAndWriteIntoInternalTable(m_numLit.m_cache,KoGenStyle::NumericNumberStyle);
0193     }
0194 
0195     return chartReader->AlocateAndWriteIntoInternalTable(m_strLit.m_cache,KoGenStyle::NumericTextStyle);
0196 }
0197 
0198 
0199 class YVal {
0200 public:
0201     NumRef m_numRef;
0202     NumLit m_numLit;
0203 
0204     QString writeRefToInternalTable(XlsxXmlChartReader *chartReader);
0205     QString writeLitToInternalTable(XlsxXmlChartReader *chartReader);
0206 };
0207 
0208 QString YVal::writeRefToInternalTable(XlsxXmlChartReader *chartReader)
0209 {
0210     chartReader->WriteIntoInternalTable(m_numRef.m_f,m_numRef.m_numCache.m_cache,KoGenStyle::NumericNumberStyle);
0211     return m_numRef.m_f;
0212 }
0213 
0214 QString YVal::writeLitToInternalTable(XlsxXmlChartReader *chartReader)
0215 {
0216     return chartReader->AlocateAndWriteIntoInternalTable(m_numLit.m_cache,KoGenStyle::NumericNumberStyle);
0217 }
0218 
0219 
0220 class BubbleSize {
0221 public:
0222     NumRef m_numRef;
0223     NumLit m_numLit;
0224 
0225     QString writeRefToInternalTable(XlsxXmlChartReader *chartReader);
0226     QString writeLitToInternalTable(XlsxXmlChartReader *chartReader);
0227 };
0228 
0229 QString BubbleSize::writeRefToInternalTable(XlsxXmlChartReader *chartReader)
0230 {
0231     chartReader->WriteIntoInternalTable(m_numRef.m_f,m_numRef.m_numCache.m_cache,KoGenStyle::NumericNumberStyle);
0232     return m_numRef.m_f;
0233 }
0234 
0235 QString BubbleSize::writeLitToInternalTable(XlsxXmlChartReader *chartReader)
0236 {
0237     return chartReader->AlocateAndWriteIntoInternalTable(m_numLit.m_cache,KoGenStyle::NumericNumberStyle);
0238 }
0239 
0240 class Ser
0241 {
0242 };
0243 
0244 class ValSeries : public Ser
0245 {
0246 public:
0247     int m_idx;
0248     int m_order;
0249     Tx  m_tx;
0250     Cat m_cat;
0251     Val m_val;
0252     ValSeries() : m_idx(0), m_order(0) {}
0253 };
0254 
0255 class BubbleSeries : public Ser
0256 {
0257 public:
0258     int m_idx;
0259     int m_order;
0260     Tx  m_tx;
0261     XVal m_xVal;
0262     YVal m_yVal;
0263     BubbleSize m_bubbleSize;
0264     BubbleSeries() : m_idx(0), m_order(0) {}
0265 };
0266 
0267 class ScatterSeries : public Ser
0268 {
0269 public:
0270     int m_idx;
0271     int m_order;
0272     Tx  m_tx;
0273     XVal m_xVal;
0274     YVal m_yVal;
0275     SpPr m_spPr;
0276     ScatterSeries() : m_idx(0), m_order(0) {}
0277 };
0278 
0279 class LineSeries :public ValSeries
0280 {
0281 public:
0282     LineSeries() {}
0283 };
0284 
0285 class PieSeries :public ValSeries
0286 {
0287 public:
0288     int m_explosion;
0289     PieSeries() : m_explosion(0) {}
0290 };
0291 
0292 class BarSeries :public ValSeries
0293 {
0294 public:
0295     BarSeries() {}
0296 };
0297 
0298 class AreaSeries :public ValSeries
0299 {
0300 public:
0301     AreaSeries() {}
0302 };
0303 
0304 class RadarSeries :public ValSeries
0305 {
0306 public:
0307     RadarSeries() {}
0308 };
0309 
0310 class SurfaceSeries :public ValSeries
0311 {
0312 public:
0313     SurfaceSeries() {}
0314 };
0315 
0316 class XlsxXmlChartReader::Private
0317 {
0318 public:
0319     Private();
0320     QList<Ser*> m_seriesData;
0321     QVariant::Type m_currentType;
0322     int *m_currentIdx;
0323     int *m_currentOrder;
0324     int *m_currentExplosion;
0325     Tx  *m_currentTx;
0326     Cat *m_currentCat;
0327     Val *m_currentVal;
0328     StrRef *m_currentStrRef;
0329     QString *m_currentF;
0330     StrCache *m_currentStrCache;
0331     int *m_currentPtCount;
0332     QVector< QString >  *m_currentPtCache;
0333     NumRef *m_currentNumRef;
0334     NumLit *m_currentNumLit;
0335     NumCache *m_currentNumCache;
0336     XVal *m_currentXVal;
0337     YVal *m_currentYVal;
0338     BubbleSize *m_currentBubbleSize;
0339     int m_numReadSeries;
0340 };
0341 
0342 XlsxXmlChartReader::Private::Private ( )
0343     : m_numReadSeries( 0 )
0344 {
0345     //sebsauer; hmmmm... does that really make sense?
0346     qDeleteAll(m_seriesData);
0347     m_seriesData.clear();
0348 }
0349 
0350 // calculates the column width in pixels
0351 int columnWidth(unsigned long col, unsigned long dx = 0, qreal defaultColumnWidth = 8.43) {
0352     QFont font("Arial", 10);
0353     QFontMetricsF fm(font);
0354     const qreal characterWidth = fm.width("h");
0355     defaultColumnWidth *= characterWidth;
0356     return (defaultColumnWidth * col) + (dx / 1024.0 * defaultColumnWidth);
0357 }
0358 
0359 // calculates the row height in pixels
0360 int rowHeight(unsigned long row, unsigned long dy = 0, qreal defaultRowHeight = 12.75)
0361 {
0362     return defaultRowHeight * row + dy;
0363 }
0364 
0365 // Returns A for 1, B for 2, C for 3, etc.
0366 QString columnName(uint column)
0367 {
0368     QString s;
0369     column = column - 1;
0370     unsigned digits = 1;
0371     unsigned offset = 0;
0372     for (unsigned limit = 26; column >= limit + offset; limit *= 26, ++digits)
0373         offset += limit;
0374     for (unsigned col = column - offset; digits; --digits, col /= 26)
0375         s.prepend(QChar('A' + (col % 26)));
0376     return s;
0377 }
0378 
0379 
0380 
0381 XlsxXmlChartReaderContext::XlsxXmlChartReaderContext(KoStore* _storeout,
0382                              XlsxChartOdfWriter* _chartWriter)
0383     : MSOOXML::MsooXmlReaderContext()
0384     , m_storeout(_storeout)
0385     , m_chart(_chartWriter->chart())
0386     , m_chartWriter(_chartWriter)
0387 {
0388 }
0389 
0390 XlsxXmlChartReaderContext::~XlsxXmlChartReaderContext()
0391 {
0392     delete m_chart;
0393     delete m_chartWriter;
0394 }
0395 
0396 XlsxXmlChartReader::XlsxXmlChartReader(KoOdfWriters *writers)
0397     : MSOOXML::MsooXmlCommonReader(writers)
0398     , m_context(0)
0399     , m_currentSeries(0)
0400     , m_currentShapeProperties(0)
0401     , m_readTxContext( None )
0402     , m_areaContext( ChartArea )
0403     , m_serMarkerDefined(false)
0404     , m_autoTitleDeleted(true)
0405     , d ( new Private( ) )
0406 {
0407 }
0408 
0409 XlsxXmlChartReader::~XlsxXmlChartReader()
0410 {
0411      delete d;
0412 }
0413 
0414 //! chart (Chart)
0415 /*! ECMA-376, 21.2.2.29, p.3768.
0416 
0417  Parent elements:
0418   - chartSpace (§21.2.2.29)
0419 
0420  Child elements:
0421   - [Done]autoTitleDeleted (Auto Title Is Deleted) §21.2.2.7
0422   - backWall (Back Wall) §21.2.2.11
0423   - dispBlanksAs (Display Blanks As) §21.2.2.42
0424   - extLst (Chart Extensibility) §21.2.2.64
0425   - floor (Floor) §21.2.2.69
0426   - [Done]legend (Legend) §21.2.2.93
0427   - pivotFmts (Pivot Formats) §21.2.2.143
0428   - [Done]plotArea (Plot Area) §21.2.2.145
0429   - plotVisOnly (Plot Visible Only) §21.2.2.146
0430   - showDLblsOverMax (Show Data Labels over Maximum) §21.2.2.180
0431   - sideWall (Side Wall) §21.2.2.191
0432   - [Done]title (Title) §21.2.2.210
0433   - view3D (View In 3D) §21.2.2.228
0434 */
0435 KoFilter::ConversionStatus XlsxXmlChartReader::read(MSOOXML::MsooXmlReaderContext* context)
0436 {
0437     m_context = dynamic_cast<XlsxXmlChartReaderContext*>(context);
0438     Q_ASSERT(m_context);
0439 
0440     readNext();
0441     if (!isStartDocument()) {
0442         return KoFilter::WrongFormat;
0443     }
0444 
0445     readNext();
0446     if (!expectEl("c:chartSpace")) {
0447         return KoFilter::WrongFormat;
0448     }
0449 
0450     while (!atEnd()) {
0451         QXmlStreamReader::TokenType tokenType = readNext();
0452         if(tokenType == QXmlStreamReader::Invalid || tokenType == QXmlStreamReader::EndDocument) break;
0453         if (isStartElement()) {
0454             m_areaContext = ChartArea;
0455             TRY_READ_IF(plotArea)
0456             ELSE_TRY_READ_IF(title)
0457             ELSE_TRY_READ_IF(legend)
0458             ELSE_TRY_READ_IF(spPr)
0459             ELSE_TRY_READ_IF(txPr)
0460             if (qualifiedName() == QLatin1String(QUALIFIED_NAME(autoTitleDeleted))) {
0461                 const QXmlStreamAttributes attrs(attributes());
0462                 TRY_READ_ATTR_WITHOUT_NS(val)
0463                 m_autoTitleDeleted = MSOOXML::Utils::convertBooleanAttr(val, true);
0464             }
0465             if (qualifiedName() == QLatin1String(QUALIFIED_NAME(style))) {
0466                 const QXmlStreamAttributes attrs(attributes());
0467                 TRY_READ_ATTR_WITHOUT_NS(val)
0468                 m_context->m_chart->m_style = val.toInt();
0469             }
0470         }
0471     }
0472 
0473     if (!m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty())
0474         m_context->m_chart->m_title = "Chart Title";
0475 
0476     // static is fine here cause we only need to take care that that number is unique in the
0477     // exported ODS file and do not take if the number is continuous or whatever.
0478     static int chartNumber = 0;
0479     m_context->m_chartWriter->m_href = QString("Chart%1").arg(++chartNumber);
0480 
0481     KoChart::Chart* c = m_context->m_chart;
0482     if (!c->m_cellRangeAddress.isNull() ) {
0483         m_context->m_chartWriter->m_cellRangeAddress.clear();
0484         if (!c->m_sheetName.isEmpty())
0485             m_context->m_chartWriter->m_cellRangeAddress += c->m_sheetName + '.';
0486         m_context->m_chartWriter->m_cellRangeAddress += columnName(c->m_cellRangeAddress.left()) + QString::number(c->m_cellRangeAddress.top()) + ":" +
0487                                                         columnName(c->m_cellRangeAddress.right()) + QString::number(c->m_cellRangeAddress.bottom());
0488     }
0489 
0490     if (m_currentSeries) {
0491         m_context->m_chartWriter->m_notifyOnUpdateOfRanges = m_currentSeries->m_valuesCellRangeAddress; //m_cellRangeAddress
0492     }
0493 
0494     // the index will by written by the XlsxXmlWorksheetReader
0495     //m_context->m_chartWriter->saveIndex(body);
0496 
0497     // write the embedded object file
0498     m_context->m_chartWriter->saveContent(m_context->m_storeout, manifest);
0499 
0500     m_context = 0;
0501     return KoFilter::OK;
0502 }
0503 
0504 #undef CURRENT_EL
0505 #define CURRENT_EL txPr
0506 KoFilter::ConversionStatus XlsxXmlChartReader::read_txPr()
0507 {
0508     READ_PROLOGUE
0509     while( !atEnd() )
0510     {
0511         readNext();
0512         BREAK_IF_END_OF(CURRENT_EL)
0513         if ( isStartElement() )
0514             if ( qualifiedName() == "a:p" )
0515                 read_p();
0516     }
0517     READ_EPILOGUE
0518     return KoFilter::OK;
0519 }
0520 
0521 #undef CURRENT_EL
0522 #define CURRENT_EL p
0523 KoFilter::ConversionStatus XlsxXmlChartReader::read_p()
0524 {
0525     //READ_PROLOGUE
0526     while( !atEnd() )
0527     {
0528         readNext();
0529         if ( isEndElement() && qualifiedName() == QLatin1String( "a:p") )
0530             break;
0531         if ( isStartElement() )
0532             if ( qualifiedName() == "a:pPr" )
0533                 read_pPr();
0534             //TRY_READ_IF_NS(a,pPr);
0535     }
0536     //READ_EPILOGUE
0537     return KoFilter::OK;
0538 }
0539 
0540 #undef CURRENT_EL
0541 #define CURRENT_EL pPr
0542 KoFilter::ConversionStatus XlsxXmlChartReader::read_pPr()
0543 {
0544     //READ_PROLOGUE
0545     while( !atEnd() )
0546     {
0547         readNext();
0548         if ( isEndElement() && qualifiedName() == QLatin1String( "a:pPr") )
0549             break;
0550         if ( isStartElement() )
0551             if ( qualifiedName() == "a:defRPr" )
0552                 read_defRPr();
0553     }
0554     //READ_EPILOGUE
0555     return KoFilter::OK;
0556 }
0557 
0558 #undef CURRENT_EL
0559 #define CURRENT_EL defRPr
0560 KoFilter::ConversionStatus XlsxXmlChartReader::read_defRPr()
0561 {
0562     //READ_PROLOGUE
0563     const QXmlStreamAttributes attrs(attributes());
0564     TRY_READ_ATTR_WITHOUT_NS(sz);
0565     bool ok = false;
0566     const qreal size = sz.toDouble( &ok );
0567     if ( ok )
0568     {
0569         m_context->m_chart->m_textSize = size / 100.0;
0570     }
0571     while( !atEnd() )
0572     {
0573         if ( isEndElement() && qualifiedName() == QLatin1String( "a:defRPr") )
0574             break;
0575         readNext();
0576         //BREAK_IF_END_OF(CURRENT_EL)
0577     }
0578     //READ_EPILOGUE
0579     return KoFilter::OK;
0580 }
0581 
0582 
0583 
0584 #undef CURRENT_EL
0585 #define CURRENT_EL valAx
0586 KoFilter::ConversionStatus XlsxXmlChartReader::read_valAx()
0587 {
0588     READ_PROLOGUE
0589 
0590     // The logic here is that if the x-axis defines a category then it should be already
0591     // set above using the read_catAx else this read_valAx could be either a x-axis or
0592     // a y-axis. In that case we just look if there was already a x-axis defined in
0593     // which case we know if must be the y-axis or, if not, then it's the a-axis.
0594     // This sounds hacky (and it certainly is) but that's how OO.org does it too.
0595     bool xAxisAlreadyDefined = !m_context->m_chart->m_verticalCellRangeAddress.isEmpty();
0596     if (!xAxisAlreadyDefined) {
0597         foreach(KoChart::Axis* axis, m_context->m_chart->m_axes) {
0598             if (axis->m_type == KoChart::Axis::HorizontalValueAxis) {
0599                 xAxisAlreadyDefined = true;
0600                 break;
0601             }
0602         }
0603     }
0604     KoChart::Axis* axis = new KoChart::Axis( xAxisAlreadyDefined ? KoChart::Axis::VerticalValueAxis : KoChart::Axis::HorizontalValueAxis );
0605 
0606     m_context->m_chart->m_axes.push_back( axis );
0607     while (!atEnd()) {
0608         readNext();
0609         BREAK_IF_END_OF(CURRENT_EL)
0610         if (isStartElement()) {
0611             if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(axPos) ) ) {
0612 //                   const QXmlStreamAttributes attrs(attributes());
0613 //                   TRY_READ_ATTR_WITHOUT_NS(val)
0614 //                   if ( val == QLatin1String( "b" ) ){
0615 //                       axis->m_type = KoChart::Axis::HorizontalValueAxis;
0616 //                   }
0617 //                   else if ( val == QLatin1String( "l" ) ){
0618 //                   }
0619 //             }
0620             }
0621             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(majorGridlines) ) ) {
0622                 axis->m_majorGridlines = KoChart::Axis::Gridline( KoChart::LineFormat( KoChart::LineFormat::Solid ) );
0623             }
0624             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(numFmt) ) ) {
0625                 const QXmlStreamAttributes attrs(attributes());
0626                 axis->m_numberFormat = attrs.value("formatCode").toString();
0627             }
0628             ELSE_TRY_READ_IF(scaling)
0629         }
0630     }
0631     READ_EPILOGUE
0632 }
0633 
0634 #undef CURRENT_EL
0635 #define CURRENT_EL catAx
0636 KoFilter::ConversionStatus XlsxXmlChartReader::read_catAx()
0637 {
0638     READ_PROLOGUE
0639     // category-axis or date-axis are always x-axis. They are only defined for the case the
0640     // x-axis itself defines a category. If not then the x-axis will be defined via read_valAx.
0641     KoChart::Axis* axis = new KoChart::Axis( KoChart::Axis::HorizontalValueAxis );
0642     m_context->m_chart->m_axes.push_back( axis );
0643     while (!atEnd()) {
0644         readNext();
0645         BREAK_IF_END_OF(CURRENT_EL)
0646         if (isStartElement()) {
0647             if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(axPos) ) ) {
0648 //                   const QXmlStreamAttributes attrs(attributes());
0649 //                   TRY_READ_ATTR_WITHOUT_NS(val)
0650 //                   if ( val == QLatin1String( "b" ) ){
0651 //                   }
0652 //                   else if ( val == QLatin1String( "l" ) ){
0653 //                   }
0654             }
0655             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(majorGridlines) ) ) {
0656                   axis->m_majorGridlines = KoChart::Axis::Gridline( KoChart::LineFormat( KoChart::LineFormat::Solid ) );
0657             }
0658             ELSE_TRY_READ_IF(scaling)
0659         }
0660     }
0661     READ_EPILOGUE
0662 }
0663 
0664 #undef CURRENT_EL
0665 #define CURRENT_EL scaling
0666 KoFilter::ConversionStatus XlsxXmlChartReader::read_scaling()
0667 {
0668     READ_PROLOGUE
0669     Q_ASSERT(!m_context->m_chart->m_axes.isEmpty());
0670     KoChart::Axis* axis = m_context->m_chart->m_axes.last();
0671     while (!atEnd()) {
0672         readNext();
0673         BREAK_IF_END_OF(CURRENT_EL)
0674         if (isStartElement()) {
0675             const QXmlStreamAttributes attrs(attributes());
0676             if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(orientation) ) ) {
0677                 TRY_READ_ATTR_WITHOUT_NS(val)
0678                 axis->m_reversed = ( val == QLatin1String( "maxMin" ) );
0679             }
0680             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(logBase) ) ) {
0681                 TRY_READ_ATTR_WITHOUT_NS(val)
0682                 axis->m_logarithmic = ( val.toDouble() >= 2. );
0683             }
0684             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(max) ) ) {
0685                 TRY_READ_ATTR_WITHOUT_NS(val)
0686                 axis->m_maximum = val.toDouble();
0687                 axis->m_autoMaximum = false;
0688             }
0689             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(min) ) ) {
0690                 TRY_READ_ATTR_WITHOUT_NS(val)
0691                 axis->m_minimum = val.toDouble();
0692                 axis->m_autoMinimum = false;
0693             }
0694         }
0695     }
0696     READ_EPILOGUE
0697 }
0698 
0699 #undef CURRENT_EL
0700 #define CURRENT_EL plotArea
0701 //! plotArea (Plot Area)
0702 /*! ECMA-376, 21.2.2.145, p.3828.
0703 
0704  Parent elements:
0705   - chart (§21.2.2.27)
0706 
0707  Child elements:
0708   - [Done]area3DChart (3D Area Charts) §21.2.2.4
0709   - [Done]areaChart (Area Charts) §21.2.2.5
0710   - [Done]bar3DChart (3D Bar Charts) §21.2.2.15
0711   - [Done]barChart (Bar Charts) §21.2.2.16
0712   - [Done]bubbleChart (Bubble Charts) §21.2.2.20
0713   - [Done]catAx (Category Axis Data) §21.2.2.25
0714   - dateAx (Date Axis) §21.2.2.39
0715   - [Done]doughnutChart (Doughnut Charts) §21.2.2.50
0716   - dTable (Data Table) §21.2.2.54
0717   - extLst (Chart Extensibility) §21.2.2.64
0718   - layout (Layout) §21.2.2.88
0719   - [Done]line3DChart (3D Line Charts) §21.2.2.96
0720   - [Done]lineChart (Line Charts) §21.2.2.97
0721   - [Done]ofPieChart (Pie of Pie or Bar of Pie Charts) §21.2.2.126
0722   - [Done]pie3DChart (3D Pie Charts) §21.2.2.140
0723   - [Done]pieChart (Pie Charts) §21.2.2.141
0724   - [Done]radarChart (Radar Charts) §21.2.2.153
0725   - [Done]scatterChart (Scatter Charts) §21.2.2.161
0726   - serAx (Series Axis) §21.2.2.175
0727   - [Done]spPr (Shape Properties) §21.2.2.197
0728   - [Done]stockChart (Stock Charts) §21.2.2.198
0729   - [Done]surface3DChart (3D Surface Charts) §21.2.2.203
0730   - [Done]surfaceChart (Surface Charts) §21.2.2.204
0731   - [Done]valAx (Value Axis) §21.2.2.226
0732 */
0733 KoFilter::ConversionStatus XlsxXmlChartReader::read_plotArea()
0734 {
0735     m_areaContext = PlotArea;
0736     if (!m_context->m_chart->m_plotArea) {
0737         m_context->m_chart->m_plotArea = new KoChart::PlotArea();
0738     }
0739     READ_PROLOGUE
0740     while (!atEnd()) {
0741         readNext();
0742         BREAK_IF_END_OF(CURRENT_EL)
0743         if (isStartElement()) {
0744             TRY_READ_IF(spPr)
0745             ELSE_TRY_READ_IF(valAx) // x-axis or y-axis
0746             ELSE_TRY_READ_IF(catAx) // x-axis
0747             //ELSE_TRY_READ_IF(serAx) // z-axis
0748             ELSE_TRY_READ_IF(pieChart)
0749             ELSE_TRY_READ_IF(pie3DChart)
0750             ELSE_TRY_READ_IF(ofPieChart)
0751             ELSE_TRY_READ_IF(doughnutChart)
0752             ELSE_TRY_READ_IF(areaChart)
0753             ELSE_TRY_READ_IF(area3DChart)
0754             ELSE_TRY_READ_IF(barChart)
0755             ELSE_TRY_READ_IF(bar3DChart)
0756             ELSE_TRY_READ_IF(lineChart)
0757             ELSE_TRY_READ_IF(line3DChart)
0758             ELSE_TRY_READ_IF(scatterChart)
0759             ELSE_TRY_READ_IF(radarChart)
0760             ELSE_TRY_READ_IF(surfaceChart)
0761             ELSE_TRY_READ_IF(surface3DChart)
0762             ELSE_TRY_READ_IF(bubbleChart)
0763             ELSE_TRY_READ_IF(stockChart)
0764             SKIP_UNKNOWN
0765         }
0766     }
0767     READ_EPILOGUE
0768     m_areaContext = ChartArea;
0769 }
0770 
0771 #undef CURRENT_EL
0772 #define CURRENT_EL title
0773 /*! Read the horizontal value. */
0774 KoFilter::ConversionStatus XlsxXmlChartReader::read_title()
0775 {
0776     m_readTxContext = Title;
0777     READ_PROLOGUE
0778     while (!atEnd()) {
0779         readNext();
0780         BREAK_IF_END_OF(CURRENT_EL)
0781         if (isStartElement()) {
0782             if(QUALIFIED_NAME_IS(tx)) {
0783                 TRY_READ(chartText_Tx)
0784             }
0785         }
0786     }
0787     m_readTxContext = None;
0788     READ_EPILOGUE
0789 }
0790 
0791 #undef CURRENT_EL
0792 #define CURRENT_EL val
0793 //! val (Values)
0794 /*! ECMA-376, 21.2.2.224, p.3867.
0795 
0796  Parent elements:
0797   - ser §21.2.2.168
0798   - ser §21.2.2.170
0799   - ser §21.2.2.174
0800   - ser §21.2.2.171
0801   - ser §21.2.2.172
0802   - ser §21.2.2.169
0803   - ser §21.2.2.167
0804   - ser §21.2.2.173
0805 
0806  Child elements:
0807   - numLit (Number Literal) §21.2.2.122
0808   - [Done] numRef (Number Reference) §21.2.2.123
0809 */
0810 KoFilter::ConversionStatus XlsxXmlChartReader::read_val()
0811 {
0812     READ_PROLOGUE
0813     d->m_currentNumRef = &d->m_currentVal->m_numRef;
0814     while (!atEnd()) {
0815         readNext();
0816         BREAK_IF_END_OF(CURRENT_EL)
0817         if (isStartElement()) {
0818             TRY_READ_IF(numRef)
0819         }
0820     }
0821     READ_EPILOGUE
0822 }
0823 
0824 #undef CURRENT_EL
0825 #define CURRENT_EL xVal
0826 //! xVal (X Values)
0827 /*! ECMA-376, 21.2.2.234, p.3872.
0828 
0829  Parent elements:
0830   - ser §21.2.2.174
0831   - ser §21.2.2.167
0832 
0833  Child elements:
0834   - multiLvlStrRef (Multi Level String Reference) §21.2.2.115
0835   - numLit (Number Literal) §21.2.2.122
0836   - [Done]numRef (Number Reference) §21.2.2.123
0837   - strLit (String Literal) §21.2.2.200
0838   - [Done]strRef (String Reference) §21.2.2.201
0839 */
0840 KoFilter::ConversionStatus XlsxXmlChartReader::read_xVal()
0841 {
0842     READ_PROLOGUE
0843     d->m_currentNumRef = &d->m_currentXVal->m_numRef;
0844     d->m_currentStrRef = &d->m_currentXVal->m_strRef;
0845     while (!atEnd()) {
0846         readNext();
0847         BREAK_IF_END_OF(CURRENT_EL)
0848         if (isStartElement()) {
0849             TRY_READ_IF(numRef)
0850             ELSE_TRY_READ_IF(strRef)
0851         }
0852     }
0853     READ_EPILOGUE
0854 }
0855 
0856 #undef CURRENT_EL
0857 #define CURRENT_EL yVal
0858 //! yVal (Y Values)
0859 /*! ECMA-376, 21.2.2.237, p.3873.
0860 
0861  Parent elements:
0862   - ser §21.2.2.174
0863   - ser §21.2.2.167
0864 
0865  Child elements:
0866   - numLit (Number Literal) §21.2.2.122
0867   - numRef (Number Reference) §21.2.2.123
0868 */
0869 KoFilter::ConversionStatus XlsxXmlChartReader::read_yVal()
0870 {
0871     READ_PROLOGUE
0872     d->m_currentNumRef = &d->m_currentYVal->m_numRef;
0873     while (!atEnd()) {
0874         readNext();
0875         BREAK_IF_END_OF(CURRENT_EL)
0876         if (isStartElement()) {
0877             TRY_READ_IF(numRef)
0878         }
0879     }
0880     READ_EPILOGUE
0881 }
0882 
0883 #undef CURRENT_EL
0884 #define CURRENT_EL cat
0885 //! cat (Category Axis Data)
0886 /*! ECMA-376, 21.2.2.24, p.3766.
0887 
0888  Parent elements:
0889   - ser §21.2.2.168
0890   - ser §21.2.2.170
0891   - ser §21.2.2.174
0892   - ser §21.2.2.171
0893   - ser §21.2.2.172
0894   - ser §21.2.2.169
0895   - ser §21.2.2.167
0896   - ser §21.2.2.173
0897 
0898  Child elements:
0899   - multiLvlStrRef (Multi Level String Reference) §21.2.2.115
0900   - numLit (Number Literal) §21.2.2.122
0901   - [Done]numRef (Number Reference) §21.2.2.123
0902   - strLit (String Literal) §21.2.2.200
0903   - strRef (String Reference) §21.2.2.201
0904 */
0905 KoFilter::ConversionStatus XlsxXmlChartReader::read_cat()
0906 {
0907     READ_PROLOGUE
0908     d->m_currentStrRef = &d->m_currentCat->m_strRef;
0909     d->m_currentNumRef = &d->m_currentCat->m_numRef;
0910     while (!atEnd()) {
0911         readNext();
0912         BREAK_IF_END_OF(CURRENT_EL)
0913         if (isStartElement()) {
0914             TRY_READ_IF(strRef)
0915             ELSE_TRY_READ_IF(multiLvlStrRef)
0916             ELSE_TRY_READ_IF(numRef)
0917         }
0918     }
0919     READ_EPILOGUE
0920 }
0921 
0922 #undef CURRENT_EL
0923 #define CURRENT_EL tx
0924 //! tx (Chart Text)
0925 /*! ECMA-376, 21.2.2.215, p.3863.
0926 
0927  Parent elements:
0928   - dispUnitsLbl (§21.2.2.46)
0929   - dLbl (§21.2.2.47)
0930   - title (§21.2.2.210)
0931   - trendlineLbl (§21.2.2.212)
0932 
0933  Child elements:
0934   - rich (Rich Text) §21.2.2.156
0935   - strRef (String Reference) §21.2.2.201
0936 */
0937 
0938 /*! This element specifies text to use on a chart, including rich text formatting. */
0939 KoFilter::ConversionStatus XlsxXmlChartReader::read_chartText_Tx()
0940 {
0941     READ_PROLOGUE2(chartText_Tx)
0942     enum { Start, InStrRef, InRichText } state;
0943     state = Start;
0944     while (!atEnd()) {
0945         readNext();
0946         BREAK_IF_END_OF(CURRENT_EL)
0947         switch(state) {
0948             case Start:
0949                 if (qualifiedName() == QLatin1String(QUALIFIED_NAME(strRef)))
0950                     state = isStartElement() ? InStrRef : Start;
0951                 else if (qualifiedName() == QLatin1String(QUALIFIED_NAME(rich)))
0952                     state = isStartElement() ? InRichText : Start;
0953                 break;
0954             case InStrRef: // plaintext within a series
0955 //                if (isStartElement() && !m_currentSeriesData->m_datasetValue.contains(KoChart::Value::SeriesLegendOrTrendlineName)) {
0956 //                    if (qualifiedName() == QLatin1String(QUALIFIED_NAME(f))) {
0957 //                        KoChart::Value* v = new KoChart::Value(KoChart::Value::SeriesLegendOrTrendlineName, KoChart::Value::CellRange, readElementText());
0958 //                        m_currentSeriesData->m_datasetValue[v->m_dataId] = v;
0959 //                    } else if (qualifiedName() == QLatin1String(QUALIFIED_NAME(v))) {
0960 //                        KoChart::Value* v = new KoChart::Value(KoChart::Value::SeriesLegendOrTrendlineName, KoChart::Value::TextOrValue, readElementText());
0961 //                        m_currentSeriesData->m_datasetValue[v->m_dataId] = v;
0962 //                    }
0963 //                }
0964                 break;
0965             case InRichText: // richtext means the title text
0966                 // we extract the text from the richtext cause we cannot handle the richtext formattings anyway
0967                 QString result;
0968                 enum { Rich, Paragraph, TextRun } s;
0969                 s = Rich;
0970                 while (!atEnd()) {
0971                     readNext();
0972                     switch(s) {
0973                         case Rich:
0974                             if (isStartElement() && qualifiedName() == QLatin1String("a:p")) s = Paragraph;
0975                             break;
0976                         case Paragraph:
0977                             if (qualifiedName() == QLatin1String("a:r")) // text run
0978                             s = isStartElement() ? TextRun : Rich;
0979                         break;
0980                         case TextRun:
0981                             if (qualifiedName() == QLatin1String("a:t")) {
0982                                 if(isStartElement()) {
0983                                     if(!result.isEmpty()) result += ' '; //concat multiple strings into one result
0984                                     const QString text = readElementText();
0985                                     result += text;
0986                                     m_context->m_chart->m_title = text;
0987                                 } else
0988                                     s = Paragraph;
0989                             }
0990                             break;
0991                     }
0992                     BREAK_IF_END_OF(rich)
0993                 }
0994                 if(!result.isEmpty())
0995                     m_context->m_chart->m_texts << new KoChart::Text(result);
0996                 state = Start;
0997                 break;
0998         }
0999     }
1000     READ_EPILOGUE
1001 }
1002 
1003 #undef CURRENT_EL
1004 #define CURRENT_EL tx
1005 //! tx (Series Text)
1006 /*! ECMA-376, 21.2.2.215, p.3863.
1007 
1008  Parent elements:
1009   - ser §21.2.2.168
1010   - ser §21.2.2.170
1011   - ser §21.2.2.174
1012   - ser §21.2.2.171
1013   - ser §21.2.2.172
1014   - ser §21.2.2.169
1015   - ser §21.2.2.167
1016   - ser §21.2.2.173
1017 
1018  Child elements:
1019   - [Done]strRef (String Reference) §21.2.2.201
1020   - v (Text Value) §21.2.2.223
1021 */
1022 
1023 /*! This element specifies text to use on a chart, including rich text formatting. */
1024 KoFilter::ConversionStatus XlsxXmlChartReader::read_seriesText_Tx()
1025 {
1026     READ_PROLOGUE2(seriesText_Tx)
1027 
1028     d->m_currentStrRef = &d->m_currentTx->m_strRef;
1029     while (!atEnd()) {
1030         readNext();
1031         BREAK_IF_END_OF(CURRENT_EL)
1032         if (isStartElement()) {
1033             TRY_READ_IF(strRef)
1034         }
1035     }
1036     READ_EPILOGUE
1037 }
1038 
1039 #undef CURRENT_EL
1040 #define CURRENT_EL numCache
1041 //! numCache (Number Cache)
1042 /*! ECMA-376, 21.2.2.120, p.3813.
1043 
1044  Parent elements:
1045  - numRef (§21.2.2.123)
1046 
1047  Child elements:
1048   - extLst (Chart Extensibility) §21.2.2.64
1049   - formatCode (Format Code) §21.2.2.71
1050   - [Done]pt (Numeric Point) §21.2.2.150
1051   - [Done]ptCount (Point Count) §21.2.2.152
1052 
1053 */
1054 KoFilter::ConversionStatus XlsxXmlChartReader::read_numCache()
1055 {
1056     READ_PROLOGUE
1057 
1058     d->m_currentPtCount = &d->m_currentNumCache->m_ptCount;
1059     d->m_currentPtCache = &d->m_currentNumCache->m_cache;
1060 
1061     while (!atEnd()) {
1062         readNext();
1063         BREAK_IF_END_OF(CURRENT_EL)
1064         if (isStartElement()) {
1065             TRY_READ_IF(ptCount)
1066             ELSE_TRY_READ_IF(pt)
1067             ELSE_TRY_READ_IF(formatCode)
1068         }
1069     }
1070     READ_EPILOGUE
1071 }
1072 
1073 
1074 #undef CURRENT_EL
1075 #define CURRENT_EL formatCode
1076 //! formatCode (Format Code)
1077 /*! ECMA-376, 21.2.2.71, p.3802.
1078 
1079  Parent elements:
1080  - numCache (§21.2.2.120)
1081 
1082 */
1083 KoFilter::ConversionStatus XlsxXmlChartReader::read_formatCode()
1084 {
1085     READ_PROLOGUE
1086     const QString val = readElementText();
1087     d->m_currentNumCache->formatCode = val;
1088 //     while (!atEnd()) {
1089 //         readNext();
1090 //         BREAK_IF_END_OF(CURRENT_EL)
1091 //         
1092 //     }
1093     READ_EPILOGUE
1094 }
1095 
1096 #undef CURRENT_EL
1097 #define CURRENT_EL legend
1098 KoFilter::ConversionStatus XlsxXmlChartReader::read_legend()
1099 {
1100     READ_PROLOGUE
1101     if (!m_context->m_chart->m_legend) {
1102         m_context->m_chart->m_legend = new KoChart::Legend();
1103     }
1104     while (!atEnd()) {
1105         readNext();
1106         BREAK_IF_END_OF(CURRENT_EL)
1107         //TODO
1108     }
1109     READ_EPILOGUE
1110 }
1111 
1112 void XlsxXmlChartReader::read_showDataLabel()
1113 {
1114     if ( m_currentSeries ) {
1115         const QXmlStreamAttributes attrs(attributes());
1116         if ( qualifiedName() == "c:showVal" ) {
1117             m_currentSeries->m_showDataLabelValues = MSOOXML::Utils::convertBooleanAttr(attrs.value("val").toString(), true);
1118         } else if ( qualifiedName() == "c:showPercent" ) {
1119             m_currentSeries->m_showDataLabelPercent = MSOOXML::Utils::convertBooleanAttr(attrs.value("val").toString(), true);
1120         } else if ( qualifiedName() == "c:showCatName" ) {
1121             m_currentSeries->m_showDataLabelCategory = MSOOXML::Utils::convertBooleanAttr(attrs.value("val").toString(), true);
1122         } else if ( qualifiedName() == "c:showSerName" ) {
1123             m_currentSeries->m_showDataLabelSeries = MSOOXML::Utils::convertBooleanAttr(attrs.value("val").toString(), true);
1124         }
1125     }
1126 }
1127 
1128 #undef CURRENT_EL
1129 #define CURRENT_EL dLbl
1130 //! dLbl (Data Label)
1131 /*! ECMA-376, 21.2.2.47, p.3780.
1132 
1133  Parent elements:
1134  - dLbls (§21.2.2.49)
1135  - pivotFmt (§21.2.2.142)
1136 
1137  Child elements:
1138   - delete (Delete) §21.2.2.40
1139   - dLblPos (Data Label Position) §21.2.2.48
1140   - extLst (Chart Extensibility) §21.2.2.64
1141   - idx (Index) §21.2.2.84
1142   - layout (Layout) §21.2.2.88
1143   - numFmt (Number Format) §21.2.2.121
1144   - separator (Separator) §21.2.2.166
1145   - showBubbleSize (Show Bubble Size) §21.2.2.178
1146   - showCatName (Show Category Name) §21.2.2.179
1147   - showLegendKey (Show Legend Key) §21.2.2.184
1148   - showPercent (Show Percent) §21.2.2.187
1149   - showSerName (Show Series Name) §21.2.2.188
1150   - [Done]showVal (Show Value) §21.2.2.189
1151   - spPr (Shape Properties) §21.2.2.197
1152   - tx (Chart Text) §21.2.2.214
1153   - txPr (Text Properties) §21.2.2.216
1154 
1155 */
1156 KoFilter::ConversionStatus XlsxXmlChartReader::read_dLbl()
1157 {
1158     READ_PROLOGUE
1159     while (!atEnd()) {
1160         readNext();
1161         BREAK_IF_END_OF(CURRENT_EL)
1162         if (isStartElement()) {
1163             read_showDataLabel();
1164         }
1165     }
1166     READ_EPILOGUE
1167 }
1168 
1169 #undef CURRENT_EL
1170 #define CURRENT_EL dLbls
1171 //! dLbls (Data Labels)
1172 /*! ECMA-376, 21.2.2.49, p.3781.
1173 
1174  Parent elements:
1175  - area3DChart (§21.2.2.4)
1176  - areaChart (§21.2.2.5)
1177  - bar3DChart (§21.2.2.15)
1178  - barChart (§21.2.2.16)
1179  - bubbleChart (§21.2.2.20)
1180  - doughnutChart (§21.2.2.50)
1181  - line3DChart (§21.2.2.96)
1182  - lineChart (§21.2.2.97)
1183  - ofPieChart (§21.2.2.126)
1184  - pie3DChart (§21.2.2.140)
1185  - pieChart (§21.2.2.141)
1186  - radarChart (§21.2.2.153)
1187  - scatterChart (§21.2.2.161)
1188  - ser (§21.2.2.168)
1189  - ser (§21.2.2.170)
1190  - ser (§21.2.2.174)
1191  - ser (§21.2.2.171)
1192  - ser (§21.2.2.172)
1193  - ser (§21.2.2.169)
1194  - ser (§21.2.2.167)
1195  - stockChart (§21.2.2.198)
1196 
1197  Child elements:
1198   - delete (Delete) §21.2.2.40
1199   - [Done]dLbl (Data Label) §21.2.2.47
1200   - dLblPos (Data Label Position) §21.2.2.48
1201   - extLst (Chart Extensibility) §21.2.2.64
1202   - leaderLines (Leader Lines) §21.2.2.92
1203   - numFmt (Number Format) §21.2.2.121
1204   - separator (Separator) §21.2.2.166
1205   - showBubbleSize (Show Bubble Size) §21.2.2.178
1206   - showCatName (Show Category Name) §21.2.2.179
1207   - showLeaderLines (Show Leader Lines) §21.2.2.183
1208   - showLegendKey (Show Legend Key) §21.2.2.184
1209   - showPercent (Show Percent) §21.2.2.187
1210   - showSerName (Show Series Name) §21.2.2.188
1211   - [Done]showVal (Show Value) §21.2.2.189
1212   - spPr (Shape Properties) §21.2.2.197
1213   - txPr (Text Properties) §21.2.2.216
1214 
1215 */
1216 KoFilter::ConversionStatus XlsxXmlChartReader::read_dLbls()
1217 {
1218     READ_PROLOGUE
1219     while (!atEnd()) {
1220         readNext();
1221         BREAK_IF_END_OF(CURRENT_EL)
1222         if (isStartElement()) {
1223             TRY_READ_IF(dLbl)
1224             else if ( qualifiedName() == QLatin1String( QUALIFIED_NAME(numFmt) ) ) {
1225                 const QXmlStreamAttributes attrs(attributes());
1226                 m_currentSeries->m_numberFormat = attrs.value("formatCode").toString();
1227             }
1228             read_showDataLabel();
1229         }
1230     }
1231     READ_EPILOGUE
1232 }
1233 
1234 #undef CURRENT_EL
1235 #define CURRENT_EL spPr
1236 // Visual shape properties that can be applied to a shape.
1237 /*!
1238  * spPr Shape Properties
1239  * ECMA-376, 5.7.2.98, p.4108.
1240  * Parent Elements:
1241  *  - backWall( §5.7.2.11 )
1242  *  - bandFmt( §5.7.2.13 )
1243  *  - catAx( §5.7.2.25 )
1244  *  - chartspace( §5.7.2.29 )
1245  *  - dataAx( §5.7.2.39 )
1246  *  - dispUnitsLbl( §5.7.2.46 )
1247  *  - dLbl( §5.7.2.47 )
1248  *  - dLbls( §5.7.2.49 )
1249  *  - downBars( §5.7.2.51)
1250  *  - dPt( §5.7.2.52 )
1251  * ...
1252  *
1253  * Child elements:
1254  *  - blipFill( Picture Fill ) §5.1.10.14
1255  *  - customGeom( Custom Geometry ) §5.1.11.8
1256  *  - effectDag( Effect Container ) §5.1.10.25
1257  *  - effectLst( Effect Container ) §5.1.10.26
1258  *  - gradFill ( Gradient Fill ) §5.1.10.33
1259  *  - gradFill ( Group Fill ) §5.1.10.35
1260  *  - ln ( Outline ) §5.1.2.1.24
1261  *  - noFill( No Fill ) §5.1.10.44
1262  *  - pattFill( Pattern Fill ) §5.1.10.47
1263  *  - prstGeom( Preset geometry ) §5.1.11.18
1264  *  - scene3d ( 3D Scene Properties ) §5.1.4.1.26
1265  *  - solidFill( Solid Fill ) §5.1.10.54
1266  *  - sp3d ( Apply 3D shape properties ) §5.1.7.12
1267  *  - xrfm( 2D Transform for Individual Objects ) § 5.1.9.6
1268  *
1269  *  attributes:
1270  *  - bwMode ( Black and White Mode ) §5.1.12.10
1271  */
1272 KoFilter::ConversionStatus XlsxXmlChartReader::read_spPr()
1273 {
1274     enum State { Start, NoFill, InFill };
1275     State state = Start;
1276     READ_PROLOGUE
1277     int level = 0;
1278     bool readingGradient = false;
1279     bool readingGradientStop = false;
1280     KoChart::Gradient* gradient = nullptr;
1281     KoChart::Gradient::GradientStop currentStop;
1282     while (!atEnd()) {
1283         readNext();
1284         BREAK_IF_END_OF(CURRENT_EL)
1285         if ( !m_currentShapeProperties )
1286             continue;
1287         if(isStartElement()) ++level;
1288         else if(isEndElement()) --level;
1289 
1290         if (qualifiedName() == "a:solidFill" || qualifiedName() == "a:pattFill" || qualifiedName() == "a:gradFill") {
1291             if (level == 1)
1292                 state = isStartElement() ? InFill : Start;
1293         } else if (qualifiedName() == "a:noFill") {
1294             m_currentShapeProperties->lineFill.setType( KoChart::Fill::None );
1295             if (level == 1)
1296                 state = isStartElement() ? NoFill : Start;
1297         } else if ((state == NoFill || state == InFill) && qualifiedName() == "a:srgbClr") {
1298             const QXmlStreamAttributes attrs(attributes());
1299             TRY_READ_ATTR_WITHOUT_NS(val)
1300             if(!val.isEmpty() && !m_context->m_chart->m_areaFormat) {
1301                 if(!val.startsWith('#')) val.prepend('#');
1302                     if ( readingGradientStop ) {
1303                         currentStop.knownColorValue = QColor( val );
1304                     } else {
1305                         KoChart::AreaFormat *areaFormat = new KoChart::AreaFormat(QColor(val), QColor(), state == InFill);
1306                         if ( m_areaContext == ChartArea )
1307                             m_context->m_chart->m_areaFormat = areaFormat;
1308                         else
1309                             m_context->m_chart->m_plotArea->m_areaFormat = areaFormat;
1310                     }
1311             }
1312             state = Start; // job done
1313         } else if ( qualifiedName() == "a:srgbClr" ) {
1314             if ( isStartElement() ) {
1315                 const QXmlStreamAttributes attrs(attributes());
1316                 TRY_READ_ATTR_WITHOUT_NS(val)
1317                 if(!val.isEmpty() && !m_context->m_chart->m_areaFormat) {
1318                     if(!val.startsWith('#')) val.prepend('#');
1319                     if ( readingGradientStop ) {
1320                         currentStop.knownColorValue = QColor( val );
1321                     } else {
1322                         KoChart::AreaFormat *areaFormat = new KoChart::AreaFormat(QColor(val), QColor(), state == InFill);
1323                         if ( m_areaContext == ChartArea ) {
1324                             m_context->m_chart->m_areaFormat = areaFormat;
1325                         } else {
1326                             m_context->m_chart->m_plotArea->m_areaFormat = areaFormat;
1327                         }
1328                     }
1329                 }
1330             }
1331         } else if ( qualifiedName() == "a:alpha" ) {
1332             const QXmlStreamAttributes attrs(attributes());
1333             TRY_READ_ATTR_WITHOUT_NS(val)
1334             if ( !val.isEmpty() ) {
1335                 if ( readingGradientStop ) {
1336                     currentStop.knownColorValue.setAlphaF( val.toDouble() / 100000.0 );
1337                 } else {
1338                     if ( m_areaContext == ChartArea ) {
1339                         if ( m_context->m_chart->m_areaFormat )
1340                             m_context->m_chart->m_areaFormat->m_foreground.setAlphaF( val.toDouble() / 100000.0 );
1341                     } else {
1342                         if ( m_context->m_chart->m_plotArea->m_areaFormat )
1343                             m_context->m_chart->m_plotArea->m_areaFormat->m_foreground.setAlphaF( val.toDouble() / 100000.0 );
1344                     }
1345                 }
1346             }
1347         } else if ( qualifiedName() == "a:gsLst" ) {
1348             if ( isStartElement() ) {
1349                 readingGradient = true;
1350                 gradient =  new KoChart::Gradient;
1351             } else if ( isEndElement() ) {
1352                 readingGradient = false;
1353                 switch ( m_areaContext ) {
1354                     case( PlotArea ):
1355                       m_context->m_chart->m_plotAreaFillGradient = gradient;
1356                       break;
1357                     case( ChartArea ):
1358                       m_context->m_chart->m_fillGradient = gradient;
1359                       break;
1360                 }
1361                 gradient = nullptr;
1362             }
1363         } else if ( qualifiedName() == "a:gs" && readingGradient ) {
1364             if ( isStartElement() ) {
1365                 readingGradientStop = true;
1366                 const QXmlStreamAttributes attrs(attributes());
1367                 TRY_READ_ATTR_WITHOUT_NS(pos)
1368                 if ( !pos.isEmpty() )
1369                     currentStop.position = pos.toDouble() / 1000.0;
1370 
1371             } else if ( isEndElement() ) {
1372                 // append the current gradient stop
1373                 gradient->gradientStops.append( currentStop );
1374                 readingGradientStop = false;
1375                 currentStop.reset();
1376             }
1377         } else if ( qualifiedName() == "a:schemeClr" && readingGradientStop ) {
1378             if ( isStartElement() ) {
1379                 const QXmlStreamAttributes attrs(attributes());
1380                 TRY_READ_ATTR_WITHOUT_NS(val)
1381                 if ( !val.isEmpty() )
1382                     currentStop.referenceColor = val;
1383             } else if ( isEndElement() ) {
1384             }
1385         } else if ( qualifiedName() == "a:tint" && readingGradientStop ) {
1386             const QXmlStreamAttributes attrs(attributes());
1387                 TRY_READ_ATTR_WITHOUT_NS(val)
1388                 if ( !val.isEmpty() )
1389                     currentStop.tintVal = val.toDouble() / 1000.0;
1390         } else if ( qualifiedName() == "a:satMod" && readingGradientStop ) {
1391             const QXmlStreamAttributes attrs(attributes());
1392             TRY_READ_ATTR_WITHOUT_NS(val)
1393             if ( !val.isEmpty() )
1394                 currentStop.satVal = val.toDouble() / 1000.0;
1395         } else if ( qualifiedName() == "a:lin" && readingGradient ) {
1396             const QXmlStreamAttributes attrs(attributes());
1397             TRY_READ_ATTR_WITHOUT_NS(ang)
1398             if ( !ang.isEmpty() )
1399                 gradient->angle = ang.toDouble() / 60000.0;
1400         } else if ( qualifiedName() == "a:noFill" ) {
1401             m_currentShapeProperties->lineFill.setType( KoChart::Fill::None );
1402         }
1403     }
1404     READ_EPILOGUE
1405 }
1406 
1407 #undef CURRENT_EL
1408 #define CURRENT_EL pieChart
1409 //! pieChart (Pie Charts)
1410 /*! ECMA-376, 21.2.2.141, p.3826.
1411 
1412  Parent elements:
1413  - plotArea §21.2.2.145
1414 
1415  Child elements:
1416  - dLbls (Data Labels) §21.2.2.49
1417  - extLst (Chart Extensibility) §21.2.2.64
1418  - [Done]firstSliceAng (First Slice Angle) §21.2.2.68
1419  - [Done] ser (Pie Chart Series) §21.2.2.172
1420  - varyColors (Vary Colors by Point) §21.2.2.227
1421 */
1422 KoFilter::ConversionStatus XlsxXmlChartReader::read_pieChart()
1423 {
1424     if(!m_context->m_chart->m_impl) {
1425         m_context->m_chart->m_impl = new KoChart::PieImpl();
1426     }
1427 
1428     while (!atEnd()) {
1429         readNext();
1430         BREAK_IF_END_OF(CURRENT_EL)
1431         if (isStartElement()) {
1432             if (QUALIFIED_NAME_IS(ser)) {
1433                 TRY_READ(pieChart_Ser)
1434             }
1435             ELSE_TRY_READ_IF(firstSliceAng)
1436         }
1437     }
1438 
1439     qDeleteAll(d->m_seriesData);
1440     d->m_seriesData.clear();
1441 
1442     return KoFilter::OK;
1443 }
1444 
1445 #undef CURRENT_EL
1446 #define CURRENT_EL pie3DChart
1447 //! pie3DChart (3D Pie Charts)
1448 /*! ECMA-376, 21.2.2.140, p.3826.
1449 
1450  Parent elements:
1451  - plotArea §21.2.2.145
1452 
1453  Child elements:
1454  - dLbls (Data Labels) §21.2.2.49
1455  - extLst (Chart Extensibility) §21.2.2.64
1456  - [Done] ser (Pie Chart Series) §21.2.2.172
1457  - varyColors (Vary Colors by Point) §21.2.2.227
1458 */
1459 KoFilter::ConversionStatus XlsxXmlChartReader::read_pie3DChart()
1460 {
1461     if(!m_context->m_chart->m_impl) {
1462         m_context->m_chart->m_impl = new KoChart::PieImpl();
1463         m_context->m_chart->m_is3d = true;
1464     }
1465 
1466     while (!atEnd()) {
1467         readNext();
1468         BREAK_IF_END_OF(CURRENT_EL)
1469         if (isStartElement()) {
1470             if (QUALIFIED_NAME_IS(ser)) {
1471                 TRY_READ(pieChart_Ser)
1472             }
1473         }
1474     }
1475 
1476 //    // if there is only one c:ser, then c:tx can be chart title
1477 //    if ((m_context->m_chart->m_title == "Chart Title") && (d->m_seriesData.size() == 1)) {
1478 //        PieSeries * tempPieSeriesData = (PieSeries *)d->m_seriesData[0];
1479 //        if (tempPieSeriesData->m_tx.m_strRef.m_strCache.m_cache.size() == 1) {
1480 //            m_context->m_chart->m_title =  tempPieSeriesData->m_tx.m_strRef.m_strCache.m_cache[0];
1481 //        }
1482 //    }
1483 
1484     qDeleteAll(d->m_seriesData);
1485     d->m_seriesData.clear();
1486 
1487     return KoFilter::OK;
1488 }
1489 
1490 #undef CURRENT_EL
1491 #define CURRENT_EL ofPieChart
1492 //! ofPieChart (Pie of Pie or Bar of Pie Charts)
1493 /*! ECMA-376, §21.2.2.126, p.4057.
1494 
1495  Parent elements:
1496  - plotArea §21.2.2.145
1497 
1498  Child elements:
1499  - custSplit (Custom Split) §5.7.2.35
1500  - dLbls (Data Labels) §5.7.2.49
1501  - extLst (Chart Extensibility) §5.7.2.64
1502  - gapWidth (Gap Width) §5.7.2.75
1503  - ofPieType (Pie of Pie or Bar of Pie Type) §5.7.2.128
1504  - secondPieSize (Second Pie Size) §5.7.2.165
1505  - ser (Pie Chart Series) §5.7.2.170
1506  - serLines (Series Lines) §5.7.2.177
1507  - splitPos (Split Position) §5.7.2.196
1508  - splitType (Split Type) §5.7.2.197
1509  - varyColors (Vary Colors by Point) §5.7.2.228
1510 */
1511 KoFilter::ConversionStatus XlsxXmlChartReader::read_ofPieChart()
1512 {
1513     // KDChart used in the charting-plugin doesn't support pie-of-pie or bar-of-pie
1514     // charts nor does ODF. So, we do the same OO.org is doing and just translate
1515     // it to pie-chart what is better then nothing.
1516     if(!m_context->m_chart->m_impl) {
1517         m_context->m_chart->m_impl = new KoChart::PieImpl();
1518     }
1519     while (!atEnd()) {
1520         readNext();
1521         BREAK_IF_END_OF(CURRENT_EL)
1522         if (isStartElement()) {
1523             if (QUALIFIED_NAME_IS(ser)) {
1524                 TRY_READ(pieChart_Ser)
1525             }
1526         }
1527     }
1528     qDeleteAll(d->m_seriesData);
1529     d->m_seriesData.clear();
1530     return KoFilter::OK;
1531 }
1532 
1533 #undef CURRENT_EL
1534 #define CURRENT_EL doughnutChart
1535 //! doughnutChart (Doughnut Charts)
1536 /*! ECMA-376, 21.2.2.50, p.3782.
1537 
1538  Parent elements:
1539  - plotArea §21.2.2.145
1540 
1541  Child elements:
1542  - dLbls (Data Labels) §21.2.2.49
1543  - extLst (Chart Extensibility) §21.2.2.64
1544  - firstSliceAng (First Slice Angle) §21.2.2.68
1545  - [Done]holeSize (Hole Size) §21.2.2.82
1546  - [Done]ser (Pie Chart Series) §21.2.2.172
1547  - varyColors (Vary Colors by Point) §21.2.2.227
1548 */
1549 KoFilter::ConversionStatus XlsxXmlChartReader::read_doughnutChart()
1550 {
1551     if(!m_context->m_chart->m_impl) {
1552         m_context->m_chart->m_impl = new KoChart::RingImpl();
1553     }
1554 
1555     while (!atEnd()) {
1556         readNext();
1557         BREAK_IF_END_OF(CURRENT_EL)
1558         if (isStartElement()) {
1559             if (QUALIFIED_NAME_IS(ser)) {
1560                 TRY_READ(pieChart_Ser)
1561             }
1562             ELSE_TRY_READ_IF(holeSize)
1563         }
1564     }
1565 
1566     qDeleteAll(d->m_seriesData);
1567     d->m_seriesData.clear();
1568 
1569     return KoFilter::OK;
1570 }
1571 
1572 #undef CURRENT_EL
1573 #define CURRENT_EL areaChart
1574 //! areaChart (Area Charts)
1575 /*! ECMA-376, 21.2.2.5, p.3757.
1576 
1577  Parent elements:
1578  - plotArea §21.2.2.145
1579 
1580  Child elements:
1581  - axId (Axis ID) §21.2.2.9
1582  - dLbls (Data Labels) §21.2.2.49
1583  - dropLines (Drop Lines) §21.2.2.53
1584  - extLst (Chart Extensibility) §21.2.2.64
1585  - [done] grouping (Grouping) §21.2.2.76
1586  - [Done] ser (Area Chart Series) §21.2.2.168
1587  - varyColors (Vary Colors by Point) §21.2.2.227
1588 */
1589 KoFilter::ConversionStatus XlsxXmlChartReader::read_areaChart()
1590 {
1591     if(!m_context->m_chart->m_impl) {
1592         m_context->m_chart->m_impl = new KoChart::AreaImpl();
1593     }
1594 
1595     while (!atEnd()) {
1596         readNext();
1597         BREAK_IF_END_OF(CURRENT_EL)
1598         if (isStartElement()) {
1599             if (QUALIFIED_NAME_IS(ser)) {
1600                 TRY_READ(areaChart_Ser)
1601             }
1602             ELSE_TRY_READ_IF(grouping)
1603         }
1604     }
1605 
1606     qDeleteAll(d->m_seriesData);
1607     d->m_seriesData.clear();
1608 
1609     return KoFilter::OK;
1610 }
1611 
1612 #undef CURRENT_EL
1613 #define CURRENT_EL area3DChart
1614 //! area3DChart (3D Area Charts)
1615 /*! ECMA-376, 21.2.2.4, p.3757.
1616 
1617  Parent elements:
1618  - plotArea §21.2.2.145
1619 
1620  Child elements:
1621  - axId (Axis ID) §21.2.2.9
1622  - dLbls (Data Labels) §21.2.2.49
1623  - dropLines (Drop Lines) §21.2.2.53
1624  - extLst (Chart Extensibility) §21.2.2.64
1625  - gapDepth (Gap Depth) §21.2.2.74
1626  - [done] grouping (Grouping) §21.2.2.76
1627  - [Done] ser (Area Chart Series) §21.2.2.168
1628  - varyColors (Vary Colors by Point) §21.2.2.227
1629 */
1630 KoFilter::ConversionStatus XlsxXmlChartReader::read_area3DChart()
1631 {
1632     if(!m_context->m_chart->m_impl) {
1633         m_context->m_chart->m_impl = new KoChart::AreaImpl();
1634         m_context->m_chart->m_is3d = true;
1635     }
1636 
1637     while (!atEnd()) {
1638         readNext();
1639         BREAK_IF_END_OF(CURRENT_EL)
1640         if (isStartElement()) {
1641             if (QUALIFIED_NAME_IS(ser)) {
1642                 TRY_READ(areaChart_Ser)
1643             }
1644             ELSE_TRY_READ_IF(grouping)
1645         }
1646     }
1647 
1648     qDeleteAll(d->m_seriesData);
1649     d->m_seriesData.clear();
1650 
1651     return KoFilter::OK;
1652 }
1653 
1654 #undef CURRENT_EL
1655 #define CURRENT_EL barChart
1656 //! barChart (Bar Charts)
1657 /*! ECMA-376, 21.2.2.16, p.3863.
1658 
1659  Parent elements:
1660  - plotArea §21.2.2.145
1661 
1662  Child elements:
1663  - axId (Axis ID) §21.2.2.9
1664  - [Done]barDir (Bar Direction) §21.2.2.17
1665  - dLbls (Data Labels) §21.2.2.49
1666  - extLst (Chart Extensibility) §21.2.2.64
1667  - gapWidth (Gap Width) §21.2.2.75
1668  - [Done]grouping (Bar Grouping) §21.2.2.77
1669  - overlap (Overlap) §21.2.2.131
1670  - [Done]ser (Bar Chart Series) §21.2.2.170
1671  - serLines (Series Lines) §21.2.2.176
1672  - varyColors (Vary Colors by Point) §21.2.2.227
1673 */
1674 KoFilter::ConversionStatus XlsxXmlChartReader::read_barChart()
1675 {
1676     if(!m_context->m_chart->m_impl) {
1677         m_context->m_chart->m_impl = new KoChart::BarImpl();
1678     }
1679 
1680     while (!atEnd()) {
1681         readNext();
1682         BREAK_IF_END_OF(CURRENT_EL)
1683         if (isStartElement()) {
1684             if (QUALIFIED_NAME_IS(ser)) {
1685                 TRY_READ(barChart_Ser)
1686             }
1687             ELSE_TRY_READ_IF(barDir)
1688             ELSE_TRY_READ_IF(grouping)
1689         }
1690     }
1691 
1692     qDeleteAll(d->m_seriesData);
1693     d->m_seriesData.clear();
1694 
1695     return KoFilter::OK;
1696 }
1697 
1698 #undef CURRENT_EL
1699 #define CURRENT_EL bar3DChart
1700 //! bar3DChart (3D Bar Charts)
1701 /*! ECMA-376, 21.2.2.15, p.3862.
1702 
1703  Parent elements:
1704  - plotArea §21.2.2.145
1705 
1706  Child elements:
1707  - axId (Axis ID) §21.2.2.9
1708  - [done]barDir (Bar Direction) §21.2.2.17
1709  - dLbls (Data Labels) §21.2.2.49
1710  - extLst (Chart Extensibility) §21.2.2.64
1711  - gapDepth (Gap Depth) §21.2.2.74
1712  - gapWidth (Gap Width) §21.2.2.75
1713  - [Done]grouping (Bar Grouping) §21.2.2.77
1714  - [Done]ser (Bar Chart Series) §21.2.2.170
1715  - shape (Shape) §21.2.2.177
1716  - varyColors (Vary Colors by Point) §21.2.2.227
1717 */
1718 KoFilter::ConversionStatus XlsxXmlChartReader::read_bar3DChart()
1719 {
1720     if(!m_context->m_chart->m_impl) {
1721         m_context->m_chart->m_impl = new KoChart::BarImpl();
1722         m_context->m_chart->m_is3d = true;
1723     }
1724 
1725     while (!atEnd()) {
1726         readNext();
1727         BREAK_IF_END_OF(CURRENT_EL)
1728         if (isStartElement()) {
1729             if (QUALIFIED_NAME_IS(ser)) {
1730                 TRY_READ(barChart_Ser)
1731             }
1732             ELSE_TRY_READ_IF(barDir)
1733             ELSE_TRY_READ_IF(grouping)
1734         }
1735     }
1736 
1737     qDeleteAll(d->m_seriesData);
1738     d->m_seriesData.clear();
1739 
1740     return KoFilter::OK;
1741 }
1742 
1743 #undef CURRENT_EL
1744 #define CURRENT_EL lineChart
1745 //! lineChart (Line Charts)
1746 /*! ECMA-376, 21.2.2.97, p.3804.
1747 
1748  Parent elements:
1749  - plotArea §21.2.2.145
1750 
1751  Child elements:
1752  - axId (Axis ID) §21.2.2.9
1753  - dLbls (Data Labels) §21.2.2.49
1754  - dropLines (Drop Lines) §21.2.2.53
1755  - extLst (Chart Extensibility) §21.2.2.64
1756  - [Done]grouping (Grouping) §21.2.2.76
1757  - hiLowLines (High Low Lines) §21.2.2.80
1758  - marker (Show Marker) §21.2.2.105
1759  - [Done]ser (Line Chart Series) §21.2.2.171
1760  - smooth (Smoothing) §21.2.2.194
1761  - upDownBars (Up/Down Bars) §21.2.2.218
1762  - varyColors (Vary Colors by Point) §21.2.2.227
1763 */
1764 KoFilter::ConversionStatus XlsxXmlChartReader::read_lineChart()
1765 {
1766     if(!m_context->m_chart->m_impl) {
1767         m_context->m_chart->m_impl = new KoChart::LineImpl();
1768     }
1769 
1770     while (!atEnd()) {
1771         readNext();
1772         BREAK_IF_END_OF(CURRENT_EL)
1773         if (isStartElement()) {
1774             if (QUALIFIED_NAME_IS(ser)) {
1775                 TRY_READ(lineChart_Ser)
1776             }
1777             ELSE_TRY_READ_IF(grouping)
1778             ELSE_TRY_READ_IF(marker)
1779         }
1780     }
1781 
1782     qDeleteAll(d->m_seriesData);
1783     d->m_seriesData.clear();
1784 
1785     return KoFilter::OK;
1786 }
1787 
1788 #undef CURRENT_EL
1789 #define CURRENT_EL line3DChart
1790 //! line3DChart (3D Line Charts)
1791 /*! ECMA-376, 21.2.2.96, p.3803.
1792 
1793  Parent elements:
1794  - plotArea §21.2.2.145
1795 
1796  Child elements:
1797  - axId (Axis ID) §21.2.2.9
1798  - dLbls (Data Labels) §21.2.2.49
1799  - dropLines (Drop Lines) §21.2.2.53
1800  - extLst (Chart Extensibility) §21.2.2.64
1801  - gapDepth (Gap Depth) §21.2.2.74
1802  - [Done]grouping (Grouping) §21.2.2.76
1803  - [Done]ser (Line Chart Series) §21.2.2.171
1804  - varyColors (Vary Colors by Point) §21.2.2.227
1805 */
1806 KoFilter::ConversionStatus XlsxXmlChartReader::read_line3DChart()
1807 {
1808     if(!m_context->m_chart->m_impl) {
1809         m_context->m_chart->m_impl = new KoChart::LineImpl();
1810         m_context->m_chart->m_is3d = true;
1811     }
1812 
1813     while (!atEnd()) {
1814         readNext();
1815         BREAK_IF_END_OF(CURRENT_EL)
1816         if (isStartElement()) {
1817             if (QUALIFIED_NAME_IS(ser)) {
1818                 TRY_READ(lineChart_Ser)
1819             }
1820             ELSE_TRY_READ_IF(grouping)
1821         }
1822     }
1823 
1824     qDeleteAll(d->m_seriesData);
1825     d->m_seriesData.clear();
1826 
1827     return KoFilter::OK;
1828 }
1829 
1830 #undef CURRENT_EL
1831 #define CURRENT_EL scatterChart
1832 //! scatterChart (Scatter Charts)
1833 /*! ECMA-376, 21.2.2.161, p.3836.
1834 
1835  Parent elements:
1836  - plotArea §21.2.2.145
1837 
1838  Child elements:
1839  - axId (Axis ID) §21.2.2.9
1840  - dLbls (Data Labels) §21.2.2.49
1841  - extLst (Chart Extensibility) §21.2.2.64
1842  - scatterStyle (Scatter Style) §21.2.2.162
1843  - [Done]ser (Scatter Chart Series) §21.2.2.167
1844  - varyColors (Vary Colors by Point) §21.2.2.227
1845 */
1846 KoFilter::ConversionStatus XlsxXmlChartReader::read_scatterChart()
1847 {
1848     KoChart::ScatterImpl* impl = dynamic_cast<KoChart::ScatterImpl*>(m_context->m_chart->m_impl);
1849     if (!impl) {
1850         m_context->m_chart->m_impl = impl = new KoChart::ScatterImpl();
1851     }
1852 
1853     while (!atEnd()) {
1854         readNext();
1855         BREAK_IF_END_OF(CURRENT_EL)
1856         if (isStartElement()) {
1857             if (QUALIFIED_NAME_IS(ser)) {
1858                 TRY_READ(scatterChart_Ser)
1859             }
1860             else if (QUALIFIED_NAME_IS(scatterStyle))
1861             {
1862                 const QXmlStreamAttributes attrs(attributes());
1863                 TRY_READ_ATTR_WITHOUT_NS(val);
1864                 if ( val == "none" )
1865                     impl->style = KoChart::ScatterImpl::None;
1866                 else if ( val == "line" )
1867                     impl->style = KoChart::ScatterImpl::Line;
1868                 else if ( val == "lineMarker" )
1869                     impl->style = KoChart::ScatterImpl::LineMarker;
1870                 else if ( val == "marker" )
1871                     impl->style = KoChart::ScatterImpl::Marker;
1872                 else if ( val == "smooth" )
1873                     impl->style = KoChart::ScatterImpl::Smooth;
1874                 else if ( val == "smoothMarker" )
1875                     impl->style = KoChart::ScatterImpl::SmoothMarker;
1876             }
1877         }
1878     }
1879 
1880     qDeleteAll(d->m_seriesData);
1881     d->m_seriesData.clear();
1882 
1883     return KoFilter::OK;
1884 }
1885 
1886 #undef CURRENT_EL
1887 #define CURRENT_EL radarChart
1888 //! radarChart (Radar Charts)
1889 /*! ECMA-376, 21.2.2.153, p.3832.
1890 
1891  Parent elements:
1892  - plotArea §21.2.2.145
1893 
1894  Child elements:
1895  - axId (Axis ID) §21.2.2.9
1896  - dLbls (Data Labels) §21.2.2.49
1897  - extLst (Chart Extensibility) §21.2.2.64
1898  - radarStyle (Radar Style) §21.2.2.154
1899  - [Done]ser (Radar Chart Series) §21.2.2.169
1900  - varyColors (Vary Colors by Point) §21.2.2.227
1901 */
1902 KoFilter::ConversionStatus XlsxXmlChartReader::read_radarChart()
1903 {
1904     KoChart::RadarImpl* impl = dynamic_cast<KoChart::RadarImpl*>(m_context->m_chart->m_impl);
1905     if (!impl) {
1906         m_context->m_chart->m_impl = impl = new KoChart::RadarImpl(false);
1907     }
1908 
1909     while (!atEnd()) {
1910         readNext();
1911         BREAK_IF_END_OF(CURRENT_EL)
1912         if (isStartElement()) {
1913             if (QUALIFIED_NAME_IS(radarStyle)) {
1914                 const QXmlStreamAttributes attrs(attributes());
1915                 TRY_READ_ATTR_WITHOUT_NS(val)
1916                 if (val == "filled")
1917                     impl->m_filled = true;
1918             }
1919             else if (QUALIFIED_NAME_IS(ser)) {
1920                 TRY_READ(radarChart_Ser)
1921             }
1922         }
1923     }
1924 
1925     qDeleteAll(d->m_seriesData);
1926     d->m_seriesData.clear();
1927 
1928     return KoFilter::OK;
1929 }
1930 
1931 #undef CURRENT_EL
1932 #define CURRENT_EL surfaceChart
1933 //! surface3DChart (3D Surface Charts)
1934 /*! ECMA-376, 21.2.2.203, p.3858.
1935 
1936  Parent elements:
1937  - plotArea §21.2.2.145
1938 
1939  Child elements:
1940  - axId (Axis ID) §21.2.2.9
1941  - bandFmts (Band Formats) §21.2.2.14
1942  - extLst (Chart Extensibility) §21.2.2.64
1943  - [Done]ser (Surface Chart Series) §21.2.2.173
1944  - wireframe (Wireframe) §21.2.2.230
1945 */
1946 KoFilter::ConversionStatus XlsxXmlChartReader::read_surfaceChart()
1947 {
1948     if(!m_context->m_chart->m_impl) {
1949         m_context->m_chart->m_impl = new KoChart::SurfaceImpl();
1950     }
1951 
1952     while (!atEnd()) {
1953         readNext();
1954         BREAK_IF_END_OF(CURRENT_EL)
1955         if (isStartElement()) {
1956             if (QUALIFIED_NAME_IS(ser)) {
1957                 TRY_READ(surfaceChart_Ser)
1958             }
1959         }
1960     }
1961 
1962     qDeleteAll(d->m_seriesData);
1963     d->m_seriesData.clear();
1964 
1965     return KoFilter::OK;
1966 }
1967 
1968 #undef CURRENT_EL
1969 #define CURRENT_EL surface3DChart
1970 //! surfaceChart (Surface Charts)
1971 /*! ECMA-376, 21.2.2.204, p.3858.
1972 
1973  Parent elements:
1974  - plotArea §21.2.2.145
1975 
1976  Child elements:
1977  - axId (Axis ID) §21.2.2.9
1978  - bandFmts (Band Formats) §21.2.2.14
1979  - extLst (Chart Extensibility) §21.2.2.64
1980  - ser (Surface Chart Series) §21.2.2.173
1981  - wireframe (Wireframe) §21.2.2.230
1982 */
1983 KoFilter::ConversionStatus XlsxXmlChartReader::read_surface3DChart()
1984 {
1985     if(!m_context->m_chart->m_impl) {
1986         m_context->m_chart->m_impl = new KoChart::SurfaceImpl();
1987         m_context->m_chart->m_is3d = true;
1988     }
1989 
1990     while (!atEnd()) {
1991         readNext();
1992         BREAK_IF_END_OF(CURRENT_EL)
1993         if (isStartElement()) {
1994             if (QUALIFIED_NAME_IS(ser)) {
1995                 TRY_READ(surfaceChart_Ser)
1996             }
1997         }
1998     }
1999 
2000     qDeleteAll(d->m_seriesData);
2001     d->m_seriesData.clear();
2002 
2003     return KoFilter::OK;
2004 }
2005 
2006 #undef CURRENT_EL
2007 #define CURRENT_EL bubbleChart
2008 //! bubbleChart (Bubble Charts)
2009 /*! ECMA-376, 21.2.2.20, p.3765.
2010 
2011  Parent elements:
2012  - plotArea §21.2.2.145
2013 
2014  Child elements:
2015  - axId (Axis ID) §21.2.2.9
2016  - [Done]bubble3D (3D Bubble) §21.2.2.19
2017  - [Done]bubbleScale (Bubble Scale) §21.2.2.21
2018  - dLbls (Data Labels) §21.2.2.49
2019  - extLst (Chart Extensibility) §21.2.2.64
2020  - [Done]ser (Bubble Chart Series) §21.2.2.174
2021  - showNegBubbles (Show Negative Bubbles) §21.2.2.185
2022  - sizeRepresents (Size Represents) §21.2.2.193
2023  - varyColors (Vary Colors by Point) §21.2.2.227
2024 */
2025 KoFilter::ConversionStatus XlsxXmlChartReader::read_bubbleChart()
2026 {
2027     if(!m_context->m_chart->m_impl) {
2028         m_context->m_chart->m_impl = new KoChart::BubbleImpl();
2029         m_context->m_chart->m_is3d = true;
2030     }
2031 
2032     while (!atEnd()) {
2033         readNext();
2034         BREAK_IF_END_OF(CURRENT_EL)
2035         if (isStartElement()) {
2036             if (QUALIFIED_NAME_IS(ser)) {
2037                 TRY_READ(bubbleChart_Ser)
2038             }
2039             ELSE_TRY_READ_IF(bubbleScale)
2040             ELSE_TRY_READ_IF(bubble3D)
2041         }
2042     }
2043 
2044     // check if there are some c:strLit or c:numLit data and if yes then write them into internalTable
2045 //    for (int i=0; i<d->m_seriesData.size(); i++ ){
2046 //        QString range = ((BubbleSeries *)d->m_seriesData[i])->m_bubbleSize.writeLitToInternalTable(this);
2047 //        if (!range.isEmpty()) {
2048 //            m_context->m_chart->m_series[i]->m_domainValuesCellRangeAddress.push_back(range);
2049 //        }
2050 //    }
2051 
2052     qDeleteAll(d->m_seriesData);
2053     d->m_seriesData.clear();
2054 
2055     return KoFilter::OK;
2056 }
2057 
2058 #undef CURRENT_EL
2059 #define CURRENT_EL stockChart
2060 //! stockChart (Stock Charts)
2061 /*! ECMA-376, 21.2.2.199, p.3856.
2062 
2063  Parent elements:
2064  - plotArea §21.2.2.145
2065 
2066  Child elements:
2067  - axId (Axis ID) §21.2.2.9
2068  - dLbls (Data Labels) §21.2.2.49
2069  - dropLines (Drop Lines) §21.2.2.53
2070  - extLst (Chart Extensibility) §21.2.2.64
2071  - hiLowLines (High Low Lines) §21.2.2.80
2072  - [done]ser (Line Chart Series) §21.2.2.171
2073  - upDownBars (Up/Down Bars) §21.2.2.218
2074 */
2075 KoFilter::ConversionStatus XlsxXmlChartReader::read_stockChart()
2076 {
2077     if(!m_context->m_chart->m_impl) {
2078         m_context->m_chart->m_impl = new KoChart::StockImpl();
2079     }
2080 
2081     while (!atEnd()) {
2082         readNext();
2083         BREAK_IF_END_OF(CURRENT_EL)
2084         if (isStartElement()) {
2085             if (QUALIFIED_NAME_IS(ser)) {
2086                 TRY_READ(lineChart_Ser)
2087             }
2088         }
2089     }
2090 
2091     qDeleteAll(d->m_seriesData);
2092     d->m_seriesData.clear();
2093 
2094     return KoFilter::OK;
2095 }
2096 
2097 #undef CURRENT_EL
2098 #define CURRENT_EL ser
2099 //! ser (Pie Chart Series)
2100 /*! ECMA-376, 21.2.2.172, p.3842.
2101 
2102  Parent elements:
2103  - doughnutChart §21.2.2.50
2104  - ofPieChart §21.2.2.126
2105  - pie3DChart §21.2.2.140
2106  - pieChart §21.2.2.141
2107 
2108  Child elements:
2109  - cat (Category Axis Data) §21.2.2.24
2110  - [Done]dLbls (Data Labels) §21.2.2.49
2111  - dPt (Data Point) §21.2.2.52
2112  - explosion (Explosion) §21.2.2.61
2113  - extLst (Chart Extensibility) §21.2.2.64
2114  - [Done]idx (Index) §21.2.2.84
2115  - [Done] order (Order) §21.2.2.128
2116  - spPr (Shape Properties) §21.2.2.197
2117  - tx (Series Text) §21.2.2.215
2118  - val (Values) §21.2.2.224
2119 
2120 */
2121 
2122 KoFilter::ConversionStatus XlsxXmlChartReader::read_pieChart_Ser()
2123 {
2124     READ_PROLOGUE2(pieChart_Ser)
2125 
2126     m_currentSeries  = new KoChart::Series();
2127     m_context->m_chart->m_series << m_currentSeries;
2128 
2129     PieSeries * tempPieSeriesData = new PieSeries();
2130     d->m_seriesData << tempPieSeriesData;
2131 
2132     d->m_currentIdx = &tempPieSeriesData->m_idx;
2133     d->m_currentOrder = &tempPieSeriesData->m_order;
2134     d->m_currentTx = &tempPieSeriesData->m_tx;
2135     d->m_currentCat = &tempPieSeriesData->m_cat;
2136     d->m_currentVal = &tempPieSeriesData->m_val;
2137     d->m_currentExplosion = &tempPieSeriesData->m_explosion;
2138 
2139     while (!atEnd()) {
2140         readNext();
2141         BREAK_IF_END_OF(CURRENT_EL)
2142         if (isStartElement()) {
2143             TRY_READ_IF(order)
2144             ELSE_TRY_READ_IF(idx)
2145             if (QUALIFIED_NAME_IS(tx)) {
2146                 TRY_READ(seriesText_Tx)
2147             }
2148             ELSE_TRY_READ_IF(cat)
2149             ELSE_TRY_READ_IF(val)
2150             ELSE_TRY_READ_IF(explosion)
2151             ELSE_TRY_READ_IF(dLbls)
2152         }
2153     }
2154 
2155     // set data ranges and write data to internal table
2156     m_currentSeries->m_countYValues = tempPieSeriesData->m_val.m_numRef.m_numCache.m_ptCount;
2157 
2158     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempPieSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2159         m_context->m_chart->m_title = tempPieSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2160 
2161     m_currentSeries->m_labelCell = tempPieSeriesData->m_tx.writeRefToInternalTable(this);
2162 
2163     m_currentSeries->m_valuesCellRangeAddress = tempPieSeriesData->m_val.writeRefToInternalTable(this);
2164 
2165     m_context->m_chart->m_verticalCellRangeAddress = tempPieSeriesData->m_cat.writeRefToInternalTable(this);
2166 
2167     // set explosion
2168     if (tempPieSeriesData->m_explosion != 0) {
2169         if(KoChart::PieImpl* pie = dynamic_cast<KoChart::PieImpl*>(m_context->m_chart->m_impl)) {
2170             Q_UNUSED(pie);
2171             m_currentSeries->m_datasetFormat << new KoChart::PieFormat(tempPieSeriesData->m_explosion);
2172         }
2173     }
2174 
2175     READ_EPILOGUE
2176 }
2177 
2178 #undef CURRENT_EL
2179 #define CURRENT_EL ser
2180 //! ser (Bubble Chart Series)
2181 /*! ECMA-376, 21.2.2.174, p.3843.
2182 
2183  Parent elements:
2184   - ser (Bubble Chart Series)
2185 
2186  Child elements:
2187  - [Done]bubble3D (3D Bubble) §21.2.2.19
2188  - [Done]bubbleSize (Bubble Size) §21.2.2.22
2189  - [Done]dLbls (Data Labels) §21.2.2.49
2190  - dPt (Data Point) §21.2.2.52
2191  - errBars (Error Bars) §21.2.2.55
2192  - extLst (Chart Extensibility) §21.2.2.64
2193  - [Done]idx (Index) §21.2.2.84
2194  - invertIfNegative (Invert if Negative) §21.2.2.86
2195  - [Done]order (Order) §21.2.2.128
2196  - spPr (Shape Properties) §21.2.2.197
2197  - trendline (Trendlines) §21.2.2.211
2198  - [Done]tx (Series Text) §21.2.2.215
2199  - [Done]xVal (X Values) §21.2.2.234
2200  - [Done]yVal (Y Values) §21.2.2.237
2201 
2202 */
2203 
2204 KoFilter::ConversionStatus XlsxXmlChartReader::read_bubbleChart_Ser()
2205 {
2206     READ_PROLOGUE2(bubbleChart_Ser)
2207 
2208     m_currentSeries  = new KoChart::Series();
2209     m_context->m_chart->m_series << m_currentSeries;
2210 
2211     BubbleSeries * tempBubbleSeriesData = new BubbleSeries();
2212     d->m_seriesData << tempBubbleSeriesData;
2213 
2214     d->m_currentIdx = &tempBubbleSeriesData->m_idx;
2215     d->m_currentOrder = &tempBubbleSeriesData->m_order;
2216     d->m_currentTx = &tempBubbleSeriesData->m_tx;
2217     d->m_currentXVal = &tempBubbleSeriesData->m_xVal;
2218     d->m_currentYVal = &tempBubbleSeriesData->m_yVal;
2219     d->m_currentBubbleSize = &tempBubbleSeriesData->m_bubbleSize;
2220 
2221     while (!atEnd()) {
2222         readNext();
2223         BREAK_IF_END_OF(CURRENT_EL)
2224         if (isStartElement()) {
2225             TRY_READ_IF(order)
2226             ELSE_TRY_READ_IF(idx)
2227             if (QUALIFIED_NAME_IS(tx)) {
2228                 TRY_READ(seriesText_Tx)
2229             }
2230             ELSE_TRY_READ_IF(xVal)
2231             ELSE_TRY_READ_IF(yVal)
2232             ELSE_TRY_READ_IF(bubbleSize)
2233             ELSE_TRY_READ_IF(dLbls)
2234             ELSE_TRY_READ_IF(bubble3D)
2235         }
2236     }
2237 
2238     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempBubbleSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2239         m_context->m_chart->m_title = tempBubbleSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2240 
2241     // set data ranges and write data to internal table    
2242     m_currentSeries->m_labelCell = tempBubbleSeriesData->m_tx.writeRefToInternalTable(this);
2243 
2244     m_currentSeries->m_countYValues = tempBubbleSeriesData->m_yVal.m_numRef.m_numCache.m_ptCount;
2245 
2246     m_currentSeries->m_domainValuesCellRangeAddress << tempBubbleSeriesData->m_yVal.writeRefToInternalTable(this);
2247 
2248     if ( tempBubbleSeriesData->m_bubbleSize.m_numRef.m_f.isEmpty() )
2249         m_currentSeries->m_valuesCellRangeAddress = tempBubbleSeriesData->m_bubbleSize.writeLitToInternalTable(this);
2250     else
2251         m_currentSeries->m_valuesCellRangeAddress = tempBubbleSeriesData->m_bubbleSize.writeRefToInternalTable(this);
2252 
2253 
2254 //    m_currentSeries->m_domainValuesCellRangeAddress.push_back(tempBubbleSeriesData->m_xVal.writeRefToInternalTable(this));
2255 //
2256 //    QString bubbleSizeRange = tempBubbleSeriesData->m_bubbleSize.writeRefToInternalTable(this);
2257 //    if (!bubbleSizeRange.isEmpty()) {
2258 //        m_currentSeries->m_domainValuesCellRangeAddress.push_back(tempBubbleSeriesData->m_bubbleSize.writeRefToInternalTable(this));
2259 //    }
2260 
2261     READ_EPILOGUE
2262 }
2263 
2264 #undef CURRENT_EL
2265 #define CURRENT_EL ser
2266 //! ser (Scatter Chart Series)
2267 /*! ECMA-376, 21.2.2.167, p.3838.
2268 
2269  Parent elements:
2270   - scatterChart (§21.2.2.161)
2271 
2272  Child elements:
2273  - [Done]dLbls (Data Labels) §21.2.2.49
2274  - dPt (Data Point) §21.2.2.52
2275  - errBars (Error Bars) §21.2.2.55
2276  - extLst (Chart Extensibility) §21.2.2.64
2277  - [done] idx (Index) §21.2.2.84
2278  - marker (Marker) §21.2.2.106
2279  - [Done] order (Order) §21.2.2.128
2280  - smooth (Smoothing) §21.2.2.194
2281  - spPr (Shape Properties) §21.2.2.197
2282  - trendline (Trendlines) §21.2.2.211
2283  - [Done] tx (Series Text) §21.2.2.215
2284  - [Done] xVal (X Values) §21.2.2.234
2285  - [Done] yVal (Y Values) §21.2.2.237
2286 */
2287 
2288 KoFilter::ConversionStatus XlsxXmlChartReader::read_scatterChart_Ser()
2289 {
2290     READ_PROLOGUE2(scatterChart_Ser)
2291 
2292     m_currentSeries  = new KoChart::Series();
2293     m_context->m_chart->m_series << m_currentSeries;
2294 
2295     ScatterSeries * tempScatterSeriesData = new ScatterSeries();
2296     d->m_seriesData << tempScatterSeriesData;
2297 
2298     d->m_currentIdx = &tempScatterSeriesData->m_idx;
2299     d->m_currentOrder = &tempScatterSeriesData->m_order;
2300     d->m_currentTx = &tempScatterSeriesData->m_tx;
2301     d->m_currentXVal = &tempScatterSeriesData->m_xVal;
2302     d->m_currentYVal = &tempScatterSeriesData->m_yVal;
2303 
2304     while (!atEnd()) {
2305         readNext();
2306         BREAK_IF_END_OF(CURRENT_EL)
2307         if (isStartElement()) {
2308             if (QUALIFIED_NAME_IS(spPr) )
2309             {
2310                 m_currentSeries->spPr = new KoChart::ShapeProperties;
2311                 m_currentShapeProperties  = m_currentSeries->spPr;
2312             }
2313             ELSE_TRY_READ_IF(order)
2314             ELSE_TRY_READ_IF(idx)
2315             if (QUALIFIED_NAME_IS(tx)) {
2316                 TRY_READ(seriesText_Tx)
2317             }
2318             ELSE_TRY_READ_IF(xVal)
2319             ELSE_TRY_READ_IF(yVal)
2320             ELSE_TRY_READ_IF(dLbls)
2321             ELSE_TRY_READ_IF(spPr)
2322 //            ELSE_TRY_READ_IF(spPr)
2323         }
2324     }
2325 
2326     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempScatterSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2327         m_context->m_chart->m_title = tempScatterSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2328 
2329     // set data ranges and write data to internal table
2330     m_currentSeries->m_labelCell = tempScatterSeriesData->m_tx.writeRefToInternalTable(this);
2331 
2332     m_currentSeries->m_countXValues = tempScatterSeriesData->m_xVal.m_numLit.m_ptCount;
2333     if (m_currentSeries->m_countXValues == 0 ) {
2334         m_currentSeries->m_countXValues = tempScatterSeriesData->m_xVal.m_strRef.m_strCache.m_ptCount;
2335         m_currentSeries->m_domainValuesCellRangeAddress << tempScatterSeriesData->m_xVal.writeRefToInternalTable(this);
2336     } else {
2337         m_currentSeries->m_domainValuesCellRangeAddress << tempScatterSeriesData->m_xVal.writeLitToInternalTable(this);
2338     }
2339 
2340     m_currentSeries->m_countYValues = tempScatterSeriesData->m_yVal.m_numRef.m_numCache.m_ptCount;
2341     m_currentSeries->m_valuesCellRangeAddress = tempScatterSeriesData->m_yVal.writeRefToInternalTable(this);
2342 
2343     //m_currentSeries->m_domainValuesCellRangeAddress.push_back(tempScatterSeriesData->m_xVal.writeRefToInternalTable(this));
2344 
2345     READ_EPILOGUE
2346 }
2347 
2348 #undef CURRENT_EL
2349 #define CURRENT_EL ser
2350 //! ser (Bar Chart Series)
2351 /*! ECMA-376, 21.2.2.167, p.3840.
2352 
2353  Parent elements:
2354   - bar3DChart (§21.2.2.15)
2355   - barChart (§21.2.2.16)
2356 
2357  Child elements:
2358   - [Done]cat (Category Axis Data) §21.2.2.24
2359   - [Done]dLbls (Data Labels) §21.2.2.49
2360   - dPt (Data Point) §21.2.2.52
2361   - errBars (Error Bars) §21.2.2.55
2362   - extLst (Chart Extensibility) §21.2.2.64
2363   - idx (Index) §21.2.2.84
2364   - invertIfNegative (Invert if Negative) §21.2.2.86
2365   - order (Order) §21.2.2.128
2366   - pictureOptions (Picture Options) §21.2.2.138
2367   - shape (Shape) §21.2.2.177
2368   - spPr (Shape Properties) §21.2.2.197
2369   - trendline (Trendlines) §21.2.2.211
2370   - [Done]tx (Series Text) §21.2.2.215
2371   - [Done]val (Values) §21.2.2.224
2372 */
2373 
2374 KoFilter::ConversionStatus XlsxXmlChartReader::read_barChart_Ser()
2375 {
2376     READ_PROLOGUE2(barChart_Ser)
2377 
2378     m_currentSeries  = new KoChart::Series();
2379     m_context->m_chart->m_series << m_currentSeries;
2380 
2381     BarSeries * tempBarSeriesData = new BarSeries();
2382     d->m_seriesData << tempBarSeriesData;
2383 
2384     d->m_currentIdx = &tempBarSeriesData->m_idx;
2385     d->m_currentOrder = &tempBarSeriesData->m_order;
2386     d->m_currentTx = &tempBarSeriesData->m_tx;
2387     d->m_currentCat = &tempBarSeriesData->m_cat;
2388     d->m_currentVal = &tempBarSeriesData->m_val;
2389 
2390     while (!atEnd()) {
2391         readNext();
2392         BREAK_IF_END_OF(CURRENT_EL)
2393         if (isStartElement()) {
2394             TRY_READ_IF(order)
2395             ELSE_TRY_READ_IF(idx)
2396             else if (QUALIFIED_NAME_IS(tx)) {
2397                 TRY_READ(seriesText_Tx)
2398             }
2399             ELSE_TRY_READ_IF(cat)
2400             ELSE_TRY_READ_IF(val)
2401             ELSE_TRY_READ_IF(dLbls)
2402         }
2403     }
2404     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempBarSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2405         m_context->m_chart->m_title = tempBarSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2406 
2407     // set data ranges and write data to internal table
2408     m_currentSeries->m_countYValues = tempBarSeriesData->m_val.m_numRef.m_numCache.m_ptCount;
2409 
2410     m_currentSeries->m_labelCell = tempBarSeriesData->m_tx.writeRefToInternalTable(this);
2411 
2412     m_currentSeries->m_valuesCellRangeAddress = tempBarSeriesData->m_val.writeRefToInternalTable(this);
2413 
2414     m_context->m_chart->m_verticalCellRangeAddress = tempBarSeriesData->m_cat.writeRefToInternalTable(this);
2415 
2416     READ_EPILOGUE
2417 }
2418 
2419 #undef CURRENT_EL
2420 #define CURRENT_EL ser
2421 //! ser (Area Chart Series)
2422 /*! ECMA-376, 21.2.2.168, p.3839.
2423 
2424  Parent elements:
2425   - area3DChart (§21.2.2.4)
2426   - areaChart (§21.2.2.5)
2427 
2428  Child elements:
2429   - cat (Category Axis Data) §21.2.2.24
2430   - [Done]dLbls (Data Labels) §21.2.2.49
2431   - dPt (Data Point) §21.2.2.52
2432   - errBars (Error Bars) §21.2.2.55
2433   - extLst (Chart Extensibility) §21.2.2.64
2434   - idx (Index) §21.2.2.84
2435   - order (Order) §21.2.2.128
2436   - pictureOptions (Picture Options) §21.2.2.138
2437   - spPr (Shape Properties) §21.2.2.197
2438   - trendline (Trendlines) §21.2.2.211
2439   - tx (Series Text) §21.2.2.215
2440   - val (Values) §21.2.2.224
2441 */
2442 
2443 KoFilter::ConversionStatus XlsxXmlChartReader::read_areaChart_Ser()
2444 {
2445     READ_PROLOGUE2(areaChart_Ser)
2446 
2447     m_currentSeries  = new KoChart::Series();
2448     m_context->m_chart->m_series << m_currentSeries;
2449 
2450     AreaSeries * tempAreaSeriesData = new AreaSeries();
2451     d->m_seriesData << tempAreaSeriesData;
2452 
2453     d->m_currentIdx = &tempAreaSeriesData->m_idx;
2454     d->m_currentOrder = &tempAreaSeriesData->m_order;
2455     d->m_currentTx = &tempAreaSeriesData->m_tx;
2456     d->m_currentCat = &tempAreaSeriesData->m_cat;
2457     d->m_currentVal = &tempAreaSeriesData->m_val;
2458 
2459     while (!atEnd()) {
2460         readNext();
2461         BREAK_IF_END_OF(CURRENT_EL)
2462         if (isStartElement()) {
2463             TRY_READ_IF(order)
2464             ELSE_TRY_READ_IF(idx)
2465             else if (QUALIFIED_NAME_IS(tx)) {
2466                 TRY_READ(seriesText_Tx)
2467             }
2468             ELSE_TRY_READ_IF(cat)
2469             ELSE_TRY_READ_IF(val)
2470             ELSE_TRY_READ_IF(dLbls)
2471         }
2472     }
2473     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempAreaSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2474         m_context->m_chart->m_title = tempAreaSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2475 
2476     // set data ranges and write data to internal table
2477     m_currentSeries->m_countYValues = tempAreaSeriesData->m_val.m_numRef.m_numCache.m_ptCount;
2478 
2479     m_currentSeries->m_labelCell = tempAreaSeriesData->m_tx.writeRefToInternalTable(this);
2480 
2481     m_currentSeries->m_valuesCellRangeAddress = tempAreaSeriesData->m_val.writeRefToInternalTable(this);
2482 
2483     m_context->m_chart->m_verticalCellRangeAddress = tempAreaSeriesData->m_cat.writeRefToInternalTable(this);
2484 
2485     READ_EPILOGUE
2486 }
2487 
2488 #undef CURRENT_EL
2489 #define CURRENT_EL ser
2490 //! ser (Radar Chart Series)
2491 /*! ECMA-376, 21.2.2.169, p.3840.
2492 
2493  Parent elements:
2494   - radarChart (§21.2.2.153)
2495 
2496  Child elements:
2497   - [Done]cat (Category Axis Data) §21.2.2.24
2498   - [Done]dLbls (Data Labels) §21.2.2.49
2499   - dPt (Data Point) §21.2.2.52
2500   - extLst (Chart Extensibility) §21.2.2.64
2501   - [Done]idx (Index) §21.2.2.84
2502   - marker (Marker) §21.2.2.106
2503   - [Done]order (Order) §21.2.2.128
2504   - spPr (Shape Properties) §21.2.2.197
2505   - [Done]tx (Series Text) §21.2.2.215
2506   - [Done]val (Values) §21.2.2.224
2507 */
2508 
2509 KoFilter::ConversionStatus XlsxXmlChartReader::read_radarChart_Ser()
2510 {
2511     READ_PROLOGUE2(radarChart_Ser)
2512 
2513     m_currentSeries  = new KoChart::Series();
2514     m_context->m_chart->m_series << m_currentSeries;
2515 
2516     RadarSeries * tempRadarSeriesData = new RadarSeries();
2517     d->m_seriesData << tempRadarSeriesData;
2518 
2519     d->m_currentIdx = &tempRadarSeriesData->m_idx;
2520     d->m_currentOrder = &tempRadarSeriesData->m_order;
2521     d->m_currentTx = &tempRadarSeriesData->m_tx;
2522     d->m_currentCat = &tempRadarSeriesData->m_cat;
2523     d->m_currentVal = &tempRadarSeriesData->m_val;
2524 
2525     while (!atEnd()) {
2526         readNext();
2527         BREAK_IF_END_OF(CURRENT_EL)
2528         if (isStartElement()) {
2529             TRY_READ_IF(order)
2530             ELSE_TRY_READ_IF(idx)
2531             else if (QUALIFIED_NAME_IS(tx)) {
2532                 TRY_READ(seriesText_Tx)
2533             }
2534             ELSE_TRY_READ_IF(cat)
2535             ELSE_TRY_READ_IF(val)
2536             ELSE_TRY_READ_IF(dLbls)
2537         }
2538     }
2539     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempRadarSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2540         m_context->m_chart->m_title = tempRadarSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2541 
2542     // set data ranges and write data to internal table
2543     m_currentSeries->m_countYValues = tempRadarSeriesData->m_val.m_numRef.m_numCache.m_ptCount;
2544 
2545     m_currentSeries->m_labelCell = tempRadarSeriesData->m_tx.writeRefToInternalTable(this);
2546 
2547     m_currentSeries->m_valuesCellRangeAddress = tempRadarSeriesData->m_val.writeRefToInternalTable(this);
2548 
2549     m_context->m_chart->m_verticalCellRangeAddress = tempRadarSeriesData->m_cat.writeRefToInternalTable(this);
2550 
2551     READ_EPILOGUE
2552 }
2553 
2554 #undef CURRENT_EL
2555 #define CURRENT_EL ser
2556 //! ser (Line Chart Series)
2557 /*! ECMA-376, 21.2.2.168, p.3839.
2558 
2559  Parent elements:
2560   - line3DChart (§21.2.2.96)
2561   - lineChart (§21.2.2.97)
2562   - stockChart (§21.2.2.198)
2563 
2564  Child elements:
2565   - [Done]cat (Category Axis Data) §21.2.2.24
2566   - [Done]dLbls (Data Labels) §21.2.2.49
2567   - dPt (Data Point) §21.2.2.52
2568   - errBars (Error Bars) §21.2.2.55
2569   - extLst (Chart Extensibility) §21.2.2.64
2570   - [Done]idx (Index) §21.2.2.84
2571   - marker (Marker) §21.2.2.106
2572   - [Done]order (Order) §21.2.2.128
2573   - smooth (Smoothing) §21.2.2.194
2574   - spPr (Shape Properties) §21.2.2.197
2575   - trendline (Trendlines) §21.2.2.211
2576   - [Done]tx (Series Text) §21.2.2.215
2577   - [Done]val (Values) §21.2.2.224
2578 */
2579 
2580 KoFilter::ConversionStatus XlsxXmlChartReader::read_lineChart_Ser()
2581 {
2582     READ_PROLOGUE2(lineChart_Ser)
2583 
2584     m_currentSeries  = new KoChart::Series();
2585     m_context->m_chart->m_series << m_currentSeries;
2586 
2587     LineSeries * tempLineSeriesData = new LineSeries();
2588     d->m_seriesData << tempLineSeriesData;
2589 
2590     d->m_currentIdx = &tempLineSeriesData->m_idx;
2591     d->m_currentOrder = &tempLineSeriesData->m_order;
2592     d->m_currentTx = &tempLineSeriesData->m_tx;
2593     d->m_currentCat = &tempLineSeriesData->m_cat;
2594     d->m_currentVal = &tempLineSeriesData->m_val;
2595 
2596     while (!atEnd()) {
2597         readNext();
2598         BREAK_IF_END_OF(CURRENT_EL)
2599         if (isStartElement()) {
2600             TRY_READ_IF(order)
2601             ELSE_TRY_READ_IF(idx)
2602             else if (QUALIFIED_NAME_IS(tx)) {
2603                 TRY_READ(seriesText_Tx)
2604             }
2605             else if (QUALIFIED_NAME_IS(marker)) {
2606                 TRY_READ(serMarker)
2607             }
2608             ELSE_TRY_READ_IF(cat)
2609             ELSE_TRY_READ_IF(val)
2610             ELSE_TRY_READ_IF(dLbls)
2611         }
2612     }
2613     if ( !m_autoTitleDeleted && m_context->m_chart->m_title.isEmpty() && m_context->m_chart->m_series.count() == 1 && !tempLineSeriesData->m_tx.m_strRef.m_strCache.m_cache.isEmpty() )
2614         m_context->m_chart->m_title = tempLineSeriesData->m_tx.m_strRef.m_strCache.m_cache[ 0 ];
2615 
2616     // set data ranges and write data to internal table
2617     m_currentSeries->m_countYValues = tempLineSeriesData->m_val.m_numRef.m_numCache.m_ptCount;
2618 
2619     m_currentSeries->m_labelCell = tempLineSeriesData->m_tx.writeRefToInternalTable(this);
2620 
2621     m_currentSeries->m_valuesCellRangeAddress = tempLineSeriesData->m_val.writeRefToInternalTable(this);
2622 
2623     m_context->m_chart->m_verticalCellRangeAddress = tempLineSeriesData->m_cat.writeRefToInternalTable(this);
2624 
2625     READ_EPILOGUE
2626 }
2627 
2628 KoChart::MarkerType markerType(const QString &_val)
2629 {
2630     const QString val = _val.toLower();
2631     if ( val == "star" )
2632         return KoChart::StarMarker;
2633     if ( val == "dash" )
2634         return KoChart::DashMarker;
2635     if ( val == "dot" )
2636         return KoChart::DotMarker;
2637     if ( val == "plus" )
2638         return KoChart::PlusMarker;
2639     if ( val == "circle" )
2640         return KoChart::CircleMarker;
2641     if ( val == "x" )
2642         return KoChart::SymbolXMarker;
2643     if ( val == "triangle" )
2644         return KoChart::TriangleMarker;
2645     if ( val == "square" )
2646         return KoChart::SquareMarker;
2647     if ( val == "diamond" )
2648         return KoChart::DiamondMarker;
2649     return KoChart::NoMarker;
2650 }
2651 
2652 #undef CURRENT_EL
2653 #define CURRENT_EL marker
2654 KoFilter::ConversionStatus XlsxXmlChartReader::read_marker()
2655 {
2656     READ_PROLOGUE
2657 
2658     bool gotSymbol = m_serMarkerDefined;
2659     const QXmlStreamAttributes attrs(attributes());
2660     TRY_READ_ATTR_WITHOUT_NS(val)
2661 
2662     while (!atEnd()) {
2663         readNext();
2664         BREAK_IF_END_OF(CURRENT_EL)
2665         if (isStartElement()) {
2666             if ( !gotSymbol && qualifiedName() == "c:symbol" ) {
2667                 const QXmlStreamAttributes attrs(attributes());
2668                 TRY_READ_ATTR_WITHOUT_NS(val);
2669                 m_context->m_chart->m_markerType = markerType(val);
2670                 gotSymbol = true;
2671             }
2672         }
2673     }
2674 
2675     if (!gotSymbol)
2676         if (MSOOXML::Utils::convertBooleanAttr(val, true))
2677             m_context->m_chart->m_markerType = KoChart::AutoMarker;
2678 
2679     READ_EPILOGUE
2680     return KoFilter::OK;
2681 }
2682 
2683 #undef CURRENT_EL
2684 #define CURRENT_EL marker
2685 KoFilter::ConversionStatus XlsxXmlChartReader::read_serMarker()
2686 {
2687     READ_PROLOGUE2( serMarker )
2688 
2689     m_serMarkerDefined = true;
2690     bool gotSymbol = false;
2691     const QXmlStreamAttributes attrs(attributes());
2692     TRY_READ_ATTR_WITHOUT_NS(val)
2693 
2694     while (!atEnd()) {
2695         readNext();
2696         BREAK_IF_END_OF(CURRENT_EL)
2697         if (isStartElement()) {
2698             if ( qualifiedName() == "c:symbol" ) {
2699                 const QXmlStreamAttributes attrs(attributes());
2700                 TRY_READ_ATTR_WITHOUT_NS(val);
2701                 m_currentSeries->m_markerType = markerType(val);
2702                 gotSymbol = true;
2703             }
2704         }
2705     }
2706 
2707     if (!gotSymbol)
2708         if (MSOOXML::Utils::convertBooleanAttr(val, true))
2709             m_currentSeries->m_markerType = KoChart::AutoMarker;
2710 
2711     READ_EPILOGUE
2712 }
2713 
2714 #undef CURRENT_EL
2715 #define CURRENT_EL ser
2716 //! ser (Surface Chart Series)
2717 /*! ECMA-376, 21.2.2.169, p.3840.
2718 
2719  Parent elements:
2720   - surface3DChart (§21.2.2.203)
2721   - surfaceChart (§21.2.2.204)
2722 
2723  Child elements:
2724   - [Done]cat (Category Axis Data) §21.2.2.24
2725   - extLst (Chart Extensibility) §21.2.2.64
2726   - [Done]idx (Index) §21.2.2.84
2727   - marker (Marker) §21.2.2.106
2728   - [Done]order (Order) §21.2.2.128
2729   - spPr (Shape Properties) §21.2.2.197
2730   - [Done]tx (Series Text) §21.2.2.215
2731   - [Done]val (Values) §21.2.2.224
2732 */
2733 
2734 KoFilter::ConversionStatus XlsxXmlChartReader::read_surfaceChart_Ser()
2735 {
2736     READ_PROLOGUE2(surfaceChart_Ser)
2737 
2738     m_currentSeries  = new KoChart::Series();
2739     m_context->m_chart->m_series << m_currentSeries;
2740 
2741     SurfaceSeries * tempSurfaceSeriesData = new SurfaceSeries();
2742     d->m_seriesData << tempSurfaceSeriesData;
2743 
2744     d->m_currentIdx = &tempSurfaceSeriesData->m_idx;
2745     d->m_currentOrder = &tempSurfaceSeriesData->m_order;
2746     d->m_currentTx = &tempSurfaceSeriesData->m_tx;
2747     d->m_currentCat = &tempSurfaceSeriesData->m_cat;
2748     d->m_currentVal = &tempSurfaceSeriesData->m_val;
2749 
2750     while (!atEnd()) {
2751         readNext();
2752         BREAK_IF_END_OF(CURRENT_EL)
2753         if (isStartElement()) {
2754             TRY_READ_IF(order)
2755             ELSE_TRY_READ_IF(idx)
2756             else if (QUALIFIED_NAME_IS(tx)) {
2757                 TRY_READ(seriesText_Tx)
2758             }
2759             ELSE_TRY_READ_IF(cat)
2760             ELSE_TRY_READ_IF(val)
2761         }
2762     }
2763 
2764     // set data ranges and write data to internal table
2765     m_currentSeries->m_countYValues = tempSurfaceSeriesData->m_val.m_numRef.m_numCache.m_ptCount;
2766 
2767     m_currentSeries->m_labelCell = tempSurfaceSeriesData->m_tx.writeRefToInternalTable(this);
2768 
2769     m_currentSeries->m_valuesCellRangeAddress = tempSurfaceSeriesData->m_val.writeRefToInternalTable(this);
2770 
2771     m_context->m_chart->m_verticalCellRangeAddress = tempSurfaceSeriesData->m_cat.writeRefToInternalTable(this);
2772 
2773     READ_EPILOGUE
2774 }
2775 
2776 #undef CURRENT_EL
2777 #define CURRENT_EL barDir
2778 //! barDir (Bar Direction)
2779 /*! ECMA-376, 21.2.2.17, p.3763.
2780 
2781  Parent elements:
2782   - bar3DChart (§21.2.2.15)
2783   - barChart (§21.2.2.16)
2784 
2785  Attributes:
2786   - [Done] val (Bar Direction Value)
2787 */
2788 KoFilter::ConversionStatus XlsxXmlChartReader::read_barDir()
2789 {
2790     const QXmlStreamAttributes attrs(attributes());
2791     TRY_READ_ATTR_WITHOUT_NS(val)
2792     m_context->m_chart->m_transpose = (val == "bar"); // "bar" or "col"
2793     while (!atEnd()) {
2794         BREAK_IF_END_OF(CURRENT_EL)
2795         readNext();
2796     }
2797     return KoFilter::OK;
2798 }
2799 
2800 #undef CURRENT_EL
2801 #define CURRENT_EL grouping
2802 //! grouping (Bar Grouping)
2803 /*! ECMA-376, 21.2.2.77, p.3794.
2804 
2805  Parent elements:
2806   - bar3DChart (§21.2.2.15)
2807   - barChart (§21.2.2.16)
2808 
2809  Attributes:
2810   - [Done] val (Bar Grouping Value)
2811 */
2812 KoFilter::ConversionStatus XlsxXmlChartReader::read_grouping()
2813 {
2814     const QXmlStreamAttributes attrs(attributes());
2815     TRY_READ_ATTR_WITHOUT_NS(val)
2816     if(val == "stacked") {
2817         m_context->m_chart->m_stacked = true;
2818     } else if(val == "percentStacked") {
2819         m_context->m_chart->m_stacked = true;
2820         m_context->m_chart->m_f100 = true;
2821     } else if(val == "clustered") {
2822         //TODO
2823     } // else if(val == "standard") is not needed cause that's the default anyway
2824     while (!atEnd()) {
2825         BREAK_IF_END_OF(CURRENT_EL)
2826         readNext();
2827     }
2828     return KoFilter::OK;
2829 }
2830 
2831 #undef CURRENT_EL
2832 #define CURRENT_EL firstSliceAng
2833 //! firstSliceAng (First Slice Angle)
2834 /*! ECMA-376, 21.2.2.68, p.3790.
2835 
2836  Parent elements:
2837   - doughnutChart (§21.2.2.50)
2838   - pieChart (§21.2.2.141)
2839 
2840  Child elements:
2841   - val (First Slice Angle Value)
2842 */
2843 KoFilter::ConversionStatus XlsxXmlChartReader::read_firstSliceAng()
2844 {
2845     if(KoChart::PieImpl* pie = dynamic_cast<KoChart::PieImpl*>(m_context->m_chart->m_impl)) {
2846         const QXmlStreamAttributes attrs(attributes());
2847         QString val(attrs.value("val").toString());
2848         pie->m_anStart = val.toInt(); // default value is zero
2849     }
2850     while (!atEnd()) {
2851         BREAK_IF_END_OF(CURRENT_EL)
2852         readNext();
2853     }
2854     return KoFilter::OK;
2855 }
2856 
2857 #undef CURRENT_EL
2858 #define CURRENT_EL holeSize
2859 //! holeSize (Hole Size)
2860 /*! ECMA-376, 21.2.2.82, p.3797.
2861 
2862  Parent elements:
2863   - doughnutChart (§21.2.2.50)
2864 
2865  Child elements:
2866   - val (Hole Size Value)
2867 */
2868 KoFilter::ConversionStatus XlsxXmlChartReader::read_holeSize()
2869 {
2870     if(KoChart::RingImpl* ring = dynamic_cast<KoChart::RingImpl*>(m_context->m_chart->m_impl)) {
2871         const QXmlStreamAttributes attrs(attributes());
2872         QString val(attrs.value("val").toString());
2873         ring->m_pcDonut = val.toInt(); // default value is zero
2874     }
2875     while (!atEnd()) {
2876         BREAK_IF_END_OF(CURRENT_EL)
2877         readNext();
2878     }
2879     return KoFilter::OK;
2880 }
2881 
2882 #undef CURRENT_EL
2883 #define CURRENT_EL bubbleSize
2884 //! bubbleSize (Bubble Size)
2885 /*! ECMA-376, 21.2.2.22, p.3876.
2886 
2887  Parent elements:
2888   - ser §21.2.2.174
2889 
2890  Child elements:
2891   - [done] numLit (Number Literal) §21.2.2.122
2892   - [done] numRef (Number Reference) §21.2.2.123
2893 */
2894 KoFilter::ConversionStatus XlsxXmlChartReader::read_bubbleSize()
2895 {
2896     READ_PROLOGUE
2897     d->m_currentNumRef = &d->m_currentBubbleSize->m_numRef;
2898     d->m_currentNumLit = &d->m_currentBubbleSize->m_numLit;
2899     while (!atEnd()) {
2900         readNext();
2901         BREAK_IF_END_OF(CURRENT_EL)
2902         if (isStartElement()) {
2903             TRY_READ_IF(numRef)
2904             ELSE_TRY_READ_IF(numLit)
2905             ELSE_WRONG_FORMAT
2906         }
2907     }
2908     READ_EPILOGUE
2909 }
2910 
2911 #undef CURRENT_EL
2912 #define CURRENT_EL bubbleScale
2913 //! bubbleScale (Bubble Scale)
2914 /*! ECMA-376, 21.2.2.21, p.3765.
2915 
2916  Parent elements:
2917   - bubbleChart (§21.2.2.20)
2918 
2919  Attributes:
2920   - [Done] val (Bubble Scale Value)
2921 */
2922 KoFilter::ConversionStatus XlsxXmlChartReader::read_bubbleScale()
2923 {
2924     READ_PROLOGUE
2925 
2926     const QXmlStreamAttributes attrs(attributes());
2927     QString val(attrs.value("val").toString());
2928 
2929     if(KoChart::BubbleImpl* bubble = dynamic_cast<KoChart::BubbleImpl*>(m_context->m_chart->m_impl)) {
2930         bool ok;
2931         const int i = val.toInt(&ok);
2932         if(ok)
2933             bubble->m_sizeRatio = i;
2934     }
2935     readNext();
2936     READ_EPILOGUE
2937 }
2938 
2939 #undef CURRENT_EL
2940 #define CURRENT_EL bubble3D
2941 //! bubble3D (3D Bubble)
2942 /*! ECMA-376, 21.2.2.21, p.3765.
2943 
2944  Parent elements:
2945   - bubbleChart (§21.2.2.20)
2946   - dPt (§21.2.2.52)
2947   - ser (§21.2.2.174)
2948 
2949  Attributes:
2950   - [Done] val (Boolean Value)
2951 */
2952 KoFilter::ConversionStatus XlsxXmlChartReader::read_bubble3D()
2953 {
2954     READ_PROLOGUE
2955 
2956     const QXmlStreamAttributes attrs(attributes());
2957     QString val(attrs.value("val").toString());
2958 
2959     m_context->m_chart->m_is3d  = val.toInt();
2960     readNext();
2961     READ_EPILOGUE
2962 }
2963 
2964 #undef CURRENT_EL
2965 #define CURRENT_EL numLit
2966 //! numLit (Number Literal)
2967 /*! ECMA-376, 21.2.2.122, p.3815.
2968 
2969  Parent elements:
2970   - bubbleSize (§21.2.2.22)
2971   - cat (§21.2.2.24)
2972   - minus (§21.2.2.113)
2973   - plus (§21.2.2.147)
2974   - val (§21.2.2.224)
2975   - xVal(§21.2.2.234)
2976   - yVal (§21.2.2.237)
2977 
2978  Child elements:
2979   - extLst (Chart Extensibility) §21.2.2.64
2980   - formatCode (Format Code) §21.2.2.71
2981   - [Done]pt (Numeric Point) §21.2.2.150
2982   - [Done]ptCount (Point Count) §21.2.2.152
2983 */
2984 KoFilter::ConversionStatus XlsxXmlChartReader::read_numLit()
2985 {
2986     READ_PROLOGUE
2987     d->m_currentPtCount = &d->m_currentNumLit->m_ptCount;
2988     d->m_currentPtCache = &d->m_currentNumLit->m_cache;
2989     while ( !atEnd() ) {
2990         readNext();
2991         BREAK_IF_END_OF( CURRENT_EL )
2992         if ( isStartElement() ) {
2993             TRY_READ_IF(ptCount)
2994             ELSE_TRY_READ_IF(pt)
2995         }
2996     }
2997     READ_EPILOGUE
2998 }
2999 
3000 #undef CURRENT_EL
3001 #define CURRENT_EL pt
3002 //! pt (String Point)
3003 /*! ECMA-376, 21.2.2.151, p.3831.
3004 
3005  Parent elements:
3006   - lvl (§21.2.2.99)
3007   - strCache (§21.2.2.199)
3008   - strLit (§21.2.2.200)
3009 
3010  Child elements:
3011   - [Done]v (Text Value)
3012 
3013  Attributes:
3014   - idx (Index)
3015 */
3016 KoFilter::ConversionStatus XlsxXmlChartReader::read_pt()
3017 {
3018     READ_PROLOGUE
3019     while ( !atEnd() ) {
3020         readNext();
3021         BREAK_IF_END_OF( CURRENT_EL )
3022         if ( isStartElement() ) {
3023           if ( qualifiedName() == QLatin1String( QUALIFIED_NAME( v ) ) ) {
3024               d->m_currentPtCache->append(readElementText());
3025           }
3026         }
3027     }
3028     READ_EPILOGUE
3029 }
3030 
3031 #undef CURRENT_EL
3032 #define CURRENT_EL order
3033 //! order (Order)
3034 /*! ECMA-376, 21.2.2.128, p.3817.
3035 
3036  Parent elements:
3037   - ser §21.2.2.168
3038   - ser §21.2.2.170
3039   - ser §21.2.2.174
3040   - ser §21.2.2.171
3041   - ser §21.2.2.172
3042   - ser §21.2.2.169
3043   - ser §21.2.2.167
3044   - ser §21.2.2.173
3045 
3046  Attributes:
3047   - [Done] val (Integer Value)
3048 */
3049 KoFilter::ConversionStatus XlsxXmlChartReader::read_order()
3050 {
3051     READ_PROLOGUE
3052 
3053     const QXmlStreamAttributes attrs(attributes());
3054     QString val(attrs.value("val").toString());
3055     *d->m_currentOrder = val.toInt();
3056 
3057     readNext();
3058     READ_EPILOGUE
3059 }
3060 
3061 #undef CURRENT_EL
3062 #define CURRENT_EL idx
3063 //! idx (Index)
3064 /*! ECMA-376, 21.2.2.84, p.3798.
3065 
3066  Parent elements:
3067   - bandFmt (§21.2.2.13)
3068   - dLbl (§21.2.2.47)
3069   - dPt (§21.2.2.52)
3070   - legendEntry (§21.2.2.94)
3071   - pivotFmt (§21.2.2.142)
3072   - ser §21.2.2.168
3073   - ser §21.2.2.170
3074   - ser §21.2.2.174
3075   - ser §21.2.2.171
3076   - ser §21.2.2.172
3077   - ser §21.2.2.169
3078   - ser §21.2.2.167
3079   - ser §21.2.2.173
3080 
3081  Attributes:
3082   - [Done] val (Integer Value)
3083 */
3084 KoFilter::ConversionStatus XlsxXmlChartReader::read_idx()
3085 {
3086     READ_PROLOGUE
3087 
3088     const QXmlStreamAttributes attrs(attributes());
3089     QString val(attrs.value("val").toString());
3090     *d->m_currentIdx = val.toInt();
3091 
3092     readNext();
3093     READ_EPILOGUE
3094 }
3095 
3096 #undef CURRENT_EL
3097 #define CURRENT_EL explosion
3098 //! explosion (Explosion)
3099 /*! ECMA-376, 21.2.2.61, p.3787.
3100 
3101  Parent elements:
3102   - dPt (§21.2.2.52)
3103   - ser (§21.2.2.172)
3104 
3105  Attributes:
3106   - [Done] val (Integer Value)
3107 */
3108 KoFilter::ConversionStatus XlsxXmlChartReader::read_explosion()
3109 {
3110     READ_PROLOGUE
3111 
3112     const QXmlStreamAttributes attrs(attributes());
3113     QString val(attrs.value("val").toString());
3114     *d->m_currentExplosion = val.toInt();
3115 
3116     readNext();
3117     READ_EPILOGUE
3118 }
3119 
3120 #undef CURRENT_EL
3121 #define CURRENT_EL strRef
3122 //! strRef (String Reference)
3123 /*! ECMA-376, 21.2.2.201, p.3857.
3124 
3125  Parent elements:
3126   - cat (§21.2.2.24)
3127   - tx (§21.2.2.215)
3128   - tx (§21.2.2.214)
3129   - xVal (§21.2.2.234)
3130 
3131  Child elements:
3132   - extLst (Chart Extensibility) §21.2.2.64
3133   - [Done] f (Formula) §21.2.2.65
3134   - [Done] strCache (String Cache) §21.2.2.199
3135 */
3136 KoFilter::ConversionStatus XlsxXmlChartReader::read_strRef()
3137 {
3138     READ_PROLOGUE
3139 
3140     d->m_currentF = &d->m_currentStrRef->m_f;
3141     d->m_currentStrCache = &d->m_currentStrRef->m_strCache;
3142 
3143     while (!atEnd()) {
3144         readNext();
3145         BREAK_IF_END_OF(CURRENT_EL)
3146         if (isStartElement()) {
3147             TRY_READ_IF(f)
3148             ELSE_TRY_READ_IF(strCache)
3149         }
3150     }
3151     READ_EPILOGUE
3152 }
3153 
3154 #undef CURRENT_EL
3155 #define CURRENT_EL multiLvlStrRef
3156 //! multiLvlStrRef (Multi Level String Reference)
3157 /*! ECMA-376, 5.7.2.116, p.4060
3158 
3159  Parent Elements:
3160   - cat (§5.7.2.24); xVal (§5.7.2.235)
3161 
3162  Child Elements:
3163   - extLst (Chart Extensibility) §5.7.2.64
3164   - f (Formula) §5.7.2.65
3165   - multiLvlStrCache (Multi Level String Cache) §5.7.2.115
3166 */
3167 KoFilter::ConversionStatus XlsxXmlChartReader::read_multiLvlStrRef()
3168 {
3169     READ_PROLOGUE
3170 
3171     d->m_currentF = &d->m_currentStrRef->m_f;
3172     d->m_currentStrCache = &d->m_currentStrRef->m_strCache;
3173 
3174     while (!atEnd()) {
3175         readNext();
3176         BREAK_IF_END_OF(CURRENT_EL)
3177         if (isStartElement()) {
3178             TRY_READ_IF(f)
3179             ELSE_TRY_READ_IF(multiLvlStrCache)
3180         }
3181     }
3182     READ_EPILOGUE
3183 }
3184 
3185 #undef CURRENT_EL
3186 #define CURRENT_EL multiLvlStrCache
3187 KoFilter::ConversionStatus XlsxXmlChartReader::read_multiLvlStrCache()
3188 {
3189     READ_PROLOGUE
3190     while (!atEnd()) {
3191         readNext();
3192         BREAK_IF_END_OF(CURRENT_EL)
3193         if (isStartElement()) {
3194             TRY_READ_IF(lvl)
3195         }
3196     }
3197     READ_EPILOGUE
3198 }
3199 
3200 #undef CURRENT_EL
3201 #define CURRENT_EL lvl
3202 KoFilter::ConversionStatus XlsxXmlChartReader::read_lvl()
3203 {
3204     READ_PROLOGUE
3205 
3206     d->m_currentPtCount = &d->m_currentStrCache->m_ptCount;
3207     d->m_currentPtCache = &d->m_currentStrCache->m_cache;
3208 
3209     while (!atEnd()) {
3210         readNext();
3211         BREAK_IF_END_OF(CURRENT_EL)
3212         if (isStartElement()) {
3213             TRY_READ_IF(ptCount)
3214             ELSE_TRY_READ_IF(pt)
3215         }
3216     }
3217     READ_EPILOGUE
3218 }
3219 
3220 #undef CURRENT_EL
3221 #define CURRENT_EL numRef
3222 //! numRef (String Reference)
3223 /*! ECMA-376, 21.2.2.123, p.3815.
3224 
3225  Parent elements:
3226   - bubbleSize (§21.2.2.22)
3227   - cat (§21.2.2.24)
3228   - minus (§21.2.2.113)
3229   - plus (§21.2.2.147)
3230   - val (§21.2.2.224)
3231   - xVal (§21.2.2.234)
3232   - yVal (§21.2.2.237)
3233 
3234  Child elements:
3235   - extLst (Chart Extensibility) §21.2.2.64
3236   - [Done]f (Formula) §21.2.2.65
3237   - [Done]numCache (Number Cache) §21.2.2.120
3238 */
3239 KoFilter::ConversionStatus XlsxXmlChartReader::read_numRef()
3240 {
3241     READ_PROLOGUE
3242 
3243     d->m_currentF = &d->m_currentNumRef->m_f;
3244     d->m_currentNumCache = &d->m_currentNumRef->m_numCache;
3245 
3246     while (!atEnd()) {
3247         readNext();
3248         BREAK_IF_END_OF(CURRENT_EL)
3249         if (isStartElement()) {
3250             TRY_READ_IF(f)
3251             ELSE_TRY_READ_IF(numCache)
3252         }
3253     }
3254     READ_EPILOGUE
3255 }
3256 
3257 #undef CURRENT_EL
3258 #define CURRENT_EL f
3259 //! f (Formula)
3260 /*! ECMA-376, 21.2.2.65, p.3789.
3261 
3262  Parent elements:
3263   - multiLvlStrRef (§21.2.2.115)
3264   - numRef (§21.2.2.123)
3265   - strRef (§21.2.2.201)
3266 */
3267 KoFilter::ConversionStatus XlsxXmlChartReader::read_f()
3268 {
3269     READ_PROLOGUE
3270 
3271     const QXmlStreamAttributes attrs(attributes());
3272     *d->m_currentF = readElementText();
3273     while (!atEnd()) {
3274         BREAK_IF_END_OF(CURRENT_EL)
3275         readNext();
3276     }
3277 
3278     if (d->m_currentF->size() != 0) {
3279         QPair<QString,QRect> result = splitCellRange( *d->m_currentF );
3280         m_context->m_chart->addRange( result.second );
3281     }
3282 
3283     READ_EPILOGUE
3284 }
3285 
3286 #undef CURRENT_EL
3287 #define CURRENT_EL ptCount
3288 //! ptCount (Point Count)
3289 /*! ECMA-376, 21.2.2.152, p.3832.
3290 
3291  Parent elements:
3292   - multiLvlStrCache (§21.2.2.114)
3293   - numCache (§21.2.2.120)
3294   - numLit (§21.2.2.122)
3295   - strCache (§21.2.2.199)
3296   - strLit (§21.2.2.200)
3297 
3298  Attributes:
3299   - [Done] val (Integer Value)
3300 */
3301 KoFilter::ConversionStatus XlsxXmlChartReader::read_ptCount()
3302 {
3303     READ_PROLOGUE
3304 
3305     const QXmlStreamAttributes attrs(attributes());
3306     QString val(attrs.value("val").toString());
3307     *d->m_currentPtCount = val.toInt();
3308 
3309     readNext();
3310     READ_EPILOGUE
3311 }
3312 
3313 #undef CURRENT_EL
3314 #define CURRENT_EL strCache
3315 //! strCache (String Cache)
3316 /*! ECMA-376, 21.2.2.199, p.3856.
3317 
3318  Parent elements:
3319  - strRef (§21.2.2.201)
3320 
3321  Child elements:
3322   - extLst (Chart Extensibility) §21.2.2.64
3323   - [Done]pt (String Point) §21.2.2.151
3324   - [Done]ptCount (Point Count) §21.2.2.152
3325 
3326 */
3327 KoFilter::ConversionStatus XlsxXmlChartReader::read_strCache()
3328 {
3329     READ_PROLOGUE
3330 
3331     d->m_currentPtCount = &d->m_currentStrCache->m_ptCount;
3332     d->m_currentPtCache = &d->m_currentStrCache->m_cache;
3333 
3334     while (!atEnd()) {
3335         readNext();
3336         BREAK_IF_END_OF(CURRENT_EL)
3337         if (isStartElement()) {
3338             TRY_READ_IF(ptCount)
3339             ELSE_TRY_READ_IF(pt)
3340         }
3341     }
3342     READ_EPILOGUE
3343 }
3344 
3345 int charToInt( const QString& string )
3346 {
3347     if (string.isEmpty()) {
3348         return -1;
3349     }
3350 
3351     int ret = 0;
3352     int multiplier = 1;
3353     for(int i=string.size()-1; i>-1; i--,multiplier = multiplier*26) {
3354         const char val = string[i].toLatin1();
3355         if ( val >= 65 && val <= 90 ) {
3356             ret = ret +  (val - 64)*multiplier;
3357         } else {
3358             ret = -1;
3359             break;
3360         }
3361     }
3362     return ret;
3363 }
3364 
3365 QString XlsxXmlChartReader::AlocateAndWriteIntoInternalTable(QVector< QString > &buffer, KoGenStyle::Type formatType)
3366 {
3367     if (buffer.size() == 0)
3368         return QString();
3369 
3370     //create range where to place the data
3371     QString range("local");
3372     KoChart::InternalTable *internalTable = &m_context->m_chart->m_internalTable;
3373 
3374     range += "!$" + columnName(internalTable->maxColumn()+1) +"$" + "1" + ":$" + columnName(internalTable->maxColumn()+1) +
3375              "$" + QString::number(buffer.size());
3376 
3377     WriteIntoInternalTable(range, buffer, formatType);
3378     return range;
3379 }
3380 
3381 QString convertToFormat( KoGenStyle::Type formatType )
3382 {
3383     switch (formatType) {
3384         case KoGenStyle::NumericDateStyle:
3385             return "date";
3386         case KoGenStyle::NumericTimeStyle:
3387             return "time";
3388         case KoGenStyle::NumericPercentageStyle:
3389             return "percentage";
3390         case KoGenStyle::NumericCurrencyStyle:
3391             return "currency";
3392         case KoGenStyle::NumericTextStyle:
3393             return "string";
3394         case KoGenStyle::NumericBooleanStyle:
3395             return "boolean";
3396         case KoGenStyle::NumericNumberStyle:
3397         case KoGenStyle::NumericFractionStyle:
3398         case KoGenStyle::NumericScientificStyle:
3399             return "float";
3400         default:
3401             qWarning() << "Unhandled format-type=" << formatType;
3402             break;
3403     }
3404     return "string";
3405 }
3406 
3407 QString convertToFormat( KoGenStyle::Type formatType, const QString& formatString, const QString& value )
3408 {
3409     switch (formatType) {
3410         case KoGenStyle::NumericDateStyle: {
3411             QString f = formatString;
3412             f.replace( QRegExp( "[m{1}]" ), "M" );
3413             QDateTime dt( QDate( 1899, 12, 30 ) );
3414             return dt.addDays( value.toInt() ).toString( f );
3415         }
3416         case KoGenStyle::NumericTimeStyle: {
3417             QTime t(0,0,0,0);
3418             t = t.addSecs( value.toInt() );
3419             return t.toString( Qt::ISODate );
3420         }
3421         case KoGenStyle::NumericPercentageStyle: {
3422             return value + '%';
3423         }
3424         /*TODO
3425         case KoGenStyle::NumericCurrencyStyle:
3426         case KoGenStyle::NumericBooleanStyle:
3427         case KoGenStyle::NumericFractionStyle:
3428         case KoGenStyle::NumericScientificStyle:
3429         */
3430         case KoGenStyle::NumericNumberStyle:
3431         case KoGenStyle::NumericTextStyle:
3432             return value;
3433         default:
3434             qWarning() << "Unhandled format-type=" << formatType;
3435             break;
3436     }
3437     return value;
3438 }
3439 
3440 void XlsxXmlChartReader::WriteIntoInternalTable(QString &range, QVector< QString > &buffer, KoGenStyle::Type formatType, const QString& formatString)
3441 {
3442     if(range.isEmpty()) {
3443         return;
3444     }
3445     const QString sheet = range.section( '!', 0, 0 );
3446     const QString cellRange = range.section( '!', 1, -1 );
3447     const QStringList& res = cellRange.split( QRegExp( "[$:]" ), QString::SkipEmptyParts );
3448 
3449     if (res.count() <= 1) {
3450         return;
3451     }
3452 
3453     int startColumn = charToInt( res[ 0 ] );
3454     int startRow = res[ 1 ].toInt();
3455     int endColumn = 0;
3456     int endRow = 0;
3457     if (res.size() >= 4) {
3458         endColumn = charToInt( res[ 2 ] );
3459         endRow = res[ 3 ].toInt();
3460     } else {
3461         endColumn = startColumn ;
3462         endRow = startRow;
3463     }
3464 
3465 //    kDebug()<<"range " << range;
3466 //    kDebug()<<"sheet " << sheet;
3467 //    kDebug()<<"cellRange " << cellRange;
3468 //    kDebug()<<"startColumn " << startColumn;
3469 //    kDebug()<<"startRow " << startRow;
3470 //    kDebug()<<"endColumn " << endColumn;
3471 //    kDebug()<<"endRow " << endRow;
3472 //
3473 //    kDebug()<<"buffer.size() " << buffer.size();
3474 
3475     KoChart::InternalTable *internalTable = &m_context->m_chart->m_internalTable;
3476     if (startColumn < endColumn) {
3477         if ((endColumn - startColumn +1) == buffer.size()) {
3478 
3479             int bufferIndex = 0;
3480             for(int i = startColumn; i <=endColumn; i++,bufferIndex++) {
3481                 KoChart::Cell *cell = internalTable->cell(i,startRow,true);
3482                 cell->m_valueType = convertToFormat( formatType );
3483                 cell->m_value = convertToFormat( formatType, formatString, buffer[bufferIndex] );
3484 //                kDebug()<<"m_value " << format;
3485 //                kDebug()<<"buffer[bufferIndex] " << buffer[bufferIndex];
3486 //                kDebug()<<"cell row" << startRow;
3487 //                kDebug()<<"cell column " << i;
3488             }
3489         }
3490     } else if (startRow < endRow){
3491         if ((endRow - startRow +1) == buffer.size()) {
3492 
3493             int bufferIndex = 0;
3494             for(int i = startRow; i <=endRow; i++,bufferIndex++) {
3495                 KoChart::Cell *cell = internalTable->cell(startColumn,i,true);
3496                 cell->m_valueType = convertToFormat( formatType );
3497                 cell->m_value = convertToFormat( formatType, formatString, buffer[bufferIndex] );
3498 //                kDebug()<<"m_value " << format;
3499 //                kDebug()<<"buffer[bufferIndex] " << buffer[bufferIndex];
3500 //                kDebug()<<"cell row" << i;
3501 //                kDebug()<<"cell column " << startColumn;
3502             }
3503         }
3504     } else {
3505         if (buffer.size() != 0) {
3506             KoChart::Cell *cell = internalTable->cell(startColumn,startRow,true);
3507             cell->m_valueType = convertToFormat( formatType );
3508             cell->m_value = convertToFormat( formatType, formatString, buffer[ 0 ] );
3509 //            kDebug()<<"m_value " << format;
3510 //            kDebug()<<"buffer[bufferIndex] " << buffer[0];
3511 //            kDebug()<<"cell row" << startRow;
3512 //            kDebug()<<"cell column " << startColumn;
3513         }
3514     }
3515 }