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