2101 lines
		
	
	
		
			74 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			2101 lines
		
	
	
		
			74 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // xlsxchart.cpp
 | |
| 
 | |
| #include "xlsxcellrange.h"
 | |
| #include "xlsxchart_p.h"
 | |
| #include "xlsxutility_p.h"
 | |
| #include "xlsxworksheet.h"
 | |
| 
 | |
| #include <QDebug>
 | |
| #include <QIODevice>
 | |
| #include <QString>
 | |
| #include <QXmlStreamReader>
 | |
| #include <QXmlStreamWriter>
 | |
| #include <QtGlobal>
 | |
| 
 | |
| QT_BEGIN_NAMESPACE_XLSX
 | |
| 
 | |
| ChartPrivate::ChartPrivate(Chart *q, Chart::CreateFlag flag)
 | |
|     : AbstractOOXmlFilePrivate(q, flag)
 | |
|     , chartType(static_cast<Chart::ChartType>(0))
 | |
| {
 | |
| }
 | |
| 
 | |
| ChartPrivate::~ChartPrivate()
 | |
| {
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * \internal
 | |
|  */
 | |
| Chart::Chart(AbstractSheet *parent, CreateFlag flag)
 | |
|     : AbstractOOXmlFile(new ChartPrivate(this, flag))
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     d_func()->sheet = parent;
 | |
| 
 | |
|     // d->legendPos = Chart::ChartAxisPos::None;
 | |
|     d->legendPos             = Chart::None;
 | |
|     d->legendOverlay         = false;
 | |
|     d->majorGridlinesEnabled = false;
 | |
|     d->minorGridlinesEnabled = false;
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * Destroys the chart.
 | |
|  */
 | |
| Chart::~Chart()
 | |
| {
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * Add the data series which is in the range \a range of the \a sheet.
 | |
|  */
 | |
| void Chart::addSeries(const CellRange &range,
 | |
|                       AbstractSheet *sheet,
 | |
|                       bool headerH,
 | |
|                       bool headerV,
 | |
|                       bool swapHeaders)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     if (!range.isValid())
 | |
|         return;
 | |
|     if (sheet && sheet->sheetType() != AbstractSheet::ST_WorkSheet)
 | |
|         return;
 | |
|     if (!sheet && d->sheet->sheetType() != AbstractSheet::ST_WorkSheet)
 | |
|         return;
 | |
| 
 | |
|     QString sheetName = sheet ? sheet->sheetName() : d->sheet->sheetName();
 | |
|     // In case sheetName contains space or '
 | |
|     sheetName = escapeSheetName(sheetName);
 | |
| 
 | |
|     if (range.columnCount() == 1 || range.rowCount() == 1) {
 | |
|         auto series = std::make_shared<XlsxSeries>();
 | |
|         series->numberDataSource_numRef =
 | |
|             sheetName + QLatin1String("!") + range.toString(true, true);
 | |
|         d->seriesList.append(series);
 | |
|     } else if ((range.columnCount() < range.rowCount()) || swapHeaders) {
 | |
|         // Column based series
 | |
|         int firstDataRow    = range.firstRow();
 | |
|         int firstDataColumn = range.firstColumn();
 | |
| 
 | |
|         QString axDataSouruce_numRef;
 | |
|         if (d->chartType == CT_ScatterChart || d->chartType == CT_BubbleChart) {
 | |
|             firstDataColumn += 1;
 | |
|             CellRange subRange(
 | |
|                 range.firstRow(), range.firstColumn(), range.lastRow(), range.firstColumn());
 | |
|             axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
|         }
 | |
| 
 | |
|         if (headerH) {
 | |
|             firstDataRow += 1;
 | |
|         }
 | |
|         if (headerV) {
 | |
|             firstDataColumn += 1;
 | |
|         }
 | |
| 
 | |
|         for (int col = firstDataColumn; col <= range.lastColumn(); ++col) {
 | |
|             CellRange subRange(firstDataRow, col, range.lastRow(), col);
 | |
|             auto series                 = std::make_shared<XlsxSeries>();
 | |
|             series->axDataSource_numRef = axDataSouruce_numRef;
 | |
|             series->numberDataSource_numRef =
 | |
|                 sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
| 
 | |
|             if (headerH) {
 | |
|                 CellRange subRange(range.firstRow(), col, range.firstRow(), col);
 | |
|                 series->headerH_numRef =
 | |
|                     sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
|             } else {
 | |
|                 series->headerH_numRef = QString();
 | |
|             }
 | |
|             if (headerV) {
 | |
|                 CellRange subRange(
 | |
|                     firstDataRow, range.firstColumn(), range.lastRow(), range.firstColumn());
 | |
|                 series->headerV_numRef =
 | |
|                     sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
|             } else {
 | |
|                 series->headerV_numRef = QString();
 | |
|             }
 | |
|             series->swapHeader = swapHeaders;
 | |
| 
 | |
|             d->seriesList.append(series);
 | |
|         }
 | |
| 
 | |
|     } else {
 | |
|         // Row based series
 | |
|         int firstDataRow    = range.firstRow();
 | |
|         int firstDataColumn = range.firstColumn();
 | |
| 
 | |
|         QString axDataSouruce_numRef;
 | |
|         if (d->chartType == CT_ScatterChart || d->chartType == CT_BubbleChart) {
 | |
|             firstDataRow += 1;
 | |
|             CellRange subRange(
 | |
|                 range.firstRow(), range.firstColumn(), range.firstRow(), range.lastColumn());
 | |
|             axDataSouruce_numRef = sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
|         }
 | |
| 
 | |
|         if (headerH) {
 | |
|             firstDataRow += 1;
 | |
|         }
 | |
|         if (headerV) {
 | |
|             firstDataColumn += 1;
 | |
|         }
 | |
| 
 | |
|         for (int row = firstDataRow; row <= range.lastRow(); ++row) {
 | |
|             CellRange subRange(row, firstDataColumn, row, range.lastColumn());
 | |
|             auto series                 = std::make_shared<XlsxSeries>();
 | |
|             series->axDataSource_numRef = axDataSouruce_numRef;
 | |
|             series->numberDataSource_numRef =
 | |
|                 sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
| 
 | |
|             if (headerH) {
 | |
|                 CellRange subRange(
 | |
|                     range.firstRow(), firstDataColumn, range.firstRow(), range.lastColumn());
 | |
|                 series->headerH_numRef =
 | |
|                     sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
|             } else {
 | |
|                 series->headerH_numRef = QString();
 | |
|             }
 | |
| 
 | |
|             if (headerV) {
 | |
|                 CellRange subRange(row, range.firstColumn(), row, range.firstColumn());
 | |
|                 series->headerV_numRef =
 | |
|                     sheetName + QLatin1String("!") + subRange.toString(true, true);
 | |
|             } else {
 | |
|                 series->headerV_numRef = QString();
 | |
|             }
 | |
|             series->swapHeader = swapHeaders;
 | |
| 
 | |
|             d->seriesList.append(series);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * Set the type of the chart to \a type
 | |
|  */
 | |
| void Chart::setChartType(ChartType type)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     d->chartType = type;
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * \internal
 | |
|  *
 | |
|  */
 | |
| void Chart::setChartStyle(int id)
 | |
| {
 | |
|     Q_UNUSED(id)
 | |
|     //! Todo
 | |
| }
 | |
| 
 | |
| void Chart::setAxisTitle(Chart::ChartAxisPos pos, QString axisTitle)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     if (axisTitle.isEmpty())
 | |
|         return;
 | |
| 
 | |
|     // dev24 : fixed for old compiler
 | |
|     if (pos == Chart::Left) {
 | |
|         d->axisNames[XlsxAxis::Left] = axisTitle;
 | |
|     } else if (pos == Chart::Top) {
 | |
|         d->axisNames[XlsxAxis::Top] = axisTitle;
 | |
|     } else if (pos == Chart::Right) {
 | |
|         d->axisNames[XlsxAxis::Right] = axisTitle;
 | |
|     } else if (pos == Chart::Bottom) {
 | |
|         d->axisNames[XlsxAxis::Bottom] = axisTitle;
 | |
|     }
 | |
| }
 | |
| 
 | |
| // dev25
 | |
| void Chart::setChartTitle(QString strchartTitle)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     d->chartTitle = strchartTitle;
 | |
| }
 | |
| 
 | |
| void Chart::setChartLegend(Chart::ChartAxisPos legendPos, bool overlay)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     d->legendPos     = legendPos;
 | |
|     d->legendOverlay = overlay;
 | |
| }
 | |
| 
 | |
| void Chart::setGridlinesEnable(bool majorGridlinesEnable, bool minorGridlinesEnable)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     d->majorGridlinesEnabled = majorGridlinesEnable;
 | |
|     d->minorGridlinesEnabled = minorGridlinesEnable;
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * \internal
 | |
|  */
 | |
| void Chart::saveToXmlFile(QIODevice *device) const
 | |
| {
 | |
|     Q_D(const Chart);
 | |
| 
 | |
|     /*
 | |
|         <chartSpace>
 | |
|             <chart>
 | |
|                 <view3D>
 | |
|                     <perspective val="30"/>
 | |
|                 </view3D>
 | |
|                 <plotArea>
 | |
|                     <layout/>
 | |
|                     <barChart>
 | |
|                     ...
 | |
|                     </barChart>
 | |
|                     <catAx/>
 | |
|                     <valAx/>
 | |
|                 </plotArea>
 | |
|                 <legend>
 | |
|                 ...
 | |
|                 </legend>
 | |
|             </chart>
 | |
|             <printSettings>
 | |
|             </printSettings>
 | |
|         </chartSpace>
 | |
|     */
 | |
| 
 | |
|     QXmlStreamWriter writer(device);
 | |
| 
 | |
|     writer.writeStartDocument(QStringLiteral("1.0"), true);
 | |
| 
 | |
|     // L.4.13.2.2 Chart
 | |
|     //
 | |
|     //  chartSpace is the root node, which contains an element defining the chart,
 | |
|     // and an element defining the print settings for the chart.
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:chartSpace"));
 | |
| 
 | |
|     writer.writeAttribute(QStringLiteral("xmlns:c"),
 | |
|                           QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/chart"));
 | |
|     writer.writeAttribute(QStringLiteral("xmlns:a"),
 | |
|                           QStringLiteral("http://schemas.openxmlformats.org/drawingml/2006/main"));
 | |
|     writer.writeAttribute(
 | |
|         QStringLiteral("xmlns:r"),
 | |
|         QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));
 | |
| 
 | |
|     /*
 | |
|      * chart is the root element for the chart. If the chart is a 3D chart,
 | |
|      * then a view3D element is contained, which specifies the 3D view.
 | |
|      * It then has a plot area, which defines a layout and contains an element
 | |
|      * that corresponds to, and defines, the type of chart.
 | |
|      */
 | |
| 
 | |
|     d->saveXmlChart(writer);
 | |
| 
 | |
|     writer.writeEndElement(); // c:chartSpace
 | |
|     writer.writeEndDocument();
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * \internal
 | |
|  */
 | |
| bool Chart::loadFromXmlFile(QIODevice *device)
 | |
| {
 | |
|     Q_D(Chart);
 | |
| 
 | |
|     QXmlStreamReader reader(device);
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("chart")) {
 | |
|                 if (!d->loadXmlChart(reader)) {
 | |
|                     return false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlChart(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("chart"));
 | |
| 
 | |
|     //    qDebug() << "-------------- loadXmlChart";
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
| 
 | |
|         //        qDebug() << "-------------1- " << reader.name();
 | |
| 
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
| 
 | |
|             if (reader.name() == QLatin1String("plotArea")) {
 | |
|                 if (!loadXmlPlotArea(reader)) {
 | |
|                     return false;
 | |
|                 }
 | |
|             } else if (reader.name() == QLatin1String("title")) {
 | |
|                 //! Todo
 | |
| 
 | |
|                 if (loadXmlChartTitle(reader)) {
 | |
|                 }
 | |
|             }
 | |
|             //            else if (reader.name() == QLatin1String("legend"))
 | |
|             //            {
 | |
|             //                loadXmlChartLegend(reader);
 | |
|             //                qDebug() << "-------------- loadXmlChartLegend";
 | |
|             //            }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("chart")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| // TO DEBUG: loop is not work, when i looping second element.
 | |
| /*
 | |
| dchrt_CT_PlotArea =
 | |
|     element layout { dchrt_CT_Layout }?,
 | |
|     (element areaChart { dchrt_CT_AreaChart }
 | |
|         | element area3DChart { dchrt_ CT_Area3DChart }
 | |
|         | element lineChart { dchrt_CT_LineChart }
 | |
|         | element line3DChart { dchrt_CT_Line3DChart }
 | |
|         | element stockChart { dchrt_CT_StockChart }
 | |
|         | element radarChart { dchrt_CT_RadarChart }
 | |
|         | element scatterChart { dchrt_CT_ScatterChart }
 | |
|         | element pieChart { dchrt_CT_PieChart }
 | |
|         | element pie3DChart { dchrt_CT_Pie3DChart }
 | |
|         | element doughnutChart { dchrt_CT_DoughnutChart }
 | |
|         | element barChart { dchrt_CT_BarChart }
 | |
|         | element bar3DChart { dchrt_CT_Bar3DChart }
 | |
|         | element ofPieChart { dchrt_CT_OfPieChart }
 | |
|         | element surfaceChart { dchrt_CT_SurfaceChart }
 | |
|         | element surface3DChart { dchrt_CT_Surface3DChart }
 | |
|         | element bubbleChart { dchrt_CT_BubbleChart })+,
 | |
|     (element valAx { dchrt_CT_ValAx }
 | |
|         | element catAx { dchrt_CT_CatAx }
 | |
|         | element dateAx { dchrt_CT_DateAx }
 | |
|         | element serAx { dchrt_CT_SerAx })*,
 | |
|     element dTable { dchrt_CT_DTable }?,
 | |
|     element spPr { a_CT_ShapeProperties }?,
 | |
|     element extLst { dchrt_CT_ExtensionList }?
 | |
|  */
 | |
| bool ChartPrivate::loadXmlPlotArea(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("plotArea"));
 | |
| 
 | |
|     // TO DEBUG:
 | |
| 
 | |
|     reader.readNext();
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         //        qDebug() << "-------------2- " << reader.name();
 | |
| 
 | |
|         if (reader.isStartElement()) {
 | |
|             if (!loadXmlPlotAreaElement(reader)) {
 | |
|                 qDebug() << "[debug] failed to load plotarea element.";
 | |
|                 return false;
 | |
|             } else if (reader.name() == QLatin1String("legend")) // Why here?
 | |
|             {
 | |
|                 loadXmlChartLegend(reader);
 | |
|                 //                qDebug() << "-------------- loadXmlChartLegend";
 | |
|             }
 | |
| 
 | |
|             reader.readNext();
 | |
|         } else {
 | |
|             reader.readNext();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlPlotAreaElement(QXmlStreamReader &reader)
 | |
| {
 | |
|     if (reader.name() == QLatin1String("layout")) {
 | |
|         //! ToDo extract attributes
 | |
|         layout = readSubTree(reader);
 | |
|     } else if (reader.name().endsWith(QLatin1String("Chart"))) {
 | |
|         // for pieChart, barChart, ... (choose one)
 | |
|         if (!loadXmlXxxChart(reader)) {
 | |
|             qDebug() << "[debug] failed to load chart";
 | |
|             return false;
 | |
|         }
 | |
|     } else if (reader.name() == QLatin1String("catAx")) // choose one : catAx, dateAx, serAx, valAx
 | |
|     {
 | |
|         // qDebug() << "loadXmlAxisCatAx()";
 | |
|         loadXmlAxisCatAx(reader);
 | |
|     } else if (reader.name() == QLatin1String("dateAx")) // choose one : catAx, dateAx, serAx, valAx
 | |
|     {
 | |
|         // qDebug() << "loadXmlAxisDateAx()";
 | |
|         loadXmlAxisDateAx(reader);
 | |
|     } else if (reader.name() == QLatin1String("serAx")) // choose one : catAx, dateAx, serAx, valAx
 | |
|     {
 | |
|         // qDebug() << "loadXmlAxisSerAx()";
 | |
|         loadXmlAxisSerAx(reader);
 | |
|     } else if (reader.name() == QLatin1String("valAx")) // choose one : catAx, dateAx, serAx, valAx
 | |
|     {
 | |
|         // qDebug() << "loadXmlAxisValAx()";
 | |
|         loadXmlAxisValAx(reader);
 | |
|     } else if (reader.name() == QLatin1String("dTable")) {
 | |
|         //! ToDo
 | |
|         // dTable "CT_DTable"
 | |
|         // reader.skipCurrentElement();
 | |
|     } else if (reader.name() == QLatin1String("spPr")) {
 | |
|         //! ToDo
 | |
|         // spPr "a:CT_ShapeProperties"
 | |
|         // reader.skipCurrentElement();
 | |
|     } else if (reader.name() == QLatin1String("extLst")) {
 | |
|         //! ToDo
 | |
|         // extLst "CT_ExtensionList"
 | |
|         // reader.skipCurrentElement();
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlXxxChart(QXmlStreamReader &reader)
 | |
| {
 | |
|     const auto &name = reader.name();
 | |
| 
 | |
|     if (name == QLatin1String("areaChart")) {
 | |
|         chartType = Chart::CT_AreaChart;
 | |
|     } else if (name == QLatin1String("area3DChart")) {
 | |
|         chartType = Chart::CT_Area3DChart;
 | |
|     } else if (name == QLatin1String("lineChart")) {
 | |
|         chartType = Chart::CT_LineChart;
 | |
|     } else if (name == QLatin1String("line3DChart")) {
 | |
|         chartType = Chart::CT_Line3DChart;
 | |
|     } else if (name == QLatin1String("stockChart")) {
 | |
|         chartType = Chart::CT_StockChart;
 | |
|     } else if (name == QLatin1String("radarChart")) {
 | |
|         chartType = Chart::CT_RadarChart;
 | |
|     } else if (name == QLatin1String("scatterChart")) {
 | |
|         chartType = Chart::CT_ScatterChart;
 | |
|     } else if (name == QLatin1String("pieChart")) {
 | |
|         chartType = Chart::CT_PieChart;
 | |
|     } else if (name == QLatin1String("pie3DChart")) {
 | |
|         chartType = Chart::CT_Pie3DChart;
 | |
|     } else if (name == QLatin1String("doughnutChart")) {
 | |
|         chartType = Chart::CT_DoughnutChart;
 | |
|     } else if (name == QLatin1String("barChart")) {
 | |
|         chartType = Chart::CT_BarChart;
 | |
|     } else if (name == QLatin1String("bar3DChart")) {
 | |
|         chartType = Chart::CT_Bar3DChart;
 | |
|     } else if (name == QLatin1String("ofPieChart")) {
 | |
|         chartType = Chart::CT_OfPieChart;
 | |
|     } else if (name == QLatin1String("surfaceChart")) {
 | |
|         chartType = Chart::CT_SurfaceChart;
 | |
|     } else if (name == QLatin1String("surface3DChart")) {
 | |
|         chartType = Chart::CT_Surface3DChart;
 | |
|     } else if (name == QLatin1String("bubbleChart")) {
 | |
|         chartType = Chart::CT_BubbleChart;
 | |
|     } else {
 | |
|         qDebug() << "[undefined chart type] " << name;
 | |
|         chartType = Chart::CT_NoStatementChart;
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             // dev57
 | |
| 
 | |
|             if (reader.name() == QLatin1String("ser")) {
 | |
|                 loadXmlSer(reader);
 | |
|             } else if (reader.name() == QLatin1String("varyColors")) {
 | |
|             } else if (reader.name() == QLatin1String("barDir")) {
 | |
|             } else if (reader.name() == QLatin1String("axId")) {
 | |
|                 //
 | |
| 
 | |
|             } else if (reader.name() == QLatin1String("scatterStyle")) {
 | |
|             } else if (reader.name() == QLatin1String("holeSize")) {
 | |
|             } else {
 | |
|             }
 | |
| 
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == name) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlSer(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("ser"));
 | |
| 
 | |
|     auto series = std::make_shared<XlsxSeries>();
 | |
|     seriesList.append(series);
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("ser"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             // TODO beide Header noch auswerten RTR 2019.11
 | |
|             const auto &name = reader.name();
 | |
|             if (name == QLatin1String("tx")) {
 | |
|                 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                             reader.name() == name)) {
 | |
|                     if (reader.readNextStartElement()) {
 | |
|                         if (reader.name() == QLatin1String("strRef"))
 | |
|                             series->headerV_numRef = loadXmlStrRef(reader);
 | |
|                     }
 | |
|                 }
 | |
|             } else if (name == QLatin1String("cat") || name == QLatin1String("xVal")) {
 | |
|                 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                             reader.name() == name)) {
 | |
|                     if (reader.readNextStartElement()) {
 | |
|                         if (reader.name() == QLatin1String("numRef"))
 | |
|                             series->axDataSource_numRef = loadXmlNumRef(reader);
 | |
|                         else if (reader.name() == QLatin1String("strRef"))
 | |
|                             series->headerH_numRef = loadXmlStrRef(reader);
 | |
|                     }
 | |
|                 }
 | |
|             } else if (name == QLatin1String("val") || name == QLatin1String("yVal")) {
 | |
|                 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                             reader.name() == name)) {
 | |
|                     if (reader.readNextStartElement()) {
 | |
|                         if (reader.name() == QLatin1String("numRef"))
 | |
|                             series->numberDataSource_numRef = loadXmlNumRef(reader);
 | |
|                     }
 | |
|                 }
 | |
|             } else if (name == QLatin1String("extLst")) {
 | |
|                 while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                             reader.name() == name)) {
 | |
|                     reader.readNextStartElement();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| QString ChartPrivate::loadXmlNumRef(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("numRef"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("numRef"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("f"))
 | |
|                 return reader.readElementText();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return QString();
 | |
| }
 | |
| 
 | |
| QString ChartPrivate::loadXmlStrRef(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("strRef"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("strRef"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("f"))
 | |
|                 return reader.readElementText();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return QString();
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     //----------------------------------------------------
 | |
|     // c:chart
 | |
|     writer.writeStartElement(QStringLiteral("c:chart"));
 | |
| 
 | |
|     //----------------------------------------------------
 | |
|     // c:title
 | |
| 
 | |
|     saveXmlChartTitle(writer); // write 'chart title'
 | |
| 
 | |
|     //----------------------------------------------------
 | |
|     // c:plotArea
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:plotArea"));
 | |
| 
 | |
|     // a little workaround for Start- and EndElement with starting ">" and ending without ">"
 | |
|     writer.device()->write("><c:layout>"); // layout
 | |
|     writer.device()->write(layout.toUtf8());
 | |
|     writer.device()->write("</c:layout"); // layout
 | |
| 
 | |
|     // dev35
 | |
|     switch (chartType) {
 | |
|     case Chart::CT_AreaChart:
 | |
|         saveXmlAreaChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_Area3DChart:
 | |
|         saveXmlAreaChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_LineChart:
 | |
|         saveXmlLineChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_Line3DChart:
 | |
|         saveXmlLineChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_StockChart:
 | |
|         break;
 | |
|     case Chart::CT_RadarChart:
 | |
|         break;
 | |
|     case Chart::CT_ScatterChart:
 | |
|         saveXmlScatterChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_PieChart:
 | |
|         saveXmlPieChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_Pie3DChart:
 | |
|         saveXmlPieChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_DoughnutChart:
 | |
|         saveXmlDoughnutChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_BarChart:
 | |
|         saveXmlBarChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_Bar3DChart:
 | |
|         saveXmlBarChart(writer);
 | |
|         break;
 | |
|     case Chart::CT_OfPieChart:
 | |
|         break;
 | |
|     case Chart::CT_SurfaceChart:
 | |
|         break;
 | |
|     case Chart::CT_Surface3DChart:
 | |
|         break;
 | |
|     case Chart::CT_BubbleChart:
 | |
|         break;
 | |
|     default:
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     saveXmlAxis(writer); // c:catAx, c:valAx, c:serAx, c:dateAx (choose one)
 | |
| 
 | |
|     //! TODO: write element
 | |
|     // c:dTable CT_DTable
 | |
|     // c:spPr   CT_ShapeProperties
 | |
|     // c:extLst CT_ExtensionList
 | |
| 
 | |
|     writer.writeEndElement(); // c:plotArea
 | |
| 
 | |
|     // c:legend
 | |
|     saveXmlChartLegend(writer); // c:legend
 | |
| 
 | |
|     writer.writeEndElement(); // c:chart
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlChartTitle(QXmlStreamReader &reader)
 | |
| {
 | |
|     //! TODO : load chart title
 | |
| 
 | |
|     Q_ASSERT(reader.name() == QLatin1String("title"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("title"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("tx")) // c:tx
 | |
|                 return loadXmlChartTitleTx(reader);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlChartTitleTx(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("tx"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("tx"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("rich")) // c:rich
 | |
|                 return loadXmlChartTitleTxRich(reader);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlChartTitleTxRich(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("rich"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("rich"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("p")) // a:p
 | |
|                 return loadXmlChartTitleTxRichP(reader);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlChartTitleTxRichP(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("p"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("p"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("r")) // a:r
 | |
|                 return loadXmlChartTitleTxRichP_R(reader);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlChartTitleTxRichP_R(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("r"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("r"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("t")) // a:t
 | |
|             {
 | |
|                 QString textValue = reader.readElementText();
 | |
|                 this->chartTitle  = textValue;
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| // write 'chart title'
 | |
| void ChartPrivate::saveXmlChartTitle(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     if (chartTitle.isEmpty())
 | |
|         return;
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:title"));
 | |
|     /*
 | |
|     <xsd:complexType name="CT_Title">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="tx"      type="CT_Tx"                minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="layout"  type="CT_Layout"            minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="overlay" type="CT_Boolean"           minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="spPr"    type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="txPr"    type="a:CT_TextBody"        minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst"  type="CT_ExtensionList"     minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:tx"));
 | |
|     /*
 | |
|     <xsd:complexType name="CT_Tx">
 | |
|         <xsd:sequence>
 | |
|             <xsd:choice     minOccurs="1"   maxOccurs="1">
 | |
|             <xsd:element    name="strRef"   type="CT_StrRef"        minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element    name="rich"     type="a:CT_TextBody"    minOccurs="1" maxOccurs="1"/>
 | |
|             </xsd:choice>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:rich"));
 | |
|     /*
 | |
|     <xsd:complexType name="CT_TextBody">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="bodyPr"      type="CT_TextBodyProperties"    minOccurs=" 1"
 | |
|     maxOccurs="1"/> <xsd:element name="lstStyle"    type="CT_TextListStyle"         minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:element name="p"           type="CT_TextParagraph"         minOccurs="1"
 | |
|     maxOccurs="unbounded"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("a:bodyPr")); // <a:bodyPr/>
 | |
|     /*
 | |
|     <xsd:complexType name="CT_TextBodyProperties">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="prstTxWarp" type="CT_PresetTextShape" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:group ref="EG_TextAutofit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="scene3d" type="CT_Scene3D" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:group ref="EG_Text3D" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0"
 | |
|     maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|         <xsd:attribute name="rot" type="ST_Angle" use="optional"/>
 | |
|         <xsd:attribute name="spcFirstLastPara" type="xsd:boolean" use="optional"/>
 | |
|         <xsd:attribute name="vertOverflow" type="ST_TextVertOverflowType" use="optional"/>
 | |
|         <xsd:attribute name="horzOverflow" type="ST_TextHorzOverflowType" use="optional"/>
 | |
|         <xsd:attribute name="vert" type="ST_TextVerticalType" use="optional"/>
 | |
|         <xsd:attribute name="wrap" type="ST_TextWrappingType" use="optional"/>
 | |
|         <xsd:attribute name="lIns" type="ST_Coordinate32" use="optional"/>
 | |
|         <xsd:attribute name="tIns" type="ST_Coordinate32" use="optional"/>
 | |
|         <xsd:attribute name="rIns" type="ST_Coordinate32" use="optional"/>
 | |
|         <xsd:attribute name="bIns" type="ST_Coordinate32" use="optional"/>
 | |
|         <xsd:attribute name="numCol" type="ST_TextColumnCount" use="optional"/>
 | |
|         <xsd:attribute name="spcCol" type="ST_PositiveCoordinate32" use="optional"/>
 | |
|         <xsd:attribute name="rtlCol" type="xsd:boolean" use="optional"/>
 | |
|         <xsd:attribute name="fromWordArt" type="xsd:boolean" use="optional"/>
 | |
|         <xsd:attribute name="anchor" type="ST_TextAnchoringType" use="optional"/>
 | |
|         <xsd:attribute name="anchorCtr" type="xsd:boolean" use="optional"/>
 | |
|         <xsd:attribute name="forceAA" type="xsd:boolean" use="optional"/>
 | |
|         <xsd:attribute name="upright" type="xsd:boolean" use="optional" default="false"/>
 | |
|         <xsd:attribute name="compatLnSpc" type="xsd:boolean" use="optional"/>
 | |
|     </xsd:complexType>
 | |
|      */
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("a:lstStyle")); // <a:lstStyle/>
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("a:p"));
 | |
|     /*
 | |
|     <xsd:complexType name="CT_TextParagraph">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element    name="pPr"          type="CT_TextParagraphProperties" minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:group      ref="EG_TextRun"    minOccurs="0" maxOccurs="unbounded"/>
 | |
|             <xsd:element    name="endParaRPr"   type="CT_TextCharacterProperties" minOccurs="0"
 | |
|             maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|      */
 | |
| 
 | |
|     // <a:pPr lvl="0">
 | |
|     writer.writeStartElement(QStringLiteral("a:pPr"));
 | |
| 
 | |
|     writer.writeAttribute(QStringLiteral("lvl"), QStringLiteral("0"));
 | |
| 
 | |
|     // <a:defRPr b="0"/>
 | |
|     writer.writeStartElement(QStringLiteral("a:defRPr"));
 | |
| 
 | |
|     writer.writeAttribute(QStringLiteral("b"), QStringLiteral("0"));
 | |
| 
 | |
|     writer.writeEndElement(); // a:defRPr
 | |
| 
 | |
|     writer.writeEndElement(); // a:pPr
 | |
| 
 | |
|     /*
 | |
|     <xsd:group name="EG_TextRun">
 | |
|         <xsd:choice>
 | |
|             <xsd:element name="r"   type="CT_RegularTextRun"/>
 | |
|             <xsd:element name="br"  type="CT_TextLineBreak"/>
 | |
|             <xsd:element name="fld" type="CT_TextField"/>
 | |
|         </xsd:choice>
 | |
|     </xsd:group>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("a:r"));
 | |
|     /*
 | |
|     <xsd:complexType name="CT_RegularTextRun">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="rPr" type="CT_TextCharacterProperties" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="t"   type="xsd:string" minOccurs="1" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|      */
 | |
| 
 | |
|     // <a:t>chart name</a:t>
 | |
|     writer.writeTextElement(QStringLiteral("a:t"), chartTitle);
 | |
| 
 | |
|     writer.writeEndElement(); // a:r
 | |
| 
 | |
|     writer.writeEndElement(); // a:p
 | |
| 
 | |
|     writer.writeEndElement(); // c:rich
 | |
| 
 | |
|     writer.writeEndElement(); // c:tx
 | |
| 
 | |
|     // <c:overlay val="0"/>
 | |
|     writer.writeStartElement(QStringLiteral("c:overlay"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0"));
 | |
|     writer.writeEndElement(); // c:overlay
 | |
| 
 | |
|     writer.writeEndElement(); // c:title
 | |
| }
 | |
| // }}
 | |
| 
 | |
| // write 'chart legend'
 | |
| void ChartPrivate::saveXmlChartLegend(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     if (legendPos == Chart::None)
 | |
|         return;
 | |
| 
 | |
|     //    <c:legend>
 | |
|     //    <c:legendPos val="r"/>
 | |
|     //    <c:overlay val="0"/>
 | |
|     //    </c:legend>
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:legend"));
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:legendPos"));
 | |
| 
 | |
|     QString pos;
 | |
|     switch (legendPos) {
 | |
|     // case Chart::ChartAxisPos::Right:
 | |
|     case Chart::Right:
 | |
|         pos = QStringLiteral("r");
 | |
|         break;
 | |
| 
 | |
|     // case Chart::ChartAxisPos::Left:
 | |
|     case Chart::Left:
 | |
|         pos = QStringLiteral("l");
 | |
|         break;
 | |
| 
 | |
|     // case Chart::ChartAxisPos::Top:
 | |
|     case Chart::Top:
 | |
|         pos = QStringLiteral("t");
 | |
|         break;
 | |
| 
 | |
|     // case Chart::ChartAxisPos::Bottom:
 | |
|     case Chart::Bottom:
 | |
|         pos = QStringLiteral("b");
 | |
|         break;
 | |
| 
 | |
|     default:
 | |
|         pos = QStringLiteral("r");
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     writer.writeAttribute(QStringLiteral("val"), pos);
 | |
| 
 | |
|     writer.writeEndElement(); // c:legendPos
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:overlay"));
 | |
| 
 | |
|     if (legendOverlay) {
 | |
|         writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
 | |
|     } else {
 | |
|         writer.writeAttribute(QStringLiteral("val"), QStringLiteral("0"));
 | |
|     }
 | |
| 
 | |
|     writer.writeEndElement(); // c:overlay
 | |
| 
 | |
|     writer.writeEndElement(); // c:legend
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlPieChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     QString name = chartType == Chart::CT_PieChart ? QStringLiteral("c:pieChart")
 | |
|                                                    : QStringLiteral("c:pie3DChart");
 | |
| 
 | |
|     writer.writeStartElement(name);
 | |
| 
 | |
|     // Do the same behavior as Excel, Pie prefer varyColors
 | |
|     writer.writeEmptyElement(QStringLiteral("c:varyColors"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
 | |
| 
 | |
|     for (int i = 0; i < seriesList.size(); ++i)
 | |
|         saveXmlSer(writer, seriesList[i].get(), i);
 | |
| 
 | |
|     writer.writeEndElement(); // pieChart, pie3DChart
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlBarChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     QString name = chartType == Chart::CT_BarChart ? QStringLiteral("c:barChart")
 | |
|                                                    : QStringLiteral("c:bar3DChart");
 | |
| 
 | |
|     writer.writeStartElement(name);
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("c:barDir"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QStringLiteral("col"));
 | |
| 
 | |
|     for (int i = 0; i < seriesList.size(); ++i) {
 | |
|         saveXmlSer(writer, seriesList[i].get(), i);
 | |
|     }
 | |
| 
 | |
|     if (axisList.isEmpty()) {
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(std::make_shared<XlsxAxis>(
 | |
|             XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1, axisNames[XlsxAxis::Bottom]));
 | |
| 
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(std::make_shared<XlsxAxis>(
 | |
|             XlsxAxis::T_Val, XlsxAxis::Left, 1, 0, axisNames[XlsxAxis::Left]));
 | |
|     }
 | |
| 
 | |
|     // Note: Bar3D have 2~3 axes
 | |
|     // int axisListSize = axisList.size();
 | |
|     // [dev62]
 | |
|     // Q_ASSERT( axisListSize == 2 ||
 | |
|     //          ( axisListSize == 3 && chartType == Chart::CT_Bar3DChart ) );
 | |
| 
 | |
|     for (int i = 0; i < axisList.size(); ++i) {
 | |
|         writer.writeEmptyElement(QStringLiteral("c:axId"));
 | |
|         writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
 | |
|     }
 | |
| 
 | |
|     writer.writeEndElement(); // barChart, bar3DChart
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlLineChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     QString name = chartType == Chart::CT_LineChart ? QStringLiteral("c:lineChart")
 | |
|                                                     : QStringLiteral("c:line3DChart");
 | |
| 
 | |
|     writer.writeStartElement(name);
 | |
| 
 | |
|     // writer.writeEmptyElement(QStringLiteral("grouping")); // dev22
 | |
| 
 | |
|     for (int i = 0; i < seriesList.size(); ++i)
 | |
|         saveXmlSer(writer, seriesList[i].get(), i);
 | |
| 
 | |
|     if (axisList.isEmpty()) {
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(std::make_shared<XlsxAxis>(
 | |
|             XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1, axisNames[XlsxAxis::Bottom]));
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(std::make_shared<XlsxAxis>(
 | |
|             XlsxAxis::T_Val, XlsxAxis::Left, 1, 0, axisNames[XlsxAxis::Left]));
 | |
|         if (chartType == Chart::CT_Line3DChart)
 | |
|             const_cast<ChartPrivate *>(this)->axisList.append(
 | |
|                 std::make_shared<XlsxAxis>(XlsxAxis::T_Ser, XlsxAxis::Bottom, 2, 0));
 | |
|     }
 | |
| 
 | |
|     Q_ASSERT((axisList.size() == 2 || chartType == Chart::CT_LineChart) ||
 | |
|              (axisList.size() == 3 && chartType == Chart::CT_Line3DChart));
 | |
| 
 | |
|     for (int i = 0; i < axisList.size(); ++i) {
 | |
|         writer.writeEmptyElement(QStringLiteral("c:axId"));
 | |
|         writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
 | |
|     }
 | |
| 
 | |
|     writer.writeEndElement(); // lineChart, line3DChart
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlScatterChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     const QString name = QStringLiteral("c:scatterChart");
 | |
| 
 | |
|     writer.writeStartElement(name);
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("c:scatterStyle"));
 | |
| 
 | |
|     for (int i = 0; i < seriesList.size(); ++i)
 | |
|         saveXmlSer(writer, seriesList[i].get(), i);
 | |
| 
 | |
|     if (axisList.isEmpty()) {
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(std::make_shared<XlsxAxis>(
 | |
|             XlsxAxis::T_Val, XlsxAxis::Bottom, 0, 1, axisNames[XlsxAxis::Bottom]));
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(std::make_shared<XlsxAxis>(
 | |
|             XlsxAxis::T_Val, XlsxAxis::Left, 1, 0, axisNames[XlsxAxis::Left]));
 | |
|     }
 | |
| 
 | |
|     int axisListSize = axisList.size();
 | |
|     Q_ASSERT(axisListSize == 2);
 | |
| 
 | |
|     for (int i = 0; i < axisList.size(); ++i) {
 | |
|         writer.writeEmptyElement(QStringLiteral("c:axId"));
 | |
|         writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
 | |
|     }
 | |
| 
 | |
|     writer.writeEndElement(); // c:scatterChart
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAreaChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     QString name = chartType == Chart::CT_AreaChart ? QStringLiteral("c:areaChart")
 | |
|                                                     : QStringLiteral("c:area3DChart");
 | |
| 
 | |
|     writer.writeStartElement(name);
 | |
| 
 | |
|     // writer.writeEmptyElement(QStringLiteral("grouping")); // dev22
 | |
| 
 | |
|     for (int i = 0; i < seriesList.size(); ++i)
 | |
|         saveXmlSer(writer, seriesList[i].get(), i);
 | |
| 
 | |
|     if (axisList.isEmpty()) {
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(
 | |
|             std::make_shared<XlsxAxis>(XlsxAxis::T_Cat, XlsxAxis::Bottom, 0, 1));
 | |
|         const_cast<ChartPrivate *>(this)->axisList.append(
 | |
|             std::make_shared<XlsxAxis>(XlsxAxis::T_Val, XlsxAxis::Left, 1, 0));
 | |
|     }
 | |
| 
 | |
|     // Note: Area3D have 2~3 axes
 | |
|     Q_ASSERT(axisList.size() == 2 || (axisList.size() == 3 && chartType == Chart::CT_Area3DChart));
 | |
| 
 | |
|     for (int i = 0; i < axisList.size(); ++i) {
 | |
|         writer.writeEmptyElement(QStringLiteral("c:axId"));
 | |
|         writer.writeAttribute(QStringLiteral("val"), QString::number(axisList[i]->axisId));
 | |
|     }
 | |
| 
 | |
|     writer.writeEndElement(); // lineChart, line3DChart
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlDoughnutChart(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     QString name = QStringLiteral("c:doughnutChart");
 | |
| 
 | |
|     writer.writeStartElement(name);
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("c:varyColors"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QStringLiteral("1"));
 | |
| 
 | |
|     for (int i = 0; i < seriesList.size(); ++i)
 | |
|         saveXmlSer(writer, seriesList[i].get(), i);
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:holeSize"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QString::number(50));
 | |
| 
 | |
|     writer.writeEndElement();
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlSer(QXmlStreamWriter &writer, XlsxSeries *ser, int id) const
 | |
| {
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:ser"));
 | |
|     writer.writeEmptyElement(QStringLiteral("c:idx"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QString::number(id));
 | |
|     writer.writeEmptyElement(QStringLiteral("c:order"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QString::number(id));
 | |
| 
 | |
|     QString header1;
 | |
|     QString header2;
 | |
|     if (ser->swapHeader) {
 | |
|         header1 = ser->headerH_numRef;
 | |
|         header2 = ser->headerV_numRef;
 | |
|     } else {
 | |
|         header1 = ser->headerV_numRef;
 | |
|         header2 = ser->headerH_numRef;
 | |
|     }
 | |
| 
 | |
|     if (!header1.isEmpty()) {
 | |
|         writer.writeStartElement(QStringLiteral("c:tx"));
 | |
|         writer.writeStartElement(QStringLiteral("c:strRef"));
 | |
|         writer.writeTextElement(QStringLiteral("c:f"), header1);
 | |
|         writer.writeEndElement();
 | |
|         writer.writeEndElement();
 | |
|     }
 | |
|     if (!header2.isEmpty()) {
 | |
|         writer.writeStartElement(QStringLiteral("c:cat"));
 | |
|         writer.writeStartElement(QStringLiteral("c:strRef"));
 | |
|         writer.writeTextElement(QStringLiteral("c:f"), header2);
 | |
|         writer.writeEndElement();
 | |
|         writer.writeEndElement();
 | |
|     }
 | |
| 
 | |
| #if 0
 | |
|     if (!ser->axDataSource_numRef.isEmpty())
 | |
|     {
 | |
|         if (chartType == Chart::CT_ScatterChart || chartType == Chart::CT_BubbleChart)
 | |
|         {
 | |
|             writer.writeStartElement(QStringLiteral("c:xVal"));
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             writer.writeStartElement(QStringLiteral("c:cat"));
 | |
|         }
 | |
| 
 | |
|         writer.writeStartElement(QStringLiteral("c:numRef"));
 | |
|         writer.writeTextElement(QStringLiteral("c:f"), ser->axDataSource_numRef);
 | |
|         writer.writeEndElement();//c:numRef
 | |
|         writer.writeEndElement();//c:cat or c:xVal
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     if (!ser->numberDataSource_numRef.isEmpty()) {
 | |
|         if (chartType == Chart::CT_ScatterChart || chartType == Chart::CT_BubbleChart)
 | |
|             writer.writeStartElement(QStringLiteral("c:yVal"));
 | |
|         else
 | |
|             writer.writeStartElement(QStringLiteral("c:val"));
 | |
|         writer.writeStartElement(QStringLiteral("c:numRef"));
 | |
|         writer.writeTextElement(QStringLiteral("c:f"), ser->numberDataSource_numRef);
 | |
|         writer.writeEndElement(); // c:numRef
 | |
|         writer.writeEndElement(); // c:val or c:yVal
 | |
|     }
 | |
| 
 | |
|     writer.writeEndElement(); // c:ser
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisCatAx(QXmlStreamReader &reader)
 | |
| {
 | |
| 
 | |
|     auto axis  = std::make_shared<XlsxAxis>();
 | |
|     axis->type = XlsxAxis::T_Cat;
 | |
|     axisList.append(axis);
 | |
| 
 | |
|     // load EG_AxShared
 | |
|     if (!loadXmlAxisEG_AxShared(reader, axis.get())) {
 | |
|         qDebug() << "failed to load EG_AxShared";
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     //! TODO: load element
 | |
|     // auto
 | |
|     // lblAlgn
 | |
|     // lblOffset
 | |
|     // tickLblSkip
 | |
|     // tickMarkSkip
 | |
|     // noMultiLvlLbl
 | |
|     // extLst
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisDateAx(QXmlStreamReader &reader)
 | |
| {
 | |
| 
 | |
|     auto axis  = std::make_shared<XlsxAxis>();
 | |
|     axis->type = XlsxAxis::T_Date;
 | |
|     axisList.append(axis);
 | |
| 
 | |
|     // load EG_AxShared
 | |
|     if (!loadXmlAxisEG_AxShared(reader, axis.get())) {
 | |
|         qDebug() << "failed to load EG_AxShared";
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     //! TODO: load element
 | |
|     // auto
 | |
|     // lblOffset
 | |
|     // baseTimeUnit
 | |
|     // majorUnit
 | |
|     // majorTimeUnit
 | |
|     // minorUnit
 | |
|     // minorTimeUnit
 | |
|     // extLst
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisSerAx(QXmlStreamReader &reader)
 | |
| {
 | |
| 
 | |
|     auto axis  = std::make_shared<XlsxAxis>();
 | |
|     axis->type = XlsxAxis::T_Ser;
 | |
|     axisList.append(axis);
 | |
| 
 | |
|     // load EG_AxShared
 | |
|     if (!loadXmlAxisEG_AxShared(reader, axis.get())) {
 | |
|         qDebug() << "failed to load EG_AxShared";
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     //! TODO: load element
 | |
|     // tickLblSkip
 | |
|     // tickMarkSkip
 | |
|     // extLst
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisValAx(QXmlStreamReader &reader)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("valAx"));
 | |
| 
 | |
|     auto axis  = std::make_shared<XlsxAxis>();
 | |
|     axis->type = XlsxAxis::T_Val;
 | |
|     axisList.append(axis);
 | |
| 
 | |
|     if (!loadXmlAxisEG_AxShared(reader, axis.get())) {
 | |
|         qDebug() << "failed to load EG_AxShared";
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     //! TODO: load element
 | |
|     // crossBetween
 | |
|     // majorUnit
 | |
|     // minorUnit
 | |
|     // dispUnits
 | |
|     // extLst
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| /*
 | |
| <xsd:group name="EG_AxShared">
 | |
|     <xsd:sequence>
 | |
|         <xsd:element name="axId" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)(M)
 | |
|         <xsd:element name="scaling" type="CT_Scaling" minOccurs="1" maxOccurs="1"/> (*)(M)
 | |
|         <xsd:element name="delete" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="axPos" type="CT_AxPos" minOccurs="1" maxOccurs="1"/> (*)(M)
 | |
|         <xsd:element name="majorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="minorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="title" type="CT_Title" minOccurs="0" maxOccurs="1"/> (*)
 | |
|         <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="majorTickMark" type="CT_TickMark" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="minorTickMark" type="CT_TickMark" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="tickLblPos" type="CT_TickLblPos" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="crossAx" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)(M)
 | |
|         <xsd:choice minOccurs="0" maxOccurs="1">
 | |
|             <xsd:element name="crosses" type="CT_Crosses" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="crossesAt" type="CT_Double" minOccurs="1" maxOccurs="1"/>
 | |
|         </xsd:choice>
 | |
|     </xsd:sequence>
 | |
| </xsd:group>
 | |
| */
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_ASSERT(nullptr != axis);
 | |
|     Q_ASSERT(reader.name().endsWith(QLatin1String("Ax")));
 | |
|     QString name = reader.name().toString(); //
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             // qDebug() << "[debug]" << QTime::currentTime() << reader.name().toString();
 | |
| 
 | |
|             if (reader.name() == QLatin1String("axId")) // mandatory element
 | |
|             {
 | |
|                 // dev57
 | |
|                 uint axId = reader.attributes().value(QStringLiteral("val")).toUInt(); // for Qt5.1
 | |
|                 axis->axisId = axId;
 | |
|             } else if (reader.name() == QLatin1String("scaling")) {
 | |
|                 // mandatory element
 | |
| 
 | |
|                 loadXmlAxisEG_AxShared_Scaling(reader, axis);
 | |
|             } else if (reader.name() == QLatin1String("delete")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("axPos")) {
 | |
|                 // mandatory element
 | |
| 
 | |
|                 QString axPosVal = reader.attributes().value(QLatin1String("val")).toString();
 | |
| 
 | |
|                 if (axPosVal == QLatin1String("l")) {
 | |
|                     axis->axisPos = XlsxAxis::Left;
 | |
|                 } else if (axPosVal == QLatin1String("r")) {
 | |
|                     axis->axisPos = XlsxAxis::Right;
 | |
|                 } else if (axPosVal == QLatin1String("t")) {
 | |
|                     axis->axisPos = XlsxAxis::Top;
 | |
|                 } else if (axPosVal == QLatin1String("b")) {
 | |
|                     axis->axisPos = XlsxAxis::Bottom;
 | |
|                 }
 | |
|             } else if (reader.name() == QLatin1String("majorGridlines")) {
 | |
|                 //! TODO anything else?
 | |
|                 majorGridlinesEnabled = true;
 | |
|             } else if (reader.name() == QLatin1String("minorGridlines")) {
 | |
|                 //! TODO anything else?
 | |
|                 minorGridlinesEnabled = true;
 | |
|             } else if (reader.name() == QLatin1String("title")) {
 | |
|                 // title
 | |
|                 if (!loadXmlAxisEG_AxShared_Title(reader, axis)) {
 | |
|                     qDebug() << "failed to load EG_AxShared title.";
 | |
|                     Q_ASSERT(false);
 | |
|                     return false;
 | |
|                 }
 | |
|             } else if (reader.name() == QLatin1String("numFmt")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("majorTickMark")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("minorTickMark")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("tickLblPos")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("spPr")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("txPr")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("crossAx")) // mandatory element
 | |
|             {
 | |
|                 // dev57
 | |
|                 uint crossAx =
 | |
|                     reader.attributes().value(QLatin1String("val")).toUInt(); // for Qt5.1
 | |
|                 axis->crossAx = crossAx;
 | |
|             } else if (reader.name() == QLatin1String("crosses")) {
 | |
|                 //! TODO
 | |
|             } else if (reader.name() == QLatin1String("crossesAt")) {
 | |
|                 //! TODO
 | |
|             }
 | |
| 
 | |
|             // reader.readNext();
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name().toString() == name) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Scaling(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_UNUSED(axis);
 | |
|     Q_ASSERT(reader.name() == QLatin1String("scaling"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("orientation")) {
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("scaling")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| /*
 | |
|   <xsd:complexType name="CT_Title">
 | |
|       <xsd:sequence>
 | |
|           <xsd:element name="tx" type="CT_Tx" minOccurs="0" maxOccurs="1"/>
 | |
|           <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
 | |
|           <xsd:element name="overlay" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|           <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
 | |
|           <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
 | |
|           <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|       </xsd:sequence>
 | |
|   </xsd:complexType>
 | |
| 
 | |
| <xsd:complexType name="CT_Tx">
 | |
|     <xsd:sequence>
 | |
|         <xsd:choice minOccurs="1" maxOccurs="1">
 | |
|             <xsd:element name="strRef" type="CT_StrRef" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="rich" type="a:CT_TextBody" minOccurs="1" maxOccurs="1"/>
 | |
|         </xsd:choice>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| 
 | |
| <xsd:complexType name="CT_StrRef">
 | |
|     <xsd:sequence>
 | |
|         <xsd:element name="f" type="xsd:string" minOccurs="1" maxOccurs="1"/>
 | |
|         <xsd:element name="strCache" type="CT_StrData" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| 
 | |
| <xsd:complexType name="CT_TextBody">
 | |
|     <xsd:sequence>
 | |
|         <xsd:element name="bodyPr" type="CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
 | |
|         <xsd:element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
|   */
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("title"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("tx")) {
 | |
|                 loadXmlAxisEG_AxShared_Title_Tx(reader, axis);
 | |
|             } else if (reader.name() == QLatin1String("overlay")) {
 | |
|                 //! TODO: load overlay
 | |
|                 loadXmlAxisEG_AxShared_Title_Overlay(reader, axis);
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("title")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Overlay(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_UNUSED(axis);
 | |
|     Q_ASSERT(reader.name() == QLatin1String("overlay"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("overlay")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("tx"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("rich")) {
 | |
|                 loadXmlAxisEG_AxShared_Title_Tx_Rich(reader, axis);
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("tx")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("rich"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("p")) {
 | |
|                 loadXmlAxisEG_AxShared_Title_Tx_Rich_P(reader, axis);
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("rich")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich_P(QXmlStreamReader &reader, XlsxAxis *axis)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("p"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("r")) {
 | |
|                 loadXmlAxisEG_AxShared_Title_Tx_Rich_P_R(reader, axis);
 | |
|             } else if (reader.name() == QLatin1String("pPr")) {
 | |
|                 loadXmlAxisEG_AxShared_Title_Tx_Rich_P_pPr(reader, axis);
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("p")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich_P_pPr(QXmlStreamReader &reader,
 | |
|                                                               XlsxAxis *axis)
 | |
| {
 | |
|     Q_UNUSED(axis);
 | |
|     Q_ASSERT(reader.name() == QLatin1String("pPr"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("defRPr")) {
 | |
|                 reader.readElementText();
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("pPr")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| bool ChartPrivate::loadXmlAxisEG_AxShared_Title_Tx_Rich_P_R(QXmlStreamReader &reader,
 | |
|                                                             XlsxAxis *axis)
 | |
| {
 | |
|     Q_ASSERT(reader.name() == QLatin1String("r"));
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             if (reader.name() == QLatin1String("t")) {
 | |
|                 QString strAxisName       = reader.readElementText();
 | |
|                 XlsxAxis::AxisPos axisPos = axis->axisPos;
 | |
|                 axis->axisNames[axisPos]  = strAxisName;
 | |
|             } else {
 | |
|             }
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                    reader.name() == QLatin1String("r")) {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| /*
 | |
| <xsd:complexType name="CT_PlotArea">
 | |
|     <xsd:sequence>
 | |
|         <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:choice minOccurs="1" maxOccurs="unbounded">
 | |
|             <xsd:element name="areaChart" type="CT_AreaChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="area3DChart" type="CT_Area3DChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="lineChart" type="CT_LineChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="line3DChart" type="CT_Line3DChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="stockChart" type="CT_StockChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="radarChart" type="CT_RadarChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="scatterChart" type="CT_ScatterChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="pieChart" type="CT_PieChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="pie3DChart" type="CT_Pie3DChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="doughnutChart" type="CT_DoughnutChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="barChart" type="CT_BarChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="bar3DChart" type="CT_Bar3DChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="ofPieChart" type="CT_OfPieChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="surfaceChart" type="CT_SurfaceChart" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="surface3DChart" type="CT_Surface3DChart" minOccurs="1"
 | |
| maxOccurs="1"/> <xsd:element name="bubbleChart" type="CT_BubbleChart" minOccurs="1" maxOccurs="1"/>
 | |
|         </xsd:choice>
 | |
|         <xsd:choice minOccurs="0" maxOccurs="unbounded">
 | |
|             <xsd:element name="valAx" type="CT_ValAx" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="catAx" type="CT_CatAx" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="dateAx" type="CT_DateAx" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="serAx" type="CT_SerAx" minOccurs="1" maxOccurs="1"/>
 | |
|         </xsd:choice>
 | |
|         <xsd:element name="dTable" type="CT_DTable" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| */
 | |
| 
 | |
| /*
 | |
| <xsd:complexType name="CT_CatAx">
 | |
|     <xsd:sequence>
 | |
|         <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|         <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="lblAlgn" type="CT_LblAlgn" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="noMultiLvlLbl" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| <!----------------------------------------------------------------------------->
 | |
| <xsd:complexType name="CT_DateAx">
 | |
|     <xsd:sequence>
 | |
|         <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|         <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="baseTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="majorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="minorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| <!----------------------------------------------------------------------------->
 | |
| <xsd:complexType name="CT_SerAx">
 | |
|     <xsd:sequence>
 | |
|     <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|         <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| <!----------------------------------------------------------------------------->
 | |
| <xsd:complexType name="CT_ValAx">
 | |
|     <xsd:sequence>
 | |
|         <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|         <xsd:element name="crossBetween" type="CT_CrossBetween" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="dispUnits" type="CT_DispUnits" minOccurs="0" maxOccurs="1"/>
 | |
|         <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|     </xsd:sequence>
 | |
| </xsd:complexType>
 | |
| */
 | |
| 
 | |
| void ChartPrivate::saveXmlAxis(QXmlStreamWriter &writer) const
 | |
| {
 | |
|     for (int i = 0; i < axisList.size(); ++i) {
 | |
|         XlsxAxis *axis = axisList[i].get();
 | |
|         if (nullptr == axis)
 | |
|             continue;
 | |
| 
 | |
|         if (axis->type == XlsxAxis::T_Cat) {
 | |
|             saveXmlAxisCatAx(writer, axis);
 | |
|         }
 | |
|         if (axis->type == XlsxAxis::T_Val) {
 | |
|             saveXmlAxisValAx(writer, axis);
 | |
|         }
 | |
|         if (axis->type == XlsxAxis::T_Ser) {
 | |
|             saveXmlAxisSerAx(writer, axis);
 | |
|         }
 | |
|         if (axis->type == XlsxAxis::T_Date) {
 | |
|             saveXmlAxisDateAx(writer, axis);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAxisCatAx(QXmlStreamWriter &writer, XlsxAxis *axis) const
 | |
| {
 | |
|     /*
 | |
|     <xsd:complexType name="CT_CatAx">
 | |
|         <xsd:sequence>
 | |
|             <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="lblAlgn" type="CT_LblAlgn" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="noMultiLvlLbl" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:catAx"));
 | |
| 
 | |
|     saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
 | |
| 
 | |
|     //! TODO: write element
 | |
|     // auto
 | |
|     // lblAlgn
 | |
|     // lblOffset
 | |
|     // tickLblSkip
 | |
|     // tickMarkSkip
 | |
|     // noMultiLvlLbl
 | |
|     // extLst
 | |
| 
 | |
|     writer.writeEndElement(); // c:catAx
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAxisDateAx(QXmlStreamWriter &writer, XlsxAxis *axis) const
 | |
| {
 | |
|     /*
 | |
|     <xsd:complexType name="CT_DateAx">
 | |
|         <xsd:sequence>
 | |
|             <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="auto" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="lblOffset" type="CT_LblOffset" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="baseTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="majorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="minorTimeUnit" type="CT_TimeUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:dateAx"));
 | |
| 
 | |
|     saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
 | |
| 
 | |
|     //! TODO: write element
 | |
|     // auto
 | |
|     // lblOffset
 | |
|     // baseTimeUnit
 | |
|     // majorUnit
 | |
|     // majorTimeUnit
 | |
|     // minorUnit
 | |
|     // minorTimeUnit
 | |
|     // extLst
 | |
| 
 | |
|     writer.writeEndElement(); // c:dateAx
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAxisSerAx(QXmlStreamWriter &writer, XlsxAxis *axis) const
 | |
| {
 | |
|     /*
 | |
|     <xsd:complexType name="CT_SerAx">
 | |
|         <xsd:sequence>
 | |
|         <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="tickLblSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="tickMarkSkip" type="CT_Skip" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:serAx"));
 | |
| 
 | |
|     saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
 | |
| 
 | |
|     //! TODO: write element
 | |
|     // tickLblSkip
 | |
|     // tickMarkSkip
 | |
|     // extLst
 | |
| 
 | |
|     writer.writeEndElement(); // c:serAx
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAxisValAx(QXmlStreamWriter &writer, XlsxAxis *axis) const
 | |
| {
 | |
|     /*
 | |
|     <xsd:complexType name="CT_ValAx">
 | |
|         <xsd:sequence>
 | |
|             <xsd:group ref="EG_AxShared" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="crossBetween" type="CT_CrossBetween" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="majorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="minorUnit" type="CT_AxisUnit" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="dispUnits" type="CT_DispUnits" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:valAx"));
 | |
| 
 | |
|     saveXmlAxisEG_AxShared(writer, axis); // EG_AxShared
 | |
| 
 | |
|     //! TODO: write element
 | |
|     // crossBetween
 | |
|     // majorUnit
 | |
|     // minorUnit
 | |
|     // dispUnits
 | |
|     // extLst
 | |
| 
 | |
|     writer.writeEndElement(); // c:valAx
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAxisEG_AxShared(QXmlStreamWriter &writer, XlsxAxis *axis) const
 | |
| {
 | |
|     /*
 | |
|     <xsd:group name="EG_AxShared">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="axId" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)
 | |
|             <xsd:element name="scaling" type="CT_Scaling" minOccurs="1" maxOccurs="1"/> (*)
 | |
|             <xsd:element name="delete" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="axPos" type="CT_AxPos" minOccurs="1" maxOccurs="1"/> (*)
 | |
|             <xsd:element name="majorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="minorGridlines" type="CT_ChartLines" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="title" type="CT_Title" minOccurs="0" maxOccurs="1"/>
 | |
|     (***********************) <xsd:element name="numFmt" type="CT_NumFmt" minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:element name="majorTickMark" type="CT_TickMark" minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:element name="minorTickMark" type="CT_TickMark" minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:element name="tickLblPos" type="CT_TickLblPos" minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0"
 | |
|     maxOccurs="1"/> <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="crossAx" type="CT_UnsignedInt" minOccurs="1" maxOccurs="1"/> (*)
 | |
|             <xsd:choice minOccurs="0" maxOccurs="1">
 | |
|                 <xsd:element name="crosses" type="CT_Crosses" minOccurs="1" maxOccurs="1"/>
 | |
|                 <xsd:element name="crossesAt" type="CT_Double" minOccurs="1" maxOccurs="1"/>
 | |
|             </xsd:choice>
 | |
|         </xsd:sequence>
 | |
|     </xsd:group>
 | |
|     */
 | |
| 
 | |
|     writer.writeEmptyElement(
 | |
|         QStringLiteral("c:axId")); // 21.2.2.9. axId (Axis ID) (mandatory value)
 | |
|     writer.writeAttribute(QStringLiteral("val"), QString::number(axis->axisId));
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:scaling"));     // CT_Scaling (mandatory value)
 | |
|     writer.writeEmptyElement(QStringLiteral("c:orientation")); // CT_Orientation
 | |
|     writer.writeAttribute(QStringLiteral("val"), QStringLiteral("minMax")); // ST_Orientation
 | |
|     writer.writeEndElement();                                               // c:scaling
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("c:axPos")); // axPos CT_AxPos (mandatory value)
 | |
|     QString pos = GetAxisPosString(axis->axisPos);
 | |
|     if (!pos.isEmpty()) {
 | |
|         writer.writeAttribute(QStringLiteral("val"), pos); // ST_AxPos
 | |
|     }
 | |
| 
 | |
|     if (majorGridlinesEnabled) {
 | |
|         writer.writeEmptyElement(QStringLiteral("c:majorGridlines"));
 | |
|     }
 | |
|     if (minorGridlinesEnabled) {
 | |
|         writer.writeEmptyElement(QStringLiteral("c:minorGridlines"));
 | |
|     }
 | |
| 
 | |
|     saveXmlAxisEG_AxShared_Title(writer, axis); // "c:title" CT_Title
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("c:crossAx")); // crossAx (mandatory value)
 | |
|     writer.writeAttribute(QStringLiteral("val"), QString::number(axis->crossAx));
 | |
| }
 | |
| 
 | |
| void ChartPrivate::saveXmlAxisEG_AxShared_Title(QXmlStreamWriter &writer, XlsxAxis *axis) const
 | |
| {
 | |
|     // CT_Title
 | |
| 
 | |
|     /*
 | |
|     <xsd:complexType name="CT_Title">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="tx" type="CT_Tx" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="layout" type="CT_Layout" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="overlay" type="CT_Boolean" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="spPr" type="a:CT_ShapeProperties" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="txPr" type="a:CT_TextBody" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
|     /*
 | |
|     <xsd:complexType name="CT_Tx">
 | |
|         <xsd:sequence>
 | |
|             <xsd:choice minOccurs="1" maxOccurs="1">
 | |
|                 <xsd:element name="strRef" type="CT_StrRef" minOccurs="1" maxOccurs="1"/>
 | |
|                 <xsd:element name="rich" type="a:CT_TextBody" minOccurs="1" maxOccurs="1"/>
 | |
|             </xsd:choice>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
|     /*
 | |
|     <xsd:complexType name="CT_StrRef">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="f" type="xsd:string" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="strCache" type="CT_StrData" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="extLst" type="CT_ExtensionList" minOccurs="0" maxOccurs="1"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
|     /*
 | |
|     <xsd:complexType name="CT_TextBody">
 | |
|         <xsd:sequence>
 | |
|             <xsd:element name="bodyPr" type="CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
 | |
|             <xsd:element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
 | |
|             <xsd:element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
 | |
|         </xsd:sequence>
 | |
|     </xsd:complexType>
 | |
|     */
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:title"));
 | |
| 
 | |
|     // CT_Tx {{
 | |
|     writer.writeStartElement(QStringLiteral("c:tx"));
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:rich")); // CT_TextBody
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("a:bodyPr")); // CT_TextBodyProperties
 | |
| 
 | |
|     writer.writeEmptyElement(QStringLiteral("a:lstStyle")); // CT_TextListStyle
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("a:p"));
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("a:pPr"));
 | |
|     writer.writeAttribute(QStringLiteral("lvl"), QString::number(0));
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("a:defRPr"));
 | |
|     writer.writeAttribute(QStringLiteral("b"), QString::number(0));
 | |
|     writer.writeEndElement(); // a:defRPr
 | |
|     writer.writeEndElement(); // a:pPr
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("a:r"));
 | |
|     QString strAxisName = GetAxisName(axis);
 | |
|     writer.writeTextElement(QStringLiteral("a:t"), strAxisName);
 | |
|     writer.writeEndElement(); // a:r
 | |
| 
 | |
|     writer.writeEndElement(); // a:p
 | |
| 
 | |
|     writer.writeEndElement(); // c:rich
 | |
| 
 | |
|     writer.writeEndElement(); // c:tx
 | |
|     // CT_Tx }}
 | |
| 
 | |
|     writer.writeStartElement(QStringLiteral("c:overlay"));
 | |
|     writer.writeAttribute(QStringLiteral("val"), QString::number(0)); // CT_Boolean
 | |
|     writer.writeEndElement();                                         // c:overlay
 | |
| 
 | |
|     writer.writeEndElement(); // c:title
 | |
| }
 | |
| 
 | |
| QString ChartPrivate::GetAxisPosString(XlsxAxis::AxisPos axisPos) const
 | |
| {
 | |
|     QString pos;
 | |
|     switch (axisPos) {
 | |
|     case XlsxAxis::Top:
 | |
|         pos = QStringLiteral("t");
 | |
|         break;
 | |
|     case XlsxAxis::Bottom:
 | |
|         pos = QStringLiteral("b");
 | |
|         break;
 | |
|     case XlsxAxis::Left:
 | |
|         pos = QStringLiteral("l");
 | |
|         break;
 | |
|     case XlsxAxis::Right:
 | |
|         pos = QStringLiteral("r");
 | |
|         break;
 | |
|     default:
 | |
|         break; // ??
 | |
|     }
 | |
| 
 | |
|     return pos;
 | |
| }
 | |
| 
 | |
| QString ChartPrivate::GetAxisName(XlsxAxis *axis) const
 | |
| {
 | |
|     QString strAxisName;
 | |
|     if (nullptr == axis)
 | |
|         return strAxisName;
 | |
| 
 | |
|     QString pos = GetAxisPosString(axis->axisPos); // l, t, r, b
 | |
|     if (pos.isEmpty())
 | |
|         return strAxisName;
 | |
| 
 | |
|     strAxisName = axis->axisNames[axis->axisPos];
 | |
|     return strAxisName;
 | |
| }
 | |
| 
 | |
| ///
 | |
| /// \brief ChartPrivate::readSubTree
 | |
| /// \param reader
 | |
| /// \return
 | |
| ///
 | |
| QString ChartPrivate::readSubTree(QXmlStreamReader &reader)
 | |
| {
 | |
|     QString treeString;
 | |
|     QString prefix;
 | |
|     const auto &treeName = reader.name();
 | |
| 
 | |
|     while (!reader.atEnd()) {
 | |
|         reader.readNextStartElement();
 | |
|         if (reader.tokenType() == QXmlStreamReader::StartElement) {
 | |
|             prefix = reader.prefix().toString();
 | |
| 
 | |
|             treeString += QLatin1String("<") + reader.qualifiedName().toString();
 | |
| 
 | |
|             const QXmlStreamAttributes attributes = reader.attributes();
 | |
|             for (const QXmlStreamAttribute &attr : attributes) {
 | |
|                 treeString += QLatin1String(" ") + attr.name().toString() + QLatin1String("=\"") +
 | |
|                               attr.value().toString() + QLatin1String("\"");
 | |
|             }
 | |
|             treeString += QStringLiteral(">");
 | |
|         } else if (reader.tokenType() == QXmlStreamReader::EndElement) {
 | |
|             if (reader.name() == treeName) {
 | |
|                 break;
 | |
|             }
 | |
|             treeString +=
 | |
|                 QLatin1String("</") + reader.qualifiedName().toString() + QLatin1String(">");
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return treeString;
 | |
| }
 | |
| 
 | |
| ///
 | |
| /// \brief ChartPrivate::loadXmlChartLegend
 | |
| /// \param reader
 | |
| /// \return
 | |
| ///
 | |
| bool ChartPrivate::loadXmlChartLegend(QXmlStreamReader &reader)
 | |
| {
 | |
| 
 | |
|     Q_ASSERT(reader.name() == QLatin1String("legend"));
 | |
| 
 | |
|     while (!reader.atEnd() && !(reader.tokenType() == QXmlStreamReader::EndElement &&
 | |
|                                 reader.name() == QLatin1String("legend"))) {
 | |
|         if (reader.readNextStartElement()) {
 | |
|             if (reader.name() == QLatin1String("legendPos")) // c:legendPos
 | |
|             {
 | |
|                 QString pos = reader.attributes().value(QLatin1String("val")).toString();
 | |
|                 if (pos.compare(QLatin1String("r"), Qt::CaseInsensitive) == 0) {
 | |
|                     // legendPos = Chart::ChartAxisPos::Right;
 | |
|                     legendPos = Chart::Right;
 | |
|                 } else if (pos.compare(QLatin1String("l"), Qt::CaseInsensitive) == 0) {
 | |
|                     // legendPos = Chart::ChartAxisPos::Left;
 | |
|                     legendPos = Chart::Left;
 | |
|                 } else if (pos.compare(QLatin1String("t"), Qt::CaseInsensitive) == 0) {
 | |
|                     // legendPos = Chart::ChartAxisPos::Top;
 | |
|                     legendPos = Chart::Top;
 | |
|                 } else if (pos.compare(QLatin1String("b"), Qt::CaseInsensitive) == 0) {
 | |
|                     // legendPos = Chart::ChartAxisPos::Bottom;
 | |
|                     legendPos = Chart::Bottom;
 | |
|                 } else {
 | |
|                     // legendPos = Chart::ChartAxisPos::None;
 | |
|                     legendPos = Chart::None;
 | |
|                 }
 | |
|             } else if (reader.name() == QLatin1String("overlay")) // c:legendPos
 | |
|             {
 | |
|                 QString pos = reader.attributes().value(QLatin1String("val")).toString();
 | |
|                 if (pos.compare(QLatin1String("1"), Qt::CaseInsensitive) == 0) {
 | |
|                     legendOverlay = true;
 | |
|                 } else {
 | |
|                     legendOverlay = false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| QT_END_NAMESPACE_XLSX
 | 
