xlsxchart.cpp 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339
  1. // xlsxchart.cpp
  2. #include <QtGlobal>
  3. #include <QString>
  4. #include <QIODevice>
  5. #include <QXmlStreamReader>
  6. #include <QXmlStreamWriter>
  7. #include <QDebug>
  8. #include "xlsxchart_p.h"
  9. #include "xlsxworksheet.h"
  10. #include "xlsxcellrange.h"
  11. #include "xlsxutility_p.h"
  12. QT_BEGIN_NAMESPACE_XLSX
  13. ChartPrivate::ChartPrivate(Chart *q, Chart::CreateFlag flag)
  14. : AbstractOOXmlFilePrivate(q, flag), chartType(static_cast<Chart::ChartType>(0))
  15. {
  16. }
  17. ChartPrivate::~ChartPrivate()
  18. {
  19. }
  20. /*!
  21. * \internal
  22. */
  23. Chart::Chart(AbstractSheet *parent, CreateFlag flag)
  24. : AbstractOOXmlFile(new ChartPrivate(this, flag))
  25. {
  26. Q_D(Chart);
  27. d_func()->sheet = parent;
  28. // d->legendPos = Chart::ChartAxisPos::None;
  29. d->legendPos = Chart::None;
  30. d->legendOverlay = false;
  31. d->majorGridlinesEnabled = false;
  32. d->minorGridlinesEnabled = false;
  33. }
  34. /*!
  35. * Destroys the chart.
  36. */
  37. Chart::~Chart()
  38. {
  39. }
  40. /*!
  41. * Add the data series which is in the range \a range of the \a sheet.
  42. */
  43. void Chart::addSeries(const CellRange &range, AbstractSheet *sheet, bool headerH, bool headerV, bool swapHeaders)
  44. {
  45. Q_D(Chart);
  46. if (!range.isValid())
  47. return;
  48. if (sheet && sheet->sheetType() != AbstractSheet::ST_WorkSheet)
  49. return;
  50. if (!sheet && d->sheet->sheetType() != AbstractSheet::ST_WorkSheet)
  51. return;
  52. QString sheetName = sheet ? sheet->sheetName() : d->sheet->sheetName();
  53. //In case sheetName contains space or '
  54. sheetName = escapeSheetName(sheetName);
  55. if (range.columnCount() == 1 || range.rowCount() == 1)
  56. {
  57. QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
  58. series->numberDataSource_numRef = sheetName + QLatin1String("!") + range.toString(true, true);
  59. d->seriesList.append(series);
  60. }
  61. else if ((range.columnCount() < range.rowCount()) || swapHeaders )
  62. {
  63. //Column based series
  64. int firstDataRow = range.firstRow();
  65. int firstDataColumn = range.firstColumn();
  66. QString axDataSouruce_numRef;
  67. if (d->chartType == CT_ScatterChart || d->chartType == CT_BubbleChart)
  68. {
  69. firstDataColumn += 1;
  70. CellRange subRange(range.firstRow(), range.firstColumn(), range.lastRow(), range.firstColumn());
  71. axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  72. }
  73. if( headerH )
  74. {
  75. firstDataRow += 1;
  76. }
  77. if( headerV )
  78. {
  79. firstDataColumn += 1;
  80. }
  81. for (int col=firstDataColumn; col<=range.lastColumn(); ++col)
  82. {
  83. CellRange subRange(firstDataRow, col, range.lastRow(), col);
  84. QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
  85. series->axDataSource_numRef = axDataSouruce_numRef;
  86. series->numberDataSource_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  87. if( headerH )
  88. {
  89. CellRange subRange(range.firstRow(), col, range.firstRow(), col);
  90. series->headerH_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  91. }
  92. else
  93. {
  94. series->headerH_numRef = QString();
  95. }
  96. if( headerV )
  97. {
  98. CellRange subRange(firstDataRow, range.firstColumn(), range.lastRow(), range.firstColumn());
  99. series->headerV_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  100. }
  101. else
  102. {
  103. series->headerV_numRef = QString();
  104. }
  105. series->swapHeader = swapHeaders;
  106. d->seriesList.append(series);
  107. }
  108. }
  109. else
  110. {
  111. //Row based series
  112. int firstDataRow = range.firstRow();
  113. int firstDataColumn = range.firstColumn();
  114. QString axDataSouruce_numRef;
  115. if (d->chartType == CT_ScatterChart || d->chartType == CT_BubbleChart)
  116. {
  117. firstDataRow += 1;
  118. CellRange subRange(range.firstRow(), range.firstColumn(), range.firstRow(), range.lastColumn());
  119. axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  120. }
  121. if( headerH )
  122. {
  123. firstDataRow += 1;
  124. }
  125. if( headerV )
  126. {
  127. firstDataColumn += 1;
  128. }
  129. for (int row=firstDataRow; row<=range.lastRow(); ++row)
  130. {
  131. CellRange subRange(row, firstDataColumn, row, range.lastColumn());
  132. QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
  133. series->axDataSource_numRef = axDataSouruce_numRef;
  134. series->numberDataSource_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  135. if( headerH )
  136. {
  137. CellRange subRange(range.firstRow(), firstDataColumn, range.firstRow(), range.lastColumn());
  138. series->headerH_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  139. }
  140. else
  141. {
  142. series->headerH_numRef = QString();
  143. }
  144. if( headerV )
  145. {
  146. CellRange subRange(row, range.firstColumn(), row, range.firstColumn());
  147. series->headerV_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
  148. }
  149. else
  150. {
  151. series->headerV_numRef = QString();
  152. }
  153. series->swapHeader = swapHeaders;
  154. d->seriesList.append(series);
  155. }
  156. }
  157. }
  158. /*!
  159. * Set the type of the chart to \a type
  160. */
  161. void Chart::setChartType(ChartType type)
  162. {
  163. Q_D(Chart);
  164. d->chartType = type;
  165. }
  166. /*!
  167. * \internal
  168. *
  169. */
  170. void Chart::setChartStyle(int id)
  171. {
  172. Q_UNUSED(id)
  173. //!Todo
  174. }
  175. void Chart::setAxisTitle(Chart::ChartAxisPos pos, QString axisTitle)
  176. {
  177. Q_D(Chart);
  178. if ( axisTitle.isEmpty() )
  179. return;
  180. // dev24 : fixed for old compiler
  181. if ( pos == Chart::Left )
  182. {
  183. d->axisNames[ XlsxAxis::Left ] = axisTitle;
  184. }
  185. else if ( pos == Chart::Top )
  186. {
  187. d->axisNames[ XlsxAxis::Top ] = axisTitle;
  188. }
  189. else if ( pos == Chart::Right )
  190. {
  191. d->axisNames[ XlsxAxis::Right ] = axisTitle;
  192. }
  193. else if ( pos == Chart::Bottom )
  194. {
  195. d->axisNames[ XlsxAxis::Bottom ] = axisTitle;
  196. }
  197. }
  198. // dev25
  199. void Chart::setChartTitle(QString strchartTitle)
  200. {
  201. Q_D(Chart);
  202. d->chartTitle = strchartTitle;
  203. }
  204. void Chart::setChartLegend(Chart::ChartAxisPos legendPos, bool overlay)
  205. {
  206. Q_D(Chart);
  207. d->legendPos = legendPos;
  208. d->legendOverlay = overlay;
  209. }
  210. void Chart::setGridlinesEnable(bool majorGridlinesEnable, bool minorGridlinesEnable)
  211. {
  212. Q_D(Chart);
  213. d->majorGridlinesEnabled = majorGridlinesEnable;
  214. d->minorGridlinesEnabled = minorGridlinesEnable;
  215. }
  216. /*!
  217. * \internal
  218. */
  219. void Chart::saveToXmlFile(QIODevice *device) const
  220. {
  221. Q_D(const Chart);
  222. /*
  223. <chartSpace>
  224. <chart>
  225. <view3D>
  226. <perspective val="30"/>
  227. </view3D>
  228. <plotArea>
  229. <layout/>
  230. <barChart>
  231. ...
  232. </barChart>
  233. <catAx/>
  234. <valAx/>
  235. </plotArea>
  236. <legend>
  237. ...
  238. </legend>
  239. </chart>
  240. <printSettings>
  241. </printSettings>
  242. </chartSpace>
  243. */
  244. QXmlStreamWriter writer(device);
  245. writer.writeStartDocument(QStringLiteral("1.0"), true);
  246. // L.4.13.2.2 Chart
  247. //
  248. // chartSpace is the root node, which contains an element defining the chart,
  249. // and an element defining the print settings for the chart.
  250. writer.writeStartElement(QStringLiteral("c:chartSpace"));
  251. writer.writeAttribute(QStringLiteral("xmlns:c"),
  252. QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
  253. writer.writeAttribute(QStringLiteral("xmlns:a"),
  254. QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/main"));
  255. writer.writeAttribute(QStringLiteral("xmlns:r"),
  256. QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
  257. /*
  258. * chart is the root element for the chart. If the chart is a 3D chart,
  259. * then a view3D element is contained, which specifies the 3D view.
  260. * It then has a plot area, which defines a layout and contains an element
  261. * that corresponds to, and defines, the type of chart.
  262. */
  263. d->saveXmlChart(writer);
  264. writer.writeEndElement();// c:chartSpace
  265. writer.writeEndDocument();
  266. }
  267. /*!
  268. * \internal
  269. */
  270. bool Chart::loadFromXmlFile(QIODevice *device)
  271. {
  272. Q_D(Chart);
  273. QXmlStreamReader reader(device);
  274. while (!reader.atEnd())
  275. {
  276. reader.readNextStartElement();
  277. if (reader.tokenType() == QXmlStreamReader::StartElement)
  278. {
  279. if (reader.name() == QLatin1String("chart"))
  280. {
  281. if (!d->loadXmlChart(reader))
  282. {
  283. return false;
  284. }
  285. }
  286. }
  287. }
  288. return true;
  289. }
  290. bool ChartPrivate::loadXmlChart(QXmlStreamReader &reader)
  291. {
  292. Q_ASSERT(reader.name() == QLatin1String("chart"));
  293. // qDebug() << "-------------- loadXmlChart";
  294. while (!reader.atEnd())
  295. {
  296. reader.readNextStartElement();
  297. // qDebug() << "-------------1- " << reader.name();
  298. if (reader.tokenType() == QXmlStreamReader::StartElement)
  299. {
  300. if (reader.name() == QLatin1String("plotArea"))
  301. {
  302. if (!loadXmlPlotArea(reader))
  303. {
  304. return false;
  305. }
  306. }
  307. else if (reader.name() == QLatin1String("title"))
  308. {
  309. //!Todo
  310. if ( loadXmlChartTitle(reader) )
  311. {
  312. }
  313. }
  314. // else if (reader.name() == QLatin1String("legend"))
  315. // {
  316. // loadXmlChartLegend(reader);
  317. // qDebug() << "-------------- loadXmlChartLegend";
  318. // }
  319. }
  320. else if (reader.tokenType() == QXmlStreamReader::EndElement &&
  321. reader.name() == QLatin1String("chart") )
  322. {
  323. break;
  324. }
  325. }
  326. return true;
  327. }
  328. // TO DEBUG: loop is not work, when i looping second element.
  329. /*
  330. dchrt_CT_PlotArea =
  331. element layout { dchrt_CT_Layout }?,
  332. (element areaChart { dchrt_CT_AreaChart }
  333. | element area3DChart { dchrt_ CT_Area3DChart }
  334. | element lineChart { dchrt_CT_LineChart }
  335. | element line3DChart { dchrt_CT_Line3DChart }
  336. | element stockChart { dchrt_CT_StockChart }
  337. | element radarChart { dchrt_CT_RadarChart }
  338. | element scatterChart { dchrt_CT_ScatterChart }
  339. | element pieChart { dchrt_CT_PieChart }
  340. | element pie3DChart { dchrt_CT_Pie3DChart }
  341. | element doughnutChart { dchrt_CT_DoughnutChart }
  342. | element barChart { dchrt_CT_BarChart }
  343. | element bar3DChart { dchrt_CT_Bar3DChart }
  344. | element ofPieChart { dchrt_CT_OfPieChart }
  345. | element surfaceChart { dchrt_CT_SurfaceChart }
  346. | element surface3DChart { dchrt_CT_Surface3DChart }
  347. | element bubbleChart { dchrt_CT_BubbleChart })+,
  348. (element valAx { dchrt_CT_ValAx }
  349. | element catAx { dchrt_CT_CatAx }
  350. | element dateAx { dchrt_CT_DateAx }
  351. | element serAx { dchrt_CT_SerAx })*,
  352. element dTable { dchrt_CT_DTable }?,
  353. element spPr { a_CT_ShapeProperties }?,
  354. element extLst { dchrt_CT_ExtensionList }?
  355. */
  356. bool ChartPrivate::loadXmlPlotArea(QXmlStreamReader &reader)
  357. {
  358. Q_ASSERT(reader.name() == QLatin1String("plotArea"));
  359. // TO DEBUG:
  360. reader.readNext();
  361. while (!reader.atEnd())
  362. {
  363. // qDebug() << "-------------2- " << reader.name();
  364. if (reader.isStartElement())
  365. {
  366. if (!loadXmlPlotAreaElement(reader))
  367. {
  368. qDebug() << "[debug] failed to load plotarea element.";
  369. return false;
  370. }
  371. else if (reader.name() == QLatin1String("legend")) // Why here?
  372. {
  373. loadXmlChartLegend(reader);
  374. // qDebug() << "-------------- loadXmlChartLegend";
  375. }
  376. reader.readNext();
  377. }
  378. else
  379. {
  380. reader.readNext();
  381. }
  382. }
  383. return true;
  384. }
  385. bool ChartPrivate::loadXmlPlotAreaElement(QXmlStreamReader &reader)
  386. {
  387. if (reader.name() == QLatin1String("layout"))
  388. {
  389. //!ToDo extract attributes
  390. layout = readSubTree(reader);
  391. }
  392. else if (reader.name().endsWith(QLatin1String("Chart")))
  393. {
  394. // for pieChart, barChart, ... (choose one)
  395. if ( !loadXmlXxxChart(reader) )
  396. {
  397. qDebug() << "[debug] failed to load chart";
  398. return false;
  399. }
  400. }
  401. else if (reader.name() == QLatin1String("catAx")) // choose one : catAx, dateAx, serAx, valAx
  402. {
  403. // qDebug() << "loadXmlAxisCatAx()";
  404. loadXmlAxisCatAx(reader);
  405. }
  406. else if (reader.name() == QLatin1String("dateAx")) // choose one : catAx, dateAx, serAx, valAx
  407. {
  408. // qDebug() << "loadXmlAxisDateAx()";
  409. loadXmlAxisDateAx(reader);
  410. }
  411. else if (reader.name() == QLatin1String("serAx")) // choose one : catAx, dateAx, serAx, valAx
  412. {
  413. // qDebug() << "loadXmlAxisSerAx()";
  414. loadXmlAxisSerAx(reader);
  415. }
  416. else if (reader.name() == QLatin1String("valAx")) // choose one : catAx, dateAx, serAx, valAx
  417. {
  418. // qDebug() << "loadXmlAxisValAx()";
  419. loadXmlAxisValAx(reader);
  420. }
  421. else if (reader.name() == QLatin1String("dTable"))
  422. {
  423. //!ToDo
  424. // dTable "CT_DTable"
  425. // reader.skipCurrentElement();
  426. }
  427. else if (reader.name() == QLatin1String("spPr"))
  428. {
  429. //!ToDo
  430. // spPr "a:CT_ShapeProperties"
  431. // reader.skipCurrentElement();
  432. }
  433. else if (reader.name() == QLatin1String("extLst"))
  434. {
  435. //!ToDo
  436. // extLst "CT_ExtensionList"
  437. // reader.skipCurrentElement();
  438. }
  439. return true;
  440. }
  441. bool ChartPrivate::loadXmlXxxChart(QXmlStreamReader &reader)
  442. {
  443. const auto& name = reader.name();
  444. if (name == QLatin1String("areaChart"))
  445. {
  446. chartType = Chart::CT_AreaChart;
  447. }
  448. else if (name == QLatin1String("area3DChart"))
  449. {
  450. chartType = Chart::CT_Area3DChart;
  451. }
  452. else if (name == QLatin1String("lineChart"))
  453. {
  454. chartType = Chart::CT_LineChart;
  455. }
  456. else if (name == QLatin1String("line3DChart"))
  457. {
  458. chartType = Chart::CT_Line3DChart;
  459. }
  460. else if (name == QLatin1String("stockChart"))
  461. {
  462. chartType = Chart::CT_StockChart;
  463. }
  464. else if (name == QLatin1String("radarChart"))
  465. {
  466. chartType = Chart::CT_RadarChart;
  467. }
  468. else if (name == QLatin1String("scatterChart"))
  469. {
  470. chartType = Chart::CT_ScatterChart;
  471. }
  472. else if (name == QLatin1String("pieChart"))
  473. {
  474. chartType = Chart::CT_PieChart;
  475. }
  476. else if (name == QLatin1String("pie3DChart"))
  477. {
  478. chartType = Chart::CT_Pie3DChart;
  479. }
  480. else if (name == QLatin1String("doughnutChart"))
  481. {
  482. chartType = Chart::CT_DoughnutChart;
  483. }
  484. else if (name == QLatin1String("barChart"))
  485. {
  486. chartType = Chart::CT_BarChart;
  487. }
  488. else if (name == QLatin1String("bar3DChart"))
  489. {
  490. chartType = Chart::CT_Bar3DChart;
  491. }
  492. else if (name == QLatin1String("ofPieChart"))
  493. {
  494. chartType = Chart::CT_OfPieChart;
  495. }
  496. else if (name == QLatin1String("surfaceChart"))
  497. {
  498. chartType = Chart::CT_SurfaceChart;
  499. }
  500. else if (name == QLatin1String("surface3DChart"))
  501. {
  502. chartType = Chart::CT_Surface3DChart;
  503. }
  504. else if (name == QLatin1String("bubbleChart"))
  505. {
  506. chartType = Chart::CT_BubbleChart;
  507. }
  508. else
  509. {
  510. qDebug() << "[undefined chart type] " << name;
  511. chartType = Chart::CT_NoStatementChart;
  512. return false;
  513. }
  514. while( !reader.atEnd() )
  515. {
  516. reader.readNextStartElement();
  517. if (reader.tokenType() == QXmlStreamReader::StartElement)
  518. {
  519. // dev57
  520. if ( reader.name() == QLatin1String("ser") )
  521. {
  522. loadXmlSer(reader);
  523. }
  524. else if (reader.name() == QLatin1String("varyColors"))
  525. {
  526. }
  527. else if (reader.name() == QLatin1String("barDir"))
  528. {
  529. }
  530. else if (reader.name() == QLatin1String("axId"))
  531. {
  532. //
  533. }
  534. else if (reader.name() == QLatin1String("scatterStyle"))
  535. {
  536. }
  537. else if (reader.name() == QLatin1String("holeSize"))
  538. {
  539. }
  540. else
  541. {
  542. }
  543. }
  544. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  545. reader.name() == name )
  546. {
  547. break;
  548. }
  549. }
  550. return true;
  551. }
  552. bool ChartPrivate::loadXmlSer(QXmlStreamReader &reader)
  553. {
  554. Q_ASSERT(reader.name() == QLatin1String("ser"));
  555. QSharedPointer<XlsxSeries> series = QSharedPointer<XlsxSeries>(new XlsxSeries);
  556. seriesList.append(series);
  557. while ( !reader.atEnd() &&
  558. !(reader.tokenType() == QXmlStreamReader::EndElement &&
  559. reader.name() == QLatin1String("ser")) )
  560. {
  561. if (reader.readNextStartElement())
  562. {
  563. //TODO beide Header noch auswerten RTR 2019.11
  564. const auto& name = reader.name();
  565. if ( name == QLatin1String("tx") )
  566. {
  567. while ( !reader.atEnd() &&
  568. !(reader.tokenType() == QXmlStreamReader::EndElement &&
  569. reader.name() == name))
  570. {
  571. if (reader.readNextStartElement())
  572. {
  573. if (reader.name() == QLatin1String("strRef"))
  574. series->headerV_numRef = loadXmlStrRef(reader);
  575. }
  576. }
  577. }
  578. else if ( name == QLatin1String("cat") ||
  579. name == QLatin1String("xVal") )
  580. {
  581. while ( !reader.atEnd() &&
  582. !(reader.tokenType() == QXmlStreamReader::EndElement &&
  583. reader.name() == name))
  584. {
  585. if (reader.readNextStartElement())
  586. {
  587. if (reader.name() == QLatin1String("numRef"))
  588. series->axDataSource_numRef = loadXmlNumRef(reader);
  589. else
  590. if (reader.name() == QLatin1String("strRef"))
  591. series->headerH_numRef = loadXmlStrRef(reader);
  592. }
  593. }
  594. }
  595. else if (name == QLatin1String("val") || name == QLatin1String("yVal"))
  596. {
  597. while ( !reader.atEnd() &&
  598. !(reader.tokenType() == QXmlStreamReader::EndElement &&
  599. reader.name() == name))
  600. {
  601. if (reader.readNextStartElement())
  602. {
  603. if (reader.name() == QLatin1String("numRef"))
  604. series->numberDataSource_numRef = loadXmlNumRef(reader);
  605. }
  606. }
  607. }
  608. else if (name == QLatin1String("extLst"))
  609. {
  610. while ( !reader.atEnd() &&
  611. !(reader.tokenType() == QXmlStreamReader::EndElement &&
  612. reader.name() == name))
  613. {
  614. reader.readNextStartElement();
  615. }
  616. }
  617. }
  618. }
  619. return true;
  620. }
  621. QString ChartPrivate::loadXmlNumRef(QXmlStreamReader &reader)
  622. {
  623. Q_ASSERT(reader.name() == QLatin1String("numRef"));
  624. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  625. && reader.name() == QLatin1String("numRef")))
  626. {
  627. if (reader.readNextStartElement())
  628. {
  629. if (reader.name() == QLatin1String("f"))
  630. return reader.readElementText();
  631. }
  632. }
  633. return QString();
  634. }
  635. QString ChartPrivate::loadXmlStrRef(QXmlStreamReader &reader)
  636. {
  637. Q_ASSERT(reader.name() == QLatin1String("strRef"));
  638. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  639. && reader.name() == QLatin1String("strRef")))
  640. {
  641. if (reader.readNextStartElement())
  642. {
  643. if (reader.name() == QLatin1String("f"))
  644. return reader.readElementText();
  645. }
  646. }
  647. return QString();
  648. }
  649. void ChartPrivate::saveXmlChart(QXmlStreamWriter &writer) const
  650. {
  651. //----------------------------------------------------
  652. // c:chart
  653. writer.writeStartElement(QStringLiteral("c:chart"));
  654. //----------------------------------------------------
  655. // c:title
  656. saveXmlChartTitle(writer); // write 'chart title'
  657. //----------------------------------------------------
  658. // c:plotArea
  659. writer.writeStartElement(QStringLiteral("c:plotArea"));
  660. // a little workaround for Start- and EndElement with starting ">" and ending without ">"
  661. writer.device()->write("><c:layout>"); //layout
  662. writer.device()->write(layout.toUtf8());
  663. writer.device()->write("</c:layout"); //layout
  664. // dev35
  665. switch (chartType)
  666. {
  667. case Chart::CT_AreaChart: saveXmlAreaChart(writer); break;
  668. case Chart::CT_Area3DChart: saveXmlAreaChart(writer); break;
  669. case Chart::CT_LineChart: saveXmlLineChart(writer); break;
  670. case Chart::CT_Line3DChart: saveXmlLineChart(writer); break;
  671. case Chart::CT_StockChart: break;
  672. case Chart::CT_RadarChart: break;
  673. case Chart::CT_ScatterChart: saveXmlScatterChart(writer); break;
  674. case Chart::CT_PieChart: saveXmlPieChart(writer); break;
  675. case Chart::CT_Pie3DChart: saveXmlPieChart(writer); break;
  676. case Chart::CT_DoughnutChart: saveXmlDoughnutChart(writer); break;
  677. case Chart::CT_BarChart: saveXmlBarChart(writer); break;
  678. case Chart::CT_Bar3DChart: saveXmlBarChart(writer); break;
  679. case Chart::CT_OfPieChart: break;
  680. case Chart::CT_SurfaceChart: break;
  681. case Chart::CT_Surface3DChart: break;
  682. case Chart::CT_BubbleChart: break;
  683. default: break;
  684. }
  685. saveXmlAxis(writer); // c:catAx, c:valAx, c:serAx, c:dateAx (choose one)
  686. //!TODO: write element
  687. // c:dTable CT_DTable
  688. // c:spPr CT_ShapeProperties
  689. // c:extLst CT_ExtensionList
  690. writer.writeEndElement(); // c:plotArea
  691. // c:legend
  692. saveXmlChartLegend(writer); // c:legend
  693. writer.writeEndElement(); // c:chart
  694. }
  695. bool ChartPrivate::loadXmlChartTitle(QXmlStreamReader &reader)
  696. {
  697. //!TODO : load chart title
  698. Q_ASSERT(reader.name() == QLatin1String("title"));
  699. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  700. && reader.name() == QLatin1String("title")))
  701. {
  702. if (reader.readNextStartElement())
  703. {
  704. if (reader.name() == QLatin1String("tx")) // c:tx
  705. return loadXmlChartTitleTx(reader);
  706. }
  707. }
  708. return false;
  709. }
  710. bool ChartPrivate::loadXmlChartTitleTx(QXmlStreamReader &reader)
  711. {
  712. Q_ASSERT(reader.name() == QLatin1String("tx"));
  713. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  714. && reader.name() == QLatin1String("tx")))
  715. {
  716. if (reader.readNextStartElement())
  717. {
  718. if (reader.name() == QLatin1String("rich")) // c:rich
  719. return loadXmlChartTitleTxRich(reader);
  720. }
  721. }
  722. return false;
  723. }
  724. bool ChartPrivate::loadXmlChartTitleTxRich(QXmlStreamReader &reader)
  725. {
  726. Q_ASSERT(reader.name() == QLatin1String("rich"));
  727. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  728. && reader.name() == QLatin1String("rich")))
  729. {
  730. if (reader.readNextStartElement())
  731. {
  732. if (reader.name() == QLatin1String("p")) // a:p
  733. return loadXmlChartTitleTxRichP(reader);
  734. }
  735. }
  736. return false;
  737. }
  738. bool ChartPrivate::loadXmlChartTitleTxRichP(QXmlStreamReader &reader)
  739. {
  740. Q_ASSERT(reader.name() == QLatin1String("p"));
  741. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  742. && reader.name() == QLatin1String("p")))
  743. {
  744. if (reader.readNextStartElement())
  745. {
  746. if (reader.name() == QLatin1String("r")) // a:r
  747. return loadXmlChartTitleTxRichP_R(reader);
  748. }
  749. }
  750. return false;
  751. }
  752. bool ChartPrivate::loadXmlChartTitleTxRichP_R(QXmlStreamReader &reader)
  753. {
  754. Q_ASSERT(reader.name() == QLatin1String("r"));
  755. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  756. && reader.name() == QLatin1String("r")))
  757. {
  758. if (reader.readNextStartElement())
  759. {
  760. if (reader.name() == QLatin1String("t")) // a:t
  761. {
  762. QString textValue = reader.readElementText();
  763. this->chartTitle = textValue;
  764. return true;
  765. }
  766. }
  767. }
  768. return false;
  769. }
  770. // write 'chart title'
  771. void ChartPrivate::saveXmlChartTitle(QXmlStreamWriter &writer) const
  772. {
  773. if ( chartTitle.isEmpty() )
  774. return;
  775. writer.writeStartElement(QStringLiteral("c:title"));
  776. /*
  777. <xsd:complexType name="CT_Title">
  778. <xsd:sequence>
  779. <xsd:element name="tx" type="CT_Tx" minOccurs="0" maxOccurs="1"/>
  780. <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
  781. <xsd:element name="overlay" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  782. <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
  783. <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
  784. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  785. </xsd:sequence>
  786. </xsd:complexType>
  787. */
  788. writer.writeStartElement(QStringLiteral("c:tx"));
  789. /*
  790. <xsd:complexType name="CT_Tx">
  791. <xsd:sequence>
  792. <xsd:choice minOccurs="1" maxOccurs="1">
  793. <xsd:element name="strRef" type="CT_StrRef" minOccurs="1" maxOccurs="1"/>
  794. <xsd:element name="rich" type="a:CT_TextBody" minOccurs="1" maxOccurs="1"/>
  795. </xsd:choice>
  796. </xsd:sequence>
  797. </xsd:complexType>
  798. */
  799. writer.writeStartElement(QStringLiteral("c:rich"));
  800. /*
  801. <xsd:complexType name="CT_TextBody">
  802. <xsd:sequence>
  803. <xsd:element name="bodyPr" type="CT_TextBodyProperties" minOccurs=" 1" maxOccurs="1"/>
  804. <xsd:element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
  805. <xsd:element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
  806. </xsd:sequence>
  807. </xsd:complexType>
  808. */
  809. writer.writeEmptyElement(QStringLiteral("a:bodyPr")); // <a:bodyPr/>
  810. /*
  811. <xsd:complexType name="CT_TextBodyProperties">
  812. <xsd:sequence>
  813. <xsd:element name="prstTxWarp" type="CT_PresetTextShape" minOccurs="0" maxOccurs="1"/>
  814. <xsd:group ref="EG_TextAutofit" minOccurs="0" maxOccurs="1"/>
  815. <xsd:element name="scene3d" type="CT_Scene3D" minOccurs="0" maxOccurs="1"/>
  816. <xsd:group ref="EG_Text3D" minOccurs="0" maxOccurs="1"/>
  817. <xsd:element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
  818. </xsd:sequence>
  819. <xsd:attribute name="rot" type="ST_Angle" use="optional"/>
  820. <xsd:attribute name="spcFirstLastPara" type="xsd:boolean" use="optional"/>
  821. <xsd:attribute name="vertOverflow" type="ST_TextVertOverflowType" use="optional"/>
  822. <xsd:attribute name="horzOverflow" type="ST_TextHorzOverflowType" use="optional"/>
  823. <xsd:attribute name="vert" type="ST_TextVerticalType" use="optional"/>
  824. <xsd:attribute name="wrap" type="ST_TextWrappingType" use="optional"/>
  825. <xsd:attribute name="lIns" type="ST_Coordinate32" use="optional"/>
  826. <xsd:attribute name="tIns" type="ST_Coordinate32" use="optional"/>
  827. <xsd:attribute name="rIns" type="ST_Coordinate32" use="optional"/>
  828. <xsd:attribute name="bIns" type="ST_Coordinate32" use="optional"/>
  829. <xsd:attribute name="numCol" type="ST_TextColumnCount" use="optional"/>
  830. <xsd:attribute name="spcCol" type="ST_PositiveCoordinate32" use="optional"/>
  831. <xsd:attribute name="rtlCol" type="xsd:boolean" use="optional"/>
  832. <xsd:attribute name="fromWordArt" type="xsd:boolean" use="optional"/>
  833. <xsd:attribute name="anchor" type="ST_TextAnchoringType" use="optional"/>
  834. <xsd:attribute name="anchorCtr" type="xsd:boolean" use="optional"/>
  835. <xsd:attribute name="forceAA" type="xsd:boolean" use="optional"/>
  836. <xsd:attribute name="upright" type="xsd:boolean" use="optional" default="false"/>
  837. <xsd:attribute name="compatLnSpc" type="xsd:boolean" use="optional"/>
  838. </xsd:complexType>
  839. */
  840. writer.writeEmptyElement(QStringLiteral("a:lstStyle")); // <a:lstStyle/>
  841. writer.writeStartElement(QStringLiteral("a:p"));
  842. /*
  843. <xsd:complexType name="CT_TextParagraph">
  844. <xsd:sequence>
  845. <xsd:element name="pPr" type="CT_TextParagraphProperties" minOccurs="0" maxOccurs="1"/>
  846. <xsd:group ref="EG_TextRun" minOccurs="0" maxOccurs="unbounded"/>
  847. <xsd:element name="endParaRPr" type="CT_TextCharacterProperties" minOccurs="0"
  848. maxOccurs="1"/>
  849. </xsd:sequence>
  850. </xsd:complexType>
  851. */
  852. // <a:pPr lvl="0">
  853. writer.writeStartElement(QStringLiteral("a:pPr"));
  854. writer.writeAttribute(QStringLiteral("lvl"), QStringLiteral("0"));
  855. // <a:defRPr b="0"/>
  856. writer.writeStartElement(QStringLiteral("a:defRPr"));
  857. writer.writeAttribute(QStringLiteral("b"), QStringLiteral("0"));
  858. writer.writeEndElement(); // a:defRPr
  859. writer.writeEndElement(); // a:pPr
  860. /*
  861. <xsd:group name="EG_TextRun">
  862. <xsd:choice>
  863. <xsd:element name="r" type="CT_RegularTextRun"/>
  864. <xsd:element name="br" type="CT_TextLineBreak"/>
  865. <xsd:element name="fld" type="CT_TextField"/>
  866. </xsd:choice>
  867. </xsd:group>
  868. */
  869. writer.writeStartElement(QStringLiteral("a:r"));
  870. /*
  871. <xsd:complexType name="CT_RegularTextRun">
  872. <xsd:sequence>
  873. <xsd:element name="rPr" type="CT_TextCharacterProperties" minOccurs="0" maxOccurs="1"/>
  874. <xsd:element name="t" type="xsd:string" minOccurs="1" maxOccurs="1"/>
  875. </xsd:sequence>
  876. </xsd:complexType>
  877. */
  878. // <a:t>chart name</a:t>
  879. writer.writeTextElement(QStringLiteral("a:t"), chartTitle);
  880. writer.writeEndElement(); // a:r
  881. writer.writeEndElement(); // a:p
  882. writer.writeEndElement(); // c:rich
  883. writer.writeEndElement(); // c:tx
  884. // <c:overlay val="0"/>
  885. writer.writeStartElement(QStringLiteral("c:overlay"));
  886. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0"));
  887. writer.writeEndElement(); // c:overlay
  888. writer.writeEndElement(); // c:title
  889. }
  890. // }}
  891. // write 'chart legend'
  892. void ChartPrivate::saveXmlChartLegend(QXmlStreamWriter &writer) const
  893. {
  894. if ( legendPos == Chart::None )
  895. return;
  896. // <c:legend>
  897. // <c:legendPos val="r"/>
  898. // <c:overlay val="0"/>
  899. // </c:legend>
  900. writer.writeStartElement(QStringLiteral("c:legend"));
  901. writer.writeStartElement(QStringLiteral("c:legendPos"));
  902. QString pos;
  903. switch( legendPos )
  904. {
  905. //case Chart::ChartAxisPos::Right:
  906. case Chart::Right :
  907. pos = QStringLiteral("r");
  908. break;
  909. // case Chart::ChartAxisPos::Left:
  910. case Chart::Left :
  911. pos = QStringLiteral("l");
  912. break;
  913. // case Chart::ChartAxisPos::Top:
  914. case Chart::Top :
  915. pos = QStringLiteral("t");
  916. break;
  917. // case Chart::ChartAxisPos::Bottom:
  918. case Chart::Bottom :
  919. pos = QStringLiteral("b");
  920. break;
  921. default:
  922. pos = QStringLiteral("r");
  923. break;
  924. }
  925. writer.writeAttribute(QStringLiteral("val"), pos);
  926. writer.writeEndElement(); // c:legendPos
  927. writer.writeStartElement(QStringLiteral("c:overlay"));
  928. if( legendOverlay )
  929. {
  930. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
  931. }
  932. else
  933. {
  934. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0"));
  935. }
  936. writer.writeEndElement(); // c:overlay
  937. writer.writeEndElement(); // c:legend
  938. }
  939. void ChartPrivate::saveXmlPieChart(QXmlStreamWriter &writer) const
  940. {
  941. QString name = chartType == Chart::CT_PieChart ? QStringLiteral("c:pieChart") : QStringLiteral("c:pie3DChart");
  942. writer.writeStartElement(name);
  943. //Do the same behavior as Excel, Pie prefer varyColors
  944. writer.writeEmptyElement(QStringLiteral("c:varyColors"));
  945. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
  946. for (int i=0; i<seriesList.size(); ++i)
  947. saveXmlSer(writer, seriesList[i].data(), i);
  948. writer.writeEndElement(); //pieChart, pie3DChart
  949. }
  950. void ChartPrivate::saveXmlBarChart(QXmlStreamWriter &writer) const
  951. {
  952. QString name = chartType == Chart::CT_BarChart ? QStringLiteral("c:barChart") : QStringLiteral("c:bar3DChart");
  953. writer.writeStartElement(name);
  954. writer.writeEmptyElement(QStringLiteral("c:barDir"));
  955. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("col"));
  956. for ( int i = 0 ; i < seriesList.size() ; ++i )
  957. {
  958. saveXmlSer(writer, seriesList[i].data(), i);
  959. }
  960. if ( axisList.isEmpty() )
  961. {
  962. const_cast<ChartPrivate*>(this)->axisList.append(
  963. QSharedPointer<XlsxAxis>(
  964. new XlsxAxis( XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1, axisNames[XlsxAxis::Bottom] )));
  965. const_cast<ChartPrivate*>(this)->axisList.append(
  966. QSharedPointer<XlsxAxis>(
  967. new XlsxAxis( XlsxAxis::T_Val, XlsxAxis::Left, 1, 0, axisNames[XlsxAxis::Left] )));
  968. }
  969. // Note: Bar3D have 2~3 axes
  970. // int axisListSize = axisList.size();
  971. // [dev62]
  972. // Q_ASSERT( axisListSize == 2 ||
  973. // ( axisListSize == 3 && chartType == Chart::CT_Bar3DChart ) );
  974. for ( int i = 0 ; i < axisList.size() ; ++i )
  975. {
  976. writer.writeEmptyElement(QStringLiteral("c:axId"));
  977. writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
  978. }
  979. writer.writeEndElement(); //barChart, bar3DChart
  980. }
  981. void ChartPrivate::saveXmlLineChart(QXmlStreamWriter &writer) const
  982. {
  983. QString name = chartType==Chart::CT_LineChart ? QStringLiteral("c:lineChart") : QStringLiteral("c:line3DChart");
  984. writer.writeStartElement(name);
  985. // writer.writeEmptyElement(QStringLiteral("grouping")); // dev22
  986. for (int i=0; i<seriesList.size(); ++i)
  987. saveXmlSer(writer, seriesList[i].data(), i);
  988. if (axisList.isEmpty())
  989. {
  990. const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1, axisNames[XlsxAxis::Bottom] )));
  991. const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0, axisNames[XlsxAxis::Left] )));
  992. if (chartType==Chart::CT_Line3DChart)
  993. const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Ser, XlsxAxis::Bottom, 2, 0)));
  994. }
  995. Q_ASSERT((axisList.size()==2||chartType==Chart::CT_LineChart)|| (axisList.size()==3 && chartType==Chart::CT_Line3DChart));
  996. for (int i=0; i<axisList.size(); ++i)
  997. {
  998. writer.writeEmptyElement(QStringLiteral("c:axId"));
  999. writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
  1000. }
  1001. writer.writeEndElement(); //lineChart, line3DChart
  1002. }
  1003. void ChartPrivate::saveXmlScatterChart(QXmlStreamWriter &writer) const
  1004. {
  1005. const QString name = QStringLiteral("c:scatterChart");
  1006. writer.writeStartElement(name);
  1007. writer.writeEmptyElement(QStringLiteral("c:scatterStyle"));
  1008. for (int i=0; i<seriesList.size(); ++i)
  1009. saveXmlSer(writer, seriesList[i].data(), i);
  1010. if (axisList.isEmpty())
  1011. {
  1012. const_cast<ChartPrivate*>(this)->axisList.append(
  1013. QSharedPointer<XlsxAxis>(
  1014. new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Bottom, 0, 1, axisNames[XlsxAxis::Bottom] )));
  1015. const_cast<ChartPrivate*>(this)->axisList.append(
  1016. QSharedPointer<XlsxAxis>(
  1017. new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0, axisNames[XlsxAxis::Left] )));
  1018. }
  1019. int axisListSize = axisList.size();
  1020. Q_ASSERT(axisListSize == 2);
  1021. for (int i=0; i<axisList.size(); ++i)
  1022. {
  1023. writer.writeEmptyElement(QStringLiteral("c:axId"));
  1024. writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
  1025. }
  1026. writer.writeEndElement(); //c:scatterChart
  1027. }
  1028. void ChartPrivate::saveXmlAreaChart(QXmlStreamWriter &writer) const
  1029. {
  1030. QString name = chartType==Chart::CT_AreaChart ? QStringLiteral("c:areaChart") : QStringLiteral("c:area3DChart");
  1031. writer.writeStartElement(name);
  1032. // writer.writeEmptyElement(QStringLiteral("grouping")); // dev22
  1033. for (int i=0; i<seriesList.size(); ++i)
  1034. saveXmlSer(writer, seriesList[i].data(), i);
  1035. if (axisList.isEmpty())
  1036. {
  1037. const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1)));
  1038. const_cast<ChartPrivate*>(this)->axisList.append(QSharedPointer<XlsxAxis>(new XlsxAxis(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0)));
  1039. }
  1040. //Note: Area3D have 2~3 axes
  1041. Q_ASSERT(axisList.size()==2 || (axisList.size()==3 && chartType==Chart::CT_Area3DChart));
  1042. for (int i=0; i<axisList.size(); ++i)
  1043. {
  1044. writer.writeEmptyElement(QStringLiteral("c:axId"));
  1045. writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
  1046. }
  1047. writer.writeEndElement(); //lineChart, line3DChart
  1048. }
  1049. void ChartPrivate::saveXmlDoughnutChart(QXmlStreamWriter &writer) const
  1050. {
  1051. QString name = QStringLiteral("c:doughnutChart");
  1052. writer.writeStartElement(name);
  1053. writer.writeEmptyElement(QStringLiteral("c:varyColors"));
  1054. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
  1055. for (int i=0; i<seriesList.size(); ++i)
  1056. saveXmlSer(writer, seriesList[i].data(), i);
  1057. writer.writeStartElement(QStringLiteral("c:holeSize"));
  1058. writer.writeAttribute(QStringLiteral("val"), QString::number(50));
  1059. writer.writeEndElement();
  1060. }
  1061. void ChartPrivate::saveXmlSer(QXmlStreamWriter &writer, XlsxSeries *ser, int id) const
  1062. {
  1063. writer.writeStartElement(QStringLiteral("c:ser"));
  1064. writer.writeEmptyElement(QStringLiteral("c:idx"));
  1065. writer.writeAttribute(QStringLiteral("val"), QString::number(id));
  1066. writer.writeEmptyElement(QStringLiteral("c:order"));
  1067. writer.writeAttribute(QStringLiteral("val"), QString::number(id));
  1068. QString header1;
  1069. QString header2;
  1070. if( ser->swapHeader )
  1071. {
  1072. header1 = ser->headerH_numRef;
  1073. header2 = ser->headerV_numRef;
  1074. }
  1075. else
  1076. {
  1077. header1 = ser->headerV_numRef;
  1078. header2 = ser->headerH_numRef;
  1079. }
  1080. if( !header1.isEmpty() )
  1081. {
  1082. writer.writeStartElement(QStringLiteral("c:tx"));
  1083. writer.writeStartElement(QStringLiteral("c:strRef"));
  1084. writer.writeTextElement(QStringLiteral("c:f"), header1);
  1085. writer.writeEndElement();
  1086. writer.writeEndElement();
  1087. }
  1088. if( !header2.isEmpty() )
  1089. {
  1090. writer.writeStartElement(QStringLiteral("c:cat"));
  1091. writer.writeStartElement(QStringLiteral("c:strRef"));
  1092. writer.writeTextElement(QStringLiteral("c:f"), header2);
  1093. writer.writeEndElement();
  1094. writer.writeEndElement();
  1095. }
  1096. #if 0
  1097. if (!ser->axDataSource_numRef.isEmpty())
  1098. {
  1099. if (chartType == Chart::CT_ScatterChart || chartType == Chart::CT_BubbleChart)
  1100. {
  1101. writer.writeStartElement(QStringLiteral("c:xVal"));
  1102. }
  1103. else
  1104. {
  1105. writer.writeStartElement(QStringLiteral("c:cat"));
  1106. }
  1107. writer.writeStartElement(QStringLiteral("c:numRef"));
  1108. writer.writeTextElement(QStringLiteral("c:f"), ser->axDataSource_numRef);
  1109. writer.writeEndElement();//c:numRef
  1110. writer.writeEndElement();//c:cat or c:xVal
  1111. }
  1112. #endif
  1113. if (!ser->numberDataSource_numRef.isEmpty())
  1114. {
  1115. if (chartType == Chart::CT_ScatterChart || chartType == Chart::CT_BubbleChart)
  1116. writer.writeStartElement(QStringLiteral("c:yVal"));
  1117. else
  1118. writer.writeStartElement(QStringLiteral("c:val"));
  1119. writer.writeStartElement(QStringLiteral("c:numRef"));
  1120. writer.writeTextElement(QStringLiteral("c:f"), ser->numberDataSource_numRef);
  1121. writer.writeEndElement();//c:numRef
  1122. writer.writeEndElement();//c:val or c:yVal
  1123. }
  1124. writer.writeEndElement();//c:ser
  1125. }
  1126. bool ChartPrivate::loadXmlAxisCatAx(QXmlStreamReader &reader)
  1127. {
  1128. XlsxAxis* axis = new XlsxAxis();
  1129. axis->type = XlsxAxis::T_Cat;
  1130. axisList.append( QSharedPointer<XlsxAxis>(axis) );
  1131. // load EG_AxShared
  1132. if ( ! loadXmlAxisEG_AxShared( reader, axis ) )
  1133. {
  1134. qDebug() << "failed to load EG_AxShared";
  1135. return false;
  1136. }
  1137. //!TODO: load element
  1138. // auto
  1139. // lblAlgn
  1140. // lblOffset
  1141. // tickLblSkip
  1142. // tickMarkSkip
  1143. // noMultiLvlLbl
  1144. // extLst
  1145. return true;
  1146. }
  1147. bool ChartPrivate::loadXmlAxisDateAx(QXmlStreamReader &reader)
  1148. {
  1149. XlsxAxis* axis = new XlsxAxis();
  1150. axis->type = XlsxAxis::T_Date;
  1151. axisList.append( QSharedPointer<XlsxAxis>(axis) );
  1152. // load EG_AxShared
  1153. if ( ! loadXmlAxisEG_AxShared( reader, axis ) )
  1154. {
  1155. qDebug() << "failed to load EG_AxShared";
  1156. return false;
  1157. }
  1158. //!TODO: load element
  1159. // auto
  1160. // lblOffset
  1161. // baseTimeUnit
  1162. // majorUnit
  1163. // majorTimeUnit
  1164. // minorUnit
  1165. // minorTimeUnit
  1166. // extLst
  1167. return true;
  1168. }
  1169. bool ChartPrivate::loadXmlAxisSerAx(QXmlStreamReader &reader)
  1170. {
  1171. XlsxAxis* axis = new XlsxAxis();
  1172. axis->type = XlsxAxis::T_Ser;
  1173. axisList.append( QSharedPointer<XlsxAxis>(axis) );
  1174. // load EG_AxShared
  1175. if ( ! loadXmlAxisEG_AxShared( reader, axis ) )
  1176. {
  1177. qDebug() << "failed to load EG_AxShared";
  1178. return false;
  1179. }
  1180. //!TODO: load element
  1181. // tickLblSkip
  1182. // tickMarkSkip
  1183. // extLst
  1184. return true;
  1185. }
  1186. bool ChartPrivate::loadXmlAxisValAx(QXmlStreamReader &reader)
  1187. {
  1188. Q_ASSERT(reader.name() == QLatin1String("valAx"));
  1189. XlsxAxis* axis = new XlsxAxis();
  1190. axis->type = XlsxAxis::T_Val;
  1191. axisList.append( QSharedPointer<XlsxAxis>(axis) );
  1192. if ( ! loadXmlAxisEG_AxShared( reader, axis ) )
  1193. {
  1194. qDebug() << "failed to load EG_AxShared";
  1195. return false;
  1196. }
  1197. //!TODO: load element
  1198. // crossBetween
  1199. // majorUnit
  1200. // minorUnit
  1201. // dispUnits
  1202. // extLst
  1203. return true;
  1204. }
  1205. /*
  1206. <xsd:group name="EG_AxShared">
  1207. <xsd:sequence>
  1208. <xsd:element name="axId" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)(M)
  1209. <xsd:element name="scaling" type="CT_Scaling" minOccurs="1" maxOccurs="1"/> (*)(M)
  1210. <xsd:element name="delete" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1211. <xsd:element name="axPos" type="CT_AxPos" minOccurs="1" maxOccurs="1"/> (*)(M)
  1212. <xsd:element name="majorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
  1213. <xsd:element name="minorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
  1214. <xsd:element name="title" type="CT_Title" minOccurs="0" maxOccurs="1"/> (*)
  1215. <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0" maxOccurs="1"/>
  1216. <xsd:element name="majorTickMark" type="CT_TickMark" minOccurs="0" maxOccurs="1"/>
  1217. <xsd:element name="minorTickMark" type="CT_TickMark" minOccurs="0" maxOccurs="1"/>
  1218. <xsd:element name="tickLblPos" type="CT_TickLblPos" minOccurs="0" maxOccurs="1"/>
  1219. <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
  1220. <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
  1221. <xsd:element name="crossAx" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)(M)
  1222. <xsd:choice minOccurs="0" maxOccurs="1">
  1223. <xsd:element name="crosses" type="CT_Crosses" minOccurs="1" maxOccurs="1"/>
  1224. <xsd:element name="crossesAt" type="CT_Double" minOccurs="1" maxOccurs="1"/>
  1225. </xsd:choice>
  1226. </xsd:sequence>
  1227. </xsd:group>
  1228. */
  1229. bool ChartPrivate::loadXmlAxisEG_AxShared(QXmlStreamReader &reader, XlsxAxis* axis)
  1230. {
  1231. Q_ASSERT( NULL != axis );
  1232. Q_ASSERT( reader.name().endsWith(QLatin1String("Ax")) );
  1233. QString name = reader.name().toString(); //
  1234. while ( !reader.atEnd() )
  1235. {
  1236. reader.readNextStartElement();
  1237. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1238. {
  1239. // qDebug() << "[debug]" << QTime::currentTime() << reader.name().toString();
  1240. if ( reader.name() == QLatin1String("axId") ) // mandatory element
  1241. {
  1242. // dev57
  1243. uint axId = reader.attributes().value(QStringLiteral("val")).toString().toUInt(); // for Qt5.1
  1244. axis->axisId = axId;
  1245. }
  1246. else if ( reader.name() == QLatin1String("scaling") )
  1247. {
  1248. // mandatory element
  1249. loadXmlAxisEG_AxShared_Scaling(reader, axis);
  1250. }
  1251. else if ( reader.name() == QLatin1String("delete") )
  1252. {
  1253. //!TODO
  1254. }
  1255. else if ( reader.name() == QLatin1String("axPos") )
  1256. {
  1257. // mandatory element
  1258. QString axPosVal = reader.attributes().value(QLatin1String("val")).toString();
  1259. if ( axPosVal == QLatin1String("l") ) { axis->axisPos = XlsxAxis::Left; }
  1260. else if ( axPosVal == QLatin1String("r") ) { axis->axisPos = XlsxAxis::Right; }
  1261. else if ( axPosVal == QLatin1String("t") ) { axis->axisPos = XlsxAxis::Top; }
  1262. else if ( axPosVal == QLatin1String("b") ) { axis->axisPos = XlsxAxis::Bottom; }
  1263. }
  1264. else if ( reader.name() == QLatin1String("majorGridlines") )
  1265. {
  1266. //!TODO anything else?
  1267. majorGridlinesEnabled = true;
  1268. }
  1269. else if ( reader.name() == QLatin1String("minorGridlines") )
  1270. {
  1271. //!TODO anything else?
  1272. minorGridlinesEnabled = true;
  1273. }
  1274. else if ( reader.name() == QLatin1String("title") )
  1275. {
  1276. // title
  1277. if ( !loadXmlAxisEG_AxShared_Title(reader, axis) )
  1278. {
  1279. qDebug() << "failed to load EG_AxShared title.";
  1280. Q_ASSERT(false);
  1281. return false;
  1282. }
  1283. }
  1284. else if ( reader.name() == QLatin1String("numFmt") )
  1285. {
  1286. //!TODO
  1287. }
  1288. else if ( reader.name() == QLatin1String("majorTickMark") )
  1289. {
  1290. //!TODO
  1291. }
  1292. else if ( reader.name() == QLatin1String("minorTickMark") )
  1293. {
  1294. //!TODO
  1295. }
  1296. else if ( reader.name() == QLatin1String("tickLblPos") )
  1297. {
  1298. //!TODO
  1299. }
  1300. else if ( reader.name() == QLatin1String("spPr") )
  1301. {
  1302. //!TODO
  1303. }
  1304. else if ( reader.name() == QLatin1String("txPr") )
  1305. {
  1306. //!TODO
  1307. }
  1308. else if ( reader.name() == QLatin1String("crossAx") ) // mandatory element
  1309. {
  1310. // dev57
  1311. uint crossAx = reader.attributes().value(QLatin1String("val")).toString().toUInt(); // for Qt5.1
  1312. axis->crossAx = crossAx;
  1313. }
  1314. else if ( reader.name() == QLatin1String("crosses") )
  1315. {
  1316. //!TODO
  1317. }
  1318. else if ( reader.name() == QLatin1String("crossesAt") )
  1319. {
  1320. //!TODO
  1321. }
  1322. // reader.readNext();
  1323. }
  1324. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1325. reader.name().toString() == name )
  1326. {
  1327. break;
  1328. }
  1329. }
  1330. return true;
  1331. }
  1332. bool ChartPrivate::loadXmlAxisEG_AxShared_Scaling(QXmlStreamReader &reader, XlsxAxis* axis)
  1333. {
  1334. Q_UNUSED(axis);
  1335. Q_ASSERT(reader.name() == QLatin1String("scaling"));
  1336. while ( !reader.atEnd() )
  1337. {
  1338. reader.readNextStartElement();
  1339. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1340. {
  1341. if ( reader.name() == QLatin1String("orientation") )
  1342. {
  1343. }
  1344. else
  1345. {
  1346. }
  1347. }
  1348. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1349. reader.name() == QLatin1String("scaling") )
  1350. {
  1351. break;
  1352. }
  1353. }
  1354. return true;
  1355. }
  1356. /*
  1357. <xsd:complexType name="CT_Title">
  1358. <xsd:sequence>
  1359. <xsd:element name="tx" type="CT_Tx" minOccurs="0" maxOccurs="1"/>
  1360. <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
  1361. <xsd:element name="overlay" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1362. <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
  1363. <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
  1364. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1365. </xsd:sequence>
  1366. </xsd:complexType>
  1367. <xsd:complexType name="CT_Tx">
  1368. <xsd:sequence>
  1369. <xsd:choice minOccurs="1" maxOccurs="1">
  1370. <xsd:element name="strRef" type="CT_StrRef" minOccurs="1" maxOccurs="1"/>
  1371. <xsd:element name="rich" type="a:CT_TextBody" minOccurs="1" maxOccurs="1"/>
  1372. </xsd:choice>
  1373. </xsd:sequence>
  1374. </xsd:complexType>
  1375. <xsd:complexType name="CT_StrRef">
  1376. <xsd:sequence>
  1377. <xsd:element name="f" type="xsd:string" minOccurs="1" maxOccurs="1"/>
  1378. <xsd:element name="strCache" type="CT_StrData" minOccurs="0" maxOccurs="1"/>
  1379. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1380. </xsd:sequence>
  1381. </xsd:complexType>
  1382. <xsd:complexType name="CT_TextBody">
  1383. <xsd:sequence>
  1384. <xsd:element name="bodyPr" type="CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
  1385. <xsd:element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
  1386. <xsd:element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
  1387. </xsd:sequence>
  1388. </xsd:complexType>
  1389. */
  1390. bool ChartPrivate::loadXmlAxisEG_AxShared_Title(QXmlStreamReader &reader, XlsxAxis* axis)
  1391. {
  1392. Q_ASSERT(reader.name() == QLatin1String("title"));
  1393. while ( !reader.atEnd() )
  1394. {
  1395. reader.readNextStartElement();
  1396. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1397. {
  1398. if ( reader.name() == QLatin1String("tx") )
  1399. {
  1400. loadXmlAxisEG_AxShared_Title_Tx(reader, axis);
  1401. }
  1402. else if ( reader.name() == QLatin1String("overlay") )
  1403. {
  1404. //!TODO: load overlay
  1405. loadXmlAxisEG_AxShared_Title_Overlay(reader, axis);
  1406. }
  1407. else
  1408. {
  1409. }
  1410. }
  1411. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1412. reader.name() == QLatin1String("title") )
  1413. {
  1414. break;
  1415. }
  1416. }
  1417. return true;
  1418. }
  1419. bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Overlay(QXmlStreamReader &reader, XlsxAxis* axis)
  1420. {
  1421. Q_UNUSED(axis);
  1422. Q_ASSERT(reader.name() == QLatin1String("overlay"));
  1423. while ( !reader.atEnd() )
  1424. {
  1425. reader.readNextStartElement();
  1426. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1427. {
  1428. }
  1429. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1430. reader.name() == QLatin1String("overlay") )
  1431. {
  1432. break;
  1433. }
  1434. }
  1435. return true;
  1436. }
  1437. bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx(QXmlStreamReader &reader, XlsxAxis* axis)
  1438. {
  1439. Q_ASSERT(reader.name() == QLatin1String("tx"));
  1440. while ( !reader.atEnd() )
  1441. {
  1442. reader.readNextStartElement();
  1443. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1444. {
  1445. if ( reader.name() == QLatin1String("rich") )
  1446. {
  1447. loadXmlAxisEG_AxShared_Title_Tx_Rich(reader, axis);
  1448. }
  1449. else
  1450. {
  1451. }
  1452. }
  1453. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1454. reader.name() == QLatin1String("tx") )
  1455. {
  1456. break;
  1457. }
  1458. }
  1459. return true;
  1460. }
  1461. bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich(QXmlStreamReader &reader, XlsxAxis* axis)
  1462. {
  1463. Q_ASSERT(reader.name() == QLatin1String("rich"));
  1464. while ( !reader.atEnd() )
  1465. {
  1466. reader.readNextStartElement();
  1467. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1468. {
  1469. if ( reader.name() == QLatin1String("p") )
  1470. {
  1471. loadXmlAxisEG_AxShared_Title_Tx_Rich_P(reader, axis);
  1472. }
  1473. else
  1474. {
  1475. }
  1476. }
  1477. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1478. reader.name() == QLatin1String("rich") )
  1479. {
  1480. break;
  1481. }
  1482. }
  1483. return true;
  1484. }
  1485. bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich_P(QXmlStreamReader &reader, XlsxAxis* axis)
  1486. {
  1487. Q_ASSERT(reader.name() == QLatin1String("p"));
  1488. while ( !reader.atEnd() )
  1489. {
  1490. reader.readNextStartElement();
  1491. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1492. {
  1493. if ( reader.name() == QLatin1String("r") )
  1494. {
  1495. loadXmlAxisEG_AxShared_Title_Tx_Rich_P_R(reader, axis);
  1496. }
  1497. else if ( reader.name() == QLatin1String("pPr") )
  1498. {
  1499. loadXmlAxisEG_AxShared_Title_Tx_Rich_P_pPr(reader, axis);
  1500. }
  1501. else
  1502. {
  1503. }
  1504. }
  1505. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1506. reader.name() == QLatin1String("p") )
  1507. {
  1508. break;
  1509. }
  1510. }
  1511. return true;
  1512. }
  1513. bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich_P_pPr(QXmlStreamReader &reader, XlsxAxis* axis)
  1514. {
  1515. Q_UNUSED(axis);
  1516. Q_ASSERT(reader.name() == QLatin1String("pPr"));
  1517. while ( !reader.atEnd() )
  1518. {
  1519. reader.readNextStartElement();
  1520. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1521. {
  1522. if ( reader.name() == QLatin1String("defRPr") )
  1523. {
  1524. reader.readElementText();
  1525. }
  1526. else
  1527. {
  1528. }
  1529. }
  1530. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1531. reader.name() == QLatin1String("pPr") )
  1532. {
  1533. break;
  1534. }
  1535. }
  1536. return true;
  1537. }
  1538. bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich_P_R(QXmlStreamReader &reader, XlsxAxis* axis)
  1539. {
  1540. Q_ASSERT(reader.name() == QLatin1String("r"));
  1541. while ( !reader.atEnd() )
  1542. {
  1543. reader.readNextStartElement();
  1544. if ( reader.tokenType() == QXmlStreamReader::StartElement )
  1545. {
  1546. if ( reader.name() == QLatin1String("t") )
  1547. {
  1548. QString strAxisName = reader.readElementText();
  1549. XlsxAxis::AxisPos axisPos = axis->axisPos;
  1550. axis->axisNames[ axisPos ] = strAxisName;
  1551. }
  1552. else
  1553. {
  1554. }
  1555. }
  1556. else if ( reader.tokenType() == QXmlStreamReader::EndElement &&
  1557. reader.name() == QLatin1String("r") )
  1558. {
  1559. break;
  1560. }
  1561. }
  1562. return true;
  1563. }
  1564. /*
  1565. <xsd:complexType name="CT_PlotArea">
  1566. <xsd:sequence>
  1567. <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
  1568. <xsd:choice minOccurs="1" maxOccurs="unbounded">
  1569. <xsd:element name="areaChart" type="CT_AreaChart" minOccurs="1" maxOccurs="1"/>
  1570. <xsd:element name="area3DChart" type="CT_Area3DChart" minOccurs="1" maxOccurs="1"/>
  1571. <xsd:element name="lineChart" type="CT_LineChart" minOccurs="1" maxOccurs="1"/>
  1572. <xsd:element name="line3DChart" type="CT_Line3DChart" minOccurs="1" maxOccurs="1"/>
  1573. <xsd:element name="stockChart" type="CT_StockChart" minOccurs="1" maxOccurs="1"/>
  1574. <xsd:element name="radarChart" type="CT_RadarChart" minOccurs="1" maxOccurs="1"/>
  1575. <xsd:element name="scatterChart" type="CT_ScatterChart" minOccurs="1" maxOccurs="1"/>
  1576. <xsd:element name="pieChart" type="CT_PieChart" minOccurs="1" maxOccurs="1"/>
  1577. <xsd:element name="pie3DChart" type="CT_Pie3DChart" minOccurs="1" maxOccurs="1"/>
  1578. <xsd:element name="doughnutChart" type="CT_DoughnutChart" minOccurs="1" maxOccurs="1"/>
  1579. <xsd:element name="barChart" type="CT_BarChart" minOccurs="1" maxOccurs="1"/>
  1580. <xsd:element name="bar3DChart" type="CT_Bar3DChart" minOccurs="1" maxOccurs="1"/>
  1581. <xsd:element name="ofPieChart" type="CT_OfPieChart" minOccurs="1" maxOccurs="1"/>
  1582. <xsd:element name="surfaceChart" type="CT_SurfaceChart" minOccurs="1" maxOccurs="1"/>
  1583. <xsd:element name="surface3DChart" type="CT_Surface3DChart" minOccurs="1" maxOccurs="1"/>
  1584. <xsd:element name="bubbleChart" type="CT_BubbleChart" minOccurs="1" maxOccurs="1"/>
  1585. </xsd:choice>
  1586. <xsd:choice minOccurs="0" maxOccurs="unbounded">
  1587. <xsd:element name="valAx" type="CT_ValAx" minOccurs="1" maxOccurs="1"/>
  1588. <xsd:element name="catAx" type="CT_CatAx" minOccurs="1" maxOccurs="1"/>
  1589. <xsd:element name="dateAx" type="CT_DateAx" minOccurs="1" maxOccurs="1"/>
  1590. <xsd:element name="serAx" type="CT_SerAx" minOccurs="1" maxOccurs="1"/>
  1591. </xsd:choice>
  1592. <xsd:element name="dTable" type="CT_DTable" minOccurs="0" maxOccurs="1"/>
  1593. <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
  1594. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1595. </xsd:sequence>
  1596. </xsd:complexType>
  1597. */
  1598. /*
  1599. <xsd:complexType name="CT_CatAx">
  1600. <xsd:sequence>
  1601. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1602. <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1603. <xsd:element name="lblAlgn" type="CT_LblAlgn" minOccurs="0" maxOccurs="1"/>
  1604. <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
  1605. <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1606. <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1607. <xsd:element name="noMultiLvlLbl" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1608. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1609. </xsd:sequence>
  1610. </xsd:complexType>
  1611. <!----------------------------------------------------------------------------->
  1612. <xsd:complexType name="CT_DateAx">
  1613. <xsd:sequence>
  1614. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1615. <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1616. <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
  1617. <xsd:element name="baseTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
  1618. <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1619. <xsd:element name="majorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
  1620. <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1621. <xsd:element name="minorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
  1622. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1623. </xsd:sequence>
  1624. </xsd:complexType>
  1625. <!----------------------------------------------------------------------------->
  1626. <xsd:complexType name="CT_SerAx">
  1627. <xsd:sequence>
  1628. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1629. <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1630. <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1631. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1632. </xsd:sequence>
  1633. </xsd:complexType>
  1634. <!----------------------------------------------------------------------------->
  1635. <xsd:complexType name="CT_ValAx">
  1636. <xsd:sequence>
  1637. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1638. <xsd:element name="crossBetween" type="CT_CrossBetween" minOccurs="0" maxOccurs="1"/>
  1639. <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1640. <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1641. <xsd:element name="dispUnits" type="CT_DispUnits" minOccurs="0" maxOccurs="1"/>
  1642. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1643. </xsd:sequence>
  1644. </xsd:complexType>
  1645. */
  1646. void ChartPrivate::saveXmlAxis(QXmlStreamWriter &writer) const
  1647. {
  1648. for ( int i = 0 ; i < axisList.size() ; ++i )
  1649. {
  1650. XlsxAxis* axis = axisList[i].data();
  1651. if ( NULL == axis )
  1652. continue;
  1653. if ( axis->type == XlsxAxis::T_Cat ) { saveXmlAxisCatAx( writer, axis ); }
  1654. if ( axis->type == XlsxAxis::T_Val ) { saveXmlAxisValAx( writer, axis ); }
  1655. if ( axis->type == XlsxAxis::T_Ser ) { saveXmlAxisSerAx( writer, axis ); }
  1656. if ( axis->type == XlsxAxis::T_Date ) { saveXmlAxisDateAx( writer, axis ); }
  1657. }
  1658. }
  1659. void ChartPrivate::saveXmlAxisCatAx(QXmlStreamWriter &writer, XlsxAxis* axis) const
  1660. {
  1661. /*
  1662. <xsd:complexType name="CT_CatAx">
  1663. <xsd:sequence>
  1664. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1665. <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1666. <xsd:element name="lblAlgn" type="CT_LblAlgn" minOccurs="0" maxOccurs="1"/>
  1667. <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
  1668. <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1669. <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1670. <xsd:element name="noMultiLvlLbl" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1671. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1672. </xsd:sequence>
  1673. </xsd:complexType>
  1674. */
  1675. writer.writeStartElement(QStringLiteral("c:catAx"));
  1676. saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
  1677. //!TODO: write element
  1678. // auto
  1679. // lblAlgn
  1680. // lblOffset
  1681. // tickLblSkip
  1682. // tickMarkSkip
  1683. // noMultiLvlLbl
  1684. // extLst
  1685. writer.writeEndElement(); // c:catAx
  1686. }
  1687. void ChartPrivate::saveXmlAxisDateAx(QXmlStreamWriter &writer, XlsxAxis* axis) const
  1688. {
  1689. /*
  1690. <xsd:complexType name="CT_DateAx">
  1691. <xsd:sequence>
  1692. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1693. <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1694. <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
  1695. <xsd:element name="baseTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
  1696. <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1697. <xsd:element name="majorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
  1698. <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1699. <xsd:element name="minorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
  1700. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1701. </xsd:sequence>
  1702. </xsd:complexType>
  1703. */
  1704. writer.writeStartElement(QStringLiteral("c:dateAx"));
  1705. saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
  1706. //!TODO: write element
  1707. // auto
  1708. // lblOffset
  1709. // baseTimeUnit
  1710. // majorUnit
  1711. // majorTimeUnit
  1712. // minorUnit
  1713. // minorTimeUnit
  1714. // extLst
  1715. writer.writeEndElement(); // c:dateAx
  1716. }
  1717. void ChartPrivate::saveXmlAxisSerAx(QXmlStreamWriter &writer, XlsxAxis* axis) const
  1718. {
  1719. /*
  1720. <xsd:complexType name="CT_SerAx">
  1721. <xsd:sequence>
  1722. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1723. <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1724. <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
  1725. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1726. </xsd:sequence>
  1727. </xsd:complexType>
  1728. */
  1729. writer.writeStartElement(QStringLiteral("c:serAx"));
  1730. saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
  1731. //!TODO: write element
  1732. // tickLblSkip
  1733. // tickMarkSkip
  1734. // extLst
  1735. writer.writeEndElement(); // c:serAx
  1736. }
  1737. void ChartPrivate::saveXmlAxisValAx(QXmlStreamWriter &writer, XlsxAxis* axis) const
  1738. {
  1739. /*
  1740. <xsd:complexType name="CT_ValAx">
  1741. <xsd:sequence>
  1742. <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
  1743. <xsd:element name="crossBetween" type="CT_CrossBetween" minOccurs="0" maxOccurs="1"/>
  1744. <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1745. <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
  1746. <xsd:element name="dispUnits" type="CT_DispUnits" minOccurs="0" maxOccurs="1"/>
  1747. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1748. </xsd:sequence>
  1749. </xsd:complexType>
  1750. */
  1751. writer.writeStartElement(QStringLiteral("c:valAx"));
  1752. saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
  1753. //!TODO: write element
  1754. // crossBetween
  1755. // majorUnit
  1756. // minorUnit
  1757. // dispUnits
  1758. // extLst
  1759. writer.writeEndElement(); // c:valAx
  1760. }
  1761. void ChartPrivate::saveXmlAxisEG_AxShared(QXmlStreamWriter &writer, XlsxAxis* axis) const
  1762. {
  1763. /*
  1764. <xsd:group name="EG_AxShared">
  1765. <xsd:sequence>
  1766. <xsd:element name="axId" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)
  1767. <xsd:element name="scaling" type="CT_Scaling" minOccurs="1" maxOccurs="1"/> (*)
  1768. <xsd:element name="delete" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1769. <xsd:element name="axPos" type="CT_AxPos" minOccurs="1" maxOccurs="1"/> (*)
  1770. <xsd:element name="majorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
  1771. <xsd:element name="minorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
  1772. <xsd:element name="title" type="CT_Title" minOccurs="0" maxOccurs="1"/> (***********************)
  1773. <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0" maxOccurs="1"/>
  1774. <xsd:element name="majorTickMark" type="CT_TickMark" minOccurs="0" maxOccurs="1"/>
  1775. <xsd:element name="minorTickMark" type="CT_TickMark" minOccurs="0" maxOccurs="1"/>
  1776. <xsd:element name="tickLblPos" type="CT_TickLblPos" minOccurs="0" maxOccurs="1"/>
  1777. <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
  1778. <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
  1779. <xsd:element name="crossAx" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)
  1780. <xsd:choice minOccurs="0" maxOccurs="1">
  1781. <xsd:element name="crosses" type="CT_Crosses" minOccurs="1" maxOccurs="1"/>
  1782. <xsd:element name="crossesAt" type="CT_Double" minOccurs="1" maxOccurs="1"/>
  1783. </xsd:choice>
  1784. </xsd:sequence>
  1785. </xsd:group>
  1786. */
  1787. writer.writeEmptyElement(QStringLiteral("c:axId")); // 21.2.2.9. axId (Axis ID) (mandatory value)
  1788. writer.writeAttribute(QStringLiteral("val"), QString::number(axis->axisId));
  1789. writer.writeStartElement(QStringLiteral("c:scaling")); // CT_Scaling (mandatory value)
  1790. writer.writeEmptyElement(QStringLiteral("c:orientation")); // CT_Orientation
  1791. writer.writeAttribute(QStringLiteral("val"), QStringLiteral("minMax")); // ST_Orientation
  1792. writer.writeEndElement(); // c:scaling
  1793. writer.writeEmptyElement(QStringLiteral("c:axPos")); // axPos CT_AxPos (mandatory value)
  1794. QString pos = GetAxisPosString( axis->axisPos );
  1795. if ( !pos.isEmpty() )
  1796. {
  1797. writer.writeAttribute(QStringLiteral("val"), pos); // ST_AxPos
  1798. }
  1799. if( majorGridlinesEnabled )
  1800. {
  1801. writer.writeEmptyElement(QStringLiteral("c:majorGridlines"));
  1802. }
  1803. if( minorGridlinesEnabled )
  1804. {
  1805. writer.writeEmptyElement(QStringLiteral("c:minorGridlines"));
  1806. }
  1807. saveXmlAxisEG_AxShared_Title(writer, axis); // "c:title" CT_Title
  1808. writer.writeEmptyElement(QStringLiteral("c:crossAx")); // crossAx (mandatory value)
  1809. writer.writeAttribute(QStringLiteral("val"), QString::number(axis->crossAx));
  1810. }
  1811. void ChartPrivate::saveXmlAxisEG_AxShared_Title(QXmlStreamWriter &writer, XlsxAxis* axis) const
  1812. {
  1813. // CT_Title
  1814. /*
  1815. <xsd:complexType name="CT_Title">
  1816. <xsd:sequence>
  1817. <xsd:element name="tx" type="CT_Tx" minOccurs="0" maxOccurs="1"/>
  1818. <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
  1819. <xsd:element name="overlay" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
  1820. <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
  1821. <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
  1822. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1823. </xsd:sequence>
  1824. </xsd:complexType>
  1825. */
  1826. /*
  1827. <xsd:complexType name="CT_Tx">
  1828. <xsd:sequence>
  1829. <xsd:choice minOccurs="1" maxOccurs="1">
  1830. <xsd:element name="strRef" type="CT_StrRef" minOccurs="1" maxOccurs="1"/>
  1831. <xsd:element name="rich" type="a:CT_TextBody" minOccurs="1" maxOccurs="1"/>
  1832. </xsd:choice>
  1833. </xsd:sequence>
  1834. </xsd:complexType>
  1835. */
  1836. /*
  1837. <xsd:complexType name="CT_StrRef">
  1838. <xsd:sequence>
  1839. <xsd:element name="f" type="xsd:string" minOccurs="1" maxOccurs="1"/>
  1840. <xsd:element name="strCache" type="CT_StrData" minOccurs="0" maxOccurs="1"/>
  1841. <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
  1842. </xsd:sequence>
  1843. </xsd:complexType>
  1844. */
  1845. /*
  1846. <xsd:complexType name="CT_TextBody">
  1847. <xsd:sequence>
  1848. <xsd:element name="bodyPr" type="CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
  1849. <xsd:element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
  1850. <xsd:element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
  1851. </xsd:sequence>
  1852. </xsd:complexType>
  1853. */
  1854. writer.writeStartElement(QStringLiteral("c:title"));
  1855. // CT_Tx {{
  1856. writer.writeStartElement(QStringLiteral("c:tx"));
  1857. writer.writeStartElement(QStringLiteral("c:rich")); // CT_TextBody
  1858. writer.writeEmptyElement(QStringLiteral("a:bodyPr")); // CT_TextBodyProperties
  1859. writer.writeEmptyElement(QStringLiteral("a:lstStyle")); // CT_TextListStyle
  1860. writer.writeStartElement(QStringLiteral("a:p"));
  1861. writer.writeStartElement(QStringLiteral("a:pPr"));
  1862. writer.writeAttribute(QStringLiteral("lvl"), QString::number(0));
  1863. writer.writeStartElement(QStringLiteral("a:defRPr"));
  1864. writer.writeAttribute(QStringLiteral("b"), QString::number(0));
  1865. writer.writeEndElement(); // a:defRPr
  1866. writer.writeEndElement(); // a:pPr
  1867. writer.writeStartElement(QStringLiteral("a:r"));
  1868. QString strAxisName = GetAxisName(axis);
  1869. writer.writeTextElement( QStringLiteral("a:t"), strAxisName );
  1870. writer.writeEndElement(); // a:r
  1871. writer.writeEndElement(); // a:p
  1872. writer.writeEndElement(); // c:rich
  1873. writer.writeEndElement(); // c:tx
  1874. // CT_Tx }}
  1875. writer.writeStartElement(QStringLiteral("c:overlay"));
  1876. writer.writeAttribute(QStringLiteral("val"), QString::number(0)); // CT_Boolean
  1877. writer.writeEndElement(); // c:overlay
  1878. writer.writeEndElement(); // c:title
  1879. }
  1880. QString ChartPrivate::GetAxisPosString( XlsxAxis::AxisPos axisPos ) const
  1881. {
  1882. QString pos;
  1883. switch ( axisPos )
  1884. {
  1885. case XlsxAxis::Top : pos = QStringLiteral("t"); break;
  1886. case XlsxAxis::Bottom : pos = QStringLiteral("b"); break;
  1887. case XlsxAxis::Left : pos = QStringLiteral("l"); break;
  1888. case XlsxAxis::Right : pos = QStringLiteral("r"); break;
  1889. default: break; // ??
  1890. }
  1891. return pos;
  1892. }
  1893. QString ChartPrivate::GetAxisName(XlsxAxis* axis) const
  1894. {
  1895. QString strAxisName;
  1896. if ( NULL == axis )
  1897. return strAxisName;
  1898. QString pos = GetAxisPosString( axis->axisPos ); // l, t, r, b
  1899. if ( pos.isEmpty() )
  1900. return strAxisName;
  1901. strAxisName = axis->axisNames[ axis->axisPos ];
  1902. return strAxisName;
  1903. }
  1904. ///
  1905. /// \brief ChartPrivate::readSubTree
  1906. /// \param reader
  1907. /// \return
  1908. ///
  1909. QString ChartPrivate::readSubTree(QXmlStreamReader &reader)
  1910. {
  1911. QString treeString;
  1912. QString prefix;
  1913. const auto& treeName = reader.name();
  1914. while (!reader.atEnd())
  1915. {
  1916. reader.readNextStartElement();
  1917. if (reader.tokenType() == QXmlStreamReader::StartElement)
  1918. {
  1919. prefix = reader.prefix().toString();
  1920. treeString += QLatin1String("<") + reader.qualifiedName().toString();
  1921. const QXmlStreamAttributes attributes = reader.attributes();
  1922. for (const QXmlStreamAttribute &attr : attributes) {
  1923. treeString += QLatin1String(" ") + attr.name().toString() + QLatin1String("=\"") + attr.value().toString() + QLatin1String("\"");
  1924. }
  1925. treeString += QStringLiteral(">");
  1926. }
  1927. else if (reader.tokenType() == QXmlStreamReader::EndElement )
  1928. {
  1929. if( reader.name() == treeName)
  1930. {
  1931. break;
  1932. }
  1933. treeString += QLatin1String("</") + reader.qualifiedName().toString() + QLatin1String(">");
  1934. }
  1935. }
  1936. return treeString;
  1937. }
  1938. ///
  1939. /// \brief ChartPrivate::loadXmlChartLegend
  1940. /// \param reader
  1941. /// \return
  1942. ///
  1943. bool ChartPrivate::loadXmlChartLegend(QXmlStreamReader &reader)
  1944. {
  1945. Q_ASSERT(reader.name() == QLatin1String("legend"));
  1946. while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement
  1947. && reader.name() == QLatin1String("legend")))
  1948. {
  1949. if (reader.readNextStartElement())
  1950. {
  1951. if (reader.name() == QLatin1String("legendPos")) // c:legendPos
  1952. {
  1953. QString pos = reader.attributes().value(QLatin1String("val")).toString();
  1954. if( pos.compare(QLatin1String("r"), Qt::CaseInsensitive) == 0)
  1955. {
  1956. // legendPos = Chart::ChartAxisPos::Right;
  1957. legendPos = Chart::Right;
  1958. }
  1959. else
  1960. if( pos.compare(QLatin1String("l"), Qt::CaseInsensitive) == 0)
  1961. {
  1962. // legendPos = Chart::ChartAxisPos::Left;
  1963. legendPos = Chart::Left;
  1964. }
  1965. else
  1966. if( pos.compare(QLatin1String("t"), Qt::CaseInsensitive) == 0)
  1967. {
  1968. // legendPos = Chart::ChartAxisPos::Top;
  1969. legendPos = Chart::Top;
  1970. }
  1971. else
  1972. if( pos.compare(QLatin1String("b"), Qt::CaseInsensitive) == 0)
  1973. {
  1974. // legendPos = Chart::ChartAxisPos::Bottom;
  1975. legendPos = Chart::Bottom;
  1976. }
  1977. else
  1978. {
  1979. // legendPos = Chart::ChartAxisPos::None;
  1980. legendPos = Chart::None;
  1981. }
  1982. }
  1983. else
  1984. if (reader.name() == QLatin1String("overlay")) // c:legendPos
  1985. {
  1986. QString pos = reader.attributes().value(QLatin1String("val")).toString();
  1987. if( pos.compare(QLatin1String("1"), Qt::CaseInsensitive) == 0 )
  1988. {
  1989. legendOverlay = true;
  1990. }
  1991. else
  1992. {
  1993. legendOverlay = false;
  1994. }
  1995. }
  1996. }
  1997. }
  1998. return false;
  1999. }
  2000. QT_END_NAMESPACE_XLSX