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 }