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, libodf{,2} 0020 #include <KoXmlNS.h> 0021 #include <KoXmlStreamReader.h> 0022 #include <KoXmlUtils.h> 0023 0024 // Reader library 0025 #include "OdfReader.h" 0026 #include "OdfTextReaderBackend.h" 0027 #include "OdfReaderContext.h" 0028 #include "OdfDrawReader.h" 0029 #include "OdfReaderDebug.h" 0030 0031 0032 #if 1 0033 static int debugIndent = 0; 0034 #define DEBUGSTART() \ 0035 ++debugIndent; \ 0036 DEBUG_READING("entering") 0037 #define DEBUGEND() \ 0038 DEBUG_READING("exiting"); \ 0039 --debugIndent 0040 #define DEBUG_READING(param) \ 0041 debugOdfReader << QString("%1").arg(" ", debugIndent * 2) << param << ": " \ 0042 << (reader.isStartElement() ? "start": (reader.isEndElement() ? "end" : "other")) \ 0043 << reader.qualifiedName().toString() 0044 #else 0045 #define DEBUGSTART() \ 0046 // NOTHING 0047 #define DEBUGEND() \ 0048 // NOTHING 0049 #define DEBUG_READING(param) \ 0050 // NOTHING 0051 #endif 0052 0053 0054 OdfTextReader::OdfTextReader() 0055 : m_parent(0) 0056 , m_backend(0) 0057 , m_context(0) 0058 { 0059 } 0060 0061 OdfTextReader::~OdfTextReader() 0062 { 0063 } 0064 0065 0066 // ---------------------------------------------------------------- 0067 0068 0069 void OdfTextReader::setParent(OdfReader *parent) 0070 { 0071 m_parent = parent; 0072 } 0073 0074 void OdfTextReader::setBackend(OdfTextReaderBackend *backend) 0075 { 0076 m_backend = backend; 0077 } 0078 0079 void OdfTextReader::setContext(OdfReaderContext *context) 0080 { 0081 m_context = context; 0082 } 0083 0084 0085 // ---------------------------------------------------------------- 0086 0087 0088 #if 0 0089 // This is a template function for the reader library. 0090 // Copy this one and change the name and fill in the code. 0091 void OdfTextReader::readElementNamespaceTagname(KoXmlStreamReader &reader) 0092 { 0093 DEBUGSTART(); 0094 m_backend->elementNamespaceTagname(reader, m_context); 0095 0096 // <namespace:tagname> has the following children in ODF 1.2: 0097 // FILL IN THE CHILDREN LIKE THIS EXAMPLE (taken from office:document-content): 0098 // <office:automatic-styles> 3.15.3 0099 // <office:body> 3.3 0100 // <office:font-face-decls> 3.14 0101 // <office:scripts> 3.12. 0102 while (reader.readNextStartElement()) { 0103 QString tagName = reader.qualifiedName().toString(); 0104 0105 if (tagName == "office:automatic-styles") { 0106 // FIXME: NYI 0107 reader.skipCurrentElement(); 0108 } 0109 else if (tagName == "office:body") { 0110 readElementOfficeBody(reader); 0111 } 0112 ... MORE else if () HERE 0113 else { 0114 reader.skipCurrentElement(); 0115 } 0116 } 0117 0118 m_backend->elementNamespaceTagname(reader, m_context); 0119 DEBUGEND(); 0120 } 0121 #endif 0122 0123 0124 0125 0126 // ---------------------------------------------------------------- 0127 // Text level functions 0128 0129 0130 // This function is a bit special since it doesn't handle a specific 0131 // element. Instead it handles the common child elements between a 0132 // number of text-level elements. 0133 // 0134 void OdfTextReader::readTextLevelElement(KoXmlStreamReader &reader) 0135 { 0136 DEBUGSTART(); 0137 0138 // We should not call any backend functions here. That is already 0139 // done in the functions that call this one. 0140 0141 // We define the common elements on the text level as the 0142 // following list. They are the basic text level contents that 0143 // can be found in a text box (<draw:text-box>) but also in many 0144 // other places like <table:table-cell>, <text:section>, 0145 // <office:text>, etc. 0146 // 0147 // The ones that are not text boxes can also have other children 0148 // but these are the ones we have found to be the common ones. 0149 // 0150 // <dr3d:scene> 10.5.2 0151 // <draw:a> 10.4.12 0152 // <draw:caption> 10.3.11 0153 // <draw:circle> 10.3.8 0154 // <draw:connector> 10.3.10 0155 // <draw:control> 10.3.13 0156 // <draw:custom-shape> 10.6.1 0157 // <draw:ellipse> 10.3.9 0158 // <draw:frame> 10.4.2 0159 // <draw:g> 10.3.15 0160 // <draw:line> 10.3.3 0161 // <draw:measure> 10.3.12 0162 // <draw:page-thumbnail> 10.3.14 0163 // <draw:path> 10.3.7 0164 // <draw:polygon> 10.3.5 0165 // <draw:polyline> 10.3.4 0166 // <draw:rect> 10.3.2 0167 // <draw:regular-polygon> 10.3.6 0168 // All of the above are sent to the draw reader. 0169 // 0170 // [done] <table:table> 9.1.2 0171 // <text:alphabetical-index> 8.8 0172 // <text:bibliography> 8.9 0173 // <text:change> 5.5.7.4 0174 // <text:change-end> 5.5.7.3 0175 // <text:change-start> 5.5.7.2 0176 // [done] <text:h> 5.1.2 0177 // <text:illustration-index> 8.4 0178 // [done] <text:list> 5.3.1 0179 // <text:numbered-paragraph> 5.3.6 0180 // <text:object-index> 8.6 0181 // [done] <text:p> 5.1.3 0182 // <text:section> 5.4 0183 // [done] <text:soft-page-break> 5.6 0184 // <text:table-index> 8.5 0185 // <text:table-of-content> 8.3 0186 // <text:user-index> 8.7 0187 0188 QString tagName = reader.qualifiedName().toString(); 0189 0190 if (reader.prefix() == "draw" || reader.prefix() == "dr3d") { 0191 OdfDrawReader *drawReader = m_parent->drawReader(); 0192 if (drawReader) { 0193 drawReader->readCommonGraphicsElements(reader); 0194 } 0195 else { 0196 reader.skipCurrentElement(); 0197 } 0198 } // draw | dr3d namespace 0199 else if (tagName == "text:h") { 0200 readElementTextH(reader); 0201 } 0202 else if (tagName == "text:p") { 0203 readElementTextP(reader); 0204 } 0205 else if (tagName == "text:list") { 0206 readElementTextList(reader); 0207 } 0208 else if (tagName == "table:table") { 0209 readElementTableTable(reader); 0210 } 0211 else if (tagName == "text:soft-page-break") { 0212 readElementTextSoftPageBreak(reader); 0213 } 0214 else { 0215 readUnknownElement(reader); 0216 } 0217 0218 DEBUGEND(); 0219 } 0220 0221 0222 void OdfTextReader::readElementTextH(KoXmlStreamReader &reader) 0223 { 0224 DEBUGSTART(); 0225 m_backend->elementTextH(reader, m_context); 0226 0227 // The function readParagraphContents() expects to have the reader 0228 // point to the contents of the paragraph so we have to read past 0229 // the text:h start tag here. 0230 reader.readNext(); 0231 m_context->setIsInsideParagraph(true); 0232 readParagraphContents(reader); 0233 m_context->setIsInsideParagraph(false); 0234 0235 m_backend->elementTextH(reader, m_context); 0236 DEBUGEND(); 0237 } 0238 0239 void OdfTextReader::readElementTextP(KoXmlStreamReader &reader) 0240 { 0241 DEBUGSTART(); 0242 m_backend->elementTextP(reader, m_context); 0243 0244 // The function readParagraphContents() expects to have the reader 0245 // point to the contents of the paragraph so we have to read past 0246 // the text:p start tag here. 0247 reader.readNext(); 0248 m_context->setIsInsideParagraph(true); 0249 readParagraphContents(reader); 0250 m_context->setIsInsideParagraph(false); 0251 0252 m_backend->elementTextP(reader, m_context); 0253 DEBUGEND(); 0254 } 0255 0256 void OdfTextReader::readElementTextList(KoXmlStreamReader &reader) 0257 { 0258 DEBUGSTART(); 0259 m_backend->elementTextList(reader, m_context); 0260 0261 // <text:list> has the following children in ODF 1.2: 0262 // [done] <text:list-header> 5.3.3 0263 // [done] <text:list-item> 5.3.4 0264 0265 m_context->setIsInsideParagraph(true); 0266 while (reader.readNextStartElement()) { 0267 DEBUG_READING("loop-start"); 0268 0269 QString tagName = reader.qualifiedName().toString(); 0270 //debugOdfReader << "list child:" << tagName; 0271 if (tagName == "text:list-item") { 0272 readElementTextListItem(reader); 0273 } 0274 else if (tagName == "text:list-header") { 0275 readElementTextListHeader(reader); 0276 } 0277 else { 0278 readUnknownElement(reader); 0279 } 0280 DEBUG_READING("loop-end"); 0281 } 0282 m_context->setIsInsideParagraph(false); 0283 0284 m_backend->elementTextList(reader, m_context); 0285 DEBUGEND(); 0286 } 0287 0288 // ---------------------------------------------------------------- 0289 // Tables 0290 0291 0292 void OdfTextReader::readElementTableTable(KoXmlStreamReader &reader) 0293 { 0294 DEBUGSTART(); 0295 m_backend->elementTableTable(reader, m_context); 0296 0297 // <table:table> has the following children in ODF 1.2: 0298 // <office:dde-source> 14.6.5 0299 // <office:forms> 13.2 0300 // [done] <table:desc> 9.1.14 0301 // <table:named-expressions> 9.4.11 0302 // <table:scenario> 9.2.7 0303 // <table:shapes> 9.2.8 0304 // [done] <table:table-column> 9.1.6 0305 // [done] <table:table-column-group> 9.1.10 0306 // [done] <table:table-columns> 9.1.12 0307 // [done] <table:table-header-columns> 9.1.11 0308 // [done] <table:table-header-rows> 9.1.7 0309 // [done] <table:table-row> 9.1.3 0310 // [done] <table:table-row-group> 9.1.9 0311 // [done] <table:table-rows> 9.1.8 0312 // <table:table-source> 9.2.6 0313 // [done] <table:title> 9.1.13 0314 // [done] <text:soft-page-break> 5.6 0315 while (reader.readNextStartElement()) { 0316 QString tagName = reader.qualifiedName().toString(); 0317 0318 if (tagName == "table:table-column") { 0319 readElementTableTableColumn(reader); 0320 } 0321 else if (tagName == "table:table-column-group") { 0322 readElementTableTableColumnGroup(reader); 0323 } 0324 else if (tagName == "table:table-columns") { 0325 readElementTableTableColumns(reader); 0326 } 0327 else if (tagName == "table:table-header-columns") { 0328 readElementTableTableHeaderColumns(reader); 0329 } 0330 else if (tagName == "table:table-header-rows") { 0331 readElementTableTableHeaderRows(reader); 0332 } 0333 else if (tagName == "table:table-row") { 0334 readElementTableTableRow(reader); 0335 } 0336 else if (tagName == "table:table-row-group") { 0337 readElementTableTableRowGroup(reader); 0338 } 0339 else if (tagName == "table:table-rows") { 0340 readElementTableTableRows(reader); 0341 } 0342 else if (tagName == "table:title") { 0343 QString value; 0344 readCharacterData(reader, value); 0345 m_backend->textVariable(tagName, value); 0346 } 0347 else if (tagName == "table:desc") { 0348 QString value; 0349 readCharacterData(reader, value); 0350 m_backend->textVariable(tagName, value); 0351 } 0352 else if (tagName == "text:soft-page-break") { 0353 readElementTextSoftPageBreak(reader); 0354 } 0355 else { 0356 reader.skipCurrentElement(); 0357 } 0358 } 0359 0360 m_backend->elementTableTable(reader, m_context); 0361 DEBUGEND(); 0362 } 0363 0364 void OdfTextReader::readElementTableTableColumnGroup(KoXmlStreamReader &reader) 0365 { 0366 DEBUGSTART(); 0367 m_backend->elementTableTableColumnGroup(reader, m_context); 0368 0369 // <table:table-column-group> has the following children in ODF 1.2: 0370 // <table:table-header-columns> 9.1.11 0371 // <table:table-column> 9.1.6 0372 // <table:table-column-group> 9.1.10 0373 // <table:table-columns> 9.1.12 0374 // 0375 while (reader.readNextStartElement()) { 0376 QString tagName = reader.qualifiedName().toString(); 0377 0378 if (tagName == "table:table-header-columns") { 0379 readElementTableTableHeaderColumns(reader); 0380 } 0381 else if (tagName == "table:table-column") { 0382 readElementTableTableColumn(reader); 0383 } 0384 else if (tagName == "table:table-column-group") { 0385 readElementTableTableColumnGroup(reader); 0386 } 0387 else if (tagName == "table:table-columns") { 0388 readElementTableTableColumns(reader); 0389 } 0390 else { 0391 reader.skipCurrentElement(); 0392 } 0393 } 0394 0395 m_backend->elementTableTableColumnGroup(reader, m_context); 0396 DEBUGEND(); 0397 } 0398 0399 void OdfTextReader::readElementTableTableColumns(KoXmlStreamReader &reader) 0400 { 0401 DEBUGSTART(); 0402 m_backend->elementTableTableColumns(reader, m_context); 0403 0404 // <table:table-columns> has the following children in ODF 1.2: 0405 // [done] <table:table-column> 9.1.6 0406 while (reader.readNextStartElement()) { 0407 QString tagName = reader.qualifiedName().toString(); 0408 0409 if (tagName == "table:table-column") { 0410 readElementTableTableColumn(reader); 0411 } 0412 else { 0413 reader.skipCurrentElement(); 0414 } 0415 } 0416 0417 m_backend->elementTableTableColumns(reader, m_context); 0418 DEBUGEND(); 0419 } 0420 0421 void OdfTextReader::readElementTableTableHeaderColumns(KoXmlStreamReader &reader) 0422 { 0423 DEBUGSTART(); 0424 m_backend->elementTableTableHeaderColumns(reader, m_context); 0425 0426 // <table:table-header-columns> has the following children in ODF 1.2: 0427 // [done] <table:table-column> 9.1.6 0428 while (reader.readNextStartElement()) { 0429 QString tagName = reader.qualifiedName().toString(); 0430 0431 if (tagName == "table:table-column") { 0432 readElementTableTableColumn(reader); 0433 } 0434 else { 0435 reader.skipCurrentElement(); 0436 } 0437 } 0438 0439 m_backend->elementTableTableHeaderColumns(reader, m_context); 0440 DEBUGEND(); 0441 } 0442 0443 void OdfTextReader::readElementTableTableHeaderRows(KoXmlStreamReader &reader) 0444 { 0445 DEBUGSTART(); 0446 m_backend->elementTableTableHeaderRows(reader, m_context); 0447 0448 // <table:table-header-rows> has the following children in ODF 1.2: 0449 // [done] <table:table-row> 9.1.3 0450 // [done] <text:soft-page-break> 5.6. 0451 while (reader.readNextStartElement()) { 0452 QString tagName = reader.qualifiedName().toString(); 0453 0454 if (tagName == "table:table-row") { 0455 readElementTableTableRow(reader); 0456 } 0457 else if (tagName == "text:soft-page-break") { 0458 readElementTextSoftPageBreak(reader); 0459 } 0460 else { 0461 reader.skipCurrentElement(); 0462 } 0463 } 0464 0465 m_backend->elementTableTableHeaderRows(reader, m_context); 0466 DEBUGEND(); 0467 } 0468 0469 void OdfTextReader::readElementTableTableColumn(KoXmlStreamReader &reader) 0470 { 0471 DEBUGSTART(); 0472 m_backend->elementTableTableColumn(reader, m_context); 0473 0474 // <table:table-column> has no children in ODF 1.2 0475 reader.skipCurrentElement(); 0476 0477 m_backend->elementTableTableColumn(reader, m_context); 0478 DEBUGEND(); 0479 } 0480 0481 void OdfTextReader::readElementTableTableRowGroup(KoXmlStreamReader &reader) 0482 { 0483 DEBUGSTART(); 0484 m_backend->elementTableTableRowGroup(reader, m_context); 0485 0486 // <table:table-row-group> has the following children in ODF 1.2: 0487 // <table:table-header-rows> 9.1.7 0488 // <table:table-row> 9.1.3 0489 // <table:table-row-group> 9.1.9 0490 // <table:table-rows> 9.1.8 0491 // <text:soft-page-break> 5.6 0492 // 0493 while (reader.readNextStartElement()) { 0494 QString tagName = reader.qualifiedName().toString(); 0495 0496 if (tagName == "table:table-header-rows") { 0497 readElementTableTableHeaderRows(reader); 0498 } 0499 else if (tagName == "table:table-row") { 0500 readElementTableTableRow(reader); 0501 } 0502 else if (tagName == "table:table-row-group") { 0503 readElementTableTableRowGroup(reader); 0504 } 0505 else if (tagName == "table:table-rows") { 0506 readElementTableTableRows(reader); 0507 } 0508 else if (tagName == "text:soft-page-break") { 0509 readElementTextSoftPageBreak(reader); 0510 } 0511 else { 0512 reader.skipCurrentElement(); 0513 } 0514 } 0515 0516 m_backend->elementTableTableRowGroup(reader, m_context); 0517 DEBUGEND(); 0518 } 0519 0520 void OdfTextReader::readElementTableTableRow(KoXmlStreamReader &reader) 0521 { 0522 DEBUGSTART(); 0523 m_backend->elementTableTableRow(reader, m_context); 0524 0525 // <table:table-row> has the following children in ODF 1.2: 0526 // [done] <table:covered-table-cell> 9.1.5 0527 // [done] <table:table-cell> 9.1.4. 0528 while (reader.readNextStartElement()) { 0529 QString tagName = reader.qualifiedName().toString(); 0530 0531 if (tagName == "table:covered-table-cell") { 0532 readElementTableCoveredTableCell(reader); 0533 } 0534 else if (tagName == "table:table-cell") { 0535 readElementTableTableCell(reader); 0536 } 0537 else { 0538 reader.skipCurrentElement(); 0539 } 0540 } 0541 0542 m_backend->elementTableTableRow(reader, m_context); 0543 DEBUGEND(); 0544 } 0545 0546 void OdfTextReader::readElementTableTableRows(KoXmlStreamReader &reader) 0547 { 0548 DEBUGSTART(); 0549 m_backend->elementTableTableRows(reader, m_context); 0550 0551 // <table:table-header-rows> has the following children in ODF 1.2: 0552 // [done] <table:table-row> 9.1.3 0553 // [done] <text:soft-page-break> 5.6. 0554 while (reader.readNextStartElement()) { 0555 QString tagName = reader.qualifiedName().toString(); 0556 0557 if (tagName == "table:table-row") { 0558 readElementTableTableRow(reader); 0559 } 0560 else if (tagName == "text:soft-page-break") { 0561 readElementTextSoftPageBreak(reader); 0562 } 0563 else { 0564 reader.skipCurrentElement(); 0565 } 0566 } 0567 0568 m_backend->elementTableTableRows(reader, m_context); 0569 DEBUGEND(); 0570 } 0571 0572 void OdfTextReader::readElementTableTableCell(KoXmlStreamReader &reader) 0573 { 0574 DEBUGSTART(); 0575 m_backend->elementTableTableCell(reader, m_context); 0576 0577 // <table:table-cell> has the following children in ODF 1.2: 0578 // 0579 // In addition to the text level tags like <text:p> etc that can 0580 // be found in any textbox, table cell or similar, it has the 0581 // following text document children: 0582 // 0583 // [done] <office:annotation> 14.1 0584 // <table:cell-range-source> 9.3.1 0585 // <table:detective> 9.3.2 0586 0587 while (reader.readNextStartElement()) { 0588 DEBUG_READING("loop-start"); 0589 0590 QString tagName = reader.qualifiedName().toString(); 0591 if (tagName == "office:annotation") { 0592 readElementOfficeAnnotation(reader); 0593 } 0594 else if (tagName == "table:cell-range-source") { 0595 // FIXME: NYI 0596 reader.skipCurrentElement(); 0597 } 0598 else if (tagName == "table:detective") { 0599 // FIXME: NYI 0600 reader.skipCurrentElement(); 0601 } 0602 else { 0603 readTextLevelElement(reader); 0604 } 0605 DEBUG_READING("loop-end"); 0606 } 0607 0608 m_backend->elementTableTableCell(reader, m_context); 0609 DEBUGEND(); 0610 } 0611 0612 void OdfTextReader::readElementTableCoveredTableCell(KoXmlStreamReader &reader) 0613 { 0614 DEBUGSTART(); 0615 m_backend->elementTableCoveredTableCell(reader, m_context); 0616 0617 // <table:covered-table-cell> has the following children in ODF 1.2: 0618 // 0619 // In addition to the text level tags like <text:p> etc that can 0620 // be found in any textbox, table cell or similar, it has the 0621 // following text document children: 0622 // 0623 // [done] <office:annotation> 14.1 0624 // <table:cell-range-source> 9.3.1 0625 // <table:detective> 9.3.2 0626 0627 while (reader.readNextStartElement()) { 0628 DEBUG_READING("loop-start"); 0629 0630 QString tagName = reader.qualifiedName().toString(); 0631 if (tagName == "office:annotation") { 0632 readElementOfficeAnnotation(reader); 0633 } 0634 else if (tagName == "table:cell-range-source") { 0635 // FIXME: NYI 0636 reader.skipCurrentElement(); 0637 } 0638 else if (tagName == "table:detective") { 0639 // FIXME: NYI 0640 reader.skipCurrentElement(); 0641 } 0642 else { 0643 readTextLevelElement(reader); 0644 } 0645 DEBUG_READING("loop-end"); 0646 } 0647 0648 m_backend->elementTableCoveredTableCell(reader, m_context); 0649 DEBUGEND(); 0650 } 0651 0652 0653 // ---------------------------------------------------------------- 0654 // Paragraph level functions 0655 0656 0657 // This function is a bit special since it doesn't handle a specific 0658 // element. Instead it handles the common child elements between a 0659 // number of paragraph-level elements. 0660 // 0661 void OdfTextReader::readParagraphContents(KoXmlStreamReader &reader) 0662 { 0663 DEBUGSTART(); 0664 0665 // We enter this function with the reader pointing to the first 0666 // element *inside* the paragraph. 0667 // 0668 // We should not call any backend functions here. That is already 0669 // done in the functions that call this one. 0670 0671 while (!reader.atEnd() && !reader.isEndElement()) { 0672 DEBUG_READING("loop-start"); 0673 0674 if (reader.isCharacters()) { 0675 //debugOdfReader << "Found character data"; 0676 m_backend->characterData(reader, m_context); 0677 reader.readNext(); 0678 continue; 0679 } 0680 0681 if (!reader.isStartElement()) 0682 continue; 0683 0684 // We define the common elements on the paragraph level as the 0685 // following list. They are the basic paragraph level contents that 0686 // can be found in a paragraph (text:p), heading (text:h), etc 0687 // 0688 // The common paragraph level elements are the following in ODF 1.2: 0689 // 0690 // <dr3d:scene> 10.5.2 0691 // <draw:a> 10.4.12 0692 // <draw:caption> 10.3.11 0693 // <draw:circle> 10.3.8 0694 // <draw:connector> 10.3.10 0695 // <draw:control> 10.3.13 0696 // <draw:custom-shape> 10.6.1 0697 // <draw:ellipse> 10.3.9 0698 // [done] <draw:frame> 10.4.2 0699 // <draw:g> 10.3.15 0700 // <draw:line> 10.3.3 0701 // <draw:measure> 10.3.12 0702 // <draw:page-thumbnail> 10.3.14 0703 // <draw:path> 10.3.7 0704 // <draw:polygon> 10.3.5 0705 // <draw:polyline> 10.3.4 0706 // <draw:rect> 10.3.2 0707 // <draw:regular-polygon> 10.3.6 0708 // All of the above are sent to the draw reader. 0709 // 0710 // [done] <office:annotation> 14.1 0711 // [done] <office:annotation-end> 14.2 0712 // <presentation:date-time> 10.9.3.5 0713 // <presentation:footer> 10.9.3.3 0714 // <presentation:header> 10.9.3.1 0715 // [done] <text:a> 6.1.8 0716 // <text:alphabetical-index-mark> 8.1.10 0717 // <text:alphabetical-index-mark-end> 8.1.9 0718 // <text:alphabetical-index-mark-start> 8.1.8 0719 // <text:author-initials> 7.3.7.2 0720 // <text:author-name> 7.3.7.1 0721 // <text:bibliography-mark> 8.1.11 0722 // <text:bookmark> 6.2.1.2 0723 // <text:bookmark-end> 6.2.1.4 0724 // <text:bookmark-ref> 7.7.6 0725 // <text:bookmark-start> 6.2.1.3 0726 // <text:change> 5.5.7.4 0727 // <text:change-end> 5.5.7.3 0728 // <text:change-start> 5.5.7.2 0729 // <text:chapter> 7.3.8 0730 // <text:character-count> 7.5.18.5 0731 // <text:conditional-text> 7.7.3 0732 // <text:creation-date> 7.5.3 0733 // <text:creation-time> 7.5.4 0734 // <text:creator> 7.5.17 0735 // <text:database-display> 7.6.3 0736 // <text:database-name> 7.6.7 0737 // <text:database-next> 7.6.4 0738 // <text:database-row-number> 7.6.6 0739 // <text:database-row-select> 7.6.5 0740 // <text:date> 7.3.2 0741 // <text:dde-connection> 7.7.12 0742 // <text:description> 7.5.5 0743 // <text:editing-cycles> 7.5.13 0744 // <text:editing-duration> 7.5.14 0745 // <text:execute-macro> 7.7.10 0746 // <text:expression> 7.4.14 0747 // <text:file-name> 7.3.9 0748 // <text:hidden-paragraph> 7.7.11 0749 // <text:hidden-text> 7.7.4 0750 // <text:image-count> 7.5.18.7 0751 // <text:initial-creator> 7.5.2 0752 // <text:keywords> 7.5.12 0753 // [done] <text:line-break> 6.1.5 0754 // <text:measure> 7.7.13 0755 // <text:meta> 6.1.9 0756 // <text:meta-field> 7.5.19 0757 // <text:modification-date> 7.5.16 0758 // <text:modification-time> 7.5.15 0759 // <text:note> 6.3.2 0760 // <text:note-ref> 7.7.7 0761 // <text:object-count> 7.5.18.8 0762 // <text:page-continuation> 7.3.5 0763 // <text:page-count> 7.5.18.2 0764 // <text:page-number> 7.3.4 0765 // <text:page-variable-get> 7.7.1.3 0766 // <text:page-variable-set> 7.7.1.2 0767 // <text:paragraph-count> 7.5.18.3 0768 // <text:placeholder> 7.7.2 0769 // <text:print-date> 7.5.8 0770 // <text:printed-by> 7.5.9 0771 // <text:print-time> 7.5.7 0772 // <text:reference-mark> 6.2.2.2 0773 // <text:reference-mark-end> 6.2.2.4 0774 // <text:reference-mark-start> 6.2.2.3 0775 // <text:reference-ref> 7.7.5 0776 // <text:ruby> 6.4 0777 // [done] <text:s> 6.1.3 0778 // <text:script> 7.7.9 0779 // <text:sender-city> 7.3.6.13 0780 // <text:sender-company> 7.3.6.10 0781 // <text:sender-country> 7.3.6.15 0782 // <text:sender-email> 7.3.6.7 0783 // <text:sender-fax> 7.3.6.9 0784 // <text:sender-firstname> 7.3.6.2 0785 // <text:sender-initials> 7.3.6.4 0786 // <text:sender-lastname> 7.3.6.3 0787 // <text:sender-phone-private> 7.3.6.8 0788 // <text:sender-phone-work> 7.3.6.11 0789 // <text:sender-position> 7.3.6.6 0790 // <text:sender-postal-code> 7.3.6.14 0791 // <text:sender-state-or-province> 7.3.6.16 0792 // <text:sender-street> 7.3.6.12 0793 // <text:sender-title> 7.3.6.5 0794 // <text:sequence> 7.4.13 0795 // <text:sequence-ref> 7.7.8 0796 // <text:sheet-name> 7.3.11 0797 // [done] <text:soft-page-break> 5.6 0798 // [done] <text:span> 6.1.7 0799 // <text:subject> 7.5.11 0800 // <text:tab> 6.1.4 0801 // <text:table-count> 7.5.18.6 0802 // <text:table-formula> 7.7.14 0803 // <text:template-name> 7.3.10 0804 // <text:text-input> 7.4.15 0805 // <text:time> 7.3.3 0806 // <text:title> 7.5.10 0807 // <text:toc-mark> 8.1.4 0808 // <text:toc-mark-end> 8.1.3 0809 // <text:toc-mark-start> 8.1.2 0810 // <text:user-defined> 7.5.6 0811 // <text:user-field-get> 7.4.9 0812 // <text:user-field-input> 7.4.10 0813 // <text:user-index-mark> 8.1.7 0814 // <text:user-index-mark-end> 8.1.6 0815 // <text:user-index-mark-start> 8.1.5 0816 // <text:variable-get> 7.4.5 0817 // <text:variable-input> 7.4.6 0818 // <text:variable-set> 7.4.4 0819 // <text:word-count> 7.5.18.4. 0820 // 0821 // FIXME: Only very few tags are handled right now. 0822 0823 QString tagName = reader.qualifiedName().toString(); 0824 0825 if (reader.prefix() == "draw" || reader.prefix() == "dr3d") { 0826 OdfDrawReader *drawReader = m_parent->drawReader(); 0827 if (drawReader) { 0828 drawReader->readCommonGraphicsElements(reader); 0829 } 0830 else { 0831 reader.skipCurrentElement(); 0832 } 0833 } // draw | dr3d namespace 0834 else if (reader.prefix() == "office") { 0835 if (tagName == "office:annotation") { 0836 readElementOfficeAnnotation(reader); 0837 } 0838 else if (tagName == "office:annotation-end") { 0839 readElementOfficeAnnotationEnd(reader); 0840 } 0841 else { 0842 // Unknown office: element 0843 readUnknownElement(reader); 0844 } 0845 } // office namespace 0846 else if (reader.prefix() == "text") { 0847 0848 if (tagName == "text:a") { 0849 readElementTextA(reader); 0850 } 0851 else if (tagName == "text:line-break") { 0852 readElementTextLineBreak(reader); 0853 } 0854 else if (tagName == "text:span") { 0855 readElementTextSpan(reader); 0856 } 0857 else if (tagName == "text:s") { 0858 readElementTextS(reader); 0859 } 0860 else if (tagName == "text:soft-page-break") { 0861 readElementTextSoftPageBreak(reader); 0862 } 0863 else { 0864 // Unknown text: element 0865 readUnknownElement(reader); 0866 } 0867 } // text namespace 0868 else { 0869 // Unknown namespace 0870 readUnknownElement(reader); 0871 } 0872 0873 // Read past the end tag of the just parsed element. 0874 reader.readNext(); 0875 DEBUG_READING("loop-end"); 0876 } 0877 0878 DEBUGEND(); 0879 } 0880 0881 void OdfTextReader::readElementOfficeAnnotation(KoXmlStreamReader &reader) 0882 { 0883 DEBUGSTART(); 0884 m_backend->elementOfficeAnnotation(reader, m_context); 0885 0886 // <office:annotation> has the following children in ODF 1.2: 0887 // [done] <dc:creator> 4.3.2.7 0888 // [done] <dc:date> 4.3.2.10 0889 // [done] <meta:date-string> 14.3 0890 // [done] <text:list> 5.3.1 0891 // [done] <text:p> 5.1.3 0892 while (reader.readNextStartElement()) { 0893 QString tagName = reader.qualifiedName().toString(); 0894 0895 if (tagName == "dc:creator") { 0896 readElementDcCreator(reader); 0897 } 0898 else if (tagName == "dc:date") { 0899 readElementDcDate(reader); 0900 } 0901 else if (tagName == "meta:date-string") { 0902 QString value; 0903 readCharacterData(reader, value); 0904 m_backend->textVariable(tagName, value); 0905 } 0906 else if (tagName == "text:list") { 0907 readElementTextList(reader); 0908 } 0909 else if (tagName == "text:p") { 0910 readElementTextP(reader); 0911 } 0912 else { 0913 reader.skipCurrentElement(); 0914 } 0915 } 0916 0917 m_backend->elementOfficeAnnotation(reader, m_context); 0918 DEBUGEND(); 0919 } 0920 0921 void OdfTextReader::readElementOfficeAnnotationEnd(KoXmlStreamReader &reader) 0922 { 0923 DEBUGSTART(); 0924 m_backend->elementOfficeAnnotationEnd(reader, m_context); 0925 0926 // <office:annotation-end> has no children in ODF 1.2: 0927 // FIXME: Skip current element or call parseUnknownElement? 0928 reader.skipCurrentElement(); 0929 0930 m_backend->elementOfficeAnnotationEnd(reader, m_context); 0931 DEBUGEND(); 0932 } 0933 0934 void OdfTextReader::readElementDcCreator(KoXmlStreamReader &reader) 0935 { 0936 DEBUGSTART(); 0937 m_backend->elementDcCreator(reader, m_context); 0938 0939 reader.readNext(); 0940 readParagraphContents(reader); 0941 0942 m_backend->elementDcCreator(reader, m_context); 0943 DEBUGEND(); 0944 } 0945 0946 void OdfTextReader::readElementDcDate(KoXmlStreamReader &reader) 0947 { 0948 DEBUGSTART(); 0949 m_backend->elementDcDate(reader, m_context); 0950 0951 reader.readNext(); 0952 readParagraphContents(reader); 0953 0954 m_backend->elementDcDate(reader, m_context); 0955 DEBUGEND(); 0956 } 0957 0958 void OdfTextReader::readElementTextA(KoXmlStreamReader &reader) 0959 { 0960 DEBUGSTART(); 0961 m_backend->elementTextA(reader, m_context); 0962 0963 // readParagraphContents expect to have the reader point to the 0964 // contents of the paragraph so we have to read past the text:a 0965 // start tag here. 0966 reader.readNext(); 0967 readParagraphContents(reader); 0968 0969 m_backend->elementTextA(reader, m_context); 0970 DEBUGEND(); 0971 } 0972 0973 void OdfTextReader::readElementTextLineBreak(KoXmlStreamReader &reader) 0974 { 0975 DEBUGSTART(); 0976 m_backend->elementTextLineBreak(reader, m_context); 0977 0978 // This element has no child elements in ODF 1.2. 0979 reader.skipCurrentElement(); 0980 0981 m_backend->elementTextLineBreak(reader, m_context); 0982 DEBUGEND(); 0983 } 0984 0985 void OdfTextReader::readElementTextS(KoXmlStreamReader &reader) 0986 { 0987 DEBUGSTART(); 0988 m_backend->elementTextS(reader, m_context); 0989 0990 // This element has no child elements in ODF 1.2. 0991 reader.skipCurrentElement(); 0992 0993 m_backend->elementTextS(reader, m_context); 0994 DEBUGEND(); 0995 } 0996 0997 void OdfTextReader::readElementTextSpan(KoXmlStreamReader &reader) 0998 { 0999 DEBUGSTART(); 1000 m_backend->elementTextSpan(reader, m_context); 1001 1002 reader.readNext(); 1003 readParagraphContents(reader); 1004 1005 m_backend->elementTextSpan(reader, m_context); 1006 DEBUGEND(); 1007 } 1008 1009 1010 // ---------------------------------------------------------------- 1011 // List level functions 1012 1013 1014 void OdfTextReader::readElementTextListHeader(KoXmlStreamReader &reader) 1015 { 1016 DEBUGSTART(); 1017 m_backend->elementTextListHeader(reader, m_context); 1018 1019 // <text:list-header> has the following children in ODF 1.2: 1020 // [done] <text:h> 5.1.2 1021 // [done] <text:p> 5.1.3 1022 // [done] <text:list> 5.3.1 1023 // [done] <text:soft-page-break> 5.6 1024 // <text:number> 6.1.10 1025 while(reader.readNextStartElement()) { 1026 DEBUG_READING("loop-start"); 1027 1028 QString tagName = reader.qualifiedName().toString(); 1029 if (tagName == "text:h") { 1030 readElementTextH(reader); 1031 } 1032 else if (tagName == "text:p") { 1033 readElementTextP(reader); 1034 } 1035 else if (tagName == "text:list") { 1036 readElementTextList(reader); 1037 } 1038 else if (tagName == "text:soft-page-break") { 1039 readElementTextSoftPageBreak(reader); 1040 } 1041 else if (tagName == "text:number") { 1042 // FIXME: NYI 1043 reader.skipCurrentElement(); 1044 } 1045 else { 1046 readUnknownElement(reader); 1047 } 1048 1049 DEBUG_READING("loop-end"); 1050 } 1051 1052 m_backend->elementTextListHeader(reader, m_context); 1053 DEBUGEND(); 1054 } 1055 1056 void OdfTextReader::readElementTextListItem(KoXmlStreamReader &reader) 1057 { 1058 DEBUGSTART(); 1059 m_backend->elementTextListItem(reader, m_context); 1060 1061 // <text:list-item> has the following children in ODF 1.2: 1062 // [done] <text:h> 5.1.2 1063 // [done] <text:p> 5.1.3 1064 // [done] <text:list> 5.3.1 1065 // [done] <text:soft-page-break> 5.6 1066 // <text:number> 6.1.10 1067 while(reader.readNextStartElement()) { 1068 DEBUG_READING("loop-start"); 1069 1070 QString tagName = reader.qualifiedName().toString(); 1071 debugOdfReader <<tagName; 1072 if (tagName == "text:h") { 1073 readElementTextH(reader); 1074 } 1075 else if (tagName == "text:p") { 1076 readElementTextP(reader); 1077 } 1078 else if (tagName == "text:list") { 1079 readElementTextList(reader); 1080 } 1081 else if (tagName == "text:soft-page-break") { 1082 readElementTextSoftPageBreak(reader); 1083 } 1084 else if (tagName == "text:number") { 1085 //FIXME 1086 reader.skipCurrentElement(); 1087 } 1088 else { 1089 readUnknownElement(reader); 1090 } 1091 1092 DEBUG_READING("loop-end"); 1093 } 1094 1095 m_backend->elementTextListItem(reader, m_context); 1096 DEBUGEND(); 1097 } 1098 1099 // ---------------------------------------------------------------- 1100 // Other functions 1101 1102 1103 void OdfTextReader::readElementTextSoftPageBreak(KoXmlStreamReader &reader) 1104 { 1105 DEBUGSTART(); 1106 m_backend->elementTextSoftPageBreak(reader, m_context); 1107 1108 // <text:soft-page-break> has no children in ODF 1.2 1109 reader.skipCurrentElement(); 1110 1111 m_backend->elementTextSoftPageBreak(reader, m_context); 1112 DEBUGEND(); 1113 } 1114 1115 1116 void OdfTextReader::readUnknownElement(KoXmlStreamReader &reader) 1117 { 1118 DEBUGSTART(); 1119 1120 if (m_context->isInsideParagraph()) { 1121 // readParagraphContents expect to have the reader point to the 1122 // contents of the paragraph so we have to read past the text:p 1123 // start tag here. 1124 reader.readNext(); 1125 readParagraphContents(reader); 1126 } 1127 else { 1128 while (reader.readNextStartElement()) { 1129 readTextLevelElement(reader); 1130 } 1131 } 1132 1133 DEBUGEND(); 1134 } 1135