Warning, file /office/calligra/filters/libmsooxml/MsooXmlCommonReaderDrawingMLImpl.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * This file is part of Office 2007 Filters for Calligra
0003  *
0004  * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
0005  * Contact: Suresh Chande suresh.chande@nokia.com
0006  *
0007  * Copyright (C) 2011-2012 Matus Uzak (matus.uzak@gmail.com).
0008  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Lesser General Public License
0011  * version 2.1 as published by the Free Software Foundation.
0012  *
0013  * This library is distributed in the hope that it will be useful, but
0014  * WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0016  * Lesser General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Lesser General Public
0019  * License along with this library; if not, write to the Free Software
0020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0021  * 02110-1301 USA
0022  *
0023  */
0024 
0025 #ifndef MSOOXMLCOMMONREADERDRAWINGML_IMPL_H
0026 #define MSOOXMLCOMMONREADERDRAWINGML_IMPL_H
0027 
0028 #include <QTime>
0029 #include <math.h>
0030 
0031 #ifndef M_PI
0032 #define M_PI 3.1415926535897932384626
0033 #endif
0034 
0035 //ECMA-376, 20.1.10.68, p.3431 - ST_TextFontSize (Text Font Size)
0036 #define TEXT_FONTSIZE_MIN 1
0037 #define TEXT_FONTSIZE_MAX 4000
0038 #define TEXT_FONTSIZE_DEFAULT 18
0039 
0040 #if !defined DRAWINGML_NS && !defined NO_DRAWINGML_NS
0041 #error missing DRAWINGML_NS define!
0042 #endif
0043 #if !defined DRAWINGML_PIC_NS && !defined NO_DRAWINGML_PIC_NS
0044 #error missing DRAWINGML_PIC_NS define!
0045 #endif
0046 
0047 // ================================================================
0048 //                     Namespace in {a,pic,p,xdr}
0049 // ================================================================
0050 #undef MSOOXML_CURRENT_NS
0051 #ifndef NO_DRAWINGML_PIC_NS
0052 #define MSOOXML_CURRENT_NS DRAWINGML_PIC_NS
0053 #endif
0054 
0055 #include <KoXmlWriter.h>
0056 #include <MsooXmlUnits.h>
0057 #include "Charting.h"
0058 #include "XlsxChartOdfWriter.h"
0059 #include "XlsxXmlChartReader.h"
0060 #include "ComplexShapeHandler.h"
0061 
0062 #include <MsooXmlReader.h>
0063 #include <MsooXmlCommonReader.h>
0064 #include <MsooXmlDiagramReader.h>
0065 #include <QScopedPointer>
0066 
0067 // ================================================================
0068 
0069 
0070 void MSOOXML_CURRENT_CLASS::initDrawingML()
0071 {
0072     m_currentDoubleValue = 0;
0073     m_hyperLink = false;
0074     m_listStylePropertiesAltered = false;
0075     m_inGrpSpPr = false;
0076     m_insideTable = false;
0077     m_isLockedCanvas = false;
0078     qsrand(QTime::currentTime().msec());
0079 }
0080 
0081 bool MSOOXML_CURRENT_CLASS::isCustomShape()
0082 {
0083     if (m_contentType.isEmpty()) {
0084     return false;
0085     }
0086     if (m_contentType == "rect") {
0087     return false;
0088     }
0089     if (unsupportedPredefinedShape()) {
0090     return false;
0091     }
0092     return true;
0093 }
0094 
0095 bool MSOOXML_CURRENT_CLASS::unsupportedPredefinedShape()
0096 {
0097     // TODO: Some conditions are not supported with custom shapes
0098     // properly yet, remove them when possible.
0099 
0100     // Custom geometry has its own handling
0101     if (m_contentType == "custom") {
0102         return false;
0103     }
0104 
0105     // Lines and connectors are handled elsewhere
0106     if (m_contentType == "line" || m_contentType == "arc" || m_contentType.contains("Connector")) {
0107         return false;
0108     }
0109 
0110     // These shapes are not properly supported atm. some have bugs in
0111     // predefinedShapes.xml, some might have xml_parser/calligra bugs.
0112     if (m_contentType == "circularArrow" || m_contentType == "curvedDownArrow" ||
0113         m_contentType == "curvedLeftArrow" || m_contentType == "curvedUpArrow" ||
0114         m_contentType == "curvedRightArrow" || m_contentType == "gear6" ||
0115         m_contentType == "gear9") {
0116         return true;
0117     }
0118     return false;
0119 }
0120 
0121 /* bodyPr (Body Properties) defaults
0122  * ECMA-376, 21.1.2.1.1, p.3556 - DrawingML
0123  */
0124 void MSOOXML_CURRENT_CLASS::inheritDefaultBodyProperties()
0125 {
0126     if (m_shapeTextPosition.isEmpty()) {
0127         m_shapeTextPosition = "top";
0128     }
0129     if (m_shapeTextTopOff.isEmpty()) {
0130         m_shapeTextTopOff = "45720";
0131     }
0132     if (m_shapeTextLeftOff.isEmpty()) {
0133         m_shapeTextLeftOff = "91440";
0134     }
0135     if (m_shapeTextRightOff.isEmpty()) {
0136         m_shapeTextRightOff = "91440";
0137     }
0138     if (m_shapeTextBottomOff.isEmpty()) {
0139         m_shapeTextBottomOff = "45720";
0140     }
0141 }
0142 
0143 // ----------------------------------------------------------------
0144 
0145 // ================================================================
0146 // DrawingML tags
0147 // ================================================================
0148 
0149 // Don't show this warning: it occurs because gcc gets confused, but
0150 // it _is_ used.
0151 #ifdef __GNUC__
0152 #pragma GCC diagnostic ignored "-Wunused-function"
0153 #endif
0154 
0155 static QString mirrorToOdf(bool flipH, bool flipV)
0156 {
0157     if (!flipH && !flipV)
0158         return QString();
0159     if (flipH && flipV)
0160         return QLatin1String("horizontal vertical");
0161     if (flipH)
0162         return QLatin1String("horizontal");
0163     if (flipV)
0164         return QLatin1String("vertical");
0165     return QLatin1String("none");
0166 }
0167 
0168 #undef CURRENT_EL
0169 #define CURRENT_EL pic
0170 //! pic (Picture)
0171 //! ECMA-376, 19.3.1.37, p.2848 (PresentationML)
0172 //! ECMA-376, 20.1.2.2.30, p.3049 (DrawingML)
0173 //! ECMA-376, 20.2.2.5, p.3462
0174 /*! This element specifies the existence of a picture object within
0175   the document.
0176 
0177   Parent elements:
0178   ----------------
0179   PresentationML:
0180   - control (§19.3.2.1)
0181   - [done] grpSp (§19.3.1.22)
0182   - oleObj (§19.3.2.4)
0183   - [done] spTree (§19.3.1.45)
0184 
0185   DrawingML:
0186   - [done] grpSp (§20.1.2.2.20)
0187   - [done] lockedCanvas (§20.3.2.1)
0188 
0189   Child elements:
0190   ---------------
0191   PresentationML:
0192   - [done] blipFill (Picture Fill) §19.3.1.4
0193   - extLst (Extension List with Modification Flag) §19.3.1.20
0194   - [done] nvPicPr (Non-Visual Properties for a Picture) §19.3.1.32
0195   - [done] spPr (Shape Properties) §19.3.1.44
0196   - [done] style (Shape Style) §19.3.1.46
0197 
0198   DrawingML:
0199   - [done] blipFill (Picture Fill) §20.1.8.14
0200   - extLst (Extension List) §20.1.2.2.15
0201   - [done] nvPicPr (Non-Visual Properties for a Picture) §20.1.2.2.28
0202   - [done] spPr (Shape Properties) §20.1.2.2.35
0203   - [done] style (Shape Style) §20.1.2.2.37
0204 
0205   DrawingML/Picture
0206   - [done] blipFill (Picture Fill) §20.2.2.1
0207   - [done] nvPicPr (Non-Visual Picture Properties) §20.2.2.4
0208   - [done] spPr (Shape Properties) §20.2.2.6
0209 */
0210 //! CASE #P401
0211 //! @todo CASE #P421
0212 //! CASE #P422
0213 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_pic()
0214 {
0215     if (m_isLockedCanvas) {
0216         READ_PROLOGUE_IF_NS(a);
0217     } else {
0218         READ_PROLOGUE
0219     }
0220 
0221     // Reset picture properties
0222     m_xlinkHref.clear();
0223     m_ignoreLinkHref = false;
0224     m_cNvPrId.clear();
0225     m_cNvPrName.clear();
0226     m_cNvPrDescr.clear();
0227     m_flipH = false;
0228     m_flipV = false;
0229     m_rot = 0;
0230 
0231 #ifdef XLSXXMLDRAWINGREADER_CPP
0232     KoXmlWriter *tempBodyHolder = 0;
0233     if ( m_currentDrawingObject->isAnchoredToCell() && (m_context->m_groupDepthCounter == 0)) {
0234         tempBodyHolder = body;
0235         body = m_currentDrawingObject->pictureWriter();
0236     }
0237 #endif
0238 
0239 #ifndef DOCXXMLDOCREADER_CPP
0240     // Create a new drawing style for this picture
0241     pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
0242 #endif
0243 
0244     m_referredFont = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
0245 
0246     if (m_isLockedCanvas) {
0247         while (!atEnd()) {
0248             readNext();
0249             debugMsooXml << *this;
0250             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
0251             if (isStartElement()) {
0252                 TRY_READ_IF_NS(a, spPr)
0253                 ELSE_TRY_READ_IF_NS_IN_CONTEXT(a, blipFill)
0254                 ELSE_TRY_READ_IF_NS(a, nvPicPr)
0255                 ELSE_TRY_READ_IF_NS(a, style)
0256                 SKIP_UNKNOWN
0257             }
0258         }
0259     } else {
0260         while (!atEnd()) {
0261             readNext();
0262             debugMsooXml << *this;
0263             BREAK_IF_END_OF(CURRENT_EL)
0264             if (isStartElement()) {
0265                 TRY_READ_IF(spPr)
0266                 else if (name() == QLatin1String("blipFill")) {
0267                     TRY_READ_IN_CONTEXT(blipFill)
0268                     if (!m_xlinkHref.isEmpty()) {
0269                         //spPr may also set m_xlinkHref
0270                         m_ignoreLinkHref = true;
0271                     }
0272                 }
0273 #ifdef DOCXXMLDOCUMENTREADER_H
0274                 ELSE_TRY_READ_IF_NS_IN_CONTEXT(pic, blipFill)
0275 #endif
0276                 ELSE_TRY_READ_IF(nvPicPr)
0277                 ELSE_TRY_READ_IF(style)
0278                 SKIP_UNKNOWN
0279             }
0280         }
0281     }
0282 
0283     m_ignoreLinkHref = false;
0284 
0285 #ifndef DOCXXMLDOCUMENTREADER_H
0286     body->startElement("draw:frame"); // CASE #P421
0287 #ifdef PPTXXMLSLIDEREADER_CPP
0288     if (m_context->type == Slide || m_context->type == SlideLayout) {
0289         body->addAttribute("draw:layer", "layout");
0290     }
0291     else { // Slidemaster
0292         body->addAttribute("draw:layer", "backgroundobjects");
0293     }
0294     body->addAttribute("presentation:user-transformed", MsooXmlReader::constTrue);
0295 #endif
0296 
0297 #ifdef XLSXXMLDRAWINGREADER_CPP
0298     if (m_context->m_groupDepthCounter == 0) {
0299         if (m_currentDrawingObject->m_positions.contains(XlsxDrawingObject::FromAnchor)) {
0300             XlsxDrawingObject::Position f = m_currentDrawingObject->m_positions[XlsxDrawingObject::FromAnchor];
0301             // use relative position to the cell's top-left corner
0302             m_svgX = f.m_colOff;
0303             m_svgY = f.m_rowOff;
0304 
0305             if(m_currentDrawingObject->m_positions.contains(XlsxDrawingObject::ToAnchor)) {
0306                 f = m_currentDrawingObject->m_positions[XlsxDrawingObject::ToAnchor];
0307                 QString endCellAddress = m_currentDrawingObject->toCellAddress();
0308                 QString end_x = EMU_TO_CM_STRING(f.m_colOff);
0309                 QString end_y = EMU_TO_CM_STRING(f.m_rowOff);
0310 
0311                 body->addAttribute("table:end-cell-address", endCellAddress);
0312                 body->addAttribute("table:end-x", end_x); //cm
0313                 body->addAttribute("table:end-y", end_y); //cm
0314             }
0315         }
0316     }
0317 #endif
0318 
0319     if (m_rot == 0) {
0320         body->addAttribute("svg:x", EMU_TO_CM_STRING(m_svgX));
0321         body->addAttribute("svg:y", EMU_TO_CM_STRING(m_svgY));
0322     }
0323     if (m_svgWidth > 0) {
0324         body->addAttribute("svg:width", EMU_TO_CM_STRING(m_svgWidth));
0325     }
0326     if (m_svgHeight > 0) {
0327         body->addAttribute("svg:height", EMU_TO_CM_STRING(m_svgHeight));
0328     }
0329 
0330     if (m_rot != 0) {
0331         // m_rot is in 1/60,000th of a degree
0332         qreal angle, xDiff, yDiff;
0333         MSOOXML::Utils::rotateString(m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
0334         QString rotString = QString("rotate(%1) translate(%2cm %3cm)")
0335                             .arg(angle).arg((m_svgX + xDiff)/360000, 3, 'f').arg((m_svgY + yDiff)/360000, 3, 'f');
0336         body->addAttribute("draw:transform", rotString);
0337     }
0338 
0339     // Add style information
0340     //! @todo: horizontal-on-{odd,even}?
0341     const QString mirror(mirrorToOdf(m_flipH, m_flipV));
0342     if (!mirror.isEmpty()) {
0343         m_currentDrawStyle->addProperty("style:mirror", mirror);
0344     }
0345 
0346 #ifdef PPTXXMLSLIDEREADER_CPP
0347     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
0348         m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
0349     }
0350 #elif defined DOCXXMLDOCREADER_CPP
0351     if (m_moveToStylesXml) {
0352         m_currentDrawStyle.setAutoStyleInStylesDotXml(true);
0353     }
0354 #endif
0355     const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr"));
0356     body->addAttribute("draw:style-name", styleName);
0357 #endif
0358 
0359     // Now it's time to link to the actual picture.  Only do it if
0360     // there is an image to link to.  If so, this was created in
0361     // read_blip().
0362     if (!m_xlinkHref.isEmpty()) {
0363         body->startElement("draw:image");
0364         body->addAttribute("xlink:href", m_xlinkHref);
0365         //! @todo xlink:type?
0366         body->addAttribute("xlink:type", "simple");
0367         //! @todo xlink:show?
0368         body->addAttribute("xlink:show", "embed");
0369         //! @todo xlink:actuate?
0370         body->addAttribute("xlink:actuate", "onLoad");
0371         body->endElement(); //draw:image
0372 
0373 #ifdef DOCXXMLDOCUMENTREADER_H
0374         if (!m_cNvPrName.isEmpty() || !m_cNvPrDescr.isEmpty()) {
0375             body->startElement("svg:title");
0376             body->addTextSpan(m_cNvPrDescr.isEmpty() ? m_cNvPrName : m_cNvPrDescr);
0377             body->endElement(); //svg:title
0378         }
0379 #endif
0380         m_xlinkHref.clear();
0381     }
0382 
0383 #ifndef DOCXXMLDOCUMENTREADER_H
0384     body->endElement(); //draw:frame
0385 #endif
0386 
0387 #ifdef XLSXXMLDRAWINGREADER_CPP
0388     // If we anchored to cell, we save odf to different buffer that body operates on
0389     // Here we restore the original body buffer for next drawing which might be anchored
0390     // to sheet
0391     if ( m_currentDrawingObject->isAnchoredToCell() && (m_context->m_groupDepthCounter == 0)) {
0392         body = tempBodyHolder;
0393     }
0394 #endif
0395 
0396 
0397 #ifndef DOCXXMLDOCREADER_CPP
0398     popCurrentDrawStyle();
0399 #endif
0400 
0401     if (m_isLockedCanvas) {
0402         READ_EPILOGUE_IF_NS(a)
0403     } else {
0404         READ_EPILOGUE
0405     }
0406 }
0407 
0408 #undef CURRENT_EL
0409 #define CURRENT_EL nvPicPr
0410 //! nvPicPr (Non-Visual Properties for a Picture)
0411 //! ECMA-376, 19.3.1.32, p.2845 (PresentationML)
0412 //! ECMA-376, 20.1.2.2.28, p. 3048 (DrawingML)
0413 /*! This element specifies all non-visual properties for a picture.
0414 
0415   Parent elements:
0416   ----------------
0417   PresentationML/DrawingML/SpreadsheetML:
0418   - [done] pic (§19.3.1.37)/(§20.1.2.2.30)/(§20.5.2.25)
0419 
0420   Child elements:
0421   ---------------
0422   PresentationML:
0423   - [done] cNvPicPr (Non-Visual Picture Drawing Properties) §19.3.1.11
0424   - [done] cNvPr (Non-Visual Drawing Properties) §19.3.1.12
0425   - [done] nvPr (Non-Visual Properties) §19.3.1.33
0426 
0427   DrawingML:
0428   - [done] cNvPicPr (Non-Visual Picture Drawing Properties) §20.1.2.2.7
0429   - [done] cNvPr (Non-Visual Drawing Properties) §20.1.2.2.8
0430 
0431   SpreadsheetML:
0432   - [done] cNvPicPr (Non-Visual Picture Drawing Properties) §20.5.2.7
0433   - [done] cNvPr (Non-Visual Drawing Properties) §20.5.2.8
0434 */
0435 //! @todo support all child elements
0436 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_nvPicPr()
0437 {
0438     if (m_isLockedCanvas) {
0439         READ_PROLOGUE_IF_NS(a);
0440     } else {
0441         READ_PROLOGUE
0442     }
0443 
0444     if (m_isLockedCanvas) {
0445         while (!atEnd()) {
0446             readNext();
0447             debugMsooXml << *this;
0448             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
0449             if (isStartElement()) {
0450                 TRY_READ_IF_NS(a, cNvPicPr)
0451                 ELSE_TRY_READ_IF_NS_IN_CONTEXT(a, cNvPr)
0452                 ELSE_WRONG_FORMAT
0453             }
0454         }
0455     } else {
0456         while (!atEnd()) {
0457             readNext();
0458             debugMsooXml << *this;
0459             BREAK_IF_END_OF(CURRENT_EL)
0460             if (isStartElement()) {
0461                 TRY_READ_IF(cNvPicPr)
0462                 ELSE_TRY_READ_IF_IN_CONTEXT(cNvPr)
0463 #ifdef PPTXXMLSLIDEREADER_CPP
0464                 ELSE_TRY_READ_IF(nvPr) // only §19.3.1.33
0465 #endif
0466                 ELSE_WRONG_FORMAT
0467             }
0468         }
0469     }
0470 
0471     if (m_isLockedCanvas) {
0472         READ_EPILOGUE_IF_NS(a)
0473     } else {
0474         READ_EPILOGUE
0475     }
0476 }
0477 
0478 #undef CURRENT_EL
0479 #define CURRENT_EL cNvPicPr
0480 //! cNvPicPr handler (Non-Visual Picture Drawing Properties)
0481 //! ECMA-376, 19.3.1.11, p.2823; (PresentationML)
0482 //! ECMA-376, 20.2.2.2, p.3458 (DrawingML)
0483 /*!
0484  This element specifies the non-visual properties for the picture
0485  canvas.  These properties are to be used by the generating
0486  application to determine how certain properties are to be changed for
0487  the picture object in question.
0488 
0489  Parent elements:
0490  - [done] nvPicPr (§19.3.1.32)
0491 
0492  Child elements:
0493  - extLst (Extension List) §20.1.2.2.15
0494  - picLocks (Picture Locks) §20.1.2.2.31
0495 
0496  Attributes:
0497  - preferRelativeResize (Relative Resize Preferred)
0498 */
0499 //! @todo support all child elements
0500 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_cNvPicPr()
0501 {
0502     if (m_isLockedCanvas) {
0503         READ_PROLOGUE_IF_NS(a);
0504     } else {
0505         READ_PROLOGUE
0506     }
0507 
0508     SKIP_EVERYTHING
0509 
0510 //     while (!atEnd()) {
0511 //         readNext();
0512 //         debugMsooXml << *this;
0513 //         BREAK_IF_END_OF(CURRENT_EL)
0514 //         if (isStartElement()) {
0515 // //! @todo add ELSE_WRONG_FORMAT
0516 //         }
0517 //     }
0518 
0519     if (m_isLockedCanvas) {
0520         READ_EPILOGUE_IF_NS(a)
0521     } else {
0522         READ_EPILOGUE
0523     }
0524 }
0525 
0526 #undef CURRENT_EL
0527 #define CURRENT_EL cNvPr
0528 //! cNvPr handler (Non-Visual Drawing Properties)
0529 //! ECMA-376, 19.3.1.12, p.2824 (PresentationML)
0530 //! ECMA-376, 20.2.2.3, p.3459 (DrawingML)
0531 /*! This element specifies non-visual canvas properties.  This allows
0532  for additional information that does not affect the appearance of the
0533  picture to be stored.
0534 
0535  Parent elements:
0536  ----------------
0537  PresentationML/SpreadsheetML:
0538  - [done] nvCxnSpPr (§19.3.1.29)
0539  - nvGraphicFramePr (§19.3.1.30)
0540  - nvGrpSpPr (§19.3.1.31)
0541  - [done] nvPicPr (§19.3.1.32)
0542  - [done] nvSpPr (§19.3.1.34)
0543 
0544  DrawingML:
0545  - [done] nvPicPr (§20.2.2.4)
0546  //NOTE: Part of nvCxnSpPr child list (20.1.2.2.25)
0547 
0548  Child elements:
0549  - extLst (Extension List) §20.1.2.2.15
0550  - hlinkClick (Click Hyperlink) §21.1.2.3.5
0551  - hlinkHover (Hyperlink for Hover) §20.1.2.2.23
0552 
0553  Attributes:
0554  - [done] descr (Alternative Text for Object)
0555  - hidden (Hidden)
0556  - [done] id (Unique Identifier)
0557  - [done] name (Name)
0558 */
0559 //! @todo support all elements
0560 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_cNvPr(cNvPrCaller caller)
0561 {
0562     if (m_isLockedCanvas) {
0563         READ_PROLOGUE_IF_NS(a);
0564     } else {
0565         READ_PROLOGUE
0566     }
0567 
0568     m_cNvPrId.clear();
0569     m_cNvPrName.clear();
0570     m_cNvPrDescr.clear();
0571     const QXmlStreamAttributes attrs(attributes());
0572 
0573     // for sanity, p:nvGrpSpPr can be also the caller
0574     if (caller == cNvPr_nvSpPr || caller == cNvPr_nvPicPr) {
0575         READ_ATTR_WITHOUT_NS_INTO(id, m_cNvPrId)
0576         debugMsooXml << "id:" << m_cNvPrId;
0577         TRY_READ_ATTR_WITHOUT_NS_INTO(name, m_cNvPrName)
0578         debugMsooXml << "name:" << m_cNvPrName;
0579         TRY_READ_ATTR_WITHOUT_NS_INTO(descr, m_cNvPrDescr)
0580         debugMsooXml << "descr:" << m_cNvPrDescr;
0581     }
0582 
0583     SKIP_EVERYTHING
0584 
0585     // while (!atEnd()) {
0586     //     readNext();
0587     //     debugMsooXml << *this;
0588     //     BREAK_IF_END_OF(CURRENT_EL)
0589     //     if (isStartElement()) {
0590     //         TRY_READ_IF(...)
0591     //         //! @todo add ELSE_WRONG_FORMAT
0592     //     }
0593     // }
0594 
0595     if (m_isLockedCanvas) {
0596         READ_EPILOGUE_IF_NS(a)
0597     } else {
0598         READ_EPILOGUE
0599     }
0600 }
0601 
0602 #undef CURRENT_EL
0603 #define CURRENT_EL nvSpPr
0604 //! nvSpPr handler (Non-Visual Properties for a Shape)
0605 //! ECMA-376, 19.3.1.34, p. 2846
0606 //! ECMA-376, 20.1.2.2.29, p. 3049
0607 /*!
0608   This element specifies all non-visual properties for a shape.
0609   This element is a container for the non-visual identification
0610   properties, shape properties and application properties that are
0611   to be associated with a shape.  This allows for additional
0612   information that does not affect the appearance of the shape to be
0613   stored.
0614 
0615   Parent elements:
0616   PresentationML/DrawingML:
0617   - [done] sp (§19.3.1.43)
0618 
0619   Child elements:
0620   PresentationML:
0621   - [done] cNvPr (Non-Visual Drawing Properties) §19.3.1.12
0622   - [done] cNvSpPr (Non-Visual Drawing Properties for a Shape) §19.3.1.13
0623   - [done] nvPr (Non-Visual Properties) §19.3.1.33
0624 
0625   DrawingML:
0626   - [done] cNvPr (Non-Visual Drawing Properties) §20.1.2.2.8
0627   - [done] cNvSpPr (Non-Visual Drawing Properties for a Shape) §20.1.2.2.9
0628 
0629   SpreadsheetML:
0630   - [done] cNvPr (Non-Visual Drawing Properties) §20.5.2.8
0631   - [done] cNvSpPr (Connection Non-Visual Shape Properties) §20.5.2.9
0632 */
0633 //! @todo support all child elements
0634 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_nvSpPr()
0635 {
0636     if (m_isLockedCanvas) {
0637         READ_PROLOGUE_IF_NS(a);
0638     } else {
0639         READ_PROLOGUE
0640     }
0641 
0642     if (m_isLockedCanvas) {
0643         while (!atEnd()) {
0644             readNext();
0645             debugMsooXml << *this;
0646             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
0647             if (isStartElement()) {
0648                 TRY_READ_IF_NS_IN_CONTEXT(a, cNvPr)
0649                 ELSE_TRY_READ_IF_NS(a, cNvSpPr)
0650                 ELSE_WRONG_FORMAT
0651             }
0652         }
0653     } else {
0654         while (!atEnd()) {
0655             readNext();
0656             debugMsooXml << *this;
0657             BREAK_IF_END_OF(CURRENT_EL)
0658             if (isStartElement()) {
0659                 TRY_READ_IF_IN_CONTEXT(cNvPr)
0660                 ELSE_TRY_READ_IF(cNvSpPr)
0661 #ifdef PPTXXMLSLIDEREADER_CPP
0662                 ELSE_TRY_READ_IF(nvPr) // only §19.3.1.33
0663 #endif
0664                 ELSE_WRONG_FORMAT
0665 
0666             }
0667         }
0668     }
0669 
0670 #ifdef PPTXXMLSLIDEREADER_CPP
0671     inheritShapeGeometry();
0672 #endif
0673 
0674     if (m_isLockedCanvas) {
0675         READ_EPILOGUE_IF_NS(a)
0676     } else {
0677         READ_EPILOGUE
0678     }
0679 }
0680 
0681 #undef CURRENT_EL
0682 #define CURRENT_EL grpSp
0683 //! grpSp handler (Group shape)
0684 //! ECMA-376, 19.3.1.22, p.2836 (PresentationML)
0685 //! ECMA-376, 20.1.2.2.20, p.3038 (DrawingML)
0686 /*!
0687   Parent elements:
0688   ----------------
0689   PresentationML:
0690   - [done] grpSp (§19.3.1.22)
0691   - [done] spTree (§19.3.1.45)
0692 
0693   DrawingML:
0694   - [done] grpSp (§20.1.2.2.20)
0695   - [done] lockedCanvas (§20.3.2.1)
0696 
0697   SpreadsheetML:
0698   - [done] absoluteAnchor (§20.5.2.1)
0699   - [done] grpSp (§20.5.2.17)
0700   - [done] oneCellAnchor (§20.5.2.24)
0701   - [done] twoCellAnchor (§20.5.2.33)
0702 
0703   Child elements:
0704   ---------------
0705   PresentationML:
0706   - contentPart (Content Part) §19.3.1.14
0707   - [done] cxnSp (Connection Shape) §19.3.1.19
0708   - extLst (Extension List with Modification Flag) §19.3.1.20
0709   - [done] graphicFrame (Graphic Frame) §19.3.1.21
0710   - [done] grpSp (Group Shape) §19.3.1.22
0711   - [done] grpSpPr (Group Shape Properties) §19.3.1.23
0712   - nvGrpSpPr (Non-Visual Properties for a Group Shape) §19.3.1.31
0713   - [done] pic (Picture) §19.3.1.37
0714   - [done] sp (Shape) §19.3.1.43
0715 
0716   DrawingML:
0717   - [done] cxnSp (Connection Shape) §20.1.2.2.10
0718   - extLst (Extension List) §20.1.2.2.15
0719   - graphicFrame (Graphic Frame) §20.1.2.2.18
0720   - [done] grpSp (Group shape) §20.1.2.2.20
0721   - [done] grpSpPr (Visual Group Shape Properties) §20.1.2.2.22
0722   - nvGrpSpPr (Non-Visual Properties for a Group Shape) §20.1.2.2.27
0723   - [done] pic (Picture) §20.1.2.2.30
0724   - [done] sp (Shape) §20.1.2.2.33
0725   - [done] txSp (Text Shape) §20.1.2.2.41
0726 
0727   SpreadsheetML:
0728   - [done] cxnSp (Connection Shape) §20.5.2.13
0729   - [done] graphicFrame (Graphic Frame) §20.5.2.16
0730   - [done] grpSp (Group Shape) §20.5.2.17
0731   - [done] grpSpPr (Group Shape Properties) §20.5.2.18
0732   - nvGrpSpPr (Non-Visual Properties for a Group Shape) §20.5.2.21
0733   - [done] pic (Picture) §20.5.2.25
0734   - [done] sp (Shape) §20.5.2.29
0735 */
0736 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_grpSp()
0737 {
0738     if (m_isLockedCanvas) {
0739         READ_PROLOGUE_IF_NS(a);
0740     } else {
0741         READ_PROLOGUE
0742     }
0743 
0744     pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
0745     MSOOXML::Utils::XmlWriteBuffer drawFrameBuf; // buffer this draw:g, because we have
0746 
0747     {
0748         MSOOXML::Utils::AutoRestore<KoXmlWriter> autoRestoreBody(&body);
0749 
0750         // to write after the child elements are generated
0751         body = drawFrameBuf.setWriter(body);
0752 
0753 #ifdef XLSXXMLDRAWINGREADER_CPP
0754         m_context->m_groupDepthCounter++;
0755 #endif
0756         if (m_isLockedCanvas) {
0757             while (!atEnd()) {
0758                 readNext();
0759                 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
0760                 debugMsooXml << *this;
0761                 if (isStartElement()) {
0762                     TRY_READ_IF_NS(a, grpSp)
0763                     ELSE_TRY_READ_IF_NS(a, grpSpPr)
0764                     ELSE_TRY_READ_IF_NS(a, pic)
0765                     ELSE_TRY_READ_IF_NS(a, sp)
0766                     ELSE_TRY_READ_IF_NS(a, cxnSp)
0767                     // ELSE_TRY_READ_IF_NS(a, graphicFrame)
0768                     ELSE_TRY_READ_IF_NS(a, txSp)
0769                     SKIP_UNKNOWN
0770                     //! @todo add ELSE_WRONG_FORMAT
0771                 }
0772             }
0773         } else {
0774             while (!atEnd()) {
0775                 readNext();
0776                 BREAK_IF_END_OF(CURRENT_EL)
0777                 debugMsooXml << *this;
0778                 if (isStartElement()) {
0779                     TRY_READ_IF(grpSp)
0780                     ELSE_TRY_READ_IF(grpSpPr)
0781                     ELSE_TRY_READ_IF(pic)
0782                     ELSE_TRY_READ_IF(sp)
0783                     ELSE_TRY_READ_IF(cxnSp)
0784 #if defined PPTXXMLSLIDEREADER_CPP || defined XLSXXMLDRAWINGREADER_CPP
0785                     ELSE_TRY_READ_IF(graphicFrame)
0786 #endif
0787                     SKIP_UNKNOWN
0788                     //! @todo add ELSE_WRONG_FORMAT
0789                 }
0790             }
0791         }
0792 #ifdef XLSXXMLDRAWINGREADER_CPP
0793         m_context->m_groupDepthCounter--;
0794 #endif
0795     }
0796 
0797     body = drawFrameBuf.originalWriter();
0798     body->startElement("draw:g");
0799 
0800 #ifdef PPTXXMLSLIDEREADER_CPP
0801     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
0802         m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
0803     }
0804 #elif defined DOCXXMLDOCREADER_CPP
0805     if (m_moveToStylesXml) {
0806         m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
0807     }
0808 #endif
0809     const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr"));
0810     body->addAttribute("draw:style-name", styleName);
0811 
0812     (void)drawFrameBuf.releaseWriter();
0813 
0814     body->endElement(); // draw:g
0815 
0816     // Properties are set in grpSpPr
0817     if (!m_svgProp.isEmpty()) {
0818         m_svgProp.pop_back();
0819     } else {
0820         warnMsooXml << "Element grpSpPr not processed, empty graphic style assigned to draw:g";
0821     }
0822 
0823     popCurrentDrawStyle();
0824 
0825     if (m_isLockedCanvas) {
0826         READ_EPILOGUE_IF_NS(a)
0827     } else {
0828         READ_EPILOGUE
0829     }
0830 }
0831 
0832 #undef CURRENT_EL
0833 #define CURRENT_EL grpSpPr
0834 //! grpSpPr (Group Shape Properties)
0835 //! ECMA-376, 19.3.1.23, p.2837 (PresentationML)
0836 //! ECMA-376, 20.1.2.2.22, p.3041 (DrawingML)
0837 /*!
0838  Parent elements:
0839  ----------------
0840  PresentationML:
0841  - [done] grpSp (§19.3.1.22);
0842  - [done] spTree (§19.3.1.45)
0843 
0844  DrawingML:
0845  - [done] grpSp (§20.1.2.2.20)
0846  - [done] lockedCanvas (§20.3.2.1)
0847 
0848  Child elements:
0849  - [done] blipFill (Picture Fill) §20.1.8.14
0850  - effectDag (Effect Container) §20.1.8.25
0851  - [done] effectLst (Effect Container) §20.1.8.26
0852  - extLst (Extension List) §20.1.2.2.15
0853  - [done] gradFill (Gradient Fill) §20.1.8.33
0854  - grpFill (Group Fill) §20.1.8.35
0855  - [done] noFill (No Fill) §20.1.8.44
0856  - pattFill (Pattern Fill) §20.1.8.47
0857  - scene3d (3D Scene Properties) §20.1.4.1.26
0858  - [done] solidFill (Solid Fill) §20.1.8.54
0859  - [done] xfrm (2D Transform for Grouped Objects) §20.1.7.5
0860 */
0861 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_grpSpPr()
0862 {
0863     if (m_isLockedCanvas) {
0864         READ_PROLOGUE_IF_NS(a);
0865     } else {
0866         READ_PROLOGUE
0867     }
0868     m_inGrpSpPr = true;
0869 
0870     while (!atEnd()) {
0871         readNext();
0872         debugMsooXml << *this;
0873         if (m_isLockedCanvas) {
0874             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
0875         } else {
0876             BREAK_IF_END_OF(CURRENT_EL)
0877         }
0878         if (isStartElement()) {
0879             TRY_READ_IF_NS(a, xfrm)
0880             else if (qualifiedName() == QLatin1String("a:effectLst")) {
0881                 TRY_READ(effectLst)
0882             }
0883             else if (qualifiedName() == QLatin1String("a:solidFill")) {
0884                 TRY_READ(solidFill)
0885                 // We must set the color immediately, otherwise currentColor may be modified by eg. ln
0886                 if (m_currentColor != QColor()) {
0887                     m_currentDrawStyle->addProperty("draw:fill", QLatin1String("solid"));
0888                     m_currentDrawStyle->addProperty("draw:fill-color", m_currentColor.name());
0889                     m_currentColor = QColor();
0890                 }
0891             }
0892             else if ( qualifiedName() == QLatin1String("a:ln") ) {
0893                 TRY_READ(ln)
0894             }
0895             else if (qualifiedName() == QLatin1String("a:noFill")) {
0896                 m_currentDrawStyle->addProperty("draw:fill", "none");
0897             }
0898             else if (qualifiedName() == QLatin1String("a:blipFill")) {
0899                 TRY_READ_IN_CONTEXT(blipFill)
0900                 if (!m_xlinkHref.isEmpty()) {
0901                     KoGenStyle fillStyle = KoGenStyle(KoGenStyle::FillImageStyle);
0902                     fillStyle.addProperty("xlink:href", m_xlinkHref);
0903                     fillStyle.addProperty("xlink:type", "simple");
0904                     fillStyle.addProperty("xlink:actuate", "onLoad");
0905                     const QString imageName = mainStyles->insert(fillStyle);
0906                     m_currentDrawStyle->addProperty("draw:fill", "bitmap");
0907                     m_currentDrawStyle->addProperty("draw:fill-image-name", imageName);
0908                     m_xlinkHref.clear();
0909                 }
0910             }
0911             else if (qualifiedName() == QLatin1String("a:gradFill")) {
0912                 m_currentGradientStyle = KoGenStyle(KoGenStyle::LinearGradientStyle);
0913                 TRY_READ(gradFill)
0914                 m_currentDrawStyle->addProperty("draw:fill", "gradient");
0915                 const QString gradName = mainStyles->insert(m_currentGradientStyle);
0916                 m_currentDrawStyle->addProperty("draw:fill-gradient-name", gradName);
0917             }
0918             SKIP_UNKNOWN
0919         //! @todo add ELSE_WRONG_FORMAT
0920         }
0921     }
0922 
0923     GroupProp prop;
0924     prop.svgXOld = m_svgX;
0925     prop.svgYOld = m_svgY;
0926     prop.svgWidthOld = m_svgWidth;
0927     prop.svgHeightOld = m_svgHeight;
0928     prop.svgXChOld = m_svgChX;
0929     prop.svgYChOld = m_svgChY;
0930     prop.svgWidthChOld = m_svgChWidth;
0931     prop.svgHeightChOld = m_svgChHeight;
0932 
0933     m_svgProp.push_back(prop);
0934 
0935     m_inGrpSpPr = false;
0936 
0937     if (m_isLockedCanvas) {
0938         READ_EPILOGUE_IF_NS(a)
0939     } else {
0940         READ_EPILOGUE
0941     }
0942 }
0943 
0944 #undef CURRENT_EL
0945 #define CURRENT_EL nvCxnSpPr
0946 //! nvCxnSpPr (Non-Visual Properties for a Connection Shape)
0947 //! ECMA-376, 19.3.1.29 (PresentationML)
0948 //! ECMA-376, 20.1.2.2.25 (DrawingML)
0949 //! ECMA-376, 20.5.2.19 (SpreadsheetML)
0950 /*!
0951   Parent Elements:
0952   ----------------
0953   PresentationML/DrawingML:
0954   - [done] cxnSp (§19.3.1.19)/(§20.1.2.2.10)
0955 
0956   Child Elements:
0957   ---------------
0958   PresentaionML:
0959   - cNvCxnSpPr (Non-Visual Connector Shape Drawing Properties) §19.3.1.8
0960   - [done] cNvPr (Non-Visual Drawing Properties) §19.3.1.12
0961   - [done] nvPr (Non-Visual Properties) §19.3.1.33
0962 
0963   DrawingML:
0964   - cNvCxnSpPr (Non-Visual Connector Shape Drawing Properties) §20.1.2.2.4
0965   - [done] cNvPr (Non-Visual Drawing Properties) §20.1.2.2.8
0966 
0967   SpreadsheetML:
0968   - cNvCxnSpPr (Non-Visual Connector Shape Drawing Properties) §20.5.2.4
0969   - [done] cNvPr (Non-Visual Drawing Properties) §20.5.2.8
0970 */
0971 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_nvCxnSpPr()
0972 {
0973     if (m_isLockedCanvas) {
0974         READ_PROLOGUE_IF_NS(a);
0975     } else {
0976         READ_PROLOGUE
0977     }
0978 
0979     if (m_isLockedCanvas) {
0980         while (!atEnd()) {
0981             readNext();
0982             debugMsooXml << *this;
0983             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
0984             if (isStartElement()) {
0985                 TRY_READ_IF_NS_IN_CONTEXT(a, cNvPr)
0986                 SKIP_UNKNOWN
0987             }
0988         }
0989     } else {
0990         while (!atEnd()) {
0991             readNext();
0992             debugMsooXml << *this;
0993             BREAK_IF_END_OF(CURRENT_EL)
0994             if (isStartElement()) {
0995                 TRY_READ_IF_IN_CONTEXT(cNvPr)
0996 #ifdef PPTXXMLSLIDEREADER_CPP
0997                 ELSE_TRY_READ_IF(nvPr) // only §19.3.1.33
0998 #endif
0999                 SKIP_UNKNOWN
1000             }
1001         }
1002     }
1003 
1004     if (m_isLockedCanvas) {
1005         READ_EPILOGUE_IF_NS(a)
1006     } else {
1007         READ_EPILOGUE
1008     }
1009 }
1010 
1011 #undef CURRENT_EL
1012 #define CURRENT_EL cNvSpPr
1013 //! cNvSpPr handler (Non-Visual Drawing Properties for a Shape)
1014 //! ECMA-376, 19.3.1.13, p. 2828; 20.1.2.2.9, p. 3030.
1015 /*! This element specifies the non-visual drawing properties for a shape.
1016 
1017  Parent elements:
1018  - [done] nvSpPr (§19.3.1.34)
1019  - [done] nvSpPr (§20.1.2.2.29) - DrawingML
1020 
1021  Child elements:
1022  - extLst (Extension List) §20.1.2.2.15
1023  - spLocks (Shape Locks) §20.1.2.2.34
1024 
1025  Attributes:
1026  - [done] txBox (Text Box)
1027 */
1028 //! @todo support all child elements
1029 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_cNvSpPr()
1030 {
1031     if (m_isLockedCanvas) {
1032         READ_PROLOGUE_IF_NS(a);
1033     } else {
1034         READ_PROLOGUE
1035     }
1036 
1037     SKIP_EVERYTHING
1038 
1039     // const QXmlStreamAttributes attrs(attributes());
1040 
1041     // Read attributes
1042     // FIXME: Make a member?
1043     //bool isTextBox = MSOOXML::Utils::convertBooleanAttr(attrs.value("txBox").toString(), false);
1044 
1045     // while (!atEnd()) {
1046     //     readNext();
1047     //     debugMsooXml << *this;
1048     //     BREAK_IF_END_OF(CURRENT_EL)
1049     //     if (isStartElement()) {
1050     //         TRY_READ_IF(...)
1051     //         //! @todo add ELSE_WRONG_FORMAT
1052     //     }
1053     // }
1054 
1055     if (m_isLockedCanvas) {
1056         READ_EPILOGUE_IF_NS(a)
1057     } else {
1058         READ_EPILOGUE
1059     }
1060 }
1061 
1062 void MSOOXML_CURRENT_CLASS::preReadSp()
1063 {
1064     // Reset the position and size
1065     m_svgX = 0;
1066     m_svgY = 0;
1067     m_svgWidth = -1;
1068     m_svgHeight = -1;
1069     m_xfrm_read = false;
1070     m_flipH = false;
1071     m_flipV = false;
1072     m_rot = 0;
1073 
1074 #ifdef PPTXXMLSLIDEREADER_CPP
1075     //We assume that the textbox is empty by default
1076     d->textBoxHasContent = false;
1077 
1078     m_currentPresentationStyle = KoGenStyle(KoGenStyle::PresentationAutoStyle, "presentation");
1079     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
1080         m_currentPresentationStyle.setAutoStyleInStylesDotXml(true);
1081     }
1082 
1083     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
1084         m_currentShapeProperties = new PptxShapeProperties();
1085     }
1086     else if (m_context->type == SlideLayout) {
1087         // moved down
1088         m_currentShapeProperties = 0;
1089     }
1090 #endif
1091 
1092     m_cNvPrId.clear();
1093     m_cNvPrName.clear();
1094     m_cNvPrDescr.clear();
1095 }
1096 
1097 void MSOOXML_CURRENT_CLASS::generateFrameSp()
1098 {
1099     inheritDefaultBodyProperties();
1100 
1101 #ifdef PPTXXMLSLIDEREADER_CPP
1102     debugMsooXml << "outputDrawFrame for" << (m_context->type == SlideLayout ? "SlideLayout" : "Slide");
1103 
1104     // Properties may or may not override default ones.
1105     inheritBodyProperties();
1106 
1107     // FIXME: The draw:fit-to-size attribute specifies whether to stretch the
1108     // text content of a drawing object to fill an entire object.  The
1109     // style:shrink-to-fit attribute specifies whether content is reduced in
1110     // size to fit within a cell or drawing object.  Shrinking means that the
1111     // font size of the content is decreased to fit the content into a cell or
1112     // drawing object.  That's needed to be compatible with MS PowerPoint.  Any
1113     // margin, padding or indent MUST be retained.
1114     if (m_normAutofit == MSOOXML::Utils::autoFitOn) {
1115         m_currentPresentationStyle.addProperty("draw:fit-to-size", "true", KoGenStyle::GraphicType);
1116     }
1117 #endif
1118     if (m_contentType == "line" || m_contentType == "arc") {
1119         body->startElement("draw:line");
1120     }
1121     else if (m_contentType.contains("Connector")) {
1122         // This should be maybe draw:connector but calligra doesn't
1123         // seem to handle that element atm.
1124         body->startElement("draw:line");
1125     }
1126     else if (m_contentType == "custom") {
1127         body->startElement("draw:custom-shape");
1128     }
1129     else if (!isCustomShape()) {
1130 #ifdef PPTXXMLSLIDEREADER_CPP
1131         if (d->phType == "sldImg") {
1132         // Special feature for presentation notes
1133             body->startElement("draw:page-thumbnail");
1134         } else {
1135             body->startElement("draw:frame");
1136         }
1137 #else
1138         body->startElement("draw:frame");
1139 #endif
1140     }
1141     // For predefined shapes
1142     else {
1143         body->startElement("draw:custom-shape");
1144     }
1145 
1146     if (!m_cNvPrName.isEmpty()) {
1147         body->addAttribute("draw:name", m_cNvPrName);
1148     }
1149 
1150     m_currentDrawStyle->addProperty("draw:textarea-vertical-align", m_shapeTextPosition);
1151     m_currentDrawStyle->addProperty("fo:padding-left", EMU_TO_CM_STRING(m_shapeTextLeftOff.toInt()));
1152     m_currentDrawStyle->addProperty("fo:padding-right", EMU_TO_CM_STRING(m_shapeTextRightOff.toInt()));
1153     m_currentDrawStyle->addProperty("fo:padding-top", EMU_TO_CM_STRING(m_shapeTextTopOff.toInt()));
1154     m_currentDrawStyle->addProperty("fo:padding-bottom", EMU_TO_CM_STRING(m_shapeTextBottomOff.toInt()));
1155 
1156 #ifdef PPTXXMLSLIDEREADER_CPP
1157     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
1158         m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
1159     }
1160 
1161     // NOTE: Workaround: Set padding to ZERO until the fo:wrap-option support
1162     // arrives and other text on shape related issues get fixed.
1163     if (isCustomShape()) {
1164         m_currentDrawStyle->removeProperty("fo:padding-left");
1165         m_currentDrawStyle->removeProperty("fo:padding-right");
1166         m_currentDrawStyle->removeProperty("fo:padding-top");
1167         m_currentDrawStyle->removeProperty("fo:padding-bottom");
1168         m_currentDrawStyle->addPropertyPt("fo:padding", 0);
1169     }
1170 
1171 #elif defined DOCXXMLDOCREADER_CPP
1172     if (m_moveToStylesXml) {
1173         m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
1174     }
1175 #endif
1176 
1177 #ifndef PPTXXMLSLIDEREADER_CPP
1178     const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr"));
1179     body->addAttribute("draw:style-name", styleName);
1180 #else
1181     const QString presentationClass(MSOOXML::Utils::ST_PlaceholderType_to_ODF(d->phType));
1182 
1183     if (m_context->type == Slide || m_context->type == SlideLayout) {
1184         body->addAttribute("draw:layer", "layout");
1185     }
1186     else {
1187         body->addAttribute("draw:layer", "backgroundobjects");
1188         // Phtype will be empty for any text that is in masterslide that is wanted
1189         // to be shown in the actual slides, such as company names etc.
1190         if (!d->phType.isEmpty()) {
1191             body->addAttribute("presentation:placeholder", "true");
1192             body->addAttribute("presentation:class", presentationClass);
1193         }
1194     }
1195 
1196     // only either draw:style-name or presentation:style-name
1197     // is allowed, but not both.
1198     if (!m_currentPresentationStyle.isEmpty() || !m_currentPresentationStyle.parentName().isEmpty()) {
1199         KoGenStyle::copyPropertiesFromStyle(*m_currentDrawStyle, m_currentPresentationStyle, KoGenStyle::GraphicType);
1200         KoGenStyle::copyPropertiesFromStyle(*m_currentDrawStyle, m_currentPresentationStyle, KoGenStyle::TextType);
1201         KoGenStyle::copyPropertiesFromStyle(*m_currentDrawStyle, m_currentPresentationStyle, KoGenStyle::ParagraphType);
1202         const QString presentationStyleName = mainStyles->insert(m_currentPresentationStyle, "pr");
1203         body->addAttribute("presentation:style-name", presentationStyleName);
1204     } else {
1205         const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr"));
1206         body->addAttribute("draw:style-name", styleName);
1207     }
1208     inheritShapePosition();
1209 
1210     if (m_context->type == Slide) {
1211         // CASE #P476
1212         QString id = "slide" + QString::number(m_context->slideNumber) + "item"
1213                 + m_cNvPrId;
1214         body->addAttribute("draw:id", id);
1215         body->addAttribute("xml:id", id);
1216         body->addAttribute("presentation:class", presentationClass);
1217         debugMsooXml << "presentationClass:" << d->phType << "->" << presentationClass;
1218         debugMsooXml << "m_svgWidth:" << m_svgWidth << "m_svgHeight:" << m_svgHeight
1219                  << "m_svgX:" << m_svgX << "m_svgY:" << m_svgY;
1220     }
1221 #endif
1222 
1223     if (m_svgWidth > -1 && m_svgHeight > -1) {
1224 #ifdef PPTXXMLSLIDEREADER_CPP
1225         body->addAttribute("presentation:user-transformed", MsooXmlReader::constTrue);
1226 #endif
1227         if (m_contentType == "line" || m_contentType == "arc" || m_contentType.contains("Connector")) {
1228 #ifdef XLSXXMLDRAWINGREADER_CPP
1229             XlsxDrawingObject::Position f = m_currentDrawingObject->m_positions[XlsxDrawingObject::FromAnchor];
1230             body->addAttributePt("svg:x", EMU_TO_POINT(f.m_colOff));
1231             body->addAttributePt("svg:y", EMU_TO_POINT(f.m_rowOff));
1232             QString y1 = EMU_TO_CM_STRING(f.m_rowOff);
1233             QString y2 = EMU_TO_CM_STRING(f.m_rowOff + m_svgHeight);
1234             QString x1 = EMU_TO_CM_STRING(f.m_colOff);
1235             QString x2 = EMU_TO_CM_STRING(f.m_colOff + m_svgWidth);
1236             if (m_rot != 0) {
1237                 qreal angle, xDiff, yDiff;
1238                 if (m_flipH ^ m_flipV) {
1239                     MSOOXML::Utils::rotateString(-m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
1240                 } else {
1241                     MSOOXML::Utils::rotateString(m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
1242                 }
1243                 //! @todo, in case of connector, these should maybe be reversed?
1244                 x1 = EMU_TO_CM_STRING(f.m_colOff + xDiff);
1245                 y1 = EMU_TO_CM_STRING(f.m_rowOff + yDiff);
1246                 x2 = EMU_TO_CM_STRING(f.m_colOff + m_svgWidth - xDiff);
1247                 y2 = EMU_TO_CM_STRING(f.m_rowOff + m_svgHeight - yDiff);
1248             }
1249 #else
1250             QString y1 = EMU_TO_CM_STRING(m_svgY);
1251             QString y2 = EMU_TO_CM_STRING(m_svgY + m_svgHeight);
1252             QString x1 = EMU_TO_CM_STRING(m_svgX);
1253             QString x2 = EMU_TO_CM_STRING(m_svgX + m_svgWidth);
1254             if (m_rot != 0) {
1255                 qreal angle, xDiff, yDiff;
1256                 // handle flipping of lines, logical XOR here
1257                 if (m_flipH ^ m_flipV) {
1258                     MSOOXML::Utils::rotateString(-m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
1259                 } else {
1260                     MSOOXML::Utils::rotateString(m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
1261                 }
1262 
1263                 //! @todo, in case of connector, these should maybe be reversed?
1264                 x1 = EMU_TO_CM_STRING(m_svgX + xDiff);
1265                 y1 = EMU_TO_CM_STRING(m_svgY + yDiff);
1266                 x2 = EMU_TO_CM_STRING(m_svgX + m_svgWidth - xDiff);
1267                 y2 = EMU_TO_CM_STRING(m_svgY + m_svgHeight - yDiff);
1268             }
1269 #endif
1270             if (m_flipV) {
1271                 QString temp = y2;
1272                 y2 = y1;
1273                 y1 = temp;
1274             }
1275             if (m_flipH) {
1276                 QString temp = x2;
1277                 x2 = x1;
1278                 x1 = temp;
1279             }
1280             body->addAttribute("svg:x1", x1);
1281             body->addAttribute("svg:y1", y1);
1282             body->addAttribute("svg:x2", x2);
1283             body->addAttribute("svg:y2", y2);
1284         }
1285         else {
1286             if (m_rot == 0) {
1287                 body->addAttribute("svg:x", EMU_TO_CM_STRING(m_svgX));
1288                 body->addAttribute("svg:y", EMU_TO_CM_STRING(m_svgY));
1289             } else {
1290                 // m_rot is in 1/60,000th of a degree
1291                 qreal angle, xDiff, yDiff;
1292 
1293                 // text-box vertical flipping is done with rotation by +180 degrees
1294                 // mirror/flip flag is not available in odf for text-box
1295                 if (m_contentType == "rect" && m_flipV) {
1296                     MSOOXML::Utils::rotateString(m_rot + (180 * 60000), m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
1297                 } else {
1298                     MSOOXML::Utils::rotateString(m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
1299                 }
1300 
1301                 QString rotString = QString("rotate(%1) translate(%2cm %3cm)").
1302                                     arg(angle).arg((m_svgX + xDiff)/360000, 3, 'f').
1303                                     arg((m_svgY + yDiff)/360000, 3, 'f');
1304                 body->addAttribute("draw:transform", rotString);
1305             }
1306             body->addAttribute("svg:width", EMU_TO_CM_STRING(m_svgWidth));
1307             body->addAttribute("svg:height", EMU_TO_CM_STRING(m_svgHeight));
1308         }
1309     }
1310 }
1311 
1312 void MSOOXML_CURRENT_CLASS::writeEnhancedGeometry()
1313 {
1314     if (!isCustomShape()) {
1315         return;
1316     }
1317     body->startElement("draw:enhanced-geometry");
1318     body->addAttribute("svg:viewBox", QString("0 0 %1 %2").arg(m_svgWidth).arg(m_svgHeight));
1319 
1320     if (m_flipV) {
1321         body->addAttribute("draw:mirror-vertical", "true");
1322     }
1323     if (m_flipH) {
1324         body->addAttribute("draw:mirror-horizontal", "true");
1325     }
1326 
1327     if (m_contentType == "custom") {
1328         body->addAttribute("draw:enhanced-path", m_customPath);
1329         if (!m_textareas.isEmpty()) {
1330             body->addAttribute("draw:text-areas", m_textareas);
1331         }
1332         if (!m_customEquations.isEmpty()) {
1333             body->addCompleteElement(m_customEquations.toUtf8());
1334         }
1335     } else {
1336         body->addAttribute("draw:enhanced-path", m_context->import->m_shapeHelper.attributes.value(m_contentType));
1337 
1338         QString textareas = m_context->import->m_shapeHelper.textareas.value(m_contentType);
1339         if (!textareas.isEmpty()) {
1340             body->addAttribute("draw:text-areas", textareas);
1341         }
1342         QString equations = m_context->import->m_shapeHelper.equations.value(m_contentType);
1343 
1344         // Some of the values might be overwritten by prstGeom.
1345         if (m_contentAvLstExists) {
1346             QMapIterator<QString, QString> i(m_avModifiers);
1347             while (i.hasNext()) {
1348                 i.next();
1349                 int index = 0;
1350                 index = equations.indexOf(i.key());
1351                 if (index > -1) {
1352                     // We go forward by name and '" draw:formula="'
1353                     index += i.key().length() + 16;
1354                     equations.replace(index, equations.indexOf('\"', index) - index, i.value());
1355                 }
1356             }
1357         }
1358         if (!equations.isEmpty()) {
1359             body->addCompleteElement(equations.toUtf8());
1360         }
1361     }
1362     body->endElement(); // draw:enhanced-geometry
1363 }
1364 
1365 #undef CURRENT_EL
1366 #define CURRENT_EL cxnSp
1367 //! cxnSp (Connection Shape)
1368 //! ECMA-376, 19.3.1.19, p.2833 (PresentationML)
1369 //! ECMA-376, 20.1.2.2.10, p.3029 (DrawingML)
1370 /*
1371    This element specifies a connection shape that is used to connect
1372    two sp elements.  Once a connection is specified using a cxnSp, it
1373    is left to the generating application to determine the exact path
1374    the connector takes.  That is the connector routing algorithm is
1375    left up to the generating application as the desired path might be
1376    different depending on the specific needs of the application.
1377 
1378    Parent Elements:
1379    ----------------
1380    PresentationML:
1381    - [done] grpSp (§19.3.1.22)
1382    - [done] spTree (§19.3.1.45)
1383 
1384    DrawingML:
1385    - [done] grpSp (§20.1.2.2.20)
1386    - [done] lockedCanvas (§20.3.2.1)
1387 
1388    Child Elements:
1389    ---------------
1390    PresentationML:
1391    - extLst (Extension List with Modification Flag) §19.3.1.20
1392    - [done] nvCxnSpPr (Non-Visual Properties for a Connection Shape) §19.3.1.29
1393    - [done] spPr (Shape Properties) §19.3.1.44
1394    - [done] style (Shape Style) §19.3.1.46
1395 
1396    DrawingML:
1397    - extLst (Extension List) §20.1.2.2.15
1398    - [done] nvCxnSpPr (Non-Visual Properties for a Connection Shape) §20.1.2.2.25
1399    - [done] spPr (Shape Properties) §20.1.2.2.35
1400    - [done] style (Shape Style) §20.1.2.2.37
1401 */
1402 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_cxnSp()
1403 {
1404     if (m_isLockedCanvas) {
1405         READ_PROLOGUE_IF_NS(a);
1406     } else {
1407         READ_PROLOGUE
1408     }
1409 
1410     preReadSp();
1411 
1412     pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
1413 
1414     MSOOXML::Utils::XmlWriteBuffer drawFrameBuf; // buffer this draw:frame, because we have
1415     // to write after the child elements are generated
1416     body = drawFrameBuf.setWriter(body);
1417 
1418     m_referredFont = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
1419 
1420     if (m_isLockedCanvas) {
1421         while (!atEnd()) {
1422             readNext();
1423             debugMsooXml << *this;
1424             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
1425             if (isStartElement()) {
1426                 TRY_READ_IF_NS(a, nvCxnSpPr)
1427                 ELSE_TRY_READ_IF_NS(a, spPr)
1428                 ELSE_TRY_READ_IF_NS(a, style)
1429                 SKIP_UNKNOWN
1430             }
1431         }
1432     } else {
1433         while (!atEnd()) {
1434             readNext();
1435             debugMsooXml << *this;
1436             BREAK_IF_END_OF(CURRENT_EL)
1437             if (isStartElement()) {
1438                 TRY_READ_IF(nvCxnSpPr)
1439                 ELSE_TRY_READ_IF(spPr)
1440                 ELSE_TRY_READ_IF(style)
1441                 SKIP_UNKNOWN
1442                 //! @todo add ELSE_WRONG_FORMAT
1443             }
1444         }
1445     }
1446 
1447     body = drawFrameBuf.originalWriter();
1448 
1449     generateFrameSp();
1450 
1451     (void)drawFrameBuf.releaseWriter();
1452 
1453     if (isCustomShape()) {
1454     writeEnhancedGeometry();
1455     }
1456     body->endElement(); //draw:frame, //draw:line
1457 
1458 #ifdef PPTXXMLSLIDEREADER_CPP
1459     KoFilter::ConversionStatus stat = generatePlaceHolderSp();
1460     if (stat != KoFilter::OK) {
1461         return stat;
1462     }
1463 #endif
1464 
1465     popCurrentDrawStyle();
1466 
1467     if (m_isLockedCanvas) {
1468         READ_EPILOGUE_IF_NS(a)
1469     } else {
1470         READ_EPILOGUE
1471     }
1472 }
1473 
1474 #undef CURRENT_EL
1475 #define CURRENT_EL sp
1476 //! sp handler (Shape)
1477 //! ECMA-376, 19.3.1.43, p.2854 (PresentationML)
1478 //! ECMA-376, 20.1.2.2.33, p.3053 (DrawingML)
1479 /*! This element specifies the existence of a single shape.  A shape
1480   can either be a preset or a custom geometry, defined using the
1481   DrawingML framework.
1482 
1483  Parent elements:
1484  ----------------
1485  PresentationML:
1486  - [done] grpSp (§19.3.1.22)
1487  - [done] spTree (§19.3.1.45)
1488 
1489  DrawingML:
1490  - [done] grpSp (§20.1.2.2.20)
1491  - [done] lockedCanvas (§20.3.2.1)
1492 
1493  Child elements:
1494  PresentationML:
1495  - extLst (Extension List with Modification Flag) §19.3.1.20
1496  - [done] nvSpPr (Non-Visual Properties for a Shape) §19.3.1.34
1497  - [done] spPr (Shape Properties) §19.3.1.44
1498  - [done] style (Shape Style) §19.3.1.46
1499  - [done] txBody (Shape Text Body) §19.3.1.51 - PML
1500 
1501  DrawingML:
1502  - extLst (Extension List) §20.1.2.2.15
1503  - [done] nvSpPr (Non-Visual Properties for a Shape) §20.1.2.2.29
1504  - [done] spPr (Shape Properties) §20.1.2.2.35
1505  - [done] style (Shape Style) §20.1.2.2.37
1506  - [done] txSp (Text Shape) §20.1.2.2.41
1507 
1508  Attributes:
1509  - [unsupported?] useBgFill
1510 */
1511 //! @todo support all elements
1512 //! CASE #P405
1513 //! CASE #P425
1514 //! CASE #P430
1515 //! CASE #P476
1516 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_sp()
1517 {
1518     if (m_isLockedCanvas) {
1519         READ_PROLOGUE_IF_NS(a);
1520     } else {
1521         READ_PROLOGUE
1522     }
1523 
1524     m_contentType.clear();
1525     m_xlinkHref.clear();
1526 
1527     preReadSp();
1528 
1529     pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
1530 
1531     MSOOXML::Utils::XmlWriteBuffer drawFrameBuf; // buffer this draw:frame, because we have
1532     // to write after the child elements are generated
1533     body = drawFrameBuf.setWriter(body);
1534 
1535     m_referredFont = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
1536 
1537 
1538     if (m_isLockedCanvas) {
1539         while (!atEnd()) {
1540             readNext();
1541             debugMsooXml << *this;
1542             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
1543             if (isStartElement()) {
1544                 TRY_READ_IF_NS(a, nvSpPr)
1545                 ELSE_TRY_READ_IF_NS(a, spPr)
1546                 ELSE_TRY_READ_IF_NS(a, style)
1547                 ELSE_TRY_READ_IF_NS(a, txSp)
1548                 SKIP_UNKNOWN
1549                 //! @todo add ELSE_WRONG_FORMAT
1550             }
1551         }
1552     } else {
1553         while (!atEnd()) {
1554             readNext();
1555             debugMsooXml << *this;
1556             BREAK_IF_END_OF(CURRENT_EL)
1557             if (isStartElement()) {
1558                 TRY_READ_IF(nvSpPr)
1559                 ELSE_TRY_READ_IF(spPr)
1560                 ELSE_TRY_READ_IF(style)
1561 #if defined PPTXXMLSLIDEREADER_CPP
1562                 ELSE_TRY_READ_IF(txBody)
1563 #else
1564                 else if (qualifiedName() == QLatin1String(QUALIFIED_NAME(txBody))) {
1565                     TRY_READ_IN_CONTEXT(DrawingML_txBody)
1566                 }
1567 #endif
1568                 SKIP_UNKNOWN
1569                 //! @todo add ELSE_WRONG_FORMAT
1570             }
1571         }
1572     }
1573 
1574     body = drawFrameBuf.originalWriter();
1575 
1576     generateFrameSp();
1577 
1578     (void)drawFrameBuf.releaseWriter();
1579 
1580     if (isCustomShape()) {
1581     writeEnhancedGeometry();
1582     }
1583     body->endElement(); //draw:frame, //draw:line
1584 
1585 #ifdef PPTXXMLSLIDEREADER_CPP
1586     KoFilter::ConversionStatus stat = generatePlaceHolderSp();
1587     if (stat != KoFilter::OK) {
1588         return stat;
1589     }
1590 #endif
1591 
1592     popCurrentDrawStyle();
1593 
1594     if (m_isLockedCanvas) {
1595         READ_EPILOGUE_IF_NS(a)
1596     } else {
1597         READ_EPILOGUE
1598     }
1599 }
1600 
1601 #undef CURRENT_EL
1602 #define CURRENT_EL style
1603 //! style handler (Shape style)
1604 //! ECMA-376, 21.3.2.24, p.3943 (PresentationML)
1605 //! ECMA-376, 20.1.2.2.37, p.3055 (DrawingML)
1606 /*!
1607  Parent elements:
1608  ----------------
1609  PresentationML/SpreadsheetML:
1610  - [done] cxnSp (§19.3.1.19);
1611  - [done] pic (§19.3.1.37);
1612  - [done] sp (§19.3.1.43)
1613 
1614  DrawingML:
1615  - [done] cxnSp (§20.1.2.2.10)
1616  - lnDef (§20.1.4.1.20)
1617  - [done] pic (§20.1.2.2.30)
1618  - [done] sp (§20.1.2.2.33)
1619  - spDef (§20.1.4.1.27)
1620  - txDef (§20.1.4.1.28)
1621 
1622  Child elements:
1623  - effectRef (Effect Reference) §20.1.4.2.8
1624  - [done] fillRef (Fill Reference) §20.1.4.2.10
1625  - [done] fontRef (Font Reference) §20.1.4.1.17
1626  - [done] lnRef (Line Reference) §20.1.4.2.19
1627 
1628 */
1629 //! @todo support all child elements
1630 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_style()
1631 {
1632     if (m_isLockedCanvas) {
1633         READ_PROLOGUE_IF_NS(a);
1634     } else {
1635         READ_PROLOGUE
1636     }
1637 
1638     while (!atEnd()) {
1639         readNext();
1640         debugMsooXml << *this;
1641         if (m_isLockedCanvas) {
1642             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
1643         } else {
1644             BREAK_IF_END_OF(CURRENT_EL)
1645         }
1646         if (isStartElement()) {
1647             TRY_READ_IF_NS(a, fillRef)
1648             ELSE_TRY_READ_IF_NS(a, lnRef)
1649             else if (qualifiedName() == "a:fontRef") {
1650                 m_currentColor = QColor();
1651                 m_referredFontName.clear();
1652                 TRY_READ(fontRef)
1653                 if (m_currentColor.isValid()) {
1654                     m_referredFont.addProperty("fo:color", m_currentColor.name());
1655                     m_currentColor = QColor();
1656                 }
1657                 if (!m_referredFontName.isEmpty()) {
1658                     m_referredFont.addProperty("fo:font-family", m_referredFontName);
1659                 }
1660             }
1661             SKIP_UNKNOWN
1662 //! @todo add ELSE_WRONG_FORMAT
1663         }
1664     }
1665 
1666     if (m_isLockedCanvas) {
1667         READ_EPILOGUE_IF_NS(a)
1668     } else {
1669         READ_EPILOGUE
1670     }
1671 }
1672 
1673 #undef CURRENT_EL
1674 #define CURRENT_EL spPr
1675 //! spPr handler (Shape Properties)
1676 //! ECMA-376, 19.3.1.44, p.2855; (PresentationML)
1677 //! ECMA-376, 20.1.2.2.35, p. 3055 (DrawingML)
1678 /*! This element specifies the visual shape properties that can be applied to a shape.
1679  These properties include the shape fill, outline, geometry, effects, and 3D orientation.
1680 
1681  Parent elements:
1682  ----------------
1683  PresentationML:
1684  - [done] cxnSp (§19.3.1.19)
1685  - [done] pic (§19.3.1.37)
1686  - [done] sp (§19.3.1.43)
1687 
1688  DrawingML:
1689  - [done] cxnSp (§20.1.2.2.10)
1690  - lnDef (§20.1.4.1.20)
1691  - [done] pic (§20.1.2.2.30)
1692  - [done] sp (§20.1.2.2.33)
1693  - spDef (§20.1.4.1.27)
1694  - txDef (§20.1.4.1.28)
1695 
1696  Child elements:
1697  - [done] blipFill (Picture Fill) §20.1.8.14
1698  - [done] custGeom (Custom Geometry) §20.1.9.8
1699  - effectDag (Effect Container) §20.1.8.25
1700  - [done] effectLst (Effect Container) §20.1.8.26
1701  - extLst (Extension List) §20.1.2.2.15
1702  - [done] gradFill (Gradient Fill) §20.1.8.33
1703  - grpFill (Group Fill) §20.1.8.35
1704  - [done] ln (Outline) §20.1.2.2.24
1705  - [done] noFill (No Fill) §20.1.8.44
1706  - pattFill (Pattern Fill) §20.1.8.47
1707  - [done] prstGeom (Preset geometry) §20.1.9.18
1708  - scene3d (3D Scene Properties) §20.1.4.1.26
1709  - [done] solidFill (Solid Fill) §20.1.8.54
1710  - sp3d (Apply 3D shape properties) §20.1.5.12
1711  - [done] xfrm (2D Transform for Individual Objects) §20.1.7.6
1712 
1713  Attributes:
1714  - bwMode (Black and White Mode)
1715 */
1716 //! @todo support all child elements
1717 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_spPr()
1718 {
1719     if (m_isLockedCanvas) {
1720         READ_PROLOGUE_IF_NS(a);
1721     } else {
1722         READ_PROLOGUE
1723     }
1724 
1725     m_contentAvLstExists = false;
1726     m_customPath.clear();
1727     m_customEquations.clear();
1728     m_textareas.clear();
1729 
1730     while (!atEnd()) {
1731         readNext();
1732         debugMsooXml << *this;
1733         if (m_isLockedCanvas) {
1734             BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
1735         } else {
1736             BREAK_IF_END_OF(CURRENT_EL)
1737         }
1738         if (isStartElement()) {
1739             if (qualifiedName() == QLatin1String("a:xfrm")) {
1740                 TRY_READ(xfrm)
1741                 m_xfrm_read = true;
1742             }
1743             else if (qualifiedName() == "a:custGeom") {
1744                 TRY_READ(custGeom)
1745                 m_contentType = "custom";
1746             }
1747             else if (qualifiedName() == QLatin1String("a:solidFill")) {
1748 #ifdef PPTXXMLSLIDEREADER_CPP
1749                 d->textBoxHasContent = true; // We count normal fill and gradient as content
1750 #endif
1751                 TRY_READ(solidFill)
1752                 if (m_currentColor != QColor()) {
1753                     // We must set the color immediately, otherwise
1754                     // currentColor may be modified by eg. ln
1755                     m_currentDrawStyle->addProperty("draw:fill", QLatin1String("solid"));
1756                     m_currentDrawStyle->addProperty("draw:fill-color", m_currentColor.name());
1757                     m_currentColor = QColor();
1758                     if (m_currentAlpha > 0) {
1759                         m_currentDrawStyle->addProperty("draw:opacity", QString("%1%").arg(m_currentAlpha));
1760                     }
1761                 }
1762             }
1763             else if (qualifiedName() == QLatin1String("a:ln")) {
1764                 TRY_READ(ln)
1765             }
1766             else if (qualifiedName() == QLatin1String("a:noFill")) {
1767                 m_currentDrawStyle->addProperty("draw:fill", "none");
1768             }
1769             else if (qualifiedName() == QLatin1String("a:prstGeom")) {
1770                 TRY_READ(prstGeom)
1771             }
1772             else if (!m_ignoreLinkHref && name() == QLatin1String("blipFill")) {
1773                 TRY_READ_IN_CONTEXT(blipFill)
1774                 if (!m_xlinkHref.isEmpty()) {
1775                     KoGenStyle fillStyle = KoGenStyle(KoGenStyle::FillImageStyle);
1776                     fillStyle.addProperty("xlink:href", m_xlinkHref);
1777                     fillStyle.addProperty("xlink:type", "simple");
1778                     fillStyle.addProperty("xlink:actuate", "onLoad");
1779                     const QString imageName = mainStyles->insert(fillStyle);
1780                     m_currentDrawStyle->addProperty("draw:fill", "bitmap");
1781                     m_currentDrawStyle->addProperty("draw:fill-image-name", imageName);
1782                     m_xlinkHref.clear();
1783                 }
1784             }
1785             else if (qualifiedName() == QLatin1String("a:effectLst")) {
1786                 TRY_READ(effectLst)
1787             }
1788             else if (qualifiedName() == QLatin1String("a:gradFill")) {
1789 #ifdef PPTXXMLSLIDEREADER_CPP
1790                 d->textBoxHasContent = true;
1791 #endif
1792                 m_currentGradientStyle = KoGenStyle(KoGenStyle::LinearGradientStyle);
1793                 TRY_READ(gradFill)
1794                 m_currentDrawStyle->addProperty("draw:fill", "gradient");
1795                 const QString gradName = mainStyles->insert(m_currentGradientStyle);
1796                 m_currentDrawStyle->addProperty("draw:fill-gradient-name", gradName);
1797             }
1798             SKIP_UNKNOWN
1799 //! @todo add ELSE_WRONG_FORMAT
1800         }
1801     }
1802 
1803 #ifdef PPTXXMLSLIDEREADER_CPP
1804     saveCurrentGraphicStyles();
1805 #endif
1806 
1807     if (m_isLockedCanvas) {
1808         READ_EPILOGUE_IF_NS(a)
1809     } else {
1810         READ_EPILOGUE
1811     }
1812 }
1813 
1814 // ================================================================
1815 //                     Namespace "c"
1816 // ================================================================
1817 #undef MSOOXML_CURRENT_NS
1818 #define MSOOXML_CURRENT_NS "c"
1819 
1820 #undef CURRENT_EL
1821 #define CURRENT_EL chart
1822 //! chart handler (Charting diagrams)
1823 /*!
1824 @todo documentation
1825 */
1826 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_chart()
1827 {
1828     READ_PROLOGUE
1829 
1830     const QXmlStreamAttributes attrs(attributes());
1831     TRY_READ_ATTR_WITH_NS(r, id)
1832     if (!r_id.isEmpty() && m_context->relationships) {
1833         const QString filepath = m_context->relationships->target(m_context->path, m_context->file, r_id);
1834 
1835         KoChart::Chart* chart = new KoChart::Chart;
1836         XlsxChartOdfWriter* chartWriter = new XlsxChartOdfWriter(chart, m_context->themes);
1837         bool hasStart = false, hasEnd = false;
1838 #if defined(XLSXXMLDRAWINGREADER_CPP)
1839         chart->m_sheetName = m_context->worksheetReaderContext->worksheetName;
1840         chartWriter->setSheetReplacement(false);
1841         if (m_currentDrawingObject->m_positions.contains(XlsxDrawingObject::FromAnchor)) {
1842             XlsxDrawingObject::Position f = m_currentDrawingObject->m_positions[XlsxDrawingObject::FromAnchor];
1843             //chartWriter->m_x = columnWidth(f.m_col-1, 0 /*f.m_colOff*/);
1844             //chartWriter->m_y = rowHeight(f.m_row-1, 0 /*f.m_rowOff*/);
1845             chartWriter->m_x = EMU_TO_POINT(f.m_colOff);
1846             chartWriter->m_y = EMU_TO_POINT(f.m_rowOff);
1847             hasStart = true;
1848             if (m_currentDrawingObject->m_positions.contains(XlsxDrawingObject::ToAnchor)) {
1849                 f = m_currentDrawingObject->m_positions[XlsxDrawingObject::ToAnchor];
1850                 chartWriter->m_endCellAddress = m_currentDrawingObject->toCellAddress();
1851                 //chartWriter->m_end_x = f.m_colOff;
1852                 //chartWriter->m_end_y = f.m_rowOff;
1853                 chartWriter->m_end_x = EMU_TO_POINT(f.m_colOff);
1854                 chartWriter->m_end_y = EMU_TO_POINT(f.m_rowOff);
1855                 hasEnd = true;
1856             }
1857         }
1858 #else
1859         chartWriter->m_drawLayer = true;
1860 #endif
1861         if (!hasStart) {
1862             chartWriter->m_x = EMU_TO_POINT(qMax((qint64)0, m_svgX));
1863             chartWriter->m_y = EMU_TO_POINT(qMax((qint64)0, m_svgY));
1864         }
1865         if (!hasEnd) {
1866             chartWriter->m_width = m_svgWidth > 0 ? EMU_TO_POINT(m_svgWidth) : 100;
1867             chartWriter->m_height = m_svgHeight > 0 ? EMU_TO_POINT(m_svgHeight) : 100;
1868         }
1869 
1870         KoStore* storeout = m_context->import->outputStore();
1871         QScopedPointer<XlsxXmlChartReaderContext> context(new XlsxXmlChartReaderContext(storeout, chartWriter));
1872         XlsxXmlChartReader reader(this);
1873         const KoFilter::ConversionStatus result = m_context->import->loadAndParseDocument(&reader, filepath, context.data());
1874         if (result != KoFilter::OK) {
1875             raiseError(reader.errorString());
1876             return result;
1877         }
1878 
1879 #if defined(XLSXXMLDRAWINGREADER_CPP)
1880         m_currentDrawingObject->setChart(context.take());
1881 #else
1882         chartWriter->saveIndex(body);
1883 #endif
1884     }
1885 
1886     while (!atEnd()) {
1887         readNext();
1888         BREAK_IF_END_OF(CURRENT_EL)
1889     }
1890 
1891     READ_EPILOGUE
1892 }
1893 
1894 // ================================================================
1895 //                     Namespace "dgm"
1896 // ================================================================
1897 #undef MSOOXML_CURRENT_NS
1898 #define MSOOXML_CURRENT_NS "dgm"
1899 
1900 #undef CURRENT_EL
1901 #define CURRENT_EL relIds
1902 //! relIds (Explicit Relationships to Diagram Parts)
1903 /*! ECMA-376, 21.4, p.3936
1904 
1905   This element specifies the relationship IDs used to explicitly reference each
1906   of the four constituent parts of a DrawingML diagram:
1907 
1908   Diagram Colors (cs attribute)
1909   Diagram Data (dm attribute)
1910   Diagram Layout Definition (lo attribute)
1911   Diagram Style (qs attribute)
1912 
1913   ----------
1914   DrawingML - Diagrams
1915   ECMA-376, 21.4, p.3936
1916 
1917   A DrawingML diagram allows the definition of diagrams using DrawingML objects
1918   and constructs. This namespace defines the contents of a DrawingML diagram.
1919 */
1920 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_relIds()
1921 {
1922     READ_PROLOGUE
1923 
1924     if (m_context->relationships) {
1925         const QXmlStreamAttributes attrs(attributes());
1926         TRY_READ_ATTR_WITH_NS(r, cs) // colors
1927         TRY_READ_ATTR_WITH_NS(r, dm) // data
1928         TRY_READ_ATTR_WITH_NS(r, lo) // layout
1929         TRY_READ_ATTR_WITH_NS(r, qs) // quickStyle
1930         while (!atEnd()) {
1931             readNext();
1932             BREAK_IF_END_OF(CURRENT_EL)
1933             if (isStartElement()) {
1934                 TRY_READ_IF(spPr)
1935                 ELSE_TRY_READ_IF(style)
1936             }
1937         }
1938 
1939 /*         const QString colorsfile = r_cs.isEmpty() ? QString() : m_context->relationships->target(m_context->path, m_context->file, r_cs); */
1940         const QString datafile = r_dm.isEmpty() ? QString() : m_context->relationships->target(m_context->path, m_context->file, r_dm);
1941         const QString layoutfile = r_lo.isEmpty() ? QString() : m_context->relationships->target(m_context->path, m_context->file, r_lo);
1942 /*         const QString quickstylefile = r_qs.isEmpty() ? QString() : m_context->relationships->target(m_context->path, m_context->file, r_qs); */
1943         QScopedPointer<MSOOXML::MsooXmlDiagramReaderContext> context(new MSOOXML::MsooXmlDiagramReaderContext(mainStyles));
1944 
1945         // first read the data-model
1946         MSOOXML::MsooXmlDiagramReader dataReader(this);
1947         const KoFilter::ConversionStatus dataReaderResult = m_context->import->loadAndParseDocument(&dataReader, datafile, context.data());
1948         if (dataReaderResult != KoFilter::OK) {
1949             raiseError(dataReader.errorString());
1950             return dataReaderResult;
1951         }
1952 
1953         // then read the layout definition
1954         MSOOXML::MsooXmlDiagramReader layoutReader(this);
1955         const KoFilter::ConversionStatus layoutReaderResult = m_context->import->loadAndParseDocument(&layoutReader, layoutfile, context.data());
1956         if (layoutReaderResult != KoFilter::OK) {
1957             raiseError(layoutReader.errorString());
1958             return layoutReaderResult;
1959         }
1960 
1961         if (context->shapeListSize() > 1) {
1962             m_context->graphicObjectIsGroup = true;
1963         }
1964 
1965         // and finally start the process that will produce the ODF
1966 #if defined(XLSXXMLDRAWINGREADER_CPP)
1967         m_currentDrawingObject->setDiagram(context.take());
1968 #else
1969         context->saveIndex(body, QRect(EMU_TO_CM(m_svgX), EMU_TO_CM(m_svgY), m_svgHeight > 0 ? EMU_TO_CM(m_svgWidth) : 100, m_svgHeight > 0 ? EMU_TO_CM(m_svgHeight) : 100));
1970 #endif
1971     }
1972 
1973     READ_EPILOGUE
1974 }
1975 
1976 #undef MSOOXML_CURRENT_NS
1977 #define MSOOXML_CURRENT_NS "lc"
1978 
1979 // ================================================================
1980 //                     Namespace "lc"
1981 // ================================================================
1982 
1983 #undef CURRENT_EL
1984 #define CURRENT_EL lockedCanvas
1985 //! lockedCanvas (Locked Canvas Container)
1986 /*! ECMA-376, 20.3.2.1, p.3464
1987 
1988   The locked canvas element acts as a container for more advanced
1989   drawing objects.  The notion of a locked canvas comes from the fact
1990   that the generating application opening the file cannot create this
1991   object and can thus not perform edits either.  Thus the drawing
1992   object is locked from all UI adjustments that would normally take
1993   place.
1994 
1995   Child Elements
1996   - [done] cxnSp (Connection Shape)
1997   - extLst (Extension List)
1998   - graphicFrame (Graphic Frame)
1999   - [done] grpSp (Group shape)
2000   - [done] grpSpPr (Visual Group Shape Properties)
2001   - nvGrpSpPr (Non-Visual Properties for a Group Shape)
2002   - [done] pic (Picture)
2003   - [done] sp (Shape)
2004   - [done] txSp (Text Shape)
2005 */
2006 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lockedCanvas()
2007 {
2008     // NOTE: Child elements have a client specific namespace defined
2009     // by the DRAWINGML_PIC_NS macro in case of other parent elements.
2010     // In case of lockedCanvas, child elements have namespace "a".
2011 
2012     READ_PROLOGUE
2013     m_isLockedCanvas = true;
2014     m_context->graphicObjectIsGroup = true;
2015 
2016     while (!atEnd()) {
2017         readNext();
2018         debugMsooXml << *this;
2019         BREAK_IF_END_OF(CURRENT_EL)
2020         if (isStartElement()) {
2021             TRY_READ_IF(cxnSp)
2022             ELSE_TRY_READ_IF_NS(a, grpSp)
2023             ELSE_TRY_READ_IF_NS(a, grpSpPr)
2024             ELSE_TRY_READ_IF_NS(a, pic)
2025             ELSE_TRY_READ_IF_NS(a, sp)
2026             // ELSE_TRY_READ_IF_NS(a, graphicFrame)
2027             ELSE_TRY_READ_IF_NS(a, txSp)
2028             SKIP_UNKNOWN
2029     }
2030     }
2031 
2032     m_isLockedCanvas = false;
2033     READ_EPILOGUE
2034 }
2035 
2036 // ================================================================
2037 //                     Namespace "a"
2038 // ================================================================
2039 #undef MSOOXML_CURRENT_NS
2040 #define MSOOXML_CURRENT_NS "a"
2041 
2042 #undef CURRENT_EL
2043 #define CURRENT_EL lnRef
2044 //! fillRef handler (Line reference)
2045 /*
2046  Parent elements:
2047  - [done] style (§21.3.2.24);
2048  - [done] style (§21.4.2.28);
2049  - [done] style (§20.1.2.2.37);
2050  - [done] style (§20.5.2.31);
2051  - [done] style (§19.3.1.46);
2052  - tblBg (§20.1.4.2.25);
2053  - tcStyle (§20.1.4.2.29)
2054 
2055  Child elements:
2056  - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
2057  - [done] prstClr (Preset Color) §20.1.2.3.22
2058  - [done] schemeClr (Scheme Color) §20.1.2.3.29
2059  - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
2060  - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
2061  - [done] sysClr (System Color) §20.1.2.3.33
2062 */
2063 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lnRef()
2064 {
2065     READ_PROLOGUE
2066 
2067     const QXmlStreamAttributes attrs(attributes());
2068 
2069     TRY_READ_ATTR_WITHOUT_NS(idx)
2070 
2071     const QList<KoGenStyle> *lst = &m_context->themes->formatScheme.lnStyleLst;
2072     const KoGenStyle *lnStyle = 0;
2073 
2074     if (!idx.isEmpty() && !lst->empty()) {
2075 
2076         int index = idx.toInt();
2077 
2078         if (index >= lst->size()) {
2079             index = lst->size() - 1;
2080         }
2081         lnStyle = &lst->at(index);
2082     }
2083 
2084     while (!atEnd()) {
2085         readNext();
2086         debugMsooXml << *this;
2087         BREAK_IF_END_OF(CURRENT_EL)
2088         if (isStartElement()) {
2089             TRY_READ_IF(schemeClr)
2090             ELSE_TRY_READ_IF(srgbClr)
2091             ELSE_TRY_READ_IF(sysClr)
2092             ELSE_TRY_READ_IF(scrgbClr)
2093             ELSE_TRY_READ_IF(prstClr)
2094             ELSE_TRY_READ_IF(hslClr)
2095             ELSE_WRONG_FORMAT
2096         }
2097     }
2098 
2099     // TODO: Do the following before reading of the ln element.
2100     // copyPropertiesFromStyle(lnStyle, m_currentDrawStyle, KoGenStyle::GraphicType);
2101 
2102     if (m_currentColor.isValid() && m_currentDrawStyle->property("svg:stroke-color").isEmpty()) {
2103         m_currentDrawStyle->addProperty("svg:stroke-color", m_currentColor.name());
2104     }
2105 
2106     if (lnStyle) {
2107         QString prop;
2108         if (m_currentDrawStyle->property("draw:stroke").isEmpty()) {
2109             prop = lnStyle->property("draw:stroke");
2110             if (!prop.isEmpty()) {
2111                 m_currentDrawStyle->addProperty("draw:stroke", prop);
2112             } else {
2113                 // MSOOXML default
2114                 m_currentDrawStyle->addProperty("draw:stroke", "none");
2115             }
2116         }
2117         if (m_currentDrawStyle->property("svg:stroke-width").isEmpty()) {
2118             prop = lnStyle->property("svg:stroke-width");
2119             if (!prop.isEmpty()) {
2120                 m_currentDrawStyle->addProperty("svg:stroke-width", prop);
2121             } else {
2122                 // MSOOXML default
2123                 m_currentDrawStyle->addPropertyPt("svg:stroke-width", 0);
2124             }
2125         }
2126         if (m_currentDrawStyle->property("svg:stroke-color").isEmpty()) {
2127             prop = lnStyle->property("svg:stroke-color");
2128             if (!prop.isEmpty()) {
2129                 m_currentDrawStyle->addProperty("svg:stroke-color", prop);
2130             }
2131         }
2132         if (m_currentDrawStyle->property("draw:stroke-linejoin").isEmpty()) {
2133             prop = lnStyle->property("draw:stroke-linejoin");
2134             if (!prop.isEmpty()) {
2135                 m_currentDrawStyle->addProperty("draw:stroke-linejoin", prop);
2136             } else {
2137                 // MSOOXML default
2138                 m_currentDrawStyle->addProperty("draw:stroke-linejoin", "round");
2139             }
2140         }
2141     }
2142 
2143     READ_EPILOGUE
2144 }
2145 
2146 #undef CURRENT_EL
2147 #define CURRENT_EL masterClrMapping
2148 //! masterClrMapping handler (Master Color Mapping)
2149 /* This element is a part of a choice for which color mapping is used within
2150    the document.  If this element is specified, then we specifically use the
2151    color mapping defined in the master.
2152 
2153  Parent elements:
2154  - [done] clrMapOvr (§19.3.1.7)
2155  */
2156 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_masterClrMapping()
2157 {
2158     READ_PROLOGUE
2159 
2160     // TODO: Add filter specific stuff.
2161 
2162     readNext();
2163     READ_EPILOGUE
2164 }
2165 
2166 #undef CURRENT_EL
2167 #define CURRENT_EL overrideClrMapping
2168 //! overrideClrMapping handler (Override Color Mapping)
2169 /* This element provides an override for the color mapping in a document. When
2170    defined, this color mapping is used in place of the already defined color
2171    mapping, or master color mapping. This color mapping is defined in the same
2172    manner as the other mappings within this document.
2173 
2174  Parent elements:
2175  - [done] clrMapOvr (§19.3.1.7)
2176 */
2177 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_overrideClrMapping()
2178 {
2179     READ_PROLOGUE
2180 
2181     const QXmlStreamAttributes attrs(attributes());
2182 
2183 #ifdef PPTXXMLSLIDEREADER_CPP
2184     QMap<QString, QString> colorMapBkp;
2185     if ((m_context->type == SlideLayout) || (m_context->type == Slide)) {
2186         colorMapBkp = m_context->colorMap;
2187     }
2188 #endif
2189 
2190     int index = 0;
2191     while (index < attrs.size()) {
2192         const QString handledAttr = attrs.at(index).name().toString();
2193         const QString attrValue = attrs.value(handledAttr).toString();
2194 #ifdef PPTXXMLSLIDEREADER_CPP
2195         m_context->colorMap[handledAttr] = attrValue;
2196 #endif
2197         ++index;
2198     }
2199 
2200     // FIXME: PPTX: Update styles prepared while processing the p:txStyles
2201     // element (Slide Master Text Styles).
2202     //
2203     // NOTE: Workaround!  Inform the pptx filter that the color mapping
2204     // changed compared to slideMaster.  Theme specific default colors should
2205     // be used until we get correct style:use-window-font-color support.
2206 #ifdef PPTXXMLSLIDEREADER_CPP
2207     if (m_context->type == SlideLayout) {
2208         if (m_context->colorMap != colorMapBkp) {
2209             m_context->slideLayoutProperties->overrideClrMapping = true;
2210             m_context->slideLayoutProperties->colorMap = m_context->colorMap;
2211         }
2212     }
2213     // NOTE: Workaround!  Inform the pptx filter that the color mapping
2214     // changed compared to slideMaster.  Theme specific default colors should
2215     // be used.
2216     if (m_context->type == Slide) {
2217         if (m_context->colorMap != colorMapBkp) {
2218             m_context->overrideClrMapping = true;
2219         }
2220     }
2221 #endif
2222 
2223     while (!atEnd()) {
2224         readNext();
2225         debugMsooXml << *this;
2226         BREAK_IF_END_OF(CURRENT_EL)
2227         if (isStartElement()) {
2228 //! @todo add ELSE_WRONG_FORMAT
2229         }
2230     }
2231 
2232     READ_EPILOGUE
2233 }
2234 
2235 #undef CURRENT_EL
2236 #define CURRENT_EL p
2237 //! p handler (Text Paragraphs) ECMA-376, DrawingML 21.1.2.2.6, p. 3587.
2238 //!   This element specifies the presence of a paragraph of text within the containing text body.
2239 /*!
2240  Parent elements:
2241  - rich (§21.2.2.156)
2242  - txBody (§21.3.2.26)
2243  - txBody (§20.1.2.2.40)
2244  - txBody (§20.5.2.34)
2245  - [done] txBody (§19.3.1.51) - PML
2246  - txPr (§21.2.2.216)
2247 
2248  Child elements:
2249  - [done] br (Text Line Break) §21.1.2.2.1
2250  - [done] endParaRPr (End Paragraph Run Properties) §21.1.2.2.3
2251  - [done] fld (Text Field) §21.1.2.2.4
2252  - [done] pPr (Text Paragraph Properties) §21.1.2.2.7
2253  - [done] r (Text Run) §21.1.2.3.8
2254 */
2255 //! @todo support all elements
2256 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_p()
2257 {
2258     READ_PROLOGUE2(DrawingML_p)
2259 
2260     // Using TEXT_FONTSIZE_MAX, because the font-size information might not be
2261     // provided, which would break the margin-top/margin-bottom calculation.
2262     // NOTE: This might not be the correct approach but it produces the best
2263     // results at the moment.
2264     m_minParaFontPt = TEXT_FONTSIZE_MAX;
2265     m_maxParaFontPt = TEXT_FONTSIZE_MIN;
2266 
2267     m_read_DrawingML_p_args = 0;
2268     m_paragraphStyleNameWritten = false;
2269     m_listStylePropertiesAltered = false;
2270 
2271     m_currentCombinedBulletProperties.clear();
2272 
2273 #ifdef PPTXXMLSLIDEREADER_CPP
2274     m_currentListLevel = 1; // By default we're in the first level
2275     inheritListStyles();
2276 #else
2277     // TODO: MS Word: There's a different positioning logic for a list inside
2278     // of a textbox compared to a list in a document body.
2279 /*     m_prevListLevel = m_currentListLevel = 0; */
2280     m_currentListLevel = 0;
2281 #endif
2282 
2283     MSOOXML::Utils::MSOOXMLFilter currentFilter = MSOOXML::Utils::XlsxFilter;
2284 #ifdef PPTXXMLSLIDEREADER_CPP
2285     currentFilter = MSOOXML::Utils::PptxFilter;
2286 #elif defined  DOCXXMLDOCREADER_CPP
2287     currentFilter = MSOOXML::Utils::DocxFilter;
2288 #endif
2289 
2290     QString fontSize;
2291     QString bulletColor;
2292     QString listStyleName;
2293 
2294     // Creating a list out of what we have, pPr MAY overwrite the list style
2295     m_currentListStyle = KoGenStyle(KoGenStyle::ListAutoStyle);
2296 /*     QMapIterator<int, MSOOXML::Utils::ParagraphBulletProperties> i(m_currentCombinedBulletProperties); */
2297     QMutableMapIterator<int, MSOOXML::Utils::ParagraphBulletProperties> i(m_currentCombinedBulletProperties);
2298     int index = 0;
2299     while (i.hasNext()) {
2300         index++;
2301         i.next();
2302         m_currentListStyle.addChildElement(QString("list-style-properties%1").arg(index),
2303             i.value().convertToListProperties(*mainStyles, currentFilter));
2304     }
2305 
2306     MSOOXML::Utils::XmlWriteBuffer textPBuf;
2307 
2308     body = textPBuf.setWriter(body);
2309     m_currentParagraphStyle = KoGenStyle(KoGenStyle::ParagraphAutoStyle, "paragraph");
2310 
2311 #ifdef PPTXXMLSLIDEREADER_CPP
2312     m_currentParagraphStyle.addProperty("fo:line-height", "100%" );
2313 #endif
2314     bool pprRead = false;
2315     bool rRead = false;
2316     bool brLastElement = false;
2317     QString endParaRPrFontSize;
2318 
2319     while (!atEnd()) {
2320         readNext();
2321         debugMsooXml << "isStartElement:" << isStartElement();
2322         BREAK_IF_END_OF(CURRENT_EL)
2323         if (isStartElement()) {
2324 // CASE #400.1
2325             if (QUALIFIED_NAME_IS(pPr)) {
2326                 TRY_READ(DrawingML_pPr)
2327                 pprRead = true;
2328             }
2329             else if (QUALIFIED_NAME_IS(br)) {
2330                 TRY_READ(DrawingML_br)
2331                 brLastElement = true;
2332             }
2333 // CASE #400.2
2334 //! @todo add more conditions testing the parent
2335             else if (QUALIFIED_NAME_IS(r)) {
2336                 rRead = true;
2337 #ifdef PPTXXMLSLIDEREADER_CPP
2338                 d->textBoxHasContent = true;
2339 #endif
2340                 TRY_READ(DrawingML_r)
2341                 if (fontSize.isEmpty()) {
2342                     fontSize = m_currentTextStyle.property("fo:font-size");
2343                 }
2344                 if (bulletColor.isEmpty()) {
2345                     bulletColor = m_currentTextStyle.property("fo:color");
2346                 }
2347                 brLastElement = false;
2348             }
2349             else if (QUALIFIED_NAME_IS(fld)) {
2350                 rRead = true;
2351                 TRY_READ(fld)
2352                 brLastElement = false;
2353             }
2354             else if (QUALIFIED_NAME_IS(endParaRPr)) {
2355                 m_currentTextStyleProperties = new KoCharacterStyle();
2356                 m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
2357 
2358 #ifdef PPTXXMLSLIDEREADER_CPP
2359                 if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
2360                     m_currentTextStyle.setAutoStyleInStylesDotXml(true);
2361                 }
2362 #elif defined DOCXXMLDOCREADER_CPP
2363                 if (m_moveToStylesXml) {
2364                     m_currentTextStyle.setAutoStyleInStylesDotXml(true);
2365                 }
2366 #endif
2367 #ifdef PPTXXMLSLIDEREADER_CPP
2368                 if (!m_insideTable) {
2369                     inheritTextStyle(m_currentTextStyle);
2370                 }
2371 #endif
2372                 TRY_READ(endParaRPr)
2373                 m_currentTextStyleProperties->saveOdf(m_currentTextStyle);
2374                 delete m_currentTextStyleProperties;
2375                 m_currentTextStyleProperties = 0;
2376 
2377                 if (brLastElement || !rRead) {
2378                     body->startElement("text:span");
2379                     body->addAttribute("text:style-name", mainStyles->insert(m_currentTextStyle));
2380                     body->endElement(); //text:span
2381                 }
2382                 endParaRPrFontSize = m_currentTextStyle.property("fo:font-size");
2383             }
2384             ELSE_WRONG_FORMAT
2385         }
2386     }
2387 
2388 #ifdef PPTXXMLSLIDEREADER_CPP
2389     if (!pprRead) {
2390         inheritParagraphStyle(m_currentParagraphStyle);
2391         m_currentBulletProperties = m_currentCombinedBulletProperties[m_currentListLevel];
2392     }
2393     if (m_currentParagraphStyle.property("fo:line-height").endsWith('%')) {
2394         m_currentParagraphStyle.addProperty("style:font-independent-line-spacing", "true");
2395     }
2396 #else
2397     Q_UNUSED(pprRead);
2398 #endif
2399 
2400     //---------------------------------------------
2401     // Empty lines
2402     //---------------------------------------------
2403     // The endParaRPr element specifies the text run properties that are to be
2404     // used if another run is inserted after the last run specified.
2405     if (!rRead) {
2406         QString fontSize = endParaRPrFontSize;
2407         if (!fontSize.isEmpty() && fontSize.endsWith(QLatin1String("pt"))) {
2408             fontSize.chop(2);
2409             qreal realSize = fontSize.toDouble();
2410             if (realSize > m_maxParaFontPt) {
2411                 m_maxParaFontPt = realSize;
2412             }
2413             if (realSize < m_minParaFontPt) {
2414                 m_minParaFontPt = realSize;
2415             }
2416         }
2417     }
2418 
2419     //---------------------------------------------
2420     // Prepare for the List Style
2421     //---------------------------------------------
2422 #ifdef PPTXXMLSLIDEREADER_CPP
2423     // MS PowerPoint treats each paragraph as a list-item.
2424     m_listStylePropertiesAltered = true;
2425 #else
2426     if (m_currentListLevel == 0) {
2427     m_listStylePropertiesAltered = false;
2428     }
2429 #endif
2430 
2431     //required to set size of the picture bullet properly
2432     if (m_listStylePropertiesAltered && m_currentBulletProperties.bulletSizePt() == "UNUSED") {
2433         if (!fontSize.isEmpty() && fontSize.endsWith(QLatin1String("pt"))) {
2434             fontSize.chop(2);
2435             qreal bulletSize = fontSize.toDouble();
2436 
2437             if (m_currentBulletProperties.bulletRelativeSize() != "UNUSED") {
2438                 bulletSize = (bulletSize * m_currentBulletProperties.bulletRelativeSize().toDouble()) / 100;
2439             } else {
2440                 m_currentBulletProperties.setBulletRelativeSize(100);
2441             }
2442             m_currentBulletProperties.setBulletSizePt(bulletSize);
2443         }
2444     }
2445 
2446     //---------------------------------------------
2447     // List Style
2448     //---------------------------------------------
2449     if (m_listStylePropertiesAltered) {
2450         m_currentListStyle = KoGenStyle(KoGenStyle::ListAutoStyle);
2451 #ifdef PPTXXMLSLIDEREADER_CPP
2452         if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
2453             m_currentListStyle.setAutoStyleInStylesDotXml(true);
2454         }
2455 #elif defined DOCXXMLDOCREADER_CPP
2456         if (m_moveToStylesXml) {
2457             m_currentListStyle.setAutoStyleInStylesDotXml(true);
2458         }
2459 #endif
2460         m_currentBulletProperties.m_level = m_currentListLevel;
2461         m_currentListStyle.addChildElement("list-style-properties",
2462             m_currentBulletProperties.convertToListProperties(*mainStyles, currentFilter));
2463         listStyleName = mainStyles->insert(m_currentListStyle);
2464         Q_ASSERT(!listStyleName.isEmpty());
2465 
2466         if (listStyleName != m_prevListStyleName) {
2467             m_prevListStyleName = listStyleName;
2468         } else {
2469             m_listStylePropertiesAltered = false;
2470         }
2471     }
2472     //---------------------------------------------
2473     // Update Automatic Numbering info
2474     //---------------------------------------------
2475     if (m_currentBulletProperties.m_type != MSOOXML::Utils::ParagraphBulletProperties::NumberType) {
2476         QList<quint16> levels = m_continueListNumbering.keys();
2477         for (quint16 i = 0; i < levels.size(); i++) {
2478             if (levels[i] >= m_currentListLevel) {
2479                 m_continueListNumbering.remove(levels[i]);
2480                 m_lvlXmlIdMap.remove(levels[i]);
2481             }
2482         }
2483     }
2484     if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) {
2485         if (m_prevListLevel > m_currentListLevel) {
2486             QList<quint16> levels = m_continueListNumbering.keys();
2487             for (quint16 i = 0; i < levels.size(); i++) {
2488                 if (levels[i] > m_currentListLevel) {
2489                     m_continueListNumbering.remove(levels[i]);
2490                     m_lvlXmlIdMap.remove(levels[i]);
2491                 }
2492             }
2493         }
2494     }
2495 
2496     //---------------------------------------------
2497     // Prepare for the List
2498     //---------------------------------------------
2499 
2500     // Empty paragraph is NOT considered to be a list-item at the moment.
2501     // Prevent stage of displaying a bullet in front of it.
2502 #ifdef PPTXXMLSLIDEREADER_CPP
2503     if (!rRead) {
2504         m_listStylePropertiesAltered = true;
2505         m_prevListStyleName.clear();
2506         m_currentListLevel = 0;
2507     }
2508 #endif
2509 
2510     body = textPBuf.originalWriter();
2511 
2512     // End the previous list in case a new list-style is going to be applied.
2513     if (m_listStylePropertiesAltered) {
2514         if (m_prevListLevel > 0) {
2515             body->endElement(); //text:list
2516             for (; m_prevListLevel > 1; --m_prevListLevel) {
2517                 body->endElement(); //text:list-item
2518                 body->endElement(); //text:list
2519             }
2520             m_prevListLevel = 0;
2521         }
2522     }
2523 
2524     //---------------------------------------------
2525     // Start the List/List-Item
2526     //---------------------------------------------
2527     if (m_currentListLevel > 0 || m_prevListLevel > 0) {
2528 /* #ifdef PPTXXMLSLIDEREADER_CPP */
2529         if (m_listStylePropertiesAltered) {
2530             Q_ASSERT(m_prevListLevel == 0);
2531 
2532             body->startElement("text:list");
2533             body->addAttribute("text:style-name", listStyleName);
2534             m_currentParagraphStyle.addAttribute("style:list-style-name", listStyleName);
2535 
2536             //continue numbering if applicable
2537             if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) {
2538 
2539                 QString xmlId = QString("lvl%1").arg(m_currentListLevel);
2540                 xmlId.append(QString("_%1").arg(qrand()));
2541                 body->addAttribute("xml:id", xmlId);
2542 
2543                 if (m_continueListNumbering.contains(m_currentListLevel) &&
2544                     m_continueListNumbering[m_currentListLevel]) {
2545                     body->addAttribute("text:continue-list", m_lvlXmlIdMap[m_currentListLevel]);
2546                 }
2547                 m_lvlXmlIdMap[m_currentListLevel] = xmlId;
2548             }
2549             body->startElement("text:list-item");
2550             for (int i = 1; i < m_currentListLevel; i++) {
2551                 body->startElement("text:list");
2552                 body->startElement("text:list-item");
2553             }
2554 
2555         } else if (m_prevListLevel < m_currentListLevel) {
2556             if (m_prevListLevel > 0) {
2557                 body->startElement("text:list-item");
2558             }
2559             for (int i = m_prevListLevel; i < m_currentListLevel; i++) {
2560                 body->startElement("text:list");
2561                 body->startElement("text:list-item");
2562             }
2563         } else if (m_prevListLevel > m_currentListLevel) {
2564             body->endElement(); //text:list
2565             for (int i = m_prevListLevel - 1; i > m_currentListLevel; i--) {
2566                 body->endElement(); //text:list-item
2567                 body->endElement(); //text:list
2568             }
2569             //starting our own stuff for this level
2570             if (m_currentListLevel > 0) {
2571                 body->endElement(); //text:list-item
2572                 body->startElement("text:list-item");
2573             }
2574         } else { // m_prevListLevel==m_currentListLevel
2575             body->startElement("text:list-item");
2576         }
2577         //restart numbering if applicable
2578         if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) {
2579             if (m_continueListNumbering.contains(m_currentListLevel) &&
2580                 (m_continueListNumbering[m_currentListLevel] == false)) {
2581                 body->addAttribute("text:start-value", m_currentBulletProperties.startValue());
2582             }
2583         }
2584 /* #else */
2585 /*         for (int i = 0; i < m_currentListLevel; ++i) { */
2586 /*             body->startElement("text:list"); */
2587 /*             // TODO:, should most likely add the name of the current list style */
2588 /*             body->startElement("text:list-item"); */
2589 /*         } */
2590 /* #endif */
2591         if (m_currentBulletProperties.m_type == MSOOXML::Utils::ParagraphBulletProperties::NumberType) {
2592             m_continueListNumbering[m_currentListLevel] = true;
2593         }
2594     }
2595     //---------------------------------------------
2596     // Paragraph Style
2597     //---------------------------------------------
2598 #ifdef PPTXXMLSLIDEREADER_CPP
2599     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
2600         m_currentParagraphStyle.setAutoStyleInStylesDotXml(true);
2601     }
2602 #elif defined DOCXXMLDOCREADER_CPP
2603     if (m_moveToStylesXml) {
2604         m_currentParagraphStyle.setAutoStyleInStylesDotXml(true);
2605     }
2606 #endif
2607     // Position of the list-item defined by fo:margin-left and fo:text-indent
2608     // in the style:list-level-properties element.  In ODF the paragraph style
2609     // overrides the list style.
2610     if (m_currentListLevel > 0) {
2611         m_currentParagraphStyle.removeProperty("fo:margin-left");
2612         m_currentParagraphStyle.removeProperty("fo:text-indent");
2613     }
2614 
2615     // Margins (paragraph spacing) in OOXML MIGHT be defined as percentage.
2616     // In ODF the value of margin-top/margin-bottom MAY be a percentage that
2617     // refers to the corresponding margin of a parent style.  Let's convert
2618     // the percentage value into points to keep it simple.
2619     QString spcBef = m_currentParagraphStyle.property("fo:margin-top");
2620     if (spcBef.contains('%')) {
2621         spcBef.remove('%');
2622         qreal percentage = spcBef.toDouble();
2623         qreal margin = 0;
2624 #ifdef PPTXXMLSLIDEREADER_CPP
2625         margin = processParagraphSpacing(percentage, m_minParaFontPt);
2626 #else
2627         margin = (percentage * m_maxParaFontPt) / 100.0;
2628 #endif
2629         m_currentParagraphStyle.addPropertyPt("fo:margin-top", margin);
2630     }
2631     QString spcAft = m_currentParagraphStyle.property("fo:margin-bottom");
2632     if (spcAft.contains('%')) {
2633         spcAft.remove('%');
2634         qreal percentage = spcAft.toDouble();
2635         qreal margin = 0;
2636 #ifdef PPTXXMLSLIDEREADER_CPP
2637         margin = processParagraphSpacing(percentage, m_minParaFontPt);
2638 #else
2639         margin = (percentage * m_maxParaFontPt) / 100.0;
2640 #endif
2641         m_currentParagraphStyle.addPropertyPt("fo:margin-bottom", margin);
2642     }
2643     QString currentParagraphStyleName(mainStyles->insert(m_currentParagraphStyle));
2644 
2645     //---------------------------------------------
2646     // Start Paragraph
2647     //---------------------------------------------
2648     body->startElement("text:p", false);
2649     body->addAttribute("text:style-name", currentParagraphStyleName);
2650 
2651     (void)textPBuf.releaseWriter();
2652     body->endElement(); //text:p
2653 
2654     //---------------------------------------------
2655     // End List/List-Item
2656     //---------------------------------------------
2657 /* #ifdef PPTXXMLSLIDEREADER_CPP */
2658     if (m_currentListLevel > 0) {
2659         body->endElement(); //text:list-item
2660     }
2661     m_prevListLevel = m_currentListLevel;
2662 /* #else */
2663 /*     // A new list is created for each paragraph rather then nesting the lists */
2664 /*     // cause both word and excel filter still need to be adjusted to properly */
2665 /*     // handle nested lists. */
2666 /*     for(int i = 0; i < m_currentListLevel; ++i) { */
2667 /*         body->endElement(); // text:list-item */
2668 /*         body->endElement(); // text:list */
2669 /*     } */
2670 /*     m_prevListLevel = m_currentListLevel = 0; */
2671 /* #endif */
2672     READ_EPILOGUE
2673 }
2674 
2675 #undef CURRENT_EL
2676 #define CURRENT_EL r
2677 //! r handler (Text Run)
2678 /*! ECMA-376, 21.1.2.3.8, p.3623.
2679 
2680  Parent elements:
2681  - [done] p (§21.1.2.2.6)
2682 
2683  Child elements:
2684  - [done] rPr (Text Run Properties) §21.1.2.3.9
2685  - [done] t (Text String) §21.1.2.3.11
2686 */
2687 //! @todo support all elements
2688 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_r()
2689 {
2690     READ_PROLOGUE2(DrawingML_r)
2691 
2692     m_hyperLink = false;
2693 
2694     MSOOXML::Utils::XmlWriteBuffer rBuf;
2695     body = rBuf.setWriter(body);
2696 
2697     m_currentTextStyleProperties = new KoCharacterStyle();
2698     m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
2699 #ifdef PPTXXMLSLIDEREADER_CPP
2700     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
2701         m_currentTextStyle.setAutoStyleInStylesDotXml(true);
2702     }
2703 #elif defined DOCXXMLDOCREADER_CPP
2704     if (m_moveToStylesXml) {
2705         m_currentTextStyle.setAutoStyleInStylesDotXml(true);
2706     }
2707 #endif
2708 
2709 #ifdef PPTXXMLSLIDEREADER_CPP
2710     // FIXME: There's no reason on my mind to NOT inherit the text style. (uzak)
2711     if (!m_insideTable) {
2712         inheritTextStyle(m_currentTextStyle);
2713     }
2714 #endif
2715 
2716     KoGenStyle::copyPropertiesFromStyle(m_referredFont, m_currentTextStyle, KoGenStyle::TextType);
2717 
2718     while (!atEnd()) {
2719         readNext();
2720         BREAK_IF_END_OF(CURRENT_EL)
2721         if (isStartElement()) {
2722             if (QUALIFIED_NAME_IS(rPr)) {
2723                 TRY_READ(DrawingML_rPr)
2724             }
2725             else if (QUALIFIED_NAME_IS(t)) {
2726                 TRY_READ_WITH_ARGS(t, true;)
2727             }
2728             ELSE_WRONG_FORMAT
2729         }
2730     }
2731 
2732     m_currentTextStyleProperties->saveOdf(m_currentTextStyle);
2733     delete m_currentTextStyleProperties;
2734     m_currentTextStyleProperties = 0;
2735 
2736     // elements
2737 
2738     body = rBuf.originalWriter();
2739 
2740     if (m_hyperLink) {
2741         body->startElement("text:a", false);
2742         body->addAttribute("xlink:type", "simple");
2743         body->addAttribute("xlink:href", QUrl(m_hyperLinkTarget).toEncoded());
2744     }
2745 
2746     QString fontSize = m_currentTextStyle.property("fo:font-size");
2747 
2748 #ifdef PPTXXMLSLIDEREADER_CPP
2749     if (fontSize.isEmpty()) {
2750         m_currentTextStyle.addPropertyPt("fo:font-size", TEXT_FONTSIZE_DEFAULT);
2751         fontSize = QString("%1").arg(TEXT_FONTSIZE_DEFAULT);
2752     }
2753 #endif
2754     if (!fontSize.isEmpty()) {
2755         fontSize.remove("pt");
2756         qreal realSize = fontSize.toDouble();
2757         if (realSize > m_maxParaFontPt) {
2758             m_maxParaFontPt = realSize;
2759         }
2760         if (realSize < m_minParaFontPt) {
2761             m_minParaFontPt = realSize;
2762         }
2763     }
2764 
2765     const QString currentTextStyleName(mainStyles->insert(m_currentTextStyle));
2766     body->startElement("text:span", false);
2767     body->addAttribute("text:style-name", currentTextStyleName);
2768 
2769     (void)rBuf.releaseWriter();
2770 
2771     body->endElement(); //text:span
2772     if (m_hyperLink) {
2773         body->endElement(); // text:a
2774     }
2775 
2776     READ_EPILOGUE
2777 }
2778 
2779 #undef CURRENT_EL
2780 #define CURRENT_EL br
2781 //! br (Text Line Break)
2782 //! ECMA-376, 21.1.2.2.1, p.3569
2783 /*
2784  This element specifies the existence of a vertical line break between two runs
2785  of text within a paragraph.  In addition to specifying a vertical space
2786  between two runs of text, this element can also have run properties specified
2787  via the rPr child element.  This sets the formatting of text for the line
2788  break so that if text is later inserted there that a new run can be generated
2789  with the correct formatting.
2790 
2791  Parent elements:
2792  - [done] p (§21.1.2.2.6)
2793 
2794  Child elements:
2795  - [done] rPr (Text Run Properties) §21.1.2.3.9
2796  */
2797 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_br()
2798 {
2799     READ_PROLOGUE
2800 
2801     m_currentTextStyleProperties = new KoCharacterStyle();
2802     m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
2803 
2804 #ifdef PPTXXMLSLIDEREADER_CPP
2805     if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
2806         m_currentTextStyle.setAutoStyleInStylesDotXml(true);
2807     }
2808 #elif defined DOCXXMLDOCREADER_CPP
2809     if (m_moveToStylesXml) {
2810         m_currentTextStyle.setAutoStyleInStylesDotXml(true);
2811     }
2812 #endif
2813 #ifdef PPTXXMLSLIDEREADER_CPP
2814     if (!m_insideTable) {
2815         inheritTextStyle(m_currentTextStyle);
2816     }
2817 #endif
2818 
2819     while (!atEnd()) {
2820         readNext();
2821         BREAK_IF_END_OF(CURRENT_EL)
2822         if (isStartElement()) {
2823             if (QUALIFIED_NAME_IS(rPr)) {
2824                 TRY_READ(DrawingML_rPr)
2825             }
2826             ELSE_WRONG_FORMAT
2827         }
2828     }
2829     m_currentTextStyleProperties->saveOdf(m_currentTextStyle);
2830 
2831     // NOTE: workaround: Remove selected properties to get text:line-break
2832     // applied properly during layout.  I didn't check the layout part (uzak).
2833 
2834     // If fo:text-transform is present then text:line-break is not applied.
2835     m_currentTextStyle.removeProperty("fo:text-transform");
2836 
2837     // The underline is applied until the end of the line during layout when
2838     // the text style of text:line-break equals the text style of the chunk.
2839     m_currentTextStyle.removeProperty("style:text-underline-style");
2840     m_currentTextStyle.removeProperty("style:text-underline-width");
2841 
2842     body->startElement("text:span", false);
2843     body->addAttribute("text:style-name", mainStyles->insert(m_currentTextStyle));
2844     body->startElement("text:line-break");
2845     body->endElement(); //text:line-break
2846     body->endElement(); //text:span
2847 
2848     delete m_currentTextStyleProperties;
2849     m_currentTextStyleProperties = 0;
2850 
2851     READ_EPILOGUE
2852 }
2853 
2854 
2855 #undef CURRENT_EL
2856 #define CURRENT_EL endParaRPr
2857 //! endParaRPr handler (End Paragraph Run Properties)
2858 /*
2859  Parent elements:
2860  - [done] p (§21.1.2.2.6)
2861 
2862  Child elements:
2863  - blipFill (Picture Fill) §20.1.8.14
2864  - cs (Complex Script Font) §21.1.2.3.1
2865  - ea (East Asian Font) §21.1.2.3.3
2866  - effectDag (Effect Container) §20.1.8.25
2867  - effectLst (Effect Container) §20.1.8.26
2868  - extLst (Extension List) §20.1.2.2.15
2869  - [done] gradFill (Gradient Fill) §20.1.8.33
2870  - grpFill (Group Fill) §20.1.8.35
2871  - [done] highlight (Highlight Color) §21.1.2.3.4
2872  - [done] hlinkClick (Click Hyperlink) §21.1.2.3.5
2873  - hlinkMouseOver (Mouse-Over Hyperlink) §21.1.2.3.6
2874  - [done] latin (Latin Font) §21.1.2.3.7
2875  - ln (Outline) §20.1.2.2.24
2876  - [done] noFill (No Fill) §20.1.8.44
2877  - pattFill (Pattern Fill) §20.1.8.47
2878  - rtl (Right to Left Run) §21.1.2.2.8
2879  - [done] solidFill (Solid Fill) §20.1.8.54
2880  - sym (Symbol Font) §21.1.2.3.10
2881  - uFill (Underline Fill) §21.1.2.3.12
2882  - uFillTx (Underline Fill Properties Follow Text) §21.1.2.3.13
2883  - uLn (Underline Stroke) §21.1.2.3.14
2884  - uLnTx (Underline Follows Text) §21.1.2.3.15
2885 
2886 */
2887 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_endParaRPr()
2888 {
2889     READ_PROLOGUE
2890 
2891     m_hyperLink = false;
2892 
2893     const QXmlStreamAttributes attrs(attributes());
2894 
2895     m_currentColor = QColor();
2896 
2897     while (!atEnd()) {
2898         readNext();
2899         BREAK_IF_END_OF(CURRENT_EL)
2900         if (isStartElement()) {
2901             TRY_READ_IF(latin)
2902             ELSE_TRY_READ_IF(solidFill)
2903             else if (QUALIFIED_NAME_IS(highlight)) {
2904                 TRY_READ(DrawingML_highlight)
2905             }
2906             else if (name() == "gradFill") {
2907                 TRY_READ(gradFillRpr)
2908             }
2909             else if (name() == "noFill") {
2910                 m_currentTextStyleProperties->setTextOutline(QPen(Qt::SolidLine));
2911             }
2912             ELSE_TRY_READ_IF(hlinkClick)
2913             SKIP_UNKNOWN
2914 //! @todo add ELSE_WRONG_FORMAT
2915         }
2916     }
2917 
2918     if (m_currentColor.isValid()) {
2919         m_currentTextStyle.addProperty("fo:color", m_currentColor.name());
2920         m_currentColor = QColor();
2921     }
2922 
2923     handleRprAttributes(attrs);
2924 
2925     READ_EPILOGUE
2926 }
2927 
2928 void MSOOXML_CURRENT_CLASS::handleRprAttributes(const QXmlStreamAttributes& attrs)
2929 {
2930     // DrawingML: b, i, strike, u attributes:
2931     if (attrs.hasAttribute("b")) {
2932         m_currentTextStyleProperties->setFontWeight(
2933             MSOOXML::Utils::convertBooleanAttr(attrs.value("b").toString()) ? QFont::Bold : QFont::Normal);
2934     }
2935     if (attrs.hasAttribute("i")) {
2936         m_currentTextStyleProperties->setFontItalic(
2937             MSOOXML::Utils::convertBooleanAttr(attrs.value("i").toString()));
2938     }
2939 
2940     TRY_READ_ATTR_WITHOUT_NS(cap);
2941     if (!cap.isEmpty()) {
2942         if (cap == QLatin1String("small")) {
2943             m_currentTextStyle.addProperty("fo:font-variant", "small-caps");
2944         }
2945         else if (cap == QLatin1String("all")) {
2946             m_currentTextStyle.addProperty("fo:text-transform", "uppercase");
2947         }
2948     }
2949     TRY_READ_ATTR_WITHOUT_NS(spc)
2950     if (!spc.isEmpty()) {
2951         int spcInt = spc.toInt();
2952         m_currentTextStyle.addPropertyPt("fo:letter-spacing", qreal(spcInt) / 100.0);
2953     }
2954 
2955     TRY_READ_ATTR_WITHOUT_NS(sz)
2956     if (!sz.isEmpty()) {
2957         int szInt = sz.toInt();
2958         m_currentTextStyleProperties->setFontPointSize(qreal(szInt) / 100.0);
2959     }
2960     // from 20.1.10.79 ST_TextStrikeType (Text Strike Type)
2961     TRY_READ_ATTR_WITHOUT_NS(strike)
2962     if (strike == QLatin1String("sngStrike")) {
2963         m_currentTextStyleProperties->setStrikeOutType(KoCharacterStyle::SingleLine);
2964         m_currentTextStyleProperties->setStrikeOutStyle(KoCharacterStyle::SolidLine);
2965     } else if (strike == QLatin1String("dblStrike")) {
2966         m_currentTextStyleProperties->setStrikeOutType(KoCharacterStyle::DoubleLine);
2967         m_currentTextStyleProperties->setStrikeOutStyle(KoCharacterStyle::SolidLine);
2968     } else {
2969         // empty or "noStrike"
2970     }
2971     // from
2972     TRY_READ_ATTR_WITHOUT_NS(baseline)
2973     if (!baseline.isEmpty()) {
2974         int baselineInt = baseline.toInt();
2975         if (baselineInt > 0) {
2976             m_currentTextStyleProperties->setVerticalAlignment(QTextCharFormat::AlignSuperScript);
2977         }
2978         else if (baselineInt < 0) {
2979             m_currentTextStyleProperties->setVerticalAlignment(QTextCharFormat::AlignSubScript);
2980         }
2981     }
2982 
2983     TRY_READ_ATTR_WITHOUT_NS(u)
2984     if (!u.isEmpty()) {
2985         MSOOXML::Utils::setupUnderLineStyle(u, m_currentTextStyleProperties);
2986     }
2987 }
2988 
2989 #undef CURRENT_EL
2990 #define CURRENT_EL rPr
2991 //! rPr handler (Text Run Properties) DrawingML ECMA-376, 21.1.2.3.9, p.3624.
2992 //! This element contains all run level text properties for the text runs within a containing paragraph.
2993 /*!
2994  Parent elements:
2995  - br (§21.1.2.2.1)
2996  - [done] fld (§21.1.2.2.4)
2997  - [done] r (§21.1.2.3.8)
2998 
2999  Attributes:
3000  - altLang (Alternative Language)
3001  - b (Bold)
3002  - baseline (Baseline)
3003  - bmk (Bookmark Link Target)
3004  - cap (Capitalization)
3005  - dirty (Dirty)
3006  - err (Spelling Error)
3007  - i (Italics)
3008  - kern (Kerning)
3009  - kumimoji (Kumimoji)
3010  - lang (Language ID)
3011  - noProof (No Proofing)
3012  - normalizeH (Normalize Heights)
3013  - smtClean (SmartTag Clean)
3014  - smtId (SmartTag ID)
3015  - spc (Spacing)
3016  - strike (Strikethrough)
3017  - sz (Font Size)
3018  - u (Underline)
3019 
3020  Child elements:
3021  - [done] blipFill (Picture Fill) §20.1.8.14
3022  - cs (Complex Script Font) §21.1.2.3.1
3023  - ea (East Asian Font) §21.1.2.3.3
3024  - effectDag (Effect Container) §20.1.8.25
3025  - effectLst (Effect Container) §20.1.8.26
3026  - extLst (Extension List) §20.1.2.2.15
3027  - [done] gradFill (Gradient Fill) §20.1.8.33
3028  - grpFill (Group Fill) §20.1.8.35
3029  - [done] highlight (Highlight Color) §21.1.2.3.4
3030  - [done] hlinkClick (Click Hyperlink) §21.1.2.3.5
3031  - hlinkMouseOver (Mouse-Over Hyperlink) §21.1.2.3.6
3032  - [done] latin (Latin Font) §21.1.2.3.7
3033  - [done] ln (Outline) §20.1.2.2.24
3034  - [done] noFill (No Fill) §20.1.8.44
3035  - pattFill (Pattern Fill) §20.1.8.47
3036  - rtl (Right to Left Run) §21.1.2.2.8
3037  - [done] solidFill (Solid Fill) §20.1.8.54
3038  - sym (Symbol Font) §21.1.2.3.10
3039  - uFill (Underline Fill) §21.1.2.3.12
3040  - uFillTx (Underline Fill Properties Follow Text) §21.1.2.3.13
3041  - uLn (Underline Stroke) §21.1.2.3.14
3042  - uLnTx (Underline Follows Text) §21.1.2.3.15
3043 */
3044 //! @todo support all elements
3045 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_rPr()
3046 {
3047     READ_PROLOGUE2(DrawingML_rPr)
3048 
3049     m_hyperLink = false;
3050 
3051     const QXmlStreamAttributes attrs(attributes());
3052 
3053     m_currentColor = QColor();
3054 
3055     // Read child elements
3056     while (!atEnd()) {
3057         readNext();
3058         BREAK_IF_END_OF(CURRENT_EL)
3059         if (isStartElement()) {
3060             TRY_READ_IF(latin)
3061             //ELSE_TRY_READ_IF_IN_CONTEXT(blipFill)
3062             ELSE_TRY_READ_IF(solidFill)
3063             else if (name() == "gradFill") {
3064                 TRY_READ(gradFillRpr)
3065             }
3066             else if (name() == "noFill") {
3067                 m_currentTextStyleProperties->setTextOutline(QPen(Qt::SolidLine));
3068             }
3069             else if (QUALIFIED_NAME_IS(highlight)) {
3070                 TRY_READ(DrawingML_highlight)
3071             }
3072             //ELSE_TRY_READ_IF(ln) // Disabled as this is not supported by odf
3073             ELSE_TRY_READ_IF(hlinkClick)
3074             SKIP_UNKNOWN
3075 //! @todo add ELSE_WRONG_FORMAT
3076         }
3077     }
3078 
3079     if (m_currentColor.isValid()) {
3080         m_currentTextStyle.addProperty("fo:color", m_currentColor.name());
3081         m_currentColor = QColor();
3082     }
3083 
3084     handleRprAttributes(attrs);
3085 
3086     READ_EPILOGUE
3087 }
3088 
3089 #undef CURRENT_EL
3090 #define CURRENT_EL pPr
3091 //! pPr handler (Text Paragraph Properties) 21.1.2.2.7, p.3588.
3092 /*!
3093  Parent elements:
3094   - [done] fld (§21.1.2.2.4)
3095   - [done] p (§21.1.2.2.6)
3096 
3097  Attributes:
3098   - [incomplete] algn (Alignment)
3099   - defTabSz (Default Tab Size)
3100   - eaLnBrk (East Asian Line Break)
3101   - fontAlgn (Font Alignment)
3102   - hangingPunct (Hanging Punctuation)
3103   - indent (Indent)
3104   - latinLnBrk (Latin Line Break)
3105   - [done] lvl (Level)
3106   - marL (Left Margin)
3107   - marR (Right Margin)
3108   - rtl (Right To Left)
3109 
3110  Child elements:
3111   - [done] buAutoNum (Auto-Numbered Bullet) §21.1.2.4.1
3112   - [done] buBlip (Picture Bullet) §21.1.2.4.2
3113   - [done] buChar (Character Bullet) §21.1.2.4.3
3114   - [done] buClr (Color Specified) §21.1.2.4.4
3115   - [done] buClrTx (Follow Text) §21.1.2.4.5
3116   - [done] buFont (Specified) §21.1.2.4.6
3117   - buFontTx (Follow text) §21.1.2.4.7
3118   - [done] buNone (No Bullet) §21.1.2.4.8
3119   - [done] buSzPct (Bullet Size Percentage) §21.1.2.4.9
3120   - [done] buSzPts (Bullet Size Points) §21.1.2.4.10
3121   - [done] buSzTx (Bullet Size Follows Text) §21.1.2.4.11
3122   - [done] defRPr (Default Text Run Properties) §21.1.2.3.2
3123   - extLst (Extension List) §20.1.2.2.15
3124   - [done] lnSpc (Line Spacing) §21.1.2.2.5
3125   - [done] spcAft (Space After) §21.1.2.2.9
3126   - [done] spcBef (Space Before) §21.1.2.2.10
3127   - tabLst (Tab List) §21.1.2.2.14
3128 */
3129 //! @todo support all elements
3130 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_pPr()
3131 {
3132     READ_PROLOGUE2(DrawingML_pPr)
3133     const QXmlStreamAttributes attrs(attributes());
3134 
3135     m_listStylePropertiesAltered = false;
3136 
3137     TRY_READ_ATTR_WITHOUT_NS(lvl)
3138 
3139     if (!lvl.isEmpty()) {
3140         m_currentListLevel = lvl.toInt() + 1;
3141     }
3142 
3143     m_currentBulletProperties = m_currentCombinedBulletProperties[m_currentListLevel];
3144 
3145 #ifdef PPTXXMLSLIDEREADER_CPP
3146     inheritParagraphStyle(m_currentParagraphStyle);
3147 #endif
3148 
3149     TRY_READ_ATTR_WITHOUT_NS(algn)
3150     algnToODF("fo:text-align", algn);
3151 
3152     TRY_READ_ATTR_WITHOUT_NS(marL)
3153     TRY_READ_ATTR_WITHOUT_NS(marR)
3154     TRY_READ_ATTR_WITHOUT_NS(indent)
3155     TRY_READ_ATTR_WITHOUT_NS(defTabSz)
3156 
3157     // Following settings are only applied if defined so they don't overwrite defaults
3158     // previous defined either in the slideLayout, SlideMaster or the defaultStyles.
3159     if (!marL.isEmpty()) {
3160         qreal marLeft;
3161         STRING_TO_QREAL(marL, marLeft, "attr:marL")
3162         marLeft = EMU_TO_POINT(marLeft);
3163         m_currentParagraphStyle.addPropertyPt("fo:margin-left", marLeft);
3164         m_currentBulletProperties.setMargin(marLeft);
3165         m_listStylePropertiesAltered = true;
3166     }
3167     if (!indent.isEmpty()) {
3168         qreal firstInd;
3169         STRING_TO_QREAL(indent, firstInd, "attr:indent")
3170         firstInd = EMU_TO_POINT(firstInd);
3171         m_currentParagraphStyle.addPropertyPt("fo:text-indent", firstInd);
3172         m_currentBulletProperties.setIndent(firstInd);
3173         m_listStylePropertiesAltered = true;
3174     }
3175 
3176     if (!marR.isEmpty()) {
3177         qreal marRight;
3178         STRING_TO_QREAL(marR, marRight, "attr:marR")
3179         m_currentParagraphStyle.addPropertyPt("fo:margin-right", EMU_TO_POINT(marRight));
3180     }
3181     if (!defTabSz.isEmpty()) {
3182         qreal tabSize;
3183         STRING_TO_QREAL(defTabSz, tabSize, "attr:defTabSz")
3184         m_currentParagraphStyle.addPropertyPt("style:tab-stop-distance", EMU_TO_POINT(tabSize));
3185     }
3186 
3187     m_currentTextStyleProperties = new KoCharacterStyle();
3188     m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
3189 
3190     while (!atEnd()) {
3191         readNext();
3192         BREAK_IF_END_OF(CURRENT_EL)
3193         if (isStartElement()) {
3194             TRY_READ_IF(buAutoNum)
3195             ELSE_TRY_READ_IF(defRPr)
3196             ELSE_TRY_READ_IF(buNone)
3197             ELSE_TRY_READ_IF(buChar)
3198             ELSE_TRY_READ_IF(buClrTx)
3199             ELSE_TRY_READ_IF(buClr)
3200             ELSE_TRY_READ_IF(buFont)
3201             ELSE_TRY_READ_IF(buBlip)
3202             ELSE_TRY_READ_IF(buSzPct)
3203             ELSE_TRY_READ_IF(buSzPts)
3204             else if (QUALIFIED_NAME_IS(buSzTx)) {
3205                 m_currentBulletProperties.setBulletRelativeSize(100);
3206             }
3207             else if (QUALIFIED_NAME_IS(spcBef)) {
3208                 m_currentSpacingType = spacingMarginTop;
3209                 TRY_READ(spcBef)
3210             }
3211             else if (QUALIFIED_NAME_IS(spcAft)) {
3212                 m_currentSpacingType = spacingMarginBottom;
3213                 TRY_READ(spcAft)
3214             }
3215             else if (QUALIFIED_NAME_IS(lnSpc)) {
3216                 m_currentSpacingType = spacingLines;
3217                 TRY_READ(lnSpc)
3218             }
3219             SKIP_UNKNOWN
3220         }
3221     }
3222 
3223     m_currentTextStyleProperties->saveOdf(m_currentTextStyle);
3224 
3225     delete m_currentTextStyleProperties;
3226     m_currentTextStyleProperties = 0;
3227     KoGenStyle::copyPropertiesFromStyle(m_currentTextStyle, m_currentParagraphStyle, KoGenStyle::TextType);
3228 
3229     READ_EPILOGUE
3230 }
3231 
3232 #undef CURRENT_EL
3233 #define CURRENT_EL hlinkClick
3234 //! hlinkClick handler
3235 /*!
3236  Parent elements:
3237  - cNvPr (§21.3.2.7)
3238  - cNvPr (§20.1.2.2.8)
3239  - cNvPr (§20.2.2.3)
3240  - cNvPr (§20.5.2.8)
3241  - cNvPr (§19.3.1.12)
3242  - defRPr (§21.1.2.3.2)
3243  - docPr (§20.4.2.5)
3244  - endParaRPr (§21.1.2.2.3)
3245  - [done] rPr (§21.1.2.3.9)
3246 
3247  Child elements:
3248  - extLst (§20.1.2.2.15)
3249  - snd (§20.1.2.2.32)
3250 
3251 TODO....
3252  Attributes..
3253  Children..
3254 */
3255 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_hlinkClick()
3256 {
3257     READ_PROLOGUE
3258 
3259     const QXmlStreamAttributes attrs(attributes());
3260     TRY_READ_ATTR_WITH_NS(r, id)
3261 
3262     if (!r_id.isEmpty() && m_context->relationships) {
3263         m_hyperLink = true;
3264         m_hyperLinkTarget = m_context->relationships->target(m_context->path, m_context->file, r_id);
3265         m_hyperLinkTarget.remove(0, m_context->path.length() + 1);
3266     }
3267 
3268     while (!atEnd()) {
3269         readNext();
3270         BREAK_IF_END_OF(CURRENT_EL)
3271     }
3272 
3273 #if defined(PPTXXMLSLIDEREADER_CPP)
3274     // Where there is a hyperlink, hlink value should be used by default
3275     MSOOXML::DrawingMLColorSchemeItemBase *colorItem = 0;
3276     QString valTransformed = m_context->colorMap.value("hlink");
3277     colorItem = m_context->themes->colorScheme.value(valTransformed);
3278     if (colorItem) {
3279         m_currentColor = colorItem->value();
3280     }
3281 #endif
3282 
3283     READ_EPILOGUE
3284 }
3285 
3286 #undef CURRENT_EL
3287 #define CURRENT_EL custGeom
3288 //! custGeom Handler (Custom Geometry)
3289 /*
3290  Parent elements:
3291  - [done] spPr (§21.2.2.197);
3292  - [done] spPr (§21.3.2.23);
3293  - [done] spPr (§21.4.3.7);
3294  - [done] spPr (§20.1.2.2.35);
3295  - [done] spPr (§20.2.2.6);
3296  - [done] spPr (§20.5.2.30);
3297  - [done] spPr (§19.3.1.44)
3298 
3299  Child elements:
3300  - ahLst (List of Shape Adjust Handles) §20.1.9.1
3301  - avLst (List of Shape Adjust Values) §20.1.9.5
3302  - cxnLst (List of Shape Connection Sites) §20.1.9.10
3303  - gdLst (List of Shape Guides) §20.1.9.12
3304  - pathLst (List of Shape Paths) §20.1.9.16
3305  - rect (Shape Text Rectangle) §20.1.9.22
3306 
3307 */
3308 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_custGeom()
3309 {
3310     READ_PROLOGUE
3311 
3312     ComplexShapeHandler handler;
3313     m_customEquations = handler.defaultEquations();
3314 
3315     while (!atEnd()) {
3316         readNext();
3317         BREAK_IF_END_OF(CURRENT_EL)
3318         if (isStartElement()) {
3319             if (name() == "avLst") {
3320                 m_customEquations += handler.handle_avLst(this);
3321             }
3322             else if (name() == "gdLst") {
3323                 m_customEquations += handler.handle_gdLst(this);
3324             }
3325             else if (name() == "pathLst") {
3326                 m_customPath = handler.handle_pathLst(this);
3327                 m_customEquations += handler.pathEquationsCreated();
3328             }
3329             else if (name() == "rect") {
3330                 m_textareas = handler.handle_rect(this);
3331             }
3332 
3333         }
3334     }
3335 
3336     READ_EPILOGUE
3337 }
3338 
3339 #undef CURRENT_EL
3340 #define CURRENT_EL xfrm
3341 //! xfrm  (2D Transform for Graphic Frame)
3342 //! ECMA-376, 19.3.1.53, p.2862 (PresentationML)
3343 //! ECMA-376, 20.5.2.36, p.3548 (SpreadsheetML)
3344 /*! This element specifies the transform to be applied to the
3345   corresponding graphic frame. This transformation is applied to the
3346   graphic frame just as it would be for a shape or group shape. */
3347 
3348 //! xfrm (2D Transform for Grouped Objects)
3349 //! ECMA-376, 20.1.7.5, p.3185 (DrawingML)
3350 /*! This element is nearly identical to the representation of 2-D
3351   transforms for ordinary shapes (§20.1.7.6). The only addition is a
3352   member to represent the Child offset and the Child extents. */
3353 
3354 //! xfrm (2D Transform for Individual Objects)
3355 //! ECMA-376, 20.1.7.6, p.3186 (DrawingML)
3356 /*! This element represents 2-D transforms for ordinary shapes. */
3357 /*!
3358 
3359  Parent elements:
3360  ----------------
3361  PresentationML:
3362  - [done] graphicFrame (§19.3.1.21)/(§20.5.2.16)
3363 
3364  SpreadsheetML
3365  - graphicFrame (§20.5.2.16)
3366 
3367  DrawingML:
3368  - [done] grpSpPr (§21.3.2.14)
3369  - [done] grpSpPr (§20.1.2.2.22)
3370  - [done] grpSpPr (§20.5.2.18)
3371  - [done] grpSpPr (§19.3.1.23)
3372 
3373  - graphicFrame (§20.1.2.2.18)
3374  - [done] spPr (§21.2.2.197)
3375  - [done] spPr (§21.3.2.23)
3376  - [done] spPr (§21.4.3.7)
3377  - [done] spPr (§20.1.2.2.35)
3378  - [done] spPr (§20.2.2.6)
3379  - [done] spPr (§20.5.2.30)
3380  - [done] spPr (§19.3.1.44)
3381  - [done] txSp (§20.1.2.2.41)
3382 
3383  Child elements:
3384  ---------------
3385  PresentationML/SpreadsheetML:
3386  - [done] ext (Extents) §20.1.7.3
3387  - [done] off (Offset) §20.1.7.4
3388 
3389  DrawingML:
3390  - [done] chExt (Child extends) §20.1.7.1 (grpSpPr only)
3391  - [done] chOff (Child offset) §20.1.7.2 (grpSpPr only)
3392  - [done] ext (Extents) §20.1.7.3
3393  - [done] off (Offset) §20.1.7.4
3394 
3395  Attributes:
3396  - [done] flipH (Horizontal Flip)
3397  - [done] flipV (Vertical Flip)
3398  - [done] rot (Rotation)
3399 */
3400 //! @todo support all child elements
3401 //! CASE #P476
3402 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_xfrm()
3403 {
3404     READ_PROLOGUE
3405     const QXmlStreamAttributes attrs(attributes());
3406 
3407     // Read attributes.
3408     m_flipH = MSOOXML::Utils::convertBooleanAttr(attrs.value("flipH").toString(), false);
3409     m_flipV = MSOOXML::Utils::convertBooleanAttr(attrs.value("flipV").toString(), false);
3410     m_rot = 0;
3411     TRY_READ_ATTR_WITHOUT_NS(rot)
3412     STRING_TO_INT(rot, m_rot, "xfrm@rot")
3413 
3414     while (!atEnd()) {
3415         readNext();
3416         BREAK_IF_END_OF(CURRENT_EL)
3417         if (isStartElement()) {
3418             if (QUALIFIED_NAME_IS(off)) {
3419                 TRY_READ(off);
3420             } else if (QUALIFIED_NAME_IS(ext)) {
3421                 TRY_READ(ext);
3422             }
3423             ELSE_TRY_READ_IF(chOff)
3424             ELSE_TRY_READ_IF(chExt)
3425             ELSE_WRONG_FORMAT
3426         }
3427     }
3428 
3429     READ_EPILOGUE
3430 }
3431 
3432 #undef CURRENT_EL
3433 #define CURRENT_EL off
3434 //! off handler (Offset)
3435 //! DrawingML ECMA-376, 20.1.7.4, p. 3185.
3436 /*! This element specifies the location of the bounding box of an object.
3437     Effects on an object are not included in this bounding box.
3438 
3439  Parent elements:
3440     - [done] xfrm (§21.3.2.28)
3441     - [done] xfrm (§20.1.7.5)
3442     - [done] xfrm (§20.1.7.6)
3443     - [done] xfrm (§20.5.2.36)
3444     - [done] xfrm (§19.3.1.53)
3445 
3446  No child elements.
3447 
3448  Attributes:
3449     - [done] x (X-Axis Coordinate)
3450     - [done] y (Y-Axis Coordinate)
3451 */
3452 //! @todo support all elements
3453 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_off()
3454 {
3455     READ_PROLOGUE
3456     const QXmlStreamAttributes attrs(attributes());
3457 
3458     READ_ATTR_WITHOUT_NS(x)
3459     STRING_TO_LONGLONG(x, m_svgX, "off@x")
3460     READ_ATTR_WITHOUT_NS(y)
3461     STRING_TO_LONGLONG(y, m_svgY, "off@y")
3462 
3463     if (!m_inGrpSpPr) {
3464         int index = 0;
3465         while (index < m_svgProp.size()) {
3466             //(a:off(x) - a:chOff(x))/a:chExt(x) * a(p):ext(x) + a(p):off(x)
3467             GroupProp prop = m_svgProp.at(m_svgProp.size() - 1 - index);
3468             m_svgX = (m_svgX - prop.svgXChOld) / prop.svgWidthChOld * prop.svgWidthOld + prop.svgXOld;
3469             m_svgY = (m_svgY - prop.svgYChOld) / prop.svgHeightChOld * prop.svgHeightOld + prop.svgYOld;
3470             ++index;
3471         }
3472     }
3473 
3474     readNext();
3475     READ_EPILOGUE
3476 }
3477 
3478 //! chOff handler (Child offset)
3479 //! Look parent, children
3480 #undef CURRENT_EL
3481 #define CURRENT_EL chOff
3482 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_chOff()
3483 {
3484     READ_PROLOGUE
3485     const QXmlStreamAttributes attrs(attributes());
3486 
3487     READ_ATTR_WITHOUT_NS(x)
3488     STRING_TO_INT(x, m_svgChX, "chOff@x")
3489     READ_ATTR_WITHOUT_NS(y)
3490     STRING_TO_INT(y, m_svgChY, "chOff@y")
3491 
3492     readNext();
3493     READ_EPILOGUE
3494 }
3495 
3496 #undef CURRENT_EL
3497 #define CURRENT_EL ext
3498 //! ext handler (Extents)
3499 //! DrawingML ECMA-376, 20.1.7.3, p. 3185.
3500 /*! This element specifies the size of the bounding box enclosing the referenced object.
3501  Parent elements:
3502  - [done] xfrm (§21.3.2.28)
3503  - [done] xfrm (§20.1.7.5)
3504  - [done] xfrm (§20.1.7.6)
3505  - [done] xfrm (§20.5.2.36)
3506  - [done] xfrm (§19.3.1.53)
3507  .
3508  No child elements.
3509 
3510  Attributes:
3511  - [done] cx (Extent Length) Specifies the length of the extents rectangle in EMUs. This rectangle shall dictate
3512       the size of the object as displayed (the result of any scaling to the original object).
3513  - [done] cy (Extent Width) Specifies the width of the extents rectangle in EMUs.
3514 */
3515 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_ext()
3516 {
3517     READ_PROLOGUE
3518     const QXmlStreamAttributes attrs(attributes());
3519 
3520     READ_ATTR_WITHOUT_NS(cx)
3521     STRING_TO_INT(cx, m_svgWidth, "ext@cx")
3522     READ_ATTR_WITHOUT_NS(cy)
3523     STRING_TO_INT(cy, m_svgHeight, "ext@cy")
3524 
3525     if (!m_inGrpSpPr) {
3526         int index = 0;
3527         while (index < m_svgProp.size()) {
3528             //(a:off(x) - a:chOff(x))/a:chExt(x) * a(p):ext(x) + a(p):off(x)
3529             GroupProp prop = m_svgProp.at(m_svgProp.size() - 1 - index);
3530 
3531             m_svgWidth = m_svgWidth * prop.svgWidthOld / prop.svgWidthChOld;
3532             m_svgHeight = m_svgHeight * prop.svgHeightOld / prop.svgHeightChOld;
3533             ++index;
3534         }
3535     }
3536 
3537     readNext();
3538     READ_EPILOGUE
3539 }
3540 
3541 #undef CURRENT_EL
3542 #define CURRENT_EL chExt
3543 //! chExt handler (Child extend)
3544 //! Look parent, children
3545 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_chExt()
3546 {
3547     READ_PROLOGUE
3548     const QXmlStreamAttributes attrs(attributes());
3549 
3550     READ_ATTR_WITHOUT_NS(cx)
3551     STRING_TO_INT(cx, m_svgChWidth, "chExt@cx")
3552     READ_ATTR_WITHOUT_NS(cy)
3553     STRING_TO_INT(cy, m_svgChHeight, "chExt@cy")
3554 
3555     readNext();
3556     READ_EPILOGUE
3557 }
3558 
3559 #undef CURRENT_EL
3560 #define CURRENT_EL blip
3561 //! blip handler (Blip)
3562 //! ECMA-376, 20.1.8.13, p. 3194
3563 /*! This element specifies the existence of an image (binary large image or picture)
3564     and contains a reference to the image data.
3565 
3566  Parent elements:
3567     - blipFill (§21.3.2.2) - DrawingML, p. 3919
3568     - [done] blipFill (§20.1.8.14) - DrawingML, p. 3195
3569     - blipFill (§20.2.2.1) - DrawingML, p. 3456
3570     - blipFill (§20.5.2.2) - DrawingML, p. 3518
3571     - [done] blipFill (§19.3.1.4) - PresentationML, p. 2818
3572     - [done] buBlip (§21.1.2.4.2)
3573 
3574  Child elements:
3575     - alphaBiLevel (Alpha Bi-Level Effect) §20.1.8.1
3576     - alphaCeiling (Alpha Ceiling Effect) §20.1.8.2
3577     - alphaFloor (Alpha Floor Effect) §20.1.8.3
3578     - alphaInv (Alpha Inverse Effect) §20.1.8.4
3579     - alphaMod (Alpha Modulate Effect) §20.1.8.5
3580     - alphaModFix (Alpha Modulate Fixed Effect) §20.1.8.6
3581     - alphaRepl (Alpha Replace Effect) §20.1.8.8
3582     - [done] biLevel (Bi-Level (Black/White) Effect) §20.1.8.11
3583     - blur (Blur Effect) §20.1.8.15
3584     - clrChange (Color Change Effect) §20.1.8.16
3585     - clrRepl (Solid Color Replacement) §20.1.8.18
3586     - [done] duotone (Duotone Effect) §20.1.8.23
3587     - [done] extLst (Extension List) §20.1.2.2.15
3588     - fillOverlay (Fill Overlay Effect) §20.1.8.29
3589     - [done] grayscl (Gray Scale Effect) §20.1.8.34
3590     - hsl (Hue Saturation Luminance Effect) §20.1.8.39
3591     - [done] lum (Luminance Effect) §20.1.8.42
3592     - tint (Tint Effect) §20.1.8.60
3593 
3594  Attributes:
3595     - cstate (Compression State)
3596     - [done] embed (Embedded Picture Reference), 22.8.2.1 ST_RelationshipId (Explicit Relationship ID), p. 4324
3597     - link (Linked Picture Reference)
3598 */
3599 //! @todo support all elements
3600 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_blip()
3601 {
3602     READ_PROLOGUE
3603 
3604     // Read attributes.
3605     const QXmlStreamAttributes attrs(attributes());
3606 //! @todo more attrs
3607     TRY_READ_ATTR_WITH_NS(r, embed)
3608     debugMsooXml << "embed:" << r_embed;
3609     if (!r_embed.isEmpty() && m_context->relationships) {
3610         const QString sourceName(m_context->relationships->target(m_context->path,
3611                                                                   m_context->file, r_embed));
3612         debugMsooXml << "sourceName:" << sourceName;
3613 
3614         //A test file is attached to Bug 286700.
3615         if (sourceName.endsWith(QLatin1String("NULL"))) {
3616             skipCurrentElement();
3617             READ_EPILOGUE
3618         }
3619 
3620         m_context->import->imageSize(sourceName, m_imageSize);
3621 
3622         if (sourceName.isEmpty()) {
3623             return KoFilter::FileNotFound;
3624         }
3625         QString destinationName = QLatin1String("Pictures/") + sourceName.mid(sourceName.lastIndexOf('/') + 1);
3626 
3627         RETURN_IF_ERROR( m_context->import->copyFile(sourceName, destinationName, false ) )
3628         addManifestEntryForFile(destinationName);
3629         m_recentDestName = sourceName;
3630         addManifestEntryForPicturesDir();
3631         m_xlinkHref = destinationName;
3632     }
3633 
3634     // Read child elements
3635     while (!atEnd()) {
3636         readNext();
3637         debugMsooXml << *this;
3638         BREAK_IF_END_OF(CURRENT_EL)
3639         if (isStartElement()) {
3640             TRY_READ_IF(biLevel)
3641             ELSE_TRY_READ_IF(grayscl)
3642             ELSE_TRY_READ_IF(lum)
3643             ELSE_TRY_READ_IF(duotone)
3644             SKIP_UNKNOWN
3645 //! @todo add ELSE_WRONG_FORMAT
3646         }
3647     }
3648 
3649     READ_EPILOGUE
3650 }
3651 
3652 #undef CURRENT_EL
3653 #define CURRENT_EL stretch
3654 //! stretch handler (Stretch)
3655 //! ECMA-376, 20.1.8.56, p. 3233
3656 /*! This element specifies that a BLIP should be stretched
3657  to fill the target rectangle. The other option is a tile where
3658  a BLIP is tiled to fill the available area.
3659 
3660  Parent elements:
3661     - [done]blipFill (§21.3.2.2) - DrawingML, p. 3919
3662     - [done] blipFill (§20.1.8.14) - DrawingML, p. 3195
3663     - [done] blipFill (§20.2.2.1) - DrawingML, p. 3456
3664     - [done] blipFill (§20.5.2.2) - DrawingML, p. 3518
3665     - [done] blipFill (§19.3.1.4) - PresentationML, p. 2818
3666 
3667  Child elements:
3668     - [done] fillRect (Fill Rectangle) §20.1.8.30
3669 */
3670 //! @todo support all elements
3671 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_stretch()
3672 {
3673     READ_PROLOGUE
3674 
3675     m_currentDrawStyle->addProperty("style:repeat", QLatin1String("stretch"));
3676 
3677     while (!atEnd()) {
3678         readNext();
3679         debugMsooXml << *this;
3680         BREAK_IF_END_OF(CURRENT_EL)
3681         if (isStartElement()) {
3682             TRY_READ_IF(fillRect)
3683             ELSE_WRONG_FORMAT
3684         }
3685     }
3686     READ_EPILOGUE
3687 }
3688 
3689 #undef CURRENT_EL
3690 #define CURRENT_EL biLevel
3691 //! biLevel handler (BiLevel (Black/White) Effect)
3692 /*! ECMA-376, 20.1.8.13, p. 3193
3693 
3694   This element specifies a bi-level (black/white) effect. Input colors
3695   whose luminance is less than the specified threshold value are
3696   changed to black. Input colors whose luminance are greater than or
3697   equal the specified value are set to white. The alpha effect values
3698   are unaffected by this effect.
3699 
3700  Parent elements:
3701  - [done] blip (§20.1.8.13)
3702  - cont (§20.1.8.20)
3703  - effectDag (§20.1.8.25)
3704 
3705  No child elements.
3706 
3707  Attributes
3708  - thresh (Threshold)
3709 */
3710 //! @todo support all elements
3711 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_biLevel()
3712 {
3713     READ_PROLOGUE
3714     const QXmlStreamAttributes attrs(attributes());
3715 
3716     m_currentDrawStyle->addProperty("draw:color-mode", QLatin1String("mono"));
3717 //! @todo thresh attribute (no real counterpoint in ODF)
3718 
3719     readNext();
3720     READ_EPILOGUE
3721 }
3722 
3723 #undef CURRENT_EL
3724 #define CURRENT_EL grayscl
3725 //! grayscl handler (Grayscale effect)
3726 /*! ECMA-376, 20.1.8.34, p 3217
3727 
3728   This element specifies a gray scale effect. Converts all effect
3729   color values to a shade of gray, corresponding to their
3730   luminance. Effect alpha (opacity) values are unaffected.
3731 
3732  Parent elements:
3733  - [done] blip (§20.1.8.13)
3734  - cont (§20.1.8.20)
3735  - effectDag (§20.1.8.25)
3736 
3737  No child elements.
3738 
3739  No attributes
3740 */
3741 //! @todo support all elements
3742 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_grayscl()
3743 {
3744     READ_PROLOGUE
3745 
3746     m_currentDrawStyle->addProperty("draw:color-mode", QLatin1String("greyscale"));
3747 
3748     readNext();
3749     READ_EPILOGUE
3750 }
3751 
3752 #undef CURRENT_EL
3753 #define CURRENT_EL lum
3754 //! lum handler (luminance effect)
3755 /*! ECMA-376, 20.1.8.34, p 3222
3756 
3757   This element specifies a luminance effect. Brightness linearly
3758   shifts all colors closer to white or black.  Contrast scales all
3759   colors to be either closer or further apart
3760 
3761  Parent elements:
3762  - [done] blip (§20.1.8.13)
3763  - cont (§20.1.8.20)
3764  - effectDag (§20.1.8.25)
3765 
3766  No child elements.
3767 
3768  Attributes
3769  - [done] bright (Brightness)
3770  - [done] contrast (Contrast)
3771 */
3772 //! @todo support all elements
3773 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lum()
3774 {
3775     READ_PROLOGUE
3776     const QXmlStreamAttributes attrs(attributes());
3777 
3778     TRY_READ_ATTR_WITHOUT_NS(bright)
3779     TRY_READ_ATTR_WITHOUT_NS(contrast)
3780 
3781     // Numbers are in format 70000, so we need to remove 3 zeros
3782     // Adding bright to luminance may not be correct (but better than hardcoding to watermark mode)
3783     if (!bright.isEmpty()) {
3784         m_currentDrawStyle->addProperty("draw:luminance", bright.left(bright.length()-3) + '%');
3785     }
3786 
3787     if (!contrast.isEmpty()) {
3788         m_currentDrawStyle->addProperty("draw:contrast", contrast.left(contrast.length()-3) + '%');
3789     }
3790 
3791     readNext();
3792     READ_EPILOGUE
3793 }
3794 
3795 
3796 #undef CURRENT_EL
3797 #define CURRENT_EL duotone
3798 //! duotone handler (Duotone effect)
3799 /*! ECMA-376, 20.1.8.23, p 3214
3800 
3801   This element specifies a duotone effect. For each pixel,
3802   combines clr1 and clr2 through a linear interpolation to
3803   determine the new color for that pixel.
3804 
3805   In Office, the interpolation is based on the luminance of the pixel.
3806   http://msdn.microsoft.com/en-us/library/ff534294%28v=office.12%29.aspx
3807 
3808  Parent elements:
3809  - [done] blip (§20.1.8.13)
3810  - cont (§20.1.8.20)
3811  - effectDag (§20.1.8.25)
3812 
3813  Child elements:
3814     - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
3815     - [done] prstClr (Preset Color) §20.1.2.3.22
3816     - [done] schemeClr (Scheme Color) §20.1.2.3.29
3817     - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
3818     - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
3819     - [done] sysClr (System Color) §20.1.2.3.33
3820 
3821 */
3822 //! @todo support all elements
3823 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_duotone()
3824 {
3825     READ_PROLOGUE
3826 
3827     int colorCount = 0;
3828     QColor clr1;
3829     QColor clr2;
3830 
3831     while (!atEnd()) {
3832         readNext();
3833 
3834         BREAK_IF_END_OF(CURRENT_EL)
3835         if (isStartElement()) {
3836             TRY_READ_IF(hslClr)
3837             ELSE_TRY_READ_IF(prstClr)
3838             ELSE_TRY_READ_IF(schemeClr)
3839             ELSE_TRY_READ_IF(scrgbClr)
3840             ELSE_TRY_READ_IF(srgbClr)
3841             ELSE_TRY_READ_IF(sysClr)
3842             SKIP_UNKNOWN
3843 
3844             if (colorCount == 0) {
3845                 clr1 = m_currentColor;
3846             } else {
3847                 clr2 = m_currentColor;
3848             }
3849             colorCount++;
3850         }
3851     }
3852 
3853     QImage image;
3854     m_context->import->imageFromFile(m_recentDestName, image);
3855     // don't apply duotone to unsupported picture formats in QImage like emf, wmf case
3856     if (!image.isNull()) {
3857 
3858         QColor c1 = clr1.isValid() ? clr1 : Qt::black;
3859         QColor c2 = clr2.isValid() ? clr2 : Qt::white;
3860 
3861         image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
3862         for (int y = 0; y < image.height(); y++) {
3863             QRgb *scanline = reinterpret_cast<QRgb *>(image.scanLine(y));
3864             for (int x = 0; x < image.width(); x++) {
3865                 QRgb c = scanline[x];
3866                 int luminosity = (5036060U * quint32(qRed(c)) + 9886846U * quint32(qGreen(c)) + 1920103U * quint32(qBlue(c))) >> 24;
3867                 qreal grayF = (255 - luminosity) / 255.0;
3868                 int r = grayF * c1.red()     + (1.0 - grayF) * c2.red();
3869                 int g = grayF * c1.green()   + (1.0 - grayF) * c2.green();
3870                 int b = grayF * c1.blue()    + (1.0 - grayF) * c2.blue();
3871                 scanline[x] = qRgba(r,g,b,qAlpha(c));
3872             }
3873         }
3874 
3875         QString fileName = m_recentDestName.mid(m_recentDestName.lastIndexOf('/') + 1);
3876         fileName = fileName.left(fileName.lastIndexOf('.'));
3877         QString destinationName = QLatin1String("Pictures/") + fileName + QString("_duotoned_%1_%2.png").arg(c1.name().mid(1)).arg(c2.name().mid(1));
3878 
3879         RETURN_IF_ERROR( m_context->import->createImage(image, destinationName) )
3880         addManifestEntryForFile(destinationName);
3881         m_xlinkHref = destinationName;
3882     }
3883 
3884     READ_EPILOGUE
3885 }
3886 
3887 
3888 #undef CURRENT_EL
3889 #define CURRENT_EL tile
3890 //! tile handler (Placeholder Shape)
3891 /*! ECMA-376, 19.3.1.36, p. 3234
3892  This element specifies that a BLIP should be tiled to fill the available space. This element defines a "tile"
3893  rectangle within the bounding box. The image is encompassed within the tile rectangle, and the tile rectangle
3894  is tiled across the bounding box to fill the entire area.
3895 
3896  Parent elements:
3897  - [done] blipFill (§21.3.2.2)
3898  - [done] blipFill (§20.1.8.14)
3899  - [done] blipFill (§20.2.2.1)
3900  - [done] blipFill (§20.5.2.2)
3901  - [done] blipFill (§19.3.1.4)
3902 
3903  No child elements.
3904 */
3905 //! @todo support all elements
3906 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_tile()
3907 {
3908     READ_PROLOGUE
3909     const QXmlStreamAttributes attrs(attributes());
3910     m_currentDrawStyle->addProperty("style:repeat", QLatin1String("repeat"));
3911 //! @todo algn - convert to "ODF's Fill Image Tile Reference Point"
3912     m_currentDrawStyle->addProperty("draw:fill-image-ref-point", "top-left");
3913 
3914 //! @todo flip
3915 //! @todo sx
3916 //! @todo sy
3917 //! @todo tx
3918 //! @todo ty
3919 
3920     readNext();
3921     READ_EPILOGUE
3922 }
3923 
3924 #undef CURRENT_EL
3925 #define CURRENT_EL srcRect
3926 //! srcRect handler (Source Rectangle)
3927 /*
3928  Parent elements:
3929  - [done] blipFill (§21.3.2.2);
3930  - [done] blipFill (§20.1.8.14);
3931  - [done] blipFill (§20.2.2.1);
3932  - [done] blipFill (§20.5.2.2);
3933  - [done] blipFill (§19.3.1.4)
3934 
3935  No child elements.
3936 
3937 */
3938 //! @todo support all elements
3939 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_srcRect()
3940 {
3941     READ_PROLOGUE
3942 
3943     const QXmlStreamAttributes attrs( attributes() );
3944     TRY_READ_ATTR_WITHOUT_NS(b)
3945     TRY_READ_ATTR_WITHOUT_NS(l)
3946     TRY_READ_ATTR_WITHOUT_NS(r)
3947     TRY_READ_ATTR_WITHOUT_NS(t)
3948 
3949     if (!m_recentDestName.endsWith(QLatin1String("wmf")) && !m_recentDestName.endsWith(QLatin1String("emf"))) {
3950         if (!b.isEmpty() || !l.isEmpty() || !r.isEmpty() || !t.isEmpty()) {
3951             qreal bReal = b.toDouble() / 100000;
3952             qreal tReal = t.toDouble() / 100000;
3953             qreal lReal = l.toDouble() / 100000;
3954             qreal rReal = r.toDouble() / 100000;
3955 
3956             int rectLeft = m_imageSize.rwidth() * lReal;
3957             int rectTop = m_imageSize.rheight() * tReal;
3958             int rectWidth = m_imageSize.rwidth() - m_imageSize.rwidth() * rReal - rectLeft;
3959             int rectHeight = m_imageSize.rheight() - m_imageSize.rheight() * bReal - rectTop;
3960 
3961             QString fileName = m_recentDestName.mid(m_recentDestName.lastIndexOf('/') + 1);
3962             fileName = fileName.left(fileName.lastIndexOf('.'));
3963 
3964             QString destinationName = QLatin1String("Pictures/") + fileName + QString("_cropped_%1_%2.png").arg(rectWidth).arg(rectHeight);
3965 
3966             QImage image;
3967             m_context->import->imageFromFile(m_recentDestName, image);
3968 
3969             // first copy the part we are interested in and then to the conversation what may
3970             // save us some bytes and circles when the copy is way smaller then the original
3971             // is in which case the convertToFormat is more cheap.
3972             image = image.copy(rectLeft, rectTop, rectWidth, rectHeight);
3973             image = image.convertToFormat(QImage::Format_ARGB32);
3974 
3975             RETURN_IF_ERROR( m_context->import->createImage(image, destinationName) )
3976             addManifestEntryForFile(destinationName);
3977             m_xlinkHref = destinationName;
3978         }
3979     }
3980 
3981     readNext();
3982     READ_EPILOGUE
3983 }
3984 
3985 #undef CURRENT_EL
3986 #define CURRENT_EL fillRect
3987 //! fillRect handler (Fill Rectangle)
3988 //! ECMA-376, 20.1.8.30, p. 3212
3989 /*! This element specifies a fill rectangle. When stretching of an image
3990     is specified, a source rectangle, srcRect, is scaled to fit the specified fill rectangle.
3991 
3992  Parent elements:
3993     - [done] stretch (§20.1.8.56)
3994 
3995  No child elements.
3996 
3997  Attributes:
3998     - b (Bottom Offset)
3999     - l (Left Offset)
4000     - r (Right Offset)
4001     - t (Top Offset)
4002 
4003  Complex type: CT_RelativeRect, p. 4545
4004 */
4005 //! @todo support all elements
4006 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_fillRect()
4007 {
4008     READ_PROLOGUE
4009 
4010     const QXmlStreamAttributes attrs( attributes() );
4011 //! @todo use ST_Percentage_withMsooxmlFix_to_double for attributes b, l, r, t
4012     TRY_READ_ATTR_WITHOUT_NS(b)
4013     TRY_READ_ATTR_WITHOUT_NS(l)
4014     TRY_READ_ATTR_WITHOUT_NS(r)
4015     TRY_READ_ATTR_WITHOUT_NS(t)
4016 //KOMSOOXML_EXPORT qreal ST_Percentage_withMsooxmlFix_to_double(const QString& val, bool& ok);
4017 
4018     if (!b.isEmpty() || !l.isEmpty() || !r.isEmpty() || !t.isEmpty()) {
4019         // TODO: One way to approach this would be to first scale the image to the size of the slide
4020         // then, resize it according to the percentages & make sure there are no black areas
4021     }
4022 
4023     readNext();
4024     READ_EPILOGUE
4025 }
4026 
4027 #undef CURRENT_EL
4028 #define CURRENT_EL graphic
4029 //! graphic handler (Graphic Object)
4030 /*! ECMA-376, 20.1.2.2.16, p.3037.
4031 
4032  This element specifies the existence of a single graphic object.  Document
4033  authors should refer to this element when they wish to persist a graphical
4034  object of some kind. The specification for this graphical object is provided
4035  entirely by the document author and referenced within the graphicData child
4036  element.
4037 
4038  Parent elements:
4039  - [done] anchor (§20.4.2.3)
4040  - [done] graphicFrame (§21.3.2.12)
4041  - [done] graphicFrame (§20.1.2.2.18)
4042  - [done] graphicFrame (§20.5.2.16)
4043  - [done] graphicFrame (§19.3.1.21)
4044  - [done] inline (§20.4.2.8)
4045 
4046  Child elements:
4047  - [done] graphicData (Graphic Object Data) §20.1.2.2.17
4048 */
4049 //! @todo support all elements
4050 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_graphic()
4051 {
4052     READ_PROLOGUE
4053 
4054     while (!atEnd()) {
4055         readNext();
4056         BREAK_IF_END_OF(CURRENT_EL)
4057         if (isStartElement()) {
4058             TRY_READ_IF(graphicData)
4059             ELSE_WRONG_FORMAT
4060         }
4061     }
4062     READ_EPILOGUE
4063 }
4064 
4065 #undef CURRENT_EL
4066 #define CURRENT_EL graphicData
4067 //! graphicData handler (Graphic Object Data)
4068 /*! ECMA-376, 20.1.2.2.17, p.3038.
4069 
4070  This element specifies the reference to a graphic object within the
4071  document.  This graphic object is provided entirely by the document
4072  authors who choose to persist this data within the document.
4073 
4074  Parent elements:
4075  - [done] graphic (§20.1.2.2.16)
4076 
4077  Child elements:
4078  - Any element in any namespace
4079 
4080  Attributes:
4081  - uri (Uniform Resource Identifier)
4082 */
4083 //! @todo support all elements
4084 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_graphicData()
4085 {
4086     READ_PROLOGUE
4087 
4088     // TODO: Is it possible to have a group of graphic objects in a chart?
4089     // It's possible in case of a diagram.
4090     m_context->graphicObjectIsGroup = false;
4091 
4092     while (!atEnd()) {
4093         readNext();
4094         BREAK_IF_END_OF(CURRENT_EL)
4095         if (isStartElement()) {
4096             TRY_READ_IF_NS(pic, pic)
4097             // Charting diagram
4098             ELSE_TRY_READ_IF_NS(c, chart)
4099             // DrawingML diagram
4100             ELSE_TRY_READ_IF_NS(dgm, relIds)
4101             ELSE_TRY_READ_IF_NS(lc, lockedCanvas)
4102 #ifdef PPTXXMLSLIDEREADER_CPP
4103             ELSE_TRY_READ_IF_NS(p, oleObj)
4104             ELSE_TRY_READ_IF_NS(a, tbl)
4105 #endif
4106             else if (qualifiedName() == "mc:AlternateContent") {
4107                 TRY_READ(AlternateContent)
4108             }
4109             SKIP_UNKNOWN
4110 //! @todo add ELSE_WRONG_FORMAT
4111         }
4112     }
4113     READ_EPILOGUE
4114 }
4115 
4116 #undef CURRENT_EL
4117 #define CURRENT_EL blipFill
4118 //! blipFill handler (Picture Fill)
4119 //! ECMA-376, 19.3.1.4, p.2818 (PresentationML)
4120 //! ECMA-376, 20.1.8.14, p.3195 (DrawingML)
4121 //! @todo use it in DrawingML, 20.2.2.1, p. 3456
4122 /*! This element specifies the type of picture fill that the picture
4123  object has.  Because a picture has a picture fill already by default,
4124  it is possible to have two fills specified for a picture object.
4125 
4126  BLIPs refer to Binary Large Image or Pictures. Blip Fills are made up
4127  of several components: a Blip Reference, a Source Rectangle, and a
4128  Fill Mode.  See also M.4.8.4.3 Blip Fills, ECMA-376, p. 5411.
4129 
4130  Parent elements:
4131      PresentationML:
4132      - [done] pic (§19.3.1.37)
4133 
4134      DrawingML:
4135      - bg (§21.4.3.1)
4136      - bgFillStyleLst (§20.1.4.1.7)
4137      - [done] bgPr (§19.3.1.2)
4138      - defRPr (§21.1.2.3.2)
4139      - endParaRPr (§21.1.2.2.3)
4140      - fill (§20.1.8.28)
4141      - fill (§20.1.4.2.9)
4142      - fillOverlay (§20.1.8.29)
4143      - fillStyleLst (§20.1.4.1.13)
4144      - grpSpPr (§21.3.2.14)
4145      - grpSpPr (§20.1.2.2.22)
4146      - grpSpPr (§20.5.2.18)
4147      - grpSpPr (§19.3.1.23)
4148      - [done] pic (§20.1.2.2.30)
4149      - [done] rPr (§21.1.2.3.9)
4150      - spPr (§21.2.2.197)
4151      - spPr (§21.3.2.23)
4152      - spPr (§21.4.3.7)
4153      - spPr (§20.1.2.2.35)
4154      - spPr (§20.2.2.6)
4155      - spPr (§20.5.2.30)
4156      - spPr (§19.3.1.44)
4157      - tblPr (§21.1.3.15)
4158      - tcPr (§21.1.3.17)
4159      - uFill (§21.1.2.3.12)
4160 
4161  Child elements:
4162     - [done] blip (Blip) §20.1.8.13
4163     - [done] srcRect (Source Rectangle) §20.1.8.55
4164     - [done] stretch (Stretch) §20.1.8.56
4165     - [done] tile (Tile) §20.1.8.58
4166 
4167  Attributes:
4168     - dpi (DPI Setting)
4169     - rotWithShape (Rotate With Shape)
4170 */
4171 //! @todo support all elements
4172 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_blipFill(blipFillCaller caller)
4173 {
4174     debugMsooXml << "Blip Caller:" << (char)caller;
4175     QString qn;
4176 
4177     if (m_isLockedCanvas) {
4178         READ_PROLOGUE
4179     } else {
4180         // Do not use READ_PROLOGUE because namespace depends on caller
4181         PUSH_NAME_INTERNAL
4182 
4183         QString ns;
4184         // 'p' by default; for dml in docx use 'pic'
4185 #ifdef DOCXXMLDOCREADER_CPP
4186         if (caller == blipFill_pic) {
4187             ns = QLatin1String("pic");
4188         } else {
4189             ns = QChar((char)caller);
4190         }
4191 #elif defined XLSXXMLDRAWINGREADER_CPP
4192         if (caller == blipFill_pic) {
4193             ns = QLatin1String("xdr");
4194         } else {
4195             ns = QChar((char)caller);
4196         }
4197 #else
4198         ns = QChar((char)caller);
4199 #endif
4200         qn = QString(ns + ":" STRINGIFY(CURRENT_EL));
4201         if (!expectEl(qn)) {
4202             return KoFilter::WrongFormat;
4203         }
4204     }
4205 
4206     while (!atEnd()) {
4207         readNext();
4208         debugMsooXml << *this;
4209         if (m_isLockedCanvas) {
4210             BREAK_IF_END_OF(CURRENT_EL)
4211         } else {
4212             BREAK_IF_END_OF_QSTRING(qn)
4213         }
4214         if (isStartElement()) {
4215             TRY_READ_IF(blip)
4216             ELSE_TRY_READ_IF(stretch)
4217             ELSE_TRY_READ_IF(tile)
4218             ELSE_TRY_READ_IF(srcRect)
4219             ELSE_WRONG_FORMAT
4220         }
4221     }
4222 
4223     if (m_isLockedCanvas) {
4224         READ_EPILOGUE
4225     } else {
4226         // Do not use READ_EPILOGUE because namespace depends on caller
4227         POP_NAME_INTERNAL
4228 
4229         if (!expectElEnd(qn)) {
4230             debugMsooXml << "READ_EPILOGUE:" << qn << "not found!";
4231             return KoFilter::WrongFormat;
4232         }
4233         return KoFilter::OK;
4234     }
4235 }
4236 
4237 #undef CURRENT_EL
4238 #define CURRENT_EL txSp
4239 //! txSp (Text Shape)
4240 //! ECMA-376, 20.1.2.2.41, p.3057 (DrawingML)
4241 /*! This element specifies the existence of a text shape within a
4242   parent shape. This text shape is specifically used for displaying
4243   text as it has only text related child elements.
4244 
4245   ParentElements:
4246   - [done] grpSp (§20.1.2.2.20)
4247   - [done] lockedCanvas (§20.3.2.1)
4248   - [done] sp (§20.1.2.2.33)
4249 
4250   Child Elements:
4251   - extLst (Extension List) §20.1.2.2.15
4252   - [done] txBody (Shape Text Body) §20.1.2.2.40
4253   - useSpRect (Use Shape Text Rectangle) §20.1.2.2.42
4254   - [done] xfrm (2D Transform for Individual Objects) §20.1.7.6
4255 */
4256 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_txSp()
4257 {
4258     READ_PROLOGUE
4259 
4260     while (!atEnd()) {
4261         readNext();
4262         debugMsooXml << *this;
4263         BREAK_IF_END_OF(CURRENT_EL)
4264         if (isStartElement()) {
4265 #if defined PPTXXMLSLIDEREADER_CPP
4266             TRY_READ_IF(txBody)
4267 #else
4268             if (qualifiedName() == QLatin1String(QUALIFIED_NAME(txBody))) {
4269                 TRY_READ_IN_CONTEXT(DrawingML_txBody)
4270             }
4271 #endif
4272             ELSE_TRY_READ_IF(xfrm)
4273             SKIP_UNKNOWN
4274 //! @todo add ELSE_WRONG_FORMAT
4275         }
4276     }
4277 
4278     READ_EPILOGUE
4279 }
4280 
4281 #if 0 //todo
4282 #undef CURRENT_EL
4283 #define CURRENT_EL background
4284 //! background handler (Document Background)
4285 /*! ECMA-376, 17.2.1, p. 199.
4286 */
4287 //! @todo support all elements
4288 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_background()
4289 {
4290 }
4291 #endif
4292 
4293 #include "MsooXmlDrawingMLSharedImpl.h"
4294 
4295 // ================================================================
4296 //                     Namespace in {a,wp}
4297 // ================================================================
4298 #undef MSOOXML_CURRENT_NS
4299 #ifndef NO_DRAWINGML_NS
4300 #define MSOOXML_CURRENT_NS DRAWINGML_NS
4301 #endif
4302 
4303 void MSOOXML_CURRENT_CLASS::algnToODF(const char * odfEl, const QString& ov)
4304 {
4305     if (ov.isEmpty())
4306         return;
4307 
4308     QString v;
4309     if (ov == QLatin1String("l"))
4310         v = QLatin1String("start");
4311     else if (ov == QLatin1String("r"))
4312         v = QLatin1String("end");
4313     else if (ov == QLatin1String("just"))
4314         v = QLatin1String("justify");
4315     else if (ov == QLatin1String("ctr"))
4316         v = QLatin1String("center");
4317     //@todo handle thaiDist, justLow, dist
4318     if (!v.isEmpty())
4319         m_currentParagraphStyle.addProperty(odfEl, v);
4320 }
4321 
4322 void MSOOXML_CURRENT_CLASS::distToODF(const char * odfEl, const QString& emuValue)
4323 {
4324     if (emuValue.isEmpty() || emuValue == "0") // skip 0cm which is the default
4325         return;
4326     QString s = MSOOXML::Utils::EMU_to_ODF(emuValue);
4327     if (!s.isEmpty()) {
4328         m_currentDrawStyle->addProperty(QLatin1String(odfEl), s, KoGenStyle::GraphicType);
4329     }
4330 }
4331 
4332 #undef CURRENT_EL
4333 #define CURRENT_EL lstStyle
4334 //! lstStyle handler (Text List Styles)
4335 //! ECMA-376, DrawingML 21.1.2.4.12, p. 3651.
4336 //! This element specifies the list of styles associated with this body of text.
4337 /*!
4338  Parent elements:
4339  - lnDef (§20.1.4.1.20)
4340  - rich (§21.2.2.156)
4341  - spDef (§20.1.4.1.27)
4342  - t (§21.4.3.8)
4343  - txBody (§21.3.2.26)
4344  - txBody (§20.1.2.2.40)
4345  - txBody (§20.5.2.34)
4346  - [done] txBody (§19.3.1.51)
4347  - txDef (§20.1.4.1.28)
4348  - txPr (§21.2.2.216)
4349 
4350  Child elements:
4351  - defPPr (Default Paragraph Style) §21.1.2.2.2
4352  - extLst (Extension List) §20.1.2.2.15
4353  - [done] lvl1pPr (List Level 1 Text Style) §21.1.2.4.13
4354  - [done] lvl2pPr (List Level 2 Text Style) §21.1.2.4.14
4355  - [done] lvl3pPr (List Level 3 Text Style) §21.1.2.4.15
4356  - [done] lvl4pPr (List Level 4 Text Style) §21.1.2.4.16
4357  - [done] lvl5pPr (List Level 5 Text Style) §21.1.2.4.17
4358  - [done] lvl6pPr (List Level 6 Text Style) §21.1.2.4.18
4359  - [done] lvl7pPr (List Level 7 Text Style) §21.1.2.4.19
4360  - [done] lvl8pPr (List Level 8 Text Style) §21.1.2.4.20
4361  - [done] lvl9pPr (List Level 9 Text Style) §21.1.2.4.21
4362 */
4363 //! @todo support all elements
4364 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lstStyle()
4365 {
4366     READ_PROLOGUE
4367     m_currentListStyle = KoGenStyle(KoGenStyle::ListAutoStyle);
4368 
4369     m_currentCombinedBulletProperties.clear();
4370     m_currentBulletProperties.clear();
4371     m_currentCombinedTextStyles.clear();
4372     m_currentCombinedParagraphStyles.clear();
4373 
4374 #ifdef PPTXXMLSLIDEREADER_CPP
4375     inheritListStyles();
4376     if (m_context->type == SlideMaster || m_context->type == NotesMaster || m_context->type == SlideLayout) {
4377         inheritAllTextAndParagraphStyles();
4378     }
4379 #endif
4380 
4381     while (!atEnd()) {
4382         readNext();
4383         debugMsooXml << *this;
4384         BREAK_IF_END_OF(CURRENT_EL)
4385         if (isStartElement()) {
4386             TRY_READ_IF_NS(a, lvl1pPr)
4387             ELSE_TRY_READ_IF_NS(a, lvl2pPr)
4388             ELSE_TRY_READ_IF_NS(a, lvl3pPr)
4389             ELSE_TRY_READ_IF_NS(a, lvl4pPr)
4390             ELSE_TRY_READ_IF_NS(a, lvl5pPr)
4391             ELSE_TRY_READ_IF_NS(a, lvl6pPr)
4392             ELSE_TRY_READ_IF_NS(a, lvl7pPr)
4393             ELSE_TRY_READ_IF_NS(a, lvl8pPr)
4394             ELSE_TRY_READ_IF_NS(a, lvl9pPr)
4395             SKIP_UNKNOWN
4396 //! @todo add ELSE_WRONG_FORMAT
4397         }
4398     }
4399 
4400 #ifdef PPTXXMLSLIDEREADER_CPP
4401     saveCurrentListStyles();
4402     saveCurrentStyles();
4403 #endif
4404 
4405     // Should be zero to not mess anything
4406     m_currentListLevel = 0;
4407 
4408     READ_EPILOGUE
4409 }
4410 
4411 #undef CURRENT_EL
4412 #define CURRENT_EL latin
4413 /*! latin handler (Latin Font) ECMA-376, 21.1.2.3.7, p.3621.
4414  Parent elements:
4415  - [done] defRPr (§21.1.2.3)
4416  - [done] endParaRPr (§21.1.2.2.3)
4417  - font (§20.1.4.2.13)
4418  - majorFont (§20.1.4.1.24)
4419  - minorFont (§20.1.4.1.25)
4420  - [done] rPr (§21.1.2.3.9)
4421 
4422  No child elements.
4423 
4424  Attributes:
4425  - charset (Similar Character Set)
4426  - panose (Panose Setting)
4427  - [incomplete] pitchFamily (Similar Font Family)
4428  - [done] typeface (Text Typeface)
4429 */
4430 //! @todo support all elements
4431 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_latin()
4432 {
4433     READ_PROLOGUE
4434     const QXmlStreamAttributes attrs(attributes());
4435 
4436     TRY_READ_ATTR_WITHOUT_NS(typeface)
4437 
4438 #ifdef PPTXXMLDOCUMENTREADER_CPP
4439     // TODO: Process the pitchFamili attribute.
4440     defaultLatinFonts[defaultLatinFonts.size() - 1] = typeface;
4441 
4442     // Skip reading because the theme is unknown at time of reading.
4443     skipCurrentElement();
4444     READ_EPILOGUE
4445 #endif
4446 
4447     if (!typeface.isEmpty()) {
4448         QString font = typeface;
4449         if (typeface.startsWith("+mj")) {
4450             font = m_context->themes->fontScheme.majorFonts.latinTypeface;
4451         }
4452         else if (typeface.startsWith("+mn")) {
4453             font = m_context->themes->fontScheme.minorFonts.latinTypeface;
4454         }
4455         m_currentTextStyleProperties->setFontFamily(font);
4456     }
4457 
4458     TRY_READ_ATTR_WITHOUT_NS(pitchFamily)
4459     if (!pitchFamily.isEmpty()) {
4460         int pitchFamilyInt;
4461         STRING_TO_INT(pitchFamily, pitchFamilyInt, "latin@pitchFamily")
4462         QFont::StyleHint h = QFont::AnyStyle;
4463         const int hv = pitchFamilyInt % 0x10;
4464         switch (hv) {
4465         case 1: //Roman
4466             h = QFont::Times;
4467             break;
4468         case 2: //Swiss
4469             h = QFont::SansSerif;
4470             break;
4471         case 3: //Modern
4472             h = QFont::SansSerif;
4473             //TODO:
4474             break;
4475         case 4: //Script
4476             //TODO:
4477             break;
4478         case 5: //Decorative
4479             h = QFont::Decorative;
4480             break;
4481         }
4482         const bool fixed = pitchFamilyInt & 0x01; // Fixed Pitch
4483         m_currentTextStyleProperties->setFontFixedPitch(fixed);
4484         m_currentTextStyleProperties->setFontStyleHint(h);
4485     }
4486     readNext();
4487     READ_EPILOGUE
4488 }
4489 
4490 #undef CURRENT_EL
4491 #define CURRENT_EL highlight
4492 /*! highlight handler  (Highlight Color) ECMA-376, 21.1.2.3.4, p.3616.
4493 
4494  This element specifies the highlight color that is present for a run of text.
4495 
4496  Parent elements:
4497  - [done] defRPr (§21.1.2.3.2)
4498  - [done] endParaRPr (§21.1.2.2.3)
4499  - [done] rPr (§21.1.2.3.9)
4500 
4501  Child elements:
4502  - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
4503  - [done] prstClr (Preset Color) §20.1.2.3.22
4504  - [done] schemeClr (Scheme Color) §20.1.2.3.29
4505  - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
4506  - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
4507  - [done] sysClr (System Color) §20.1.2.3.33
4508 */
4509 //! @todo support all elements
4510 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_highlight()
4511 {
4512     READ_PROLOGUE2(DrawingML_highlight)
4513 
4514     while (!atEnd()) {
4515         readNext();
4516         BREAK_IF_END_OF(CURRENT_EL)
4517         if (isStartElement()) {
4518             TRY_READ_IF(schemeClr)
4519             ELSE_TRY_READ_IF(scrgbClr)
4520             ELSE_TRY_READ_IF(srgbClr)
4521             ELSE_TRY_READ_IF(sysClr)
4522             ELSE_TRY_READ_IF(prstClr)
4523             ELSE_TRY_READ_IF(hslClr)
4524             ELSE_WRONG_FORMAT
4525         }
4526     }
4527     // note: paragraph background is unsupported in presentation applications anyway...
4528     if (m_currentColor.isValid()) {
4529         m_currentParagraphStyle.addProperty("fo:background-color", m_currentColor.name());
4530         m_currentColor = QColor();
4531     }
4532     READ_EPILOGUE
4533 }
4534 
4535 #undef CURRENT_EL
4536 #define CURRENT_EL gradFill
4537 //! Gradient Fill
4538 /*
4539  Parent Elements:
4540  - bg (§21.4.3.1);
4541  - [done] bgFillStyleLst (§20.1.4.1.7);
4542  - [done] bgPr (§19.3.1.2);
4543  - [elsewhere] defRPr (§21.1.2.3.2);
4544  - [elsewhere] endParaRPr (§21.1.2.2.3);
4545  - fill (§20.1.8.28);
4546  - fill (§20.1.4.2.9);
4547  - fillOverlay (§20.1.8.29);
4548  - [done] fillStyleLst (§20.1.4.1.13);
4549  - [done] grpSpPr (§21.3.2.14);
4550  - [done] grpSpPr (§20.1.2.2.22);
4551  - [done] grpSpPr (§20.5.2.18);
4552  - [done] grpSpPr (§19.3.1.23);
4553  - ln (§20.1.2.2.24);
4554  - lnB (§21.1.3.5);
4555  - lnBlToTr (§21.1.3.6);
4556  - lnL (§21.1.3.7);
4557  - lnR (§21.1.3.8);
4558  - lnT (§21.1.3.9);
4559  - lnTlToBr (§21.1.3.10);
4560  - [elsewhere] rPr (§21.1.2.3.9);
4561  - [done] spPr (§21.2.2.197);
4562  - [done] spPr (§21.3.2.23);
4563  - [done] spPr (§21.4.3.7);
4564  - [done] spPr (§20.1.2.2.35);
4565  - [done] spPr (§20.2.2.6);
4566  - [done] spPr (§20.5.2.30);
4567  - [done] spPr (§19.3.1.44);
4568  - tblPr (§21.1.3.15);
4569  - tcPr (§21.1.3.17);
4570  - uFill (§21.1.2.3.12);
4571  - uLn (§21.1.2.3.14)
4572 
4573  Child Elements:
4574  - [done] gsLst (Gradient Stop List) §20.1.8.37
4575  - [done] lin (Linear Gradient Fill) §20.1.8.41
4576  - path (Path Gradient) §20.1.8.46
4577  - tileRect (Tile Rectangle) §20.1.8.59
4578 
4579 */
4580 //! @todo support this properly
4581 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gradFill()
4582 {
4583     READ_PROLOGUE
4584     const QXmlStreamAttributes attrs(attributes());
4585 
4586     bool gradRotation = false;
4587 
4588     while (!atEnd()) {
4589         readNext();
4590         BREAK_IF_END_OF(CURRENT_EL)
4591         if (isStartElement()) {
4592             TRY_READ_IF(gsLst)
4593             else if (qualifiedName() == "a:lin") {
4594                 gradRotation = true;
4595                 TRY_READ(lin)
4596             }
4597             SKIP_UNKNOWN
4598         }
4599     }
4600 
4601     if (gradRotation) {
4602         qreal angle = -m_gradAngle.toDouble() / 60000.0 / 180.0 * M_PI;
4603         m_currentGradientStyle.addAttribute("svg:x1", QString("%1%").arg(50 - 50 * cos(angle)));
4604         m_currentGradientStyle.addAttribute("svg:y1", QString("%1%").arg(50 + 50 * sin(angle)));
4605         m_currentGradientStyle.addAttribute("svg:x2", QString("%1%").arg(50 + 50 * cos(angle)));
4606         m_currentGradientStyle.addAttribute("svg:y2", QString("%1%").arg(50 - 50 * sin(angle)));
4607     } else {
4608         m_currentGradientStyle.addAttribute("svg:x1", "50%");
4609         m_currentGradientStyle.addAttribute("svg:y1", "0%");
4610         m_currentGradientStyle.addAttribute("svg:x2", "50%");
4611         m_currentGradientStyle.addAttribute("svg:y2", "100%");
4612     }
4613 
4614     READ_EPILOGUE
4615 }
4616 
4617 #undef CURRENT_EL
4618 #define CURRENT_EL lin
4619 //! linear gradient fill
4620 /*
4621  Parent Elements:
4622  - [done] gradFill (§20.1.8.33)
4623 
4624  Child Elements:
4625  - none
4626 
4627 */
4628 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lin()
4629 {
4630     READ_PROLOGUE
4631     const QXmlStreamAttributes attrs(attributes());
4632 
4633     TRY_READ_ATTR_WITHOUT_NS_INTO(ang, m_gradAngle)
4634 
4635     readNext();
4636     READ_EPILOGUE
4637 }
4638 
4639 #undef CURRENT_EL
4640 #define CURRENT_EL gradFill
4641 //! Special gradFill handler for text properties
4642 // Meant to support gradFill as part of rpr as well as can be done as odf does not support
4643 // proper way
4644 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gradFillRpr()
4645 {
4646     READ_PROLOGUE2(gradFillRPr)
4647 
4648     QList<QPair<int, QColor> > gradPositions;
4649     int exactIndex = -1;
4650     int beforeIndex = -1;
4651     int afterIndex = -1;
4652 
4653     while (!atEnd()) {
4654         readNext();
4655         BREAK_IF_END_OF(CURRENT_EL)
4656         if (isStartElement()) {
4657             if (name() == "gs") {
4658                 TRY_READ(gs)
4659                 gradPositions.push_back(QPair<int, QColor>(m_gradPosition, m_currentColor));
4660                 if (m_gradPosition == 50) {
4661                     exactIndex = gradPositions.size() - 1;
4662                 } else if (m_gradPosition < 50) {
4663                     if (beforeIndex < 0) {
4664                         beforeIndex = gradPositions.size() - 1;
4665                     } else if (m_gradPosition > gradPositions.at(beforeIndex).first) {
4666                         beforeIndex = gradPositions.size() - 1;
4667                     }
4668                 } else {
4669                     if (afterIndex < 0) {
4670                         afterIndex = gradPositions.size() - 1;
4671                     } else if (m_gradPosition < gradPositions.at(afterIndex).first) {
4672                         afterIndex = gradPositions.size() - 1;
4673                     }
4674                 }
4675             }
4676         }
4677     }
4678 
4679     // The logic here is to find the color that is in the middle, or if it's not present
4680     // find the colors before and after it and calculate the middle color
4681 
4682     if (exactIndex > -1) {
4683         m_currentColor = gradPositions.at(exactIndex).second;
4684     }
4685     else {
4686         if (beforeIndex < 0) {
4687             beforeIndex = 0; // It is possible that the stops are only listed for aread 50+
4688         }
4689         if (afterIndex < 0) {
4690             afterIndex = beforeIndex; // It is possible that the stops are only listed for areas -50
4691         }
4692         int firstDistance = 50 - gradPositions.at(beforeIndex).first;
4693         int secondDistance = gradPositions.at(afterIndex).first - 50;
4694         qreal multiplier = 0;
4695         int red, green, blue;
4696 
4697         if (firstDistance <= secondDistance) {
4698             multiplier = secondDistance / firstDistance;
4699             red = multiplier * gradPositions.at(beforeIndex).second.red() + gradPositions.at(afterIndex).second.red();
4700             green = multiplier * gradPositions.at(beforeIndex).second.green() + gradPositions.at(afterIndex).second.green();
4701             blue = multiplier * gradPositions.at(beforeIndex).second.blue() + gradPositions.at(afterIndex).second.blue();
4702         } else {
4703             multiplier = firstDistance / secondDistance;
4704             red = multiplier * gradPositions.at(afterIndex).second.red() + gradPositions.at(beforeIndex).second.red();
4705             green = multiplier * gradPositions.at(afterIndex).second.green() + gradPositions.at(beforeIndex).second.green();
4706             blue = multiplier * gradPositions.at(afterIndex).second.blue() + gradPositions.at(beforeIndex).second.blue();
4707         }
4708         red = red / (multiplier + 1);
4709         green = green / (multiplier + 1);
4710         blue = blue / (multiplier + 1);
4711         m_currentColor = QColor(red, green, blue);
4712     }
4713 
4714     READ_EPILOGUE
4715 }
4716 
4717 #undef CURRENT_EL
4718 #define CURRENT_EL gsLst
4719 //! gradient stop list
4720 /*
4721  Parent Elements:
4722  - [done] gradFill (§20.1.8.33)
4723 
4724  Child Elements:
4725  - [done] gs (Gradient stops) §20.1.8.36
4726 
4727 */
4728 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gsLst()
4729 {
4730     READ_PROLOGUE
4731 
4732     int index = 0;
4733 
4734     while (!atEnd()) {
4735         readNext();
4736         BREAK_IF_END_OF(CURRENT_EL)
4737         if (isStartElement()) {
4738             if (QUALIFIED_NAME_IS(gs)) {
4739                 TRY_READ(gs)
4740                 qreal alphaLevel = 1;
4741                 if (m_currentAlpha > 0) {
4742                     alphaLevel = m_currentAlpha/100.0;
4743                 }
4744                 QString contents = QString("<svg:stop svg:offset=\"%1\" svg:stop-color=\"%2\" svg:stop-opacity=\"%3\"/>").arg(m_gradPosition/100.0).arg(m_currentColor.name()).arg(alphaLevel);
4745                 QString name = QString("%1").arg(index);
4746                 m_currentGradientStyle.addChildElement(name, contents);
4747                 ++index;
4748             }
4749             ELSE_WRONG_FORMAT
4750         }
4751     }
4752 
4753     READ_EPILOGUE
4754 }
4755 
4756 #undef CURRENT_EL
4757 #define CURRENT_EL gs
4758 //! gradient stops
4759 /*
4760  Parent Elements:
4761  - [done] gsLst (§20.1.8.37)
4762 
4763  Child Elements:
4764  - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
4765  - [done] prstClr (Preset Color) §20.1.2.3.22
4766  - [done] schemeClr (Scheme Color) §20.1.2.3.29
4767  - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
4768  - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
4769  - [done] sysClr (System Color) §20.1.2.3.33
4770 */
4771 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gs()
4772 {
4773     READ_PROLOGUE
4774     const QXmlStreamAttributes attrs(attributes());
4775     TRY_READ_ATTR_WITHOUT_NS(pos)
4776 
4777     m_gradPosition = pos.toInt() / 1000;
4778 
4779     while (!atEnd()) {
4780         readNext();
4781         BREAK_IF_END_OF(CURRENT_EL)
4782         if (isStartElement()) {
4783             TRY_READ_IF(schemeClr)
4784             ELSE_TRY_READ_IF(srgbClr)
4785             ELSE_TRY_READ_IF(sysClr)
4786             ELSE_TRY_READ_IF(scrgbClr)
4787             ELSE_TRY_READ_IF(prstClr)
4788             ELSE_TRY_READ_IF(hslClr)
4789             ELSE_WRONG_FORMAT
4790         }
4791     }
4792     READ_EPILOGUE
4793 }
4794 
4795 //noFill 20.1.8.44
4796 /*This element specifies No fill.
4797 Parents:
4798     - bg (§21.4.3.1)
4799     - bgFillStyleLst (§20.1.4.1.7)
4800     - bgPr (§19.3.1.2)
4801     - defRPr (§21.1.2.3.2)
4802     - endParaRPr (§21.1.2.2.3)
4803     - fill (§20.1.8.28)
4804     - fill (§20.1.4.2.9)
4805     - fillOverlay (§20.1.8.29)
4806     - fillStyleLst (§20.1.4.1.13)
4807     - grpSpPr (§21.3.2.14)
4808     - grpSpPr (§20.1.2.2.22)
4809     - grpSpPr (§20.5.2.18)
4810     - grpSpPr (§19.3.1.23)
4811     - ln (§20.1.2.2.24)
4812     - lnB (§21.1.3.5)
4813     - lnBlToTr(§21.1.3.6)
4814     - lnL (§21.1.3.7)
4815     - lnR (§21.1.3.8)
4816     - lnT (§21.1.3.9)
4817     - lnTlToBr (§21.1.3.10)
4818     - [done] rPr (§21.1.2.3(§21.2.2.197)
4819     - spPr (§21.3.2.23)
4820     - spPr (§21.4.3.7)
4821     - spPr (§20.1.2.2.35)
4822     - spPr (§20.2.2.6)
4823     - spPr (§20(§19.3.1.44)
4824     - tblPr (§21.1.3.15)
4825     - tcPr (§21.1.3.17)
4826     - uFill (§21.1.2.3.12)
4827     - uLn (§21.1.2.3.14)
4828 */
4829 #undef CURRENT_EL
4830 #define CURRENT_EL noFill
4831 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_noFill()
4832 {
4833     READ_PROLOGUE
4834     readNext();
4835     READ_EPILOGUE
4836 }
4837 
4838 // prstGeom (preset geometry)
4839 /*
4840  Parent elements:
4841  - [done] spPr (§21.2.2.197)
4842  - [done] spPr (§21.3.2.23)
4843  - [done] spPr (§21.4.3.7)
4844  - [done] spPr (§20.1.2.2.35)
4845  - [done] spPr (§20.2.2.6)
4846  - [done] spPr (§20.5.2.30)
4847  - [done] spPr (§19.3.1.44)
4848 
4849  Child elements:
4850  - [done] avLst (List of Shape Adjust Values) §20.1.9.5
4851 
4852 */
4853 #undef CURRENT_EL
4854 #define CURRENT_EL prstGeom
4855 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_prstGeom()
4856 {
4857     READ_PROLOGUE
4858     const QXmlStreamAttributes attrs(attributes());
4859     TRY_READ_ATTR_WITHOUT_NS(prst)
4860     m_contentType = prst;
4861 
4862     while (!atEnd()) {
4863         readNext();
4864         BREAK_IF_END_OF(CURRENT_EL)
4865         if (isStartElement()) {
4866             TRY_READ_IF(avLst)
4867             ELSE_WRONG_FORMAT
4868         }
4869     }
4870 
4871     READ_EPILOGUE
4872 }
4873 
4874 // avLst handler (List of Shape Adjust Values)
4875 /*
4876  Parent elements:
4877  - [done - special handling in customGeom] custGeom (§20.1.9.8);
4878  . [done] prstGeom (§20.1.9.18);
4879  -  prstTxWarp (§20.1.9.19)
4880 
4881  Child elements:
4882  - [done] gd (Shape Guide) §20.1.9.11
4883 
4884 */
4885 #undef CURRENT_EL
4886 #define CURRENT_EL avLst
4887 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_avLst()
4888 {
4889     READ_PROLOGUE
4890 
4891     m_contentAvLstExists = true;
4892     m_avModifiers.clear();
4893 
4894     while (!atEnd()) {
4895         readNext();
4896         BREAK_IF_END_OF(CURRENT_EL)
4897         if (isStartElement()) {
4898             TRY_READ_IF(gd)
4899             ELSE_WRONG_FORMAT
4900         }
4901     }
4902 
4903     READ_EPILOGUE
4904 }
4905 
4906 // gd handler (Shape guide)
4907 /*
4908  Parent elements:
4909  - [done] avLst (§20.1.9.5);
4910  - [done - elsewhere] gdLst (§20.1.9.12)
4911 
4912  Child elements:
4913  - none
4914 
4915 */
4916 #undef CURRENT_EL
4917 #define CURRENT_EL gd
4918 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_gd()
4919 {
4920     READ_PROLOGUE
4921 
4922     const QXmlStreamAttributes attrs(attributes());
4923     TRY_READ_ATTR_WITHOUT_NS(name)
4924     TRY_READ_ATTR_WITHOUT_NS(fmla)
4925 
4926     // In theory we should interpret all possible values here, not just "val"
4927     // in practice it does not happen
4928     if (fmla.startsWith("val ")) {
4929         fmla.remove(0, 4);
4930     }
4931 
4932     m_avModifiers[name] = fmla;
4933 
4934     readNext();
4935     READ_EPILOGUE
4936 }
4937 
4938 #undef CURRENT_EL
4939 #define CURRENT_EL effectLst
4940 //! Effect list
4941 /*
4942  Parent elements:
4943  - bg (§21.4.3.1);
4944  - [done] bgPr (§19.3.1.2);
4945  - defRPr (§21.1.2.3.2);
4946  - effect (§20.1.4.2.7);
4947  - effectStyle (§20.1.4.1.11);
4948  - endParaRPr (§21.1.2.2.3);
4949  - [done] grpSpPr (§21.3.2.14);
4950  - [done] grpSpPr (§20.1.2.2.22);
4951  - [done] grpSpPr (§20.5.2.18);
4952  - [done] grpSpPr (§19.3.1.23);
4953  - rPr (§21.1.2.3.9);
4954  - [done] spPr (§21.2.2.197);
4955  - [done] spPr (§21.3.2.23);
4956  - [done] spPr (§21.4.3.7);
4957  - [done] spPr (§20.1.2.2.35);
4958  - [done] spPr (§20.2.2.6);
4959  - [done] spPr (§20.5.2.30);
4960  - [done] spPr (§19.3.1.44);
4961  - tblPr (§21.1.3.15);
4962  - whole (§21.4.3.9)
4963 
4964  Child elements:
4965  - blur (Blur Effect) §20.1.8.15
4966  - fillOverlay (Fill Overlay Effect) §20.1.8.29
4967  - glow (Glow Effect) §20.1.8.32
4968  - innerShdw (Inner Shadow Effect) §20.1.8.40
4969  - [done] outerShdw (Outer Shadow Effect) §20.1.8.45
4970  - prstShdw (Preset Shadow) §20.1.8.49
4971  - reflection (Reflection Effect) §20.1.8.50
4972  - softEdge (Soft Edge Effect) §20.1.8.53
4973 
4974 */
4975 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_effectLst()
4976 {
4977     READ_PROLOGUE
4978 
4979     while (!atEnd()) {
4980         readNext();
4981         BREAK_IF_END_OF(CURRENT_EL)
4982         if (isStartElement()) {
4983             TRY_READ_IF(outerShdw)
4984             SKIP_UNKNOWN
4985         }
4986     }
4987 
4988     READ_EPILOGUE
4989 }
4990 
4991 #undef CURRENT_EL
4992 #define CURRENT_EL outerShdw
4993 //! Outer shadow
4994 /*
4995  Parent elements:
4996  - cont (§20.1.8.20);
4997  - effectDag (§20.1.8.25);
4998  - [done] effectLst (§20.1.8.26)
4999 
5000  Child elements:
5001  - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
5002  - [done] prstClr (Preset Color) §20.1.2.3.22
5003  - [done] schemeClr (Scheme Color) §20.1.2.3.29
5004  - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
5005  - [done] srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
5006  - [done] sysClr (System Color) §20.1.2.3.33
5007 */
5008 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_outerShdw()
5009 {
5010     READ_PROLOGUE
5011 
5012     QXmlStreamAttributes attrs(attributes());
5013 
5014     TRY_READ_ATTR_WITHOUT_NS(dir)
5015     TRY_READ_ATTR_WITHOUT_NS(dist)
5016 
5017     qreal angle = (qreal)dir.toDouble() * ((qreal)(M_PI) / (qreal)180.0)/ (qreal)60000.0;
5018     qreal xDist = EMU_TO_CM(dist.toInt() / 2) * cos(angle);
5019     qreal yDist = EMU_TO_CM(dist.toInt() / 2) * sin(angle);
5020 
5021     m_currentDrawStyle->addProperty("draw:shadow-offset-x", QString("%1cm").arg(xDist, 3, 'f'));
5022     m_currentDrawStyle->addProperty("draw:shadow-offset-y", QString("%1cm").arg(yDist, 3, 'f'));
5023 
5024     while (!atEnd()) {
5025         readNext();
5026         BREAK_IF_END_OF(CURRENT_EL)
5027         if (isStartElement()) {
5028             TRY_READ_IF(srgbClr)
5029             ELSE_TRY_READ_IF(schemeClr)
5030             ELSE_TRY_READ_IF(scrgbClr)
5031             ELSE_TRY_READ_IF(sysClr)
5032             ELSE_TRY_READ_IF(prstClr)
5033             ELSE_TRY_READ_IF(hslClr)
5034             ELSE_WRONG_FORMAT
5035         }
5036     }
5037 
5038     if (m_currentColor != QColor()) {
5039         m_currentDrawStyle->addProperty("draw:shadow", "visible");
5040         m_currentDrawStyle->addProperty("draw:shadow-color", m_currentColor.name());
5041         m_currentColor = QColor();
5042         if (m_currentAlpha > 0) {
5043             m_currentDrawStyle->addProperty("draw:shadow-opacity", QString("%1%").arg(m_currentAlpha));
5044         }
5045     }
5046 
5047     READ_EPILOGUE
5048 }
5049 
5050 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::lvlHelper(const QString& level) {
5051 
5052     const QXmlStreamAttributes attrs(attributes());
5053 
5054     Q_ASSERT(m_currentTextStyleProperties == 0);
5055     m_currentTextStyleProperties = new KoCharacterStyle();
5056 
5057     // Number 3 makes eg. lvl4 -> 4
5058     m_currentListLevel = QString(level.at(3)).toInt();
5059 
5060     m_currentBulletProperties = m_currentCombinedBulletProperties[m_currentListLevel];
5061     Q_ASSERT(m_currentListLevel > 0);
5062     m_currentBulletProperties.m_level = m_currentListLevel;
5063 
5064     TRY_READ_ATTR_WITHOUT_NS(marL)
5065     TRY_READ_ATTR_WITHOUT_NS(marR)
5066     TRY_READ_ATTR_WITHOUT_NS(indent)
5067     TRY_READ_ATTR_WITHOUT_NS(defTabSz)
5068 
5069     m_currentParagraphStyle = KoGenStyle(KoGenStyle::ParagraphAutoStyle, "paragraph");
5070     m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
5071 
5072 #ifdef PPTXXMLSLIDEREADER_CPP
5073     inheritTextStyle(m_currentTextStyle);
5074 #endif
5075 
5076     // Following settings are only applied if defined so they don't overwrite
5077     // defaults defined in {slideLayout, slideMaster, defaultStyles}.
5078     if (!marL.isEmpty()) {
5079         qreal marLeft;
5080         STRING_TO_QREAL(marL, marLeft, "attr:marL")
5081         marLeft = EMU_TO_POINT(marLeft);
5082         m_currentParagraphStyle.addPropertyPt("fo:margin-left", marLeft);
5083         m_currentBulletProperties.setMargin(marLeft);
5084     }
5085     if (!indent.isEmpty()) {
5086         qreal firstInd;
5087         STRING_TO_QREAL(indent, firstInd, "attr:indent")
5088         firstInd = EMU_TO_POINT(firstInd);
5089         m_currentParagraphStyle.addPropertyPt("fo:text-indent", firstInd);
5090         m_currentBulletProperties.setIndent(firstInd);
5091     }
5092     if (!marR.isEmpty()) {
5093         qreal marRight;
5094         STRING_TO_QREAL(marR, marRight, "attr:marR")
5095         m_currentParagraphStyle.addPropertyPt("fo:margin-right", EMU_TO_POINT(marRight));
5096     }
5097     if (!defTabSz.isEmpty()) {
5098         qreal tabSize;
5099         STRING_TO_QREAL(defTabSz, tabSize, "attr:defTabSz")
5100         m_currentParagraphStyle.addPropertyPt("style:tab-stop-distance", EMU_TO_POINT(tabSize));
5101     }
5102 
5103     TRY_READ_ATTR_WITHOUT_NS(algn)
5104     algnToODF("fo:text-align", algn);
5105 
5106     while (!atEnd()) {
5107         readNext();
5108         debugMsooXml << *this;
5109         if (isEndElement() && qualifiedName() == QString("a:%1").arg(level)) {
5110             break;
5111         }
5112         if (isStartElement()) {
5113             TRY_READ_IF(defRPr) // fills m_currentTextStyleProperties
5114             ELSE_TRY_READ_IF(buNone)
5115             ELSE_TRY_READ_IF(buAutoNum)
5116             ELSE_TRY_READ_IF(buChar)
5117             ELSE_TRY_READ_IF(buFont)
5118             ELSE_TRY_READ_IF(buBlip)
5119             ELSE_TRY_READ_IF(buClr)
5120             ELSE_TRY_READ_IF(buClrTx)
5121             ELSE_TRY_READ_IF(buSzPct)
5122             ELSE_TRY_READ_IF(buSzPts)
5123             else if (QUALIFIED_NAME_IS(buSzTx)) {
5124                 m_currentBulletProperties.setBulletRelativeSize(100);
5125             }
5126             else if (QUALIFIED_NAME_IS(spcBef)) {
5127                 m_currentSpacingType = spacingMarginTop;
5128                 TRY_READ(spcBef)
5129             }
5130             else if (QUALIFIED_NAME_IS(spcAft)) {
5131                 m_currentSpacingType = spacingMarginBottom;
5132                 TRY_READ(spcAft)
5133             }
5134             else if (QUALIFIED_NAME_IS(lnSpc)) {
5135                 m_currentSpacingType = spacingLines;
5136                 TRY_READ(lnSpc)
5137             }
5138             SKIP_UNKNOWN
5139         }
5140     }
5141 
5142     m_currentTextStyleProperties->saveOdf(m_currentTextStyle);
5143 
5144     m_currentCombinedParagraphStyles[m_currentListLevel] = m_currentParagraphStyle;
5145     m_currentCombinedTextStyles[m_currentListLevel] = m_currentTextStyle;
5146     m_currentCombinedBulletProperties[m_currentListLevel] = m_currentBulletProperties;
5147 
5148     delete m_currentTextStyleProperties;
5149     m_currentTextStyleProperties = 0;
5150 
5151     return KoFilter::OK;
5152 }
5153 
5154 #undef CURRENT_EL
5155 #define CURRENT_EL lvl1pPr
5156 //! List level 1 text style
5157 /*!
5158 
5159  Parent elements:
5160   - [done] bodyStyle (§19.3.1.5)
5161   - defaultTextStyle (§19.2.1.8)
5162   - [done] lstStyle (§21.1.2.4.12)
5163   - notesStyle (§19.3.1.28)
5164   - [done] otherStyle (§19.3.1.35)
5165   - [done] titleStyle (§19.3.1.49)
5166 
5167  Child elements:
5168   - [done] buAutoNum (Auto-Numbered Bullet)     §21.1.2.4.1
5169   - [done] buBlip (Picture Bullet)              §21.1.2.4.2
5170   - [done] buChar (Character Bullet)            §21.1.2.4.3
5171   - [done] buClr (Color Specified)              §21.1.2.4.4
5172   - [done] buClrTx (Follow Text)                §21.1.2.4.5
5173   - [done] buFont (Specified)                   §21.1.2.4.6
5174   - buFontTx (Follow text)               §21.1.2.4.7
5175   - [done] buNone (No Bullet)                   §21.1.2.4.8
5176   - [done] buSzPct (Bullet Size Percentage)     §21.1.2.4.9
5177   - [done] buSzPts (Bullet Size Points)         §21.1.2.4.10
5178   - [done] buSzTx (Bullet Size Follows Text)    §21.1.2.4.11
5179   - [done] defRPr (Default Text Run Properties) §21.1.2.3.2
5180   - extLst (Extension List)              §20.1.2.2.15
5181   - [done] lnSpc (Line Spacing)                 §21.1.2.2.5
5182   - [done] spcAft (Space After)                 §21.1.2.2.9
5183   - [done] spcBef (Space Before)                §21.1.2.2.10
5184   - tabLst (Tab List)                    §21.1.2.2.14
5185 
5186 */
5187 //! @todo support all child elements
5188 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl1pPr()
5189 {
5190     READ_PROLOGUE
5191     lvlHelper("lvl1pPr");
5192     READ_EPILOGUE
5193 }
5194 
5195 #undef CURRENT_EL
5196 #define CURRENT_EL lvl2pPr
5197 //! Look for lvl1pPr documentation
5198 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl2pPr()
5199 {
5200     READ_PROLOGUE
5201     lvlHelper("lvl2pPr");
5202     READ_EPILOGUE
5203 }
5204 
5205 #undef CURRENT_EL
5206 #define CURRENT_EL lvl3pPr
5207 //! Look for lvl1pPr documentation
5208 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl3pPr()
5209 {
5210     READ_PROLOGUE
5211     lvlHelper("lvl3pPr");
5212     READ_EPILOGUE
5213 }
5214 
5215 #undef CURRENT_EL
5216 #define CURRENT_EL lvl4pPr
5217 //! Look for lvl1pPr documentation
5218 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl4pPr()
5219 {
5220     READ_PROLOGUE
5221     lvlHelper("lvl4pPr");
5222     READ_EPILOGUE
5223 }
5224 
5225 #undef CURRENT_EL
5226 #define CURRENT_EL lvl5pPr
5227 //! Look for lvl1pPr documentation
5228 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl5pPr()
5229 {
5230     READ_PROLOGUE
5231     lvlHelper("lvl5pPr");
5232     READ_EPILOGUE
5233 }
5234 
5235 #undef CURRENT_EL
5236 #define CURRENT_EL lvl6pPr
5237 //! Look for lvl1pPr documentation
5238 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl6pPr()
5239 {
5240     READ_PROLOGUE
5241     lvlHelper("lvl6pPr");
5242     READ_EPILOGUE
5243 }
5244 
5245 #undef CURRENT_EL
5246 #define CURRENT_EL lvl7pPr
5247 //! Look for lvl1pPr documentation
5248 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl7pPr()
5249 {
5250     READ_PROLOGUE
5251     lvlHelper("lvl7pPr");
5252     READ_EPILOGUE
5253 }
5254 
5255 #undef CURRENT_EL
5256 #define CURRENT_EL lvl8pPr
5257 //! Look for lvl1pPr documentation
5258 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl8pPr()
5259 {
5260     READ_PROLOGUE
5261     lvlHelper("lvl8pPr");
5262     READ_EPILOGUE
5263 }
5264 
5265 #undef CURRENT_EL
5266 #define CURRENT_EL lvl9pPr
5267 //! Look for lvl1pPr documentation
5268 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lvl9pPr()
5269 {
5270     READ_PROLOGUE
5271     lvlHelper("lvl9pPr");
5272     READ_EPILOGUE
5273 }
5274 
5275 #undef CURRENT_EL
5276 #define CURRENT_EL buBlip
5277 //! buBlip - bullet picture
5278 /*!
5279  Parent elements:
5280  - defPPr (§21.1.2.2.2)
5281  - [done] lvl1pPr (§21.1.2.4.13)
5282  - [done] lvl2pPr (§21.1.2.4.14)
5283  - [done] lvl3pPr (§21.1.2.4.15)
5284  - [done] lvl4pPr (§21.1.2.4.16)
5285  - [done] lvl5pPr (§21.1.2.4.17)
5286  - [done] lvl6pPr (§21.1.2.4.18)
5287  - [done] lvl7pPr (§21.1.2.4.19)
5288  - [done] lvl8pPr (§21.1.2.4.20)
5289  - [done] lvl9pPr (§21.1.2.4.21)
5290  - [done] pPr (§21.1.2.2.7)
5291 
5292  Child elements:
5293  - [done] blip
5294 */
5295 //! @todo support all attributes
5296 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buBlip()
5297 {
5298     READ_PROLOGUE
5299     const QXmlStreamAttributes attrs(attributes());
5300 
5301     m_xlinkHref.clear();
5302 
5303     while (!atEnd()) {
5304         readNext();
5305         BREAK_IF_END_OF(CURRENT_EL)
5306         if (isStartElement()) {
5307             TRY_READ_IF(blip)
5308             ELSE_WRONG_FORMAT
5309         }
5310     }
5311 
5312     if (!m_xlinkHref.isEmpty()) {
5313         m_currentBulletProperties.setPicturePath(m_xlinkHref);
5314         m_listStylePropertiesAltered = true;
5315     }
5316 
5317     m_xlinkHref.clear();
5318 
5319     READ_EPILOGUE
5320 }
5321 
5322 #undef CURRENT_EL
5323 #define CURRENT_EL buChar
5324 //! buChar - bullet character
5325 /*!
5326  Parent elements:
5327  - defPPr (§21.1.2.2.2)
5328  - [done] lvl1pPr (§21.1.2.4.13)
5329  - [done] lvl2pPr (§21.1.2.4.14)
5330  - [done] lvl3pPr (§21.1.2.4.15)
5331  - [done] lvl4pPr (§21.1.2.4.16)
5332  - [done] lvl5pPr (§21.1.2.4.17)
5333  - [done] lvl6pPr (§21.1.2.4.18)
5334  - [done] lvl7pPr (§21.1.2.4.19)
5335  - [done] lvl8pPr (§21.1.2.4.20)
5336  - [done] lvl9pPr (§21.1.2.4.21)
5337  - [done] pPr (§21.1.2.2.7)
5338 */
5339 //! @todo support all attributes
5340 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buChar()
5341 {
5342     READ_PROLOGUE
5343     const QXmlStreamAttributes attrs(attributes());
5344 
5345     if (attrs.hasAttribute("char")) {
5346         m_currentBulletProperties.setBulletChar(attrs.value("char").toString());
5347         // if such a char is defined then we have actually a list-item even if OOXML doesn't handle them as such
5348     }
5349 
5350     m_listStylePropertiesAltered = true;
5351 
5352     readNext();
5353     READ_EPILOGUE
5354 }
5355 
5356 #undef CURRENT_EL
5357 #define CURRENT_EL buClr
5358 //! buClr - bullet color
5359 /*!
5360  Parent elements:
5361  - defPPr  (§21.1.2.2.2)
5362  - [done] lvl1pPr (§21.1.2.4.13)
5363  - [done] lvl2pPr (§21.1.2.4.14)
5364  - [done] lvl3pPr (§21.1.2.4.15)
5365  - [done] lvl4pPr (§21.1.2.4.16)
5366  - [done] lvl5pPr (§21.1.2.4.17)
5367  - [done] lvl6pPr (§21.1.2.4.18)
5368  - [done] lvl7pPr (§21.1.2.4.19)
5369  - [done] lvl8pPr (§21.1.2.4.20)
5370  - [done] lvl9pPr (§21.1.2.4.21)
5371  - [done] pPr (§21.1.2.2.7)
5372 
5373  Child elements:
5374  - [done] hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
5375  - [done] prstClr (Preset Color) §20.1.2.3.22
5376  - [done]schemeClr (Scheme Color) §20.1.2.3.29
5377  - [done] scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
5378  - [done]srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
5379  - [done] sysClr (System Color) §20.1.2.3.33
5380 */
5381 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buClr()
5382 {
5383     READ_PROLOGUE
5384 
5385 #ifdef PPTXXMLDOCUMENTREADER_CPP
5386     m_colorState = PptxXmlDocumentReader::buClrState;
5387 #endif
5388 
5389     while (!atEnd()) {
5390         readNext();
5391         BREAK_IF_END_OF(CURRENT_EL)
5392         if (isStartElement()) {
5393             TRY_READ_IF(srgbClr)
5394             ELSE_TRY_READ_IF(schemeClr)
5395             ELSE_TRY_READ_IF(scrgbClr)
5396             ELSE_TRY_READ_IF(sysClr)
5397             ELSE_TRY_READ_IF(prstClr)
5398             ELSE_TRY_READ_IF(hslClr)
5399             ELSE_WRONG_FORMAT
5400         }
5401     }
5402     if (m_currentColor.isValid()) {
5403     m_currentBulletProperties.setBulletColor(m_currentColor.name());
5404         m_currentColor = QColor();
5405         m_listStylePropertiesAltered = true;
5406     }
5407 
5408     READ_EPILOGUE
5409 }
5410 
5411 #undef CURRENT_EL
5412 #define CURRENT_EL buClrTx
5413 //! buClrTx - follow text
5414 /*!
5415  Parent elements:
5416  - defPPr  (§21.1.2.2.2)
5417  - [done] lvl1pPr (§21.1.2.4.13)
5418  - [done] lvl2pPr (§21.1.2.4.14)
5419  - [done] lvl3pPr (§21.1.2.4.15)
5420  - [done] lvl4pPr (§21.1.2.4.16)
5421  - [done] lvl5pPr (§21.1.2.4.17)
5422  - [done] lvl6pPr (§21.1.2.4.18)
5423  - [done] lvl7pPr (§21.1.2.4.19)
5424  - [done] lvl8pPr (§21.1.2.4.20)
5425  - [done] lvl9pPr (§21.1.2.4.21)
5426  - [done] pPr (§21.1.2.2.7)
5427 
5428  Child elements:
5429  - none
5430 */
5431 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buClrTx()
5432 {
5433     READ_PROLOGUE
5434     m_currentBulletProperties.setBulletColor("UNUSED");
5435     readNext();
5436     READ_EPILOGUE
5437 }
5438 
5439 #undef CURRENT_EL
5440 #define CURRENT_EL buSzPct
5441 //! buSzPct (Bullet Size Percentage) ECMA-376, 21.1.2.4.9, p.3638
5442 /*!
5443  Parent elements:
5444  - defPPr  (§21.1.2.2.2)
5445  - [done] lvl1pPr (§21.1.2.4.13)
5446  - [done] lvl2pPr (§21.1.2.4.14)
5447  - [done] lvl3pPr (§21.1.2.4.15)
5448  - [done] lvl4pPr (§21.1.2.4.16)
5449  - [done] lvl5pPr (§21.1.2.4.17)
5450  - [done] lvl6pPr (§21.1.2.4.18)
5451  - [done] lvl7pPr (§21.1.2.4.19)
5452  - [done] lvl8pPr (§21.1.2.4.20)
5453  - [done] lvl9pPr (§21.1.2.4.21)
5454  - [done] pPr (§21.1.2.2.7)
5455 
5456  Child elements:
5457  - none
5458 */
5459 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buSzPct()
5460 {
5461     READ_PROLOGUE
5462     const QXmlStreamAttributes attrs(attributes());
5463     TRY_READ_ATTR_WITHOUT_NS(val)
5464 
5465     if (!val.isEmpty()) {
5466         m_currentBulletProperties.setBulletRelativeSize(val.toInt()/1000);
5467     }
5468 
5469     readNext();
5470     READ_EPILOGUE
5471 }
5472 
5473 #undef CURRENT_EL
5474 #define CURRENT_EL buSzPts
5475 //! buSzPts (Bullet Size Points) ECMA-376, 21.1.2.4.10, p.3639
5476 /*!
5477  Parent elements:
5478  - defPPr  (§21.1.2.2.2)
5479  - [done] lvl1pPr (§21.1.2.4.13)
5480  - [done] lvl2pPr (§21.1.2.4.14)
5481  - [done] lvl3pPr (§21.1.2.4.15)
5482  - [done] lvl4pPr (§21.1.2.4.16)
5483  - [done] lvl5pPr (§21.1.2.4.17)
5484  - [done] lvl6pPr (§21.1.2.4.18)
5485  - [done] lvl7pPr (§21.1.2.4.19)
5486  - [done] lvl8pPr (§21.1.2.4.20)
5487  - [done] lvl9pPr (§21.1.2.4.21)
5488  - [done] pPr (§21.1.2.2.7)
5489 
5490  Child elements:
5491  - none
5492 */
5493 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buSzPts()
5494 {
5495     READ_PROLOGUE
5496     const QXmlStreamAttributes attrs(attributes());
5497     TRY_READ_ATTR_WITHOUT_NS(val)
5498 
5499     if (!val.isEmpty()) {
5500         m_currentBulletProperties.setBulletSizePt(val.toInt()/1000);
5501     }
5502 
5503     readNext();
5504     READ_EPILOGUE
5505 }
5506 
5507 #undef CURRENT_EL
5508 #define CURRENT_EL buFont
5509 //! buFont - bullet font
5510 /*!
5511  Parent elements:
5512  - defPPr (§21.1.2.2.2)
5513  - [done] lvl1pPr (§21.1.2.4.13)
5514  - [done] lvl2pPr (§21.1.2.4.14)
5515  - [done] lvl3pPr (§21.1.2.4.15)
5516  - [done] lvl4pPr (§21.1.2.4.16)
5517  - [done] lvl5pPr (§21.1.2.4.17)
5518  - [done] lvl6pPr (§21.1.2.4.18)
5519  - [done] lvl7pPr (§21.1.2.4.19)
5520  - [done] lvl8pPr (§21.1.2.4.20)
5521  - [done] lvl9pPr (§21.1.2.4.21)
5522  - [done] pPr (§21.1.2.2.7)
5523 */
5524 //! @todo support all attributes
5525 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buFont()
5526 {
5527     READ_PROLOGUE
5528     const QXmlStreamAttributes attrs(attributes());
5529 
5530     TRY_READ_ATTR_WITHOUT_NS(typeface)
5531 
5532     if (!typeface.isEmpty()) {
5533         m_currentBulletProperties.setBulletFont(attrs.value("typeface").toString());
5534     }
5535 
5536     readNext();
5537     READ_EPILOGUE
5538 }
5539 
5540 #undef CURRENT_EL
5541 #define CURRENT_EL buNone
5542 //! buNone - No bullets
5543 /*!
5544  Parent elements:
5545  - defPPr (§21.1.2.2.2)
5546  - [done] lvl1pPr (§21.1.2.4.13)
5547  - [done] lvl2pPr (§21.1.2.4.14)
5548  - [done] lvl3pPr (§21.1.2.4.15)
5549  - [done] lvl4pPr (§21.1.2.4.16)
5550  - [done] lvl5pPr (§21.1.2.4.17)
5551  - [done] lvl6pPr (§21.1.2.4.18)
5552  - [done] lvl7pPr (§21.1.2.4.19)
5553  - [done] lvl8pPr (§21.1.2.4.20)
5554  - [done] lvl9pPr (§21.1.2.4.21)
5555  - [done] pPr (§21.1.2.2.7)
5556 */
5557 //! @todo support all attributes
5558 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buNone()
5559 {
5560     READ_PROLOGUE
5561     m_currentBulletProperties.setBulletChar("");
5562     m_listStylePropertiesAltered = true;
5563     readNext();
5564     READ_EPILOGUE
5565 }
5566 
5567 #undef CURRENT_EL
5568 #define CURRENT_EL buAutoNum
5569 //! buAutoNum - Bullet Auto Numbering
5570 /*!
5571  Parent elements:
5572  - defPPr (§21.1.2.2.2)
5573  - [done] lvl1pPr (§21.1.2.4.13)
5574  - [done] lvl2pPr (§21.1.2.4.14)
5575  - [done] lvl3pPr (§21.1.2.4.15)
5576  - [done] lvl4pPr (§21.1.2.4.16)
5577  - [done] lvl5pPr (§21.1.2.4.17)
5578  - [done] lvl6pPr (§21.1.2.4.18)
5579  - [done] lvl7pPr (§21.1.2.4.19)
5580  - [done] lvl8pPr (§21.1.2.4.20)
5581  - [done] lvl9pPr (§21.1.2.4.21)
5582  - [done] pPr (§21.1.2.2.7)
5583 */
5584 //! @todo support all attributes
5585 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buAutoNum()
5586 {
5587     READ_PROLOGUE
5588     const QXmlStreamAttributes attrs(attributes());
5589 
5590     TRY_READ_ATTR_WITHOUT_NS(type)
5591 
5592     if (!type.isEmpty()) {
5593         if (type == "alphaLcParenBoth") {
5594             m_currentBulletProperties.setPrefix("(");
5595             m_currentBulletProperties.setSuffix(")");
5596             m_currentBulletProperties.setNumFormat("a");
5597         }
5598         else if (type == "alphaLcParenR") {
5599             m_currentBulletProperties.setSuffix(")");
5600             m_currentBulletProperties.setNumFormat("a");
5601         }
5602         else if (type == "alphaLcPeriod") {
5603             m_currentBulletProperties.setSuffix(".");
5604             m_currentBulletProperties.setNumFormat("a");
5605         }
5606         else if (type == "alphaUcParenBoth") {
5607             m_currentBulletProperties.setPrefix("(");
5608             m_currentBulletProperties.setSuffix(")");
5609             m_currentBulletProperties.setNumFormat("A");
5610         }
5611         else if (type == "alphaUcParenR") {
5612             m_currentBulletProperties.setSuffix(")");
5613             m_currentBulletProperties.setNumFormat("A");
5614         }
5615         else if (type == "alphaUcPeriod") {
5616             m_currentBulletProperties.setSuffix(".");
5617             m_currentBulletProperties.setNumFormat("A");
5618         }
5619         else if (type == "arabicParenBoth") {
5620             m_currentBulletProperties.setPrefix("(");
5621             m_currentBulletProperties.setSuffix(")");
5622             m_currentBulletProperties.setNumFormat("1");
5623         }
5624         else if (type == "arabicParenR") {
5625             m_currentBulletProperties.setSuffix(")");
5626             m_currentBulletProperties.setNumFormat("1");
5627         }
5628         else if (type == "arabicPeriod") {
5629             m_currentBulletProperties.setSuffix(".");
5630             m_currentBulletProperties.setNumFormat("1");
5631         }
5632         else if (type == "arabicPlain") {
5633             m_currentBulletProperties.setNumFormat("1");
5634         }
5635         else if (type == "romanLcParenBoth") {
5636             m_currentBulletProperties.setPrefix("(");
5637             m_currentBulletProperties.setSuffix(")");
5638             m_currentBulletProperties.setNumFormat("i");
5639         }
5640         else if (type == "romanLcParenR") {
5641             m_currentBulletProperties.setSuffix(")");
5642             m_currentBulletProperties.setNumFormat("i");
5643         }
5644         else if (type == "romanLcPeriod") {
5645             m_currentBulletProperties.setSuffix(".");
5646             m_currentBulletProperties.setNumFormat("i");
5647         }
5648         else if (type == "romanUcParenBoth") {
5649             m_currentBulletProperties.setPrefix("(");
5650             m_currentBulletProperties.setSuffix(")");
5651             m_currentBulletProperties.setNumFormat("I");
5652         }
5653         else if (type == "romanUcParenR") {
5654             m_currentBulletProperties.setSuffix(")");
5655             m_currentBulletProperties.setNumFormat("I");
5656         }
5657         else if (type == "romanUcPeriod") {
5658             m_currentBulletProperties.setSuffix(".");
5659             m_currentBulletProperties.setNumFormat("I");
5660         } else {
5661             m_currentBulletProperties.setSuffix(".");
5662             m_currentBulletProperties.setNumFormat("i");
5663         }
5664     }
5665 
5666     TRY_READ_ATTR_WITHOUT_NS(startAt)
5667     if (!startAt.isEmpty()) {
5668         m_currentBulletProperties.setStartValue(startAt);
5669     }
5670 
5671     m_listStylePropertiesAltered = true;
5672     readNext();
5673 
5674     READ_EPILOGUE
5675 }
5676 
5677 #undef CURRENT_EL
5678 #define CURRENT_EL fld
5679 //! fld - Text Field
5680 /*!
5681  Parent elements:
5682  - [done] p (§21.1.2.2.6)
5683 
5684  Child elements:
5685 
5686  - [done] pPr (Text Paragraph Properties) §21.1.2.2.7
5687  - [done] rPr (Text Run Properties) §21.1.2.3.9
5688  - [done] t (Text String) §21.1.2.3.11
5689 
5690 */
5691 //! @todo support all attributes
5692 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_fld()
5693 {
5694     READ_PROLOGUE
5695 
5696     const QXmlStreamAttributes attrs(attributes());
5697 
5698     TRY_READ_ATTR_WITHOUT_NS(type)
5699 
5700     MSOOXML::Utils::XmlWriteBuffer fldBuf;
5701     body = fldBuf.setWriter(body);
5702 
5703     QString textStyleName;
5704 
5705     while (!atEnd()) {
5706         readNext();
5707         BREAK_IF_END_OF(CURRENT_EL)
5708         if (isStartElement()) {
5709             if (QUALIFIED_NAME_IS(rPr)) {
5710                 m_currentTextStyleProperties = new KoCharacterStyle();
5711                 m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
5712 
5713 #ifdef PPTXXMLSLIDEREADER_CPP
5714                 if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
5715                     m_currentTextStyle.setAutoStyleInStylesDotXml(true);
5716                 }
5717 #elif defined DOCXXMLDOCREADER_CPP
5718                 if (m_moveToStylesXml) {
5719                     m_currentTextStyle.setAutoStyleInStylesDotXml(true);
5720                 }
5721 #endif
5722 #ifdef PPTXXMLSLIDEREADER_CPP
5723                 inheritTextStyle(m_currentTextStyle);
5724 #endif
5725                 KoGenStyle::copyPropertiesFromStyle(m_referredFont, m_currentTextStyle, KoGenStyle::TextType);
5726 
5727                 TRY_READ(DrawingML_rPr)
5728 
5729                 m_currentTextStyleProperties->saveOdf(m_currentTextStyle);
5730                 textStyleName = mainStyles->insert(m_currentTextStyle);
5731 
5732                 delete m_currentTextStyleProperties;
5733                 m_currentTextStyleProperties = 0;
5734             }
5735             else if (QUALIFIED_NAME_IS(pPr)) {
5736                 TRY_READ(DrawingML_pPr)
5737             }
5738             ELSE_TRY_READ_IF(t)
5739             ELSE_WRONG_FORMAT
5740         }
5741     }
5742 
5743     QString fontSize = m_currentTextStyle.property("fo:font-size");
5744 #ifdef PPTXXMLSLIDEREADER_CPP
5745     if (fontSize.isEmpty()) {
5746         m_currentTextStyle.addPropertyPt("fo:font-size", TEXT_FONTSIZE_DEFAULT);
5747         fontSize = QString("%1").arg(TEXT_FONTSIZE_DEFAULT);
5748     }
5749 #endif
5750     if (!fontSize.isEmpty()) {
5751         fontSize.remove("pt");
5752         qreal realSize = fontSize.toDouble();
5753         if (realSize > m_maxParaFontPt) {
5754             m_maxParaFontPt = realSize;
5755         }
5756         if (realSize < m_minParaFontPt) {
5757             m_minParaFontPt = realSize;
5758         }
5759     }
5760 
5761     body = fldBuf.originalWriter();
5762 
5763 //! @todo support all possible fields here
5764 
5765     body->startElement("text:span", false);
5766     body->addAttribute("text:style-name", textStyleName);
5767 
5768     if (type == "slidenum") {
5769         body->startElement("text:page-number");
5770         body->addAttribute("text:select-page", "current");
5771     } else {
5772         body->startElement("text:date");
5773     }
5774 
5775     (void)fldBuf.releaseWriter();
5776 
5777     body->endElement(); //text:page-number, some date format
5778     body->endElement(); //text:span
5779 
5780     READ_EPILOGUE
5781 }
5782 
5783 #undef CURRENT_EL
5784 #define CURRENT_EL spcBef
5785 //! spcBef - spacing before
5786 /*!
5787  Parent elements:
5788 
5789  - defPPr (§21.1.2.2.2)
5790  - [done] lvl1pPr (§21.1.2.4.13)
5791  - [done] lvl2pPr (§21.1.2.4.14)
5792  - [done] lvl3pPr (§21.1.2.4.15)
5793  - [done] lvl4pPr (§21.1.2.4.16)
5794  - [done] lvl5pPr (§21.1.2.4.17)
5795  - [done] lvl6pPr (§21.1.2.4.18)
5796  - [done] lvl7pPr (§21.1.2.4.19)
5797  - [done] lvl8pPr (§21.1.2.4.20)
5798  - [done] lvl9pPr (§21.1.2.4.21)
5799  - [done] pPr (§21.1.2.2.7)
5800 
5801  Child elements:
5802 
5803  - [done] spcPct (Spacing Percent) §21.1.2.2.11
5804  - [done] spcPts (Spacing Points)  §21.1.2.2.12
5805 
5806 */
5807 //! @todo support all attributes
5808 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_spcBef()
5809 {
5810     READ_PROLOGUE
5811 
5812     while (!atEnd()) {
5813         readNext();
5814         BREAK_IF_END_OF(CURRENT_EL)
5815         if (isStartElement()) {
5816             TRY_READ_IF(spcPts)
5817             ELSE_TRY_READ_IF(spcPct)
5818             ELSE_WRONG_FORMAT
5819         }
5820     }
5821     READ_EPILOGUE
5822 }
5823 
5824 #undef CURRENT_EL
5825 #define CURRENT_EL spcAft
5826 //! spcAft - spacing after
5827 /*!
5828  Parent elements:
5829 
5830  - defPPr (§21.1.2.2.2)
5831  - [done] lvl1pPr (§21.1.2.4.13)
5832  - [done] lvl2pPr (§21.1.2.4.14)
5833  - [done] lvl3pPr (§21.1.2.4.15)
5834  - [done] lvl4pPr (§21.1.2.4.16)
5835  - [done] lvl5pPr (§21.1.2.4.17)
5836  - [done] lvl6pPr (§21.1.2.4.18)
5837  - [done] lvl7pPr (§21.1.2.4.19)
5838  - [done] lvl8pPr (§21.1.2.4.20)
5839  - [done] lvl9pPr (§21.1.2.4.21)
5840  - [done] pPr (§21.1.2.2.7)
5841 
5842  Child elements:
5843 
5844  - [done] spcPct (Spacing Percent) §21.1.2.2.11
5845  - [done] spcPts (Spacing Points)  §21.1.2.2.12
5846 
5847 */
5848 //! @todo support all attributes
5849 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_spcAft()
5850 {
5851     READ_PROLOGUE
5852 
5853     while (!atEnd()) {
5854         readNext();
5855         BREAK_IF_END_OF(CURRENT_EL)
5856         if (isStartElement()) {
5857             TRY_READ_IF(spcPts)
5858             ELSE_TRY_READ_IF(spcPct)
5859             ELSE_WRONG_FORMAT
5860         }
5861     }
5862     READ_EPILOGUE
5863 }
5864 
5865 #undef CURRENT_EL
5866 #define CURRENT_EL lnSpc
5867 //! lnSpc - line spacing
5868 /*!
5869  Parent elements:
5870 
5871  - defPPr (§21.1.2.2.2)
5872  - [done] lvl1pPr (§21.1.2.4.13)
5873  - [done] lvl2pPr (§21.1.2.4.14)
5874  - [done] lvl3pPr (§21.1.2.4.15)
5875  - [done] lvl4pPr (§21.1.2.4.16)
5876  - [done] lvl5pPr (§21.1.2.4.17)
5877  - [done] lvl6pPr (§21.1.2.4.18)
5878  - [done] lvl7pPr (§21.1.2.4.19)
5879  - [done] lvl8pPr (§21.1.2.4.20)
5880  - [done] lvl9pPr (§21.1.2.4.21)
5881  - [done] pPr (§21.1.2.2.7)
5882 
5883  Child elements:
5884 
5885  - [done] spcPct (Spacing Percent) §21.1.2.2.11
5886  - [done] spcPts (Spacing Points)  §21.1.2.2.12
5887 
5888 */
5889 //! @todo support all attributes
5890 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lnSpc()
5891 {
5892     READ_PROLOGUE
5893     while (!atEnd()) {
5894         readNext();
5895         BREAK_IF_END_OF(CURRENT_EL)
5896         if (isStartElement()) {
5897             TRY_READ_IF(spcPct)
5898             ELSE_TRY_READ_IF(spcPts)
5899         }
5900     }
5901     READ_EPILOGUE
5902 }
5903 
5904 #undef CURRENT_EL
5905 #define CURRENT_EL spcPts
5906 //! spcPts (Spacing Points), ECMA-376, DrawingML 21.1.2.2.12, p.3600
5907 /*!
5908  Parent elements:
5909  - [done] lnSpc (§21.1.2.2.5)
5910  - [done] spcAft (§21.1.2.2.9)
5911  - [done] spcBef (§21.1.2.2.10)
5912 */
5913 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_spcPts()
5914 {
5915     READ_PROLOGUE
5916 
5917     const QXmlStreamAttributes attrs(attributes());
5918 
5919     TRY_READ_ATTR_WITHOUT_NS(val)
5920 
5921     int margin = 0;
5922     STRING_TO_INT(val, margin, "attr:val")
5923 
5924     switch (m_currentSpacingType) {
5925     case (spacingMarginTop):
5926         m_currentParagraphStyle.addPropertyPt("fo:margin-top", margin/100.0);
5927         break;
5928     case (spacingMarginBottom):
5929         m_currentParagraphStyle.addPropertyPt("fo:margin-bottom", margin/100.0);
5930         break;
5931     case (spacingLines):
5932         m_currentParagraphStyle.addPropertyPt("fo:line-height", margin/100.0);
5933         break;
5934     }
5935 
5936     readNext();
5937     READ_EPILOGUE
5938 }
5939 
5940 #undef CURRENT_EL
5941 #define CURRENT_EL spcPct
5942 //! spcPct (Spacing Percent), ECMA-376, DrawingML 21.1.2.2.11, p.3599
5943 /*!
5944  Parent elements:
5945  - [done] lnSpc (§21.1.2.2.5)
5946  - [done] spcAft (§21.1.2.2.9)
5947  - [done] spcBef (§21.1.2.2.10)
5948 */
5949 //! @todo support all attributes
5950 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_spcPct()
5951 {
5952     READ_PROLOGUE
5953 
5954     const QXmlStreamAttributes attrs(attributes());
5955 
5956     TRY_READ_ATTR_WITHOUT_NS(val)
5957 
5958     int lineSpace = 0;
5959     STRING_TO_INT(val, lineSpace, "attr:val")
5960 
5961     QString space = "%1";
5962     space = space.arg(lineSpace/1000.0);
5963     space.append('%');
5964 
5965     switch (m_currentSpacingType) {
5966     case (spacingMarginTop):
5967         m_currentParagraphStyle.addProperty("fo:margin-top", space);
5968         break;
5969     case (spacingMarginBottom):
5970         m_currentParagraphStyle.addProperty("fo:margin-bottom", space);
5971         break;
5972     case (spacingLines):
5973         m_currentParagraphStyle.addProperty("fo:line-height", space);
5974         break;
5975     }
5976 
5977     readNext();
5978     READ_EPILOGUE
5979 }
5980 
5981 #undef CURRENT_EL
5982 #define CURRENT_EL defRPr
5983 //! defRPr - Default Text Run Properties
5984 /*! ECMA-376, 21.1.2.3.2, p.3597
5985 
5986  Parent elements:
5987      - defPPr (§21.1.2.2.2)
5988      - [done] lvl1pPr (§21.1.2.4.13)
5989      - [done] lvl2pPr (§21.1.2.4.14)
5990      - [done] lvl3pPr (§21.1.2.4.15)
5991      - [done] lvl4pPr (§21.1.2.4.16)
5992      - [done] lvl5pPr (§21.1.2.4.17)
5993      - [done] lvl6pPr (§21.1.2.4.18)
5994      - [done] lvl7pPr (§21.1.2.4.19)
5995      - [done] lvl8pPr (§21.1.2.4.20)
5996      - [done] lvl9pPr (§21.1.2.4.21)
5997      - pPr (§21.1.2.2.7)
5998 
5999  Child elements:
6000      - blipFill (Picture Fill)                         §20.1.8.14
6001      - cs (Complex Script Font)                        §21.1.2.3.1
6002      - ea (East Asian Font)                            §21.1.2.3.3
6003      - effectDag (Effect Container)                    §20.1.8.25
6004      - effectLst (Effect Container)                    §20.1.8.26
6005      - extLst (Extension List)                         §20.1.2.2.15
6006      - [done] gradFill (Gradient Fill)                 §20.1.8.33
6007      - grpFill (Group Fill)                            §20.1.8.35
6008      - highlight (Highlight Color)                     §21.1.2.3.4
6009      - hlinkClick (Click Hyperlink)                    §21.1.2.3.5
6010      - hlinkMouseOver (Mouse-Over Hyperlink)           §21.1.2.3.6
6011      - [done] latin (Latin Font)                       §21.1.2.3.7
6012      - ln (Outline)                                    §20.1.2.2.24
6013      - [done] noFill (No Fill)                         §20.1.8.44
6014      - pattFill (Pattern Fill)                         §20.1.8.47
6015      - rtl (Right to Left Run)                         §21.1.2.2.8
6016      - [done] solidFill (Solid Fill)                   §20.1.8.54
6017      - sym (Symbol Font)                               §21.1.2.3.10
6018      - uFill (Underline Fill)                          §21.1.2.3.12
6019      - uFillTx (Underline Fill Properties Follow Text) §21.1.2.3.13
6020      - uLn (Underline Stroke)                          §21.1.2.3.14
6021      - uLnTx (Underline Follows Text)                  §21.1.2.3.15
6022 */
6023 //! @todo support all child elements
6024 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_defRPr()
6025 {
6026     READ_PROLOGUE
6027     const QXmlStreamAttributes attrs(attributes());
6028 
6029     m_currentColor = QColor();
6030 
6031 #ifdef PPTXXMLDOCUMENTREADER_CPP
6032     m_colorState = PptxXmlDocumentReader::defRPrState;
6033 #endif
6034 
6035     while (!atEnd()) {
6036         readNext();
6037         debugMsooXml << *this;
6038         BREAK_IF_END_OF(CURRENT_EL)
6039         if (isStartElement()) {
6040             TRY_READ_IF(solidFill)
6041             else if (name() == "gradFill") {
6042                 TRY_READ(gradFillRpr)
6043             }
6044             else if (name() == "noFill") {
6045                 m_currentTextStyleProperties->setTextOutline(QPen(Qt::SolidLine));
6046             }
6047             ELSE_TRY_READ_IF(latin)
6048             SKIP_UNKNOWN
6049 //! @todo add ELSE_WRONG_FORMAT
6050         }
6051     }
6052 
6053     if (m_currentColor.isValid()) {
6054         m_currentTextStyle.addProperty("fo:color", m_currentColor.name());
6055         m_currentColor = QColor();
6056     }
6057 
6058     handleRprAttributes(attrs);
6059 
6060     READ_EPILOGUE
6061 }
6062 
6063 #undef CURRENT_EL
6064 #define CURRENT_EL bodyPr
6065 //! bodyPr handler (Body Properties)
6066 /*! ECMA-376, 21.1.2.1.1, p.3556 - DrawingML
6067 
6068  This element defines the body properties for the text body within a
6069  shape.
6070 
6071  Parent elements:
6072  - lnDef (§20.1.4.1.20)
6073  - rich (§21.2.2.156)
6074  - spDef (§20.1.4.1.27)
6075  - t (§21.4.3.8)
6076  - txBody (§21.3.2.26)
6077  - txBody(§20.1.2.2.40)
6078  - txBody (§20.5.2.34)
6079  - [done] txBody (§19.3.1.51)
6080  - txDef (§20.1.4.1.28)
6081  - txPr (§21.2.2.216)
6082 
6083  Child elements:
6084  - extLst (Extension List) §20.1.2.2.15
6085  - flatTx (No text in 3D scene) §20.1.5.8
6086  - noAutofit (No AutoFit) §21.1.2.1.2
6087  - [done] normAutofit (Normal AutoFit) §21.1.2.1.3
6088  - [done] prstTxWarp (Preset Text Warp) §20.1.9.19
6089  - scene3d (3D Scene Properties) §20.1.4.1.26
6090  - sp3d (Apply 3D shape properties) §20.1.5.12
6091  - [done] spAutoFit (Shape AutoFit) §21.1.2.1.4
6092 
6093 */
6094 //! @todo support all attributes
6095 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_bodyPr()
6096 {
6097     READ_PROLOGUE
6098 
6099     const QXmlStreamAttributes attrs(attributes());
6100 
6101     TRY_READ_ATTR_WITHOUT_NS(anchor)
6102     TRY_READ_ATTR_WITHOUT_NS(lIns)
6103     TRY_READ_ATTR_WITHOUT_NS(rIns)
6104     TRY_READ_ATTR_WITHOUT_NS(bIns)
6105     TRY_READ_ATTR_WITHOUT_NS(tIns)
6106     TRY_READ_ATTR_WITHOUT_NS(vert)
6107     TRY_READ_ATTR_WITHOUT_NS(wrap)
6108 
6109     //TODO:
6110     /* TRY_READ_ATTR_WITHOUT_NS(fontAlgn) */
6111 
6112     //TODO:
6113     /* if (!vert.isEmpty()) { */
6114     /*     if (vert == "vert270") { */
6115     /*     } */
6116     /* } */
6117 
6118     m_shapeTextPosition.clear();
6119     m_shapeTextTopOff.clear();
6120     m_shapeTextBottomOff.clear();
6121     m_shapeTextLeftOff.clear();
6122     m_shapeTextRightOff.clear();
6123 
6124     if (!lIns.isEmpty()) {
6125         m_shapeTextLeftOff = lIns;
6126     }
6127     if (!rIns.isEmpty()) {
6128         m_shapeTextRightOff = rIns;
6129     }
6130     if (!tIns.isEmpty()) {
6131         m_shapeTextTopOff = tIns;
6132     }
6133     if (!bIns.isEmpty()) {
6134         m_shapeTextBottomOff = bIns;
6135     }
6136 
6137     if (!anchor.isEmpty()) {
6138         if (anchor == "t") {
6139             m_shapeTextPosition = "top";
6140         }
6141         else if (anchor == "b") {
6142             m_shapeTextPosition = "bottom";
6143         }
6144         else if (anchor == "ctr") {
6145             m_shapeTextPosition = "middle";
6146         }
6147         else if (anchor == "just") {
6148             m_shapeTextPosition = "justify";
6149         }
6150     }
6151 
6152 //! @todo more attributes
6153 
6154     m_normAutofit =  MSOOXML::Utils::autoFitUnUsed;
6155 
6156     bool spAutoFit = false;
6157     while (!atEnd()) {
6158         readNext();
6159         BREAK_IF_END_OF(CURRENT_EL)
6160         if (isStartElement()) {
6161             if (qualifiedName() == QLatin1String("a:spAutoFit")) {
6162                 TRY_READ(spAutoFit)
6163                 spAutoFit = true;
6164                 m_normAutofit = MSOOXML::Utils::autoFitOn;
6165             }
6166             else if (qualifiedName() == QLatin1String("a:normAutofit")) {
6167                 TRY_READ(normAutofit)
6168                 m_normAutofit = MSOOXML::Utils::autoFitOn;
6169             }
6170             else if (qualifiedName() == QLatin1String("a:prstTxWarp")) {
6171                 // This element describes text transformation, todo:
6172             }
6173             SKIP_UNKNOWN
6174         }
6175     }
6176 
6177 #ifdef PPTXXMLSLIDEREADER_CPP
6178     saveBodyProperties();
6179 
6180     const KoGenStyle::PropertyType gt = KoGenStyle::GraphicType;
6181 
6182     m_currentPresentationStyle.addProperty("draw:auto-grow-height",
6183             spAutoFit ? MsooXmlReader::constTrue : MsooXmlReader::constFalse, gt);
6184 
6185     // If the wrap attribute is omitted, then a value of square is implied.
6186     if (!spAutoFit || (wrap == QLatin1String("square") || wrap.isEmpty())) {
6187     m_currentPresentationStyle.addProperty("draw:auto-grow-width", MsooXmlReader::constFalse, gt);
6188     } else {
6189     m_currentPresentationStyle.addProperty("draw:auto-grow-width", MsooXmlReader::constTrue, gt);
6190     }
6191     // text in shape
6192     if (wrap == QLatin1String("none")) {
6193     m_currentPresentationStyle.addProperty("fo:wrap-option", "no-wrap", gt);
6194     } else {
6195     m_currentPresentationStyle.addProperty("fo:wrap-option", "wrap", gt);
6196     }
6197 #else
6198     Q_UNUSED(spAutoFit);
6199 #endif
6200     READ_EPILOGUE
6201 }
6202 
6203 #undef CURRENT_EL
6204 #define CURRENT_EL normAutofit
6205 //! Normal autofit handler (Normal AutoFit)
6206 /*! ECMA-376, 21.1.2.1.3, p.3555 - DrawingML
6207 
6208  Parent elements:
6209  - [done] bodyPr (§21.1.2.1.1)
6210 
6211  No child elements.
6212 */
6213 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_normAutofit()
6214 {
6215     READ_PROLOGUE
6216     readNext();
6217     READ_EPILOGUE
6218 }
6219 
6220 #undef CURRENT_EL
6221 #define CURRENT_EL spAutoFit
6222 //! spAutoFit handler (Shape AutoFit)
6223 /*! ECMA-376, 21.1.2.1.4, p.3567 - DrawingML
6224 
6225  This element specifies that a shape should be auto-fit to fully contain the text described within it.
6226  Auto-fitting is when text within a shape is scaled in order to contain all the text inside.
6227  If this element is omitted, then noAutofit or auto-fit off is implied.
6228 
6229  Parent elements:
6230  - [done] bodyPr (§21.1.2.1.1)
6231 
6232  No child elements.
6233 */
6234 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_spAutoFit()
6235 {
6236     READ_PROLOGUE
6237     readNext();
6238     READ_EPILOGUE
6239 }
6240 
6241 // ================================================================
6242 //                     Namespace in {a,xdr}
6243 // ================================================================
6244 #undef MSOOXML_CURRENT_NS
6245 #ifdef DRAWINGML_TXBODY_NS
6246 #define MSOOXML_CURRENT_NS DRAWINGML_TXBODY_NS
6247 #else
6248 #define MSOOXML_CURRENT_NS DRAWINGML_NS
6249 #endif
6250 
6251 #undef CURRENT_EL
6252 #define CURRENT_EL txBody
6253 //! txBody handler (Shape Text Body)
6254 //! ECMA-376, 20.1.2.2.40, p. 3058
6255 /* This element specifies the existence of text to be contained within
6256    the corresponding shape.  All visible text and visible text related
6257    properties are contained within this element.
6258 
6259    Parent Elements:
6260    ----------------
6261    PresentationML/SpreadsheetML:
6262    - [done] sp (§19.3.1.43)/(§20.5.2.29)
6263 
6264    DrawingML:
6265    - [done] tc (§21.1.3.16)
6266    - [done] txSp (§20.1.2.2.41)
6267 
6268    Child Elements:
6269    - [done] bodyPr (Body Properties) §21.1.2.1.1
6270    - [done] lstStyle (Text List Styles) §21.1.2.4.12
6271    - [done] p (Text Paragraphs) §21.1.2.2.6
6272 
6273    TODO: There's a separate implementation in the PPTX filter which
6274    should be merge with this one.
6275 
6276 */
6277 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_txBody(txBodyCaller caller)
6278 {
6279     READ_PROLOGUE2(DrawingML_txBody)
6280 
6281     m_prevListLevel = 0;
6282     m_currentListLevel = 0;
6283     m_pPr_lvl = 0;
6284     m_continueListNumbering.clear();
6285     m_prevListStyleName.clear();
6286 
6287     bool textBoxCreated = false;
6288     if (caller != DrawingML_txBody_tc) {
6289         if (!isCustomShape()) {
6290             body->startElement("draw:text-box");
6291             textBoxCreated = true;
6292         }
6293     }
6294 
6295     while (!atEnd()) {
6296         readNext();
6297         debugMsooXml << *this;
6298         BREAK_IF_END_OF(CURRENT_EL)
6299         if (isStartElement()) {
6300             TRY_READ_IF_NS(a, bodyPr)
6301             ELSE_TRY_READ_IF_NS(a, lstStyle)
6302             else if (qualifiedName() == QLatin1String("a:p")) {
6303                 TRY_READ(DrawingML_p)
6304             }
6305             SKIP_UNKNOWN
6306         }
6307     }
6308     if (m_prevListLevel > 0) {
6309         // Ending our current level
6310         body->endElement(); // text:list
6311         // Ending any additional levels needed
6312         for(; m_prevListLevel > 1; --m_prevListLevel) {
6313             body->endElement(); // text:list-item
6314             body->endElement(); // text:list
6315         }
6316         m_prevListLevel = 0;
6317     }
6318 
6319     if (textBoxCreated) {
6320         body->endElement(); //draw:text-box
6321     }
6322 
6323     READ_EPILOGUE
6324 }
6325 
6326 #endif