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