File indexing completed on 2025-01-19 10:49:27
0001 /* This file is part of the KDE project 0002 0003 SPDX-FileCopyrightText: 2012-2013 Inge Wallin <inge@lysator.liu.se> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 0009 // Own 0010 #include "OdfTextReader.h" 0011 0012 // Qt 0013 #include <QStringList> 0014 #include <QBuffer> 0015 0016 // KF5 0017 #include <klocalizedstring.h> 0018 0019 // Calligra 0020 #include <KoStore.h> 0021 #include <KoXmlStreamReader.h> 0022 #include <KoXmlNS.h> 0023 #include <KoXmlWriter.h> // For copyXmlElement 0024 #include <KoOdfReadStore.h> 0025 0026 // Reader library 0027 #include "OdfReader.h" 0028 #include "OdfChartReaderBackend.h" 0029 #include "OdfReaderContext.h" 0030 #include "OdfReaderDebug.h" 0031 0032 0033 #if 1 0034 static int debugIndent = 0; 0035 #define DEBUGSTART() \ 0036 ++debugIndent; \ 0037 DEBUG_READING("entering") 0038 #define DEBUGEND() \ 0039 DEBUG_READING("exiting"); \ 0040 --debugIndent 0041 #define DEBUG_READING(param) \ 0042 debugOdfReader << QString("%1").arg(" ", debugIndent * 2) << param << ": " \ 0043 << (reader.isStartElement() ? "start": (reader.isEndElement() ? "end" : "other")) \ 0044 << reader.qualifiedName().toString() 0045 #else 0046 #define DEBUGSTART() \ 0047 // NOTHING 0048 #define DEBUGEND() \ 0049 // NOTHING 0050 #define DEBUG_READING(param) \ 0051 // NOTHING 0052 #endif 0053 0054 0055 OdfChartReader::OdfChartReader() 0056 : m_parent(0) 0057 , m_backend(0) 0058 , m_context(0) 0059 { 0060 } 0061 0062 OdfChartReader::~OdfChartReader() 0063 { 0064 } 0065 0066 0067 // ---------------------------------------------------------------- 0068 0069 0070 void OdfChartReader::setParent(OdfReader *parent) 0071 { 0072 m_parent = parent; 0073 } 0074 0075 void OdfChartReader::setBackend(OdfChartReaderBackend *backend) 0076 { 0077 m_backend = backend; 0078 } 0079 0080 void OdfChartReader::setContext(OdfReaderContext *context) 0081 { 0082 m_context = context; 0083 } 0084 0085 0086 // ---------------------------------------------------------------- 0087 0088 0089 void OdfChartReader::readElementOfficeChart(KoXmlStreamReader &reader) 0090 { 0091 DEBUGSTART(); 0092 m_backend->elementOfficeChart(reader, m_context); 0093 0094 // <office:chart> has the following children in ODF 1.2: 0095 // [done] <chart:chart> 11.1 0096 // <table:calculation-settings> 9.4.1 0097 // <table:consolidation> 9.7 0098 // <table:content-validations> 9.4.4 0099 // <table:database-ranges> 9.4.14 0100 // <table:data-pilot-tables> 9.6.2 0101 // <table:dde-links> 9.8 0102 // <table:label-ranges> 9.4.10 0103 // <table:named-expressions> 9.4.11 0104 // <text:alphabetical-index-auto-mark-file> 8.8.3 0105 // <text:dde-connection-decls> 14.6.2 0106 // <text:sequence-decls> 7.4.11 0107 // <text:user-field-decls> 7.4.7 0108 // <text:variable-decls> 7.4.2 0109 while (reader.readNextStartElement()) { 0110 QString tagName = reader.qualifiedName().toString(); 0111 0112 if (tagName == "chart:chart") { 0113 readElementChartChart(reader); 0114 } 0115 else if (tagName == "table:calculation-settings") { 0116 // FIXME: NYI 0117 reader.skipCurrentElement(); 0118 } 0119 //... MORE else if () HERE 0120 else { 0121 reader.skipCurrentElement(); 0122 } 0123 } 0124 0125 m_backend->elementOfficeChart(reader, m_context); 0126 DEBUGEND(); 0127 } 0128 0129 void OdfChartReader::readElementChartChart(KoXmlStreamReader &reader) 0130 { 0131 DEBUGSTART(); 0132 m_backend->elementChartChart(reader, m_context); 0133 0134 // <chart:chart> has the following children in ODF 1.2: 0135 // [done] <chart:footer> 11.2.3 0136 // [done] <chart:legend> 11.3 0137 // [done] <chart:plot-area> 11.4 0138 // [done] <chart:subtitle> 11.2.2 0139 // [done] <chart:title> 11.2.1 0140 // [done] <table:table> 9.1.2 0141 while (reader.readNextStartElement()) { 0142 QString tagName = reader.qualifiedName().toString(); 0143 0144 if (tagName == "chart:footer") { 0145 readElementChartFooter(reader); 0146 } 0147 else if (tagName == "chart:subtitle") { 0148 readElementChartSubtitle(reader); 0149 } 0150 else if (tagName == "chart:title") { 0151 readElementChartTitle(reader); 0152 } 0153 else if (tagName == "chart:legend") { 0154 readElementChartLegend(reader); 0155 } 0156 else if (tagName == "chart:plot-area") { 0157 readElementChartPlotArea(reader); 0158 } 0159 else if (tagName == "table:table") { 0160 OdfTextReader *textReader = m_parent->textReader(); 0161 if (textReader) { 0162 textReader->readElementTableTable(reader); 0163 } 0164 else { 0165 reader.skipCurrentElement(); 0166 } 0167 } 0168 else { 0169 reader.skipCurrentElement(); 0170 } 0171 } 0172 0173 m_backend->elementChartChart(reader, m_context); 0174 DEBUGEND(); 0175 } 0176 0177 #define IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(readername, name) \ 0178 IMPLEMENT_READER_FUNCTION_START(readername, name) \ 0179 while (reader.readNextStartElement()) { \ 0180 QString tagName = reader.qualifiedName().toString(); \ 0181 \ 0182 if (tagName == "text:p") { \ 0183 OdfTextReader *textReader = m_parent->textReader(); \ 0184 if (textReader) { \ 0185 textReader->readElementTextP(reader); \ 0186 } \ 0187 else { \ 0188 reader.skipCurrentElement(); \ 0189 } \ 0190 } \ 0191 else { \ 0192 reader.skipCurrentElement(); \ 0193 } \ 0194 } \ 0195 IMPLEMENT_READER_FUNCTION_END(name) 0196 0197 0198 IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartFooter) 0199 IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartSubtitle) 0200 IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartTitle) 0201 IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartLegend) 0202 0203 0204 void OdfChartReader::readElementChartPlotArea(KoXmlStreamReader &reader) 0205 { 0206 DEBUGSTART(); 0207 m_backend->elementChartPlotArea(reader, m_context); 0208 0209 // <chart:plot-area> has the following children in ODF 1.2: 0210 // [done] <chart:wall> 11.6 0211 // [done] <chart:floor> 11.7 0212 // [done] <chart:axis> 11.8 0213 // [done] <chart:series> 11.11 0214 // [done] <chart:stock-gain-marker> 11.19 0215 // [done] <chart:stock-loss-marker> 11.20 0216 // [done] <chart:stock-range-line> 11.21 0217 // <dr3d:light> 10.5.3 0218 while (reader.readNextStartElement()) { 0219 QString tagName = reader.qualifiedName().toString(); 0220 0221 if (tagName == "chart:wall") { 0222 readElementChartWall(reader); 0223 } 0224 else if (tagName == "chart:floor") { 0225 readElementChartFloor(reader); 0226 } 0227 else if (tagName == "chart:axis") { 0228 readElementChartAxis(reader); 0229 } 0230 else if (tagName == "chart:series") { 0231 readElementChartSeries(reader); 0232 } 0233 else if (tagName == "chart:stock-gain-marker") { 0234 readElementChartStockGainMarker(reader); 0235 } 0236 else if (tagName == "chart:stock-loss-marker") { 0237 readElementChartStockLossMarker(reader); 0238 } 0239 else if (tagName == "chart:stock-range-line") { 0240 readElementChartStockRangeLine(reader); 0241 } 0242 else if (tagName == "dr3d:light") { 0243 // FIXME: NYI 0244 reader.skipCurrentElement(); 0245 } 0246 else { 0247 reader.skipCurrentElement(); 0248 } 0249 } 0250 0251 m_backend->elementChartPlotArea(reader, m_context); 0252 DEBUGEND(); 0253 } 0254 0255 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartWall) 0256 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartFloor) 0257 0258 void OdfChartReader::readElementChartAxis(KoXmlStreamReader &reader) 0259 { 0260 DEBUGSTART(); 0261 m_backend->elementChartAxis(reader, m_context); 0262 0263 // <chart:axis> has the following children in ODF 1.2: 0264 // [done] <chart:categories> 11.9 0265 // [done] <chart:grid> 11.10 0266 // [done] <chart:title> 11.2.1 0267 0268 while (reader.readNextStartElement()) { 0269 QString tagName = reader.qualifiedName().toString(); 0270 0271 if (tagName == "chart:categories") { 0272 readElementChartCategories(reader); 0273 } 0274 else if (tagName == "chart:grid") { 0275 readElementChartGrid(reader); 0276 } 0277 else if (tagName == "chart:title") { 0278 readElementChartTitle(reader); 0279 } 0280 else { 0281 reader.skipCurrentElement(); 0282 } 0283 } 0284 0285 m_backend->elementChartAxis(reader, m_context); 0286 DEBUGEND(); 0287 } 0288 0289 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartCategories) 0290 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartGrid) 0291 0292 // ODF 1.2 11.11: <chart:series> 0293 void OdfChartReader::readElementChartSeries(KoXmlStreamReader &reader) 0294 { 0295 DEBUGSTART(); 0296 m_backend->elementChartSeries(reader, m_context); 0297 0298 // <chart:series> has the following children in ODF 1.2: 0299 // [done] <chart:data-label> 11.14 0300 // [done] <chart:data-point> 11.13 0301 // [done] <chart:domain> 11.12 0302 // [done] <chart:error-indicator> 11.16 0303 // [done] <chart:mean-value> 11.15 0304 // [done] <chart:regression-curve> 11.17 0305 0306 while (reader.readNextStartElement()) { 0307 QString tagName = reader.qualifiedName().toString(); 0308 0309 if (tagName == "chart:data-label") { 0310 readElementChartDataLabel(reader); 0311 } 0312 else if (tagName == "chart:data-point") { 0313 readElementChartDataPoint(reader); 0314 } 0315 else if (tagName == "chart:domain") { 0316 readElementChartDomain(reader); 0317 } 0318 else if (tagName == "chart:error-indicator") { 0319 readElementChartErrorIndicator(reader); 0320 } 0321 else if (tagName == "chart:mean-value") { 0322 readElementChartMeanValue(reader); 0323 } 0324 else if (tagName == "chart:regression-curve") { 0325 readElementChartRegressionCurve(reader); 0326 } 0327 else { 0328 reader.skipCurrentElement(); 0329 } 0330 } 0331 0332 m_backend->elementChartSeries(reader, m_context); 0333 DEBUGEND(); 0334 } 0335 0336 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartDomain) // ODF 1.2 11.12 0337 IMPLEMENT_READER_FUNCTION_ONE_CHILD(OdfChartReader, ChartDataPoint, 0338 "chart:data-label", ChartDataLabel) // ODF 1.2 11.13 0339 IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartDataLabel) // ODF 1.2 11.14 0340 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartMeanValue) // ODF 1.2 11.15 0341 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartErrorIndicator) // ODF 1.2 11.16 0342 IMPLEMENT_READER_FUNCTION_ONE_CHILD(OdfChartReader, ChartRegressionCurve, 0343 "chart:equation", ChartEquation) // ODF 1.2 11.17 0344 IMPLEMENT_READER_FUNCTION_TEXTP_ONLY(OdfChartReader, ChartEquation) // ODF 1.2 11.18 0345 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartStockGainMarker) // ODF 1.2 11.19 0346 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartStockLossMarker) // ODF 1.2 11.20 0347 IMPLEMENT_READER_FUNCTION_NO_CHILDREN(OdfChartReader, ChartStockRangeLine) // ODF 1.2 11.21 0348 0349 0350 0351 // ---------------------------------------------------------------- 0352 // Other functions 0353 0354 0355 void OdfChartReader::readUnknownElement(KoXmlStreamReader &reader) 0356 { 0357 DEBUGSTART(); 0358 0359 #if 0 // FIXME: Fix this 0360 if (m_context->isInsideParagraph()) { 0361 // readParagraphContents expect to have the reader point to the 0362 // contents of the paragraph so we have to read past the chart:p 0363 // start tag here. 0364 reader.readNext(); 0365 readParagraphContents(reader); 0366 } 0367 else { 0368 while (reader.readNextStartElement()) { 0369 readTextLevelElement(reader); 0370 } 0371 } 0372 #else 0373 reader.skipCurrentElement(); 0374 #endif 0375 0376 DEBUGEND(); 0377 }