1 /*
2 * This file is part of Office 2007 Filters for Calligra
3 *
4 * Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
5 * Contact: Suresh Chande suresh.chande@nokia.com
6 *
7 * Copyright (C) 2011-2012 Matus Uzak (matus.uzak@gmail.com).
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * version 2.1 as published by the Free Software Foundation.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25 #ifndef MSOOXMLCOMMONREADERDRAWINGML_IMPL_H
26 #define MSOOXMLCOMMONREADERDRAWINGML_IMPL_H
27
28 #include <QTime>
29 #include <math.h>
30
31 #ifndef M_PI
32 #define M_PI 3.1415926535897932384626
33 #endif
34
35 //ECMA-376, 20.1.10.68, p.3431 - ST_TextFontSize (Text Font Size)
36 #define TEXT_FONTSIZE_MIN 1
37 #define TEXT_FONTSIZE_MAX 4000
38 #define TEXT_FONTSIZE_DEFAULT 18
39
40 #if !defined DRAWINGML_NS && !defined NO_DRAWINGML_NS
41 #error missing DRAWINGML_NS define!
42 #endif
43 #if !defined DRAWINGML_PIC_NS && !defined NO_DRAWINGML_PIC_NS
44 #error missing DRAWINGML_PIC_NS define!
45 #endif
46
47 // ================================================================
48 // Namespace in {a,pic,p,xdr}
49 // ================================================================
50 #undef MSOOXML_CURRENT_NS
51 #ifndef NO_DRAWINGML_PIC_NS
52 #define MSOOXML_CURRENT_NS DRAWINGML_PIC_NS
53 #endif
54
55 #include <KoXmlWriter.h>
56 #include <MsooXmlUnits.h>
57 #include "Charting.h"
58 #include "XlsxChartOdfWriter.h"
59 #include "XlsxXmlChartReader.h"
60 #include "ComplexShapeHandler.h"
61
62 #include <MsooXmlReader.h>
63 #include <MsooXmlCommonReader.h>
64 #include <MsooXmlDiagramReader.h>
65 #include <QScopedPointer>
66
67 // ================================================================
68
69
initDrawingML()70 void MSOOXML_CURRENT_CLASS::initDrawingML()
71 {
72 m_currentDoubleValue = 0;
73 m_hyperLink = false;
74 m_listStylePropertiesAltered = false;
75 m_inGrpSpPr = false;
76 m_insideTable = false;
77 m_isLockedCanvas = false;
78 qsrand(QTime::currentTime().msec());
79 }
80
isCustomShape()81 bool MSOOXML_CURRENT_CLASS::isCustomShape()
82 {
83 if (m_contentType.isEmpty()) {
84 return false;
85 }
86 if (m_contentType == "rect") {
87 return false;
88 }
89 if (unsupportedPredefinedShape()) {
90 return false;
91 }
92 return true;
93 }
94
unsupportedPredefinedShape()95 bool MSOOXML_CURRENT_CLASS::unsupportedPredefinedShape()
96 {
97 // TODO: Some conditions are not supported with custom shapes
98 // properly yet, remove them when possible.
99
100 // Custom geometry has its own handling
101 if (m_contentType == "custom") {
102 return false;
103 }
104
105 // Lines and connectors are handled elsewhere
106 if (m_contentType == "line" || m_contentType == "arc" || m_contentType.contains("Connector")) {
107 return false;
108 }
109
110 // These shapes are not properly supported atm. some have bugs in
111 // predefinedShapes.xml, some might have xml_parser/calligra bugs.
112 if (m_contentType == "circularArrow" || m_contentType == "curvedDownArrow" ||
113 m_contentType == "curvedLeftArrow" || m_contentType == "curvedUpArrow" ||
114 m_contentType == "curvedRightArrow" || m_contentType == "gear6" ||
115 m_contentType == "gear9") {
116 return true;
117 }
118 return false;
119 }
120
121 /* bodyPr (Body Properties) defaults
122 * ECMA-376, 21.1.2.1.1, p.3556 - DrawingML
123 */
inheritDefaultBodyProperties()124 void MSOOXML_CURRENT_CLASS::inheritDefaultBodyProperties()
125 {
126 if (m_shapeTextPosition.isEmpty()) {
127 m_shapeTextPosition = "top";
128 }
129 if (m_shapeTextTopOff.isEmpty()) {
130 m_shapeTextTopOff = "45720";
131 }
132 if (m_shapeTextLeftOff.isEmpty()) {
133 m_shapeTextLeftOff = "91440";
134 }
135 if (m_shapeTextRightOff.isEmpty()) {
136 m_shapeTextRightOff = "91440";
137 }
138 if (m_shapeTextBottomOff.isEmpty()) {
139 m_shapeTextBottomOff = "45720";
140 }
141 }
142
143 // ----------------------------------------------------------------
144
145 // ================================================================
146 // DrawingML tags
147 // ================================================================
148
149 // Don't show this warning: it occurs because gcc gets confused, but
150 // it _is_ used.
151 #ifdef __GNUC__
152 #pragma GCC diagnostic ignored "-Wunused-function"
153 #endif
154
mirrorToOdf(bool flipH,bool flipV)155 static QString mirrorToOdf(bool flipH, bool flipV)
156 {
157 if (!flipH && !flipV)
158 return QString();
159 if (flipH && flipV)
160 return QLatin1String("horizontal vertical");
161 if (flipH)
162 return QLatin1String("horizontal");
163 if (flipV)
164 return QLatin1String("vertical");
165 return QLatin1String("none");
166 }
167
168 #undef CURRENT_EL
169 #define CURRENT_EL pic
170 //! pic (Picture)
171 //! ECMA-376, 19.3.1.37, p.2848 (PresentationML)
172 //! ECMA-376, 20.1.2.2.30, p.3049 (DrawingML)
173 //! ECMA-376, 20.2.2.5, p.3462
174 /*! This element specifies the existence of a picture object within
175 the document.
176
177 Parent elements:
178 ----------------
179 PresentationML:
180 - control (§19.3.2.1)
181 - [done] grpSp (§19.3.1.22)
182 - oleObj (§19.3.2.4)
183 - [done] spTree (§19.3.1.45)
184
185 DrawingML:
186 - [done] grpSp (§20.1.2.2.20)
187 - [done] lockedCanvas (§20.3.2.1)
188
189 Child elements:
190 ---------------
191 PresentationML:
192 - [done] blipFill (Picture Fill) §19.3.1.4
193 - extLst (Extension List with Modification Flag) §19.3.1.20
194 - [done] nvPicPr (Non-Visual Properties for a Picture) §19.3.1.32
195 - [done] spPr (Shape Properties) §19.3.1.44
196 - [done] style (Shape Style) §19.3.1.46
197
198 DrawingML:
199 - [done] blipFill (Picture Fill) §20.1.8.14
200 - extLst (Extension List) §20.1.2.2.15
201 - [done] nvPicPr (Non-Visual Properties for a Picture) §20.1.2.2.28
202 - [done] spPr (Shape Properties) §20.1.2.2.35
203 - [done] style (Shape Style) §20.1.2.2.37
204
205 DrawingML/Picture
206 - [done] blipFill (Picture Fill) §20.2.2.1
207 - [done] nvPicPr (Non-Visual Picture Properties) §20.2.2.4
208 - [done] spPr (Shape Properties) §20.2.2.6
209 */
210 //! CASE #P401
211 //! @todo CASE #P421
212 //! CASE #P422
read_pic()213 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_pic()
214 {
215 if (m_isLockedCanvas) {
216 READ_PROLOGUE_IF_NS(a);
217 } else {
218 READ_PROLOGUE
219 }
220
221 // Reset picture properties
222 m_xlinkHref.clear();
223 m_ignoreLinkHref = false;
224 m_cNvPrId.clear();
225 m_cNvPrName.clear();
226 m_cNvPrDescr.clear();
227 m_flipH = false;
228 m_flipV = false;
229 m_rot = 0;
230
231 #ifdef XLSXXMLDRAWINGREADER_CPP
232 KoXmlWriter *tempBodyHolder = 0;
233 if ( m_currentDrawingObject->isAnchoredToCell() && (m_context->m_groupDepthCounter == 0)) {
234 tempBodyHolder = body;
235 body = m_currentDrawingObject->pictureWriter();
236 }
237 #endif
238
239 #ifndef DOCXXMLDOCREADER_CPP
240 // Create a new drawing style for this picture
241 pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
242 #endif
243
244 m_referredFont = KoGenStyle(KoGenStyle::TextAutoStyle, "text");
245
246 if (m_isLockedCanvas) {
247 while (!atEnd()) {
248 readNext();
249 debugMsooXml << *this;
250 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
251 if (isStartElement()) {
252 TRY_READ_IF_NS(a, spPr)
253 ELSE_TRY_READ_IF_NS_IN_CONTEXT(a, blipFill)
254 ELSE_TRY_READ_IF_NS(a, nvPicPr)
255 ELSE_TRY_READ_IF_NS(a, style)
256 SKIP_UNKNOWN
257 }
258 }
259 } else {
260 while (!atEnd()) {
261 readNext();
262 debugMsooXml << *this;
263 BREAK_IF_END_OF(CURRENT_EL)
264 if (isStartElement()) {
265 TRY_READ_IF(spPr)
266 else if (name() == QLatin1String("blipFill")) {
267 TRY_READ_IN_CONTEXT(blipFill)
268 if (!m_xlinkHref.isEmpty()) {
269 //spPr may also set m_xlinkHref
270 m_ignoreLinkHref = true;
271 }
272 }
273 #ifdef DOCXXMLDOCUMENTREADER_H
274 ELSE_TRY_READ_IF_NS_IN_CONTEXT(pic, blipFill)
275 #endif
276 ELSE_TRY_READ_IF(nvPicPr)
277 ELSE_TRY_READ_IF(style)
278 SKIP_UNKNOWN
279 }
280 }
281 }
282
283 m_ignoreLinkHref = false;
284
285 #ifndef DOCXXMLDOCUMENTREADER_H
286 body->startElement("draw:frame"); // CASE #P421
287 #ifdef PPTXXMLSLIDEREADER_CPP
288 if (m_context->type == Slide || m_context->type == SlideLayout) {
289 body->addAttribute("draw:layer", "layout");
290 }
291 else { // Slidemaster
292 body->addAttribute("draw:layer", "backgroundobjects");
293 }
294 body->addAttribute("presentation:user-transformed", MsooXmlReader::constTrue);
295 #endif
296
297 #ifdef XLSXXMLDRAWINGREADER_CPP
298 if (m_context->m_groupDepthCounter == 0) {
299 if (m_currentDrawingObject->m_positions.contains(XlsxDrawingObject::FromAnchor)) {
300 XlsxDrawingObject::Position f = m_currentDrawingObject->m_positions[XlsxDrawingObject::FromAnchor];
301 // use relative position to the cell's top-left corner
302 m_svgX = f.m_colOff;
303 m_svgY = f.m_rowOff;
304
305 if(m_currentDrawingObject->m_positions.contains(XlsxDrawingObject::ToAnchor)) {
306 f = m_currentDrawingObject->m_positions[XlsxDrawingObject::ToAnchor];
307 QString endCellAddress = m_currentDrawingObject->toCellAddress();
308 QString end_x = EMU_TO_CM_STRING(f.m_colOff);
309 QString end_y = EMU_TO_CM_STRING(f.m_rowOff);
310
311 body->addAttribute("table:end-cell-address", endCellAddress);
312 body->addAttribute("table:end-x", end_x); //cm
313 body->addAttribute("table:end-y", end_y); //cm
314 }
315 }
316 }
317 #endif
318
319 if (m_rot == 0) {
320 body->addAttribute("svg:x", EMU_TO_CM_STRING(m_svgX));
321 body->addAttribute("svg:y", EMU_TO_CM_STRING(m_svgY));
322 }
323 if (m_svgWidth > 0) {
324 body->addAttribute("svg:width", EMU_TO_CM_STRING(m_svgWidth));
325 }
326 if (m_svgHeight > 0) {
327 body->addAttribute("svg:height", EMU_TO_CM_STRING(m_svgHeight));
328 }
329
330 if (m_rot != 0) {
331 // m_rot is in 1/60,000th of a degree
332 qreal angle, xDiff, yDiff;
333 MSOOXML::Utils::rotateString(m_rot, m_svgWidth, m_svgHeight, angle, xDiff, yDiff);
334 QString rotString = QString("rotate(%1) translate(%2cm %3cm)")
335 .arg(angle).arg((m_svgX + xDiff)/360000, 3, 'f').arg((m_svgY + yDiff)/360000, 3, 'f');
336 body->addAttribute("draw:transform", rotString);
337 }
338
339 // Add style information
340 //! @todo: horizontal-on-{odd,even}?
341 const QString mirror(mirrorToOdf(m_flipH, m_flipV));
342 if (!mirror.isEmpty()) {
343 m_currentDrawStyle->addProperty("style:mirror", mirror);
344 }
345
346 #ifdef PPTXXMLSLIDEREADER_CPP
347 if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
348 m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
349 }
350 #elif defined DOCXXMLDOCREADER_CPP
351 if (m_moveToStylesXml) {
352 m_currentDrawStyle.setAutoStyleInStylesDotXml(true);
353 }
354 #endif
355 const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr"));
356 body->addAttribute("draw:style-name", styleName);
357 #endif
358
359 // Now it's time to link to the actual picture. Only do it if
360 // there is an image to link to. If so, this was created in
361 // read_blip().
362 if (!m_xlinkHref.isEmpty()) {
363 body->startElement("draw:image");
364 body->addAttribute("xlink:href", m_xlinkHref);
365 //! @todo xlink:type?
366 body->addAttribute("xlink:type", "simple");
367 //! @todo xlink:show?
368 body->addAttribute("xlink:show", "embed");
369 //! @todo xlink:actuate?
370 body->addAttribute("xlink:actuate", "onLoad");
371 body->endElement(); //draw:image
372
373 #ifdef DOCXXMLDOCUMENTREADER_H
374 if (!m_cNvPrName.isEmpty() || !m_cNvPrDescr.isEmpty()) {
375 body->startElement("svg:title");
376 body->addTextSpan(m_cNvPrDescr.isEmpty() ? m_cNvPrName : m_cNvPrDescr);
377 body->endElement(); //svg:title
378 }
379 #endif
380 m_xlinkHref.clear();
381 }
382
383 #ifndef DOCXXMLDOCUMENTREADER_H
384 body->endElement(); //draw:frame
385 #endif
386
387 #ifdef XLSXXMLDRAWINGREADER_CPP
388 // If we anchored to cell, we save odf to different buffer that body operates on
389 // Here we restore the original body buffer for next drawing which might be anchored
390 // to sheet
391 if ( m_currentDrawingObject->isAnchoredToCell() && (m_context->m_groupDepthCounter == 0)) {
392 body = tempBodyHolder;
393 }
394 #endif
395
396
397 #ifndef DOCXXMLDOCREADER_CPP
398 popCurrentDrawStyle();
399 #endif
400
401 if (m_isLockedCanvas) {
402 READ_EPILOGUE_IF_NS(a)
403 } else {
404 READ_EPILOGUE
405 }
406 }
407
408 #undef CURRENT_EL
409 #define CURRENT_EL nvPicPr
410 //! nvPicPr (Non-Visual Properties for a Picture)
411 //! ECMA-376, 19.3.1.32, p.2845 (PresentationML)
412 //! ECMA-376, 20.1.2.2.28, p. 3048 (DrawingML)
413 /*! This element specifies all non-visual properties for a picture.
414
415 Parent elements:
416 ----------------
417 PresentationML/DrawingML/SpreadsheetML:
418 - [done] pic (§19.3.1.37)/(§20.1.2.2.30)/(§20.5.2.25)
419
420 Child elements:
421 ---------------
422 PresentationML:
423 - [done] cNvPicPr (Non-Visual Picture Drawing Properties) §19.3.1.11
424 - [done] cNvPr (Non-Visual Drawing Properties) §19.3.1.12
425 - [done] nvPr (Non-Visual Properties) §19.3.1.33
426
427 DrawingML:
428 - [done] cNvPicPr (Non-Visual Picture Drawing Properties) §20.1.2.2.7
429 - [done] cNvPr (Non-Visual Drawing Properties) §20.1.2.2.8
430
431 SpreadsheetML:
432 - [done] cNvPicPr (Non-Visual Picture Drawing Properties) §20.5.2.7
433 - [done] cNvPr (Non-Visual Drawing Properties) §20.5.2.8
434 */
435 //! @todo support all child elements
read_nvPicPr()436 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_nvPicPr()
437 {
438 if (m_isLockedCanvas) {
439 READ_PROLOGUE_IF_NS(a);
440 } else {
441 READ_PROLOGUE
442 }
443
444 if (m_isLockedCanvas) {
445 while (!atEnd()) {
446 readNext();
447 debugMsooXml << *this;
448 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
449 if (isStartElement()) {
450 TRY_READ_IF_NS(a, cNvPicPr)
451 ELSE_TRY_READ_IF_NS_IN_CONTEXT(a, cNvPr)
452 ELSE_WRONG_FORMAT
453 }
454 }
455 } else {
456 while (!atEnd()) {
457 readNext();
458 debugMsooXml << *this;
459 BREAK_IF_END_OF(CURRENT_EL)
460 if (isStartElement()) {
461 TRY_READ_IF(cNvPicPr)
462 ELSE_TRY_READ_IF_IN_CONTEXT(cNvPr)
463 #ifdef PPTXXMLSLIDEREADER_CPP
464 ELSE_TRY_READ_IF(nvPr) // only §19.3.1.33
465 #endif
466 ELSE_WRONG_FORMAT
467 }
468 }
469 }
470
471 if (m_isLockedCanvas) {
472 READ_EPILOGUE_IF_NS(a)
473 } else {
474 READ_EPILOGUE
475 }
476 }
477
478 #undef CURRENT_EL
479 #define CURRENT_EL cNvPicPr
480 //! cNvPicPr handler (Non-Visual Picture Drawing Properties)
481 //! ECMA-376, 19.3.1.11, p.2823; (PresentationML)
482 //! ECMA-376, 20.2.2.2, p.3458 (DrawingML)
483 /*!
484 This element specifies the non-visual properties for the picture
485 canvas. These properties are to be used by the generating
486 application to determine how certain properties are to be changed for
487 the picture object in question.
488
489 Parent elements:
490 - [done] nvPicPr (§19.3.1.32)
491
492 Child elements:
493 - extLst (Extension List) §20.1.2.2.15
494 - picLocks (Picture Locks) §20.1.2.2.31
495
496 Attributes:
497 - preferRelativeResize (Relative Resize Preferred)
498 */
499 //! @todo support all child elements
read_cNvPicPr()500 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_cNvPicPr()
501 {
502 if (m_isLockedCanvas) {
503 READ_PROLOGUE_IF_NS(a);
504 } else {
505 READ_PROLOGUE
506 }
507
508 SKIP_EVERYTHING
509
510 // while (!atEnd()) {
511 // readNext();
512 // debugMsooXml << *this;
513 // BREAK_IF_END_OF(CURRENT_EL)
514 // if (isStartElement()) {
515 // //! @todo add ELSE_WRONG_FORMAT
516 // }
517 // }
518
519 if (m_isLockedCanvas) {
520 READ_EPILOGUE_IF_NS(a)
521 } else {
522 READ_EPILOGUE
523 }
524 }
525
526 #undef CURRENT_EL
527 #define CURRENT_EL cNvPr
528 //! cNvPr handler (Non-Visual Drawing Properties)
529 //! ECMA-376, 19.3.1.12, p.2824 (PresentationML)
530 //! ECMA-376, 20.2.2.3, p.3459 (DrawingML)
531 /*! This element specifies non-visual canvas properties. This allows
532 for additional information that does not affect the appearance of the
533 picture to be stored.
534
535 Parent elements:
536 ----------------
537 PresentationML/SpreadsheetML:
538 - [done] nvCxnSpPr (§19.3.1.29)
539 - nvGraphicFramePr (§19.3.1.30)
540 - nvGrpSpPr (§19.3.1.31)
541 - [done] nvPicPr (§19.3.1.32)
542 - [done] nvSpPr (§19.3.1.34)
543
544 DrawingML:
545 - [done] nvPicPr (§20.2.2.4)
546 //NOTE: Part of nvCxnSpPr child list (20.1.2.2.25)
547
548 Child elements:
549 - extLst (Extension List) §20.1.2.2.15
550 - hlinkClick (Click Hyperlink) §21.1.2.3.5
551 - hlinkHover (Hyperlink for Hover) §20.1.2.2.23
552
553 Attributes:
554 - [done] descr (Alternative Text for Object)
555 - hidden (Hidden)
556 - [done] id (Unique Identifier)
557 - [done] name (Name)
558 */
559 //! @todo support all elements
read_cNvPr(cNvPrCaller caller)560 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_cNvPr(cNvPrCaller caller)
561 {
562 if (m_isLockedCanvas) {
563 READ_PROLOGUE_IF_NS(a);
564 } else {
565 READ_PROLOGUE
566 }
567
568 m_cNvPrId.clear();
569 m_cNvPrName.clear();
570 m_cNvPrDescr.clear();
571 const QXmlStreamAttributes attrs(attributes());
572
573 // for sanity, p:nvGrpSpPr can be also the caller
574 if (caller == cNvPr_nvSpPr || caller == cNvPr_nvPicPr) {
575 READ_ATTR_WITHOUT_NS_INTO(id, m_cNvPrId)
576 debugMsooXml << "id:" << m_cNvPrId;
577 TRY_READ_ATTR_WITHOUT_NS_INTO(name, m_cNvPrName)
578 debugMsooXml << "name:" << m_cNvPrName;
579 TRY_READ_ATTR_WITHOUT_NS_INTO(descr, m_cNvPrDescr)
580 debugMsooXml << "descr:" << m_cNvPrDescr;
581 }
582
583 SKIP_EVERYTHING
584
585 // while (!atEnd()) {
586 // readNext();
587 // debugMsooXml << *this;
588 // BREAK_IF_END_OF(CURRENT_EL)
589 // if (isStartElement()) {
590 // TRY_READ_IF(...)
591 // //! @todo add ELSE_WRONG_FORMAT
592 // }
593 // }
594
595 if (m_isLockedCanvas) {
596 READ_EPILOGUE_IF_NS(a)
597 } else {
598 READ_EPILOGUE
599 }
600 }
601
602 #undef CURRENT_EL
603 #define CURRENT_EL nvSpPr
604 //! nvSpPr handler (Non-Visual Properties for a Shape)
605 //! ECMA-376, 19.3.1.34, p. 2846
606 //! ECMA-376, 20.1.2.2.29, p. 3049
607 /*!
608 This element specifies all non-visual properties for a shape.
609 This element is a container for the non-visual identification
610 properties, shape properties and application properties that are
611 to be associated with a shape. This allows for additional
612 information that does not affect the appearance of the shape to be
613 stored.
614
615 Parent elements:
616 PresentationML/DrawingML:
617 - [done] sp (§19.3.1.43)
618
619 Child elements:
620 PresentationML:
621 - [done] cNvPr (Non-Visual Drawing Properties) §19.3.1.12
622 - [done] cNvSpPr (Non-Visual Drawing Properties for a Shape) §19.3.1.13
623 - [done] nvPr (Non-Visual Properties) §19.3.1.33
624
625 DrawingML:
626 - [done] cNvPr (Non-Visual Drawing Properties) §20.1.2.2.8
627 - [done] cNvSpPr (Non-Visual Drawing Properties for a Shape) §20.1.2.2.9
628
629 SpreadsheetML:
630 - [done] cNvPr (Non-Visual Drawing Properties) §20.5.2.8
631 - [done] cNvSpPr (Connection Non-Visual Shape Properties) §20.5.2.9
632 */
633 //! @todo support all child elements
read_nvSpPr()634 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_nvSpPr()
635 {
636 if (m_isLockedCanvas) {
637 READ_PROLOGUE_IF_NS(a);
638 } else {
639 READ_PROLOGUE
640 }
641
642 if (m_isLockedCanvas) {
643 while (!atEnd()) {
644 readNext();
645 debugMsooXml << *this;
646 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
647 if (isStartElement()) {
648 TRY_READ_IF_NS_IN_CONTEXT(a, cNvPr)
649 ELSE_TRY_READ_IF_NS(a, cNvSpPr)
650 ELSE_WRONG_FORMAT
651 }
652 }
653 } else {
654 while (!atEnd()) {
655 readNext();
656 debugMsooXml << *this;
657 BREAK_IF_END_OF(CURRENT_EL)
658 if (isStartElement()) {
659 TRY_READ_IF_IN_CONTEXT(cNvPr)
660 ELSE_TRY_READ_IF(cNvSpPr)
661 #ifdef PPTXXMLSLIDEREADER_CPP
662 ELSE_TRY_READ_IF(nvPr) // only §19.3.1.33
663 #endif
664 ELSE_WRONG_FORMAT
665
666 }
667 }
668 }
669
670 #ifdef PPTXXMLSLIDEREADER_CPP
671 inheritShapeGeometry();
672 #endif
673
674 if (m_isLockedCanvas) {
675 READ_EPILOGUE_IF_NS(a)
676 } else {
677 READ_EPILOGUE
678 }
679 }
680
681 #undef CURRENT_EL
682 #define CURRENT_EL grpSp
683 //! grpSp handler (Group shape)
684 //! ECMA-376, 19.3.1.22, p.2836 (PresentationML)
685 //! ECMA-376, 20.1.2.2.20, p.3038 (DrawingML)
686 /*!
687 Parent elements:
688 ----------------
689 PresentationML:
690 - [done] grpSp (§19.3.1.22)
691 - [done] spTree (§19.3.1.45)
692
693 DrawingML:
694 - [done] grpSp (§20.1.2.2.20)
695 - [done] lockedCanvas (§20.3.2.1)
696
697 SpreadsheetML:
698 - [done] absoluteAnchor (§20.5.2.1)
699 - [done] grpSp (§20.5.2.17)
700 - [done] oneCellAnchor (§20.5.2.24)
701 - [done] twoCellAnchor (§20.5.2.33)
702
703 Child elements:
704 ---------------
705 PresentationML:
706 - contentPart (Content Part) §19.3.1.14
707 - [done] cxnSp (Connection Shape) §19.3.1.19
708 - extLst (Extension List with Modification Flag) §19.3.1.20
709 - [done] graphicFrame (Graphic Frame) §19.3.1.21
710 - [done] grpSp (Group Shape) §19.3.1.22
711 - [done] grpSpPr (Group Shape Properties) §19.3.1.23
712 - nvGrpSpPr (Non-Visual Properties for a Group Shape) §19.3.1.31
713 - [done] pic (Picture) §19.3.1.37
714 - [done] sp (Shape) §19.3.1.43
715
716 DrawingML:
717 - [done] cxnSp (Connection Shape) §20.1.2.2.10
718 - extLst (Extension List) §20.1.2.2.15
719 - graphicFrame (Graphic Frame) §20.1.2.2.18
720 - [done] grpSp (Group shape) §20.1.2.2.20
721 - [done] grpSpPr (Visual Group Shape Properties) §20.1.2.2.22
722 - nvGrpSpPr (Non-Visual Properties for a Group Shape) §20.1.2.2.27
723 - [done] pic (Picture) §20.1.2.2.30
724 - [done] sp (Shape) §20.1.2.2.33
725 - [done] txSp (Text Shape) §20.1.2.2.41
726
727 SpreadsheetML:
728 - [done] cxnSp (Connection Shape) §20.5.2.13
729 - [done] graphicFrame (Graphic Frame) §20.5.2.16
730 - [done] grpSp (Group Shape) §20.5.2.17
731 - [done] grpSpPr (Group Shape Properties) §20.5.2.18
732 - nvGrpSpPr (Non-Visual Properties for a Group Shape) §20.5.2.21
733 - [done] pic (Picture) §20.5.2.25
734 - [done] sp (Shape) §20.5.2.29
735 */
read_grpSp()736 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_grpSp()
737 {
738 if (m_isLockedCanvas) {
739 READ_PROLOGUE_IF_NS(a);
740 } else {
741 READ_PROLOGUE
742 }
743
744 pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
745 MSOOXML::Utils::XmlWriteBuffer drawFrameBuf; // buffer this draw:g, because we have
746
747 {
748 MSOOXML::Utils::AutoRestore<KoXmlWriter> autoRestoreBody(&body);
749
750 // to write after the child elements are generated
751 body = drawFrameBuf.setWriter(body);
752
753 #ifdef XLSXXMLDRAWINGREADER_CPP
754 m_context->m_groupDepthCounter++;
755 #endif
756 if (m_isLockedCanvas) {
757 while (!atEnd()) {
758 readNext();
759 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
760 debugMsooXml << *this;
761 if (isStartElement()) {
762 TRY_READ_IF_NS(a, grpSp)
763 ELSE_TRY_READ_IF_NS(a, grpSpPr)
764 ELSE_TRY_READ_IF_NS(a, pic)
765 ELSE_TRY_READ_IF_NS(a, sp)
766 ELSE_TRY_READ_IF_NS(a, cxnSp)
767 // ELSE_TRY_READ_IF_NS(a, graphicFrame)
768 ELSE_TRY_READ_IF_NS(a, txSp)
769 SKIP_UNKNOWN
770 //! @todo add ELSE_WRONG_FORMAT
771 }
772 }
773 } else {
774 while (!atEnd()) {
775 readNext();
776 BREAK_IF_END_OF(CURRENT_EL)
777 debugMsooXml << *this;
778 if (isStartElement()) {
779 TRY_READ_IF(grpSp)
780 ELSE_TRY_READ_IF(grpSpPr)
781 ELSE_TRY_READ_IF(pic)
782 ELSE_TRY_READ_IF(sp)
783 ELSE_TRY_READ_IF(cxnSp)
784 #if defined PPTXXMLSLIDEREADER_CPP || defined XLSXXMLDRAWINGREADER_CPP
785 ELSE_TRY_READ_IF(graphicFrame)
786 #endif
787 SKIP_UNKNOWN
788 //! @todo add ELSE_WRONG_FORMAT
789 }
790 }
791 }
792 #ifdef XLSXXMLDRAWINGREADER_CPP
793 m_context->m_groupDepthCounter--;
794 #endif
795 }
796
797 body = drawFrameBuf.originalWriter();
798 body->startElement("draw:g");
799
800 #ifdef PPTXXMLSLIDEREADER_CPP
801 if (m_context->type == SlideMaster || m_context->type == NotesMaster) {
802 m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
803 }
804 #elif defined DOCXXMLDOCREADER_CPP
805 if (m_moveToStylesXml) {
806 m_currentDrawStyle->setAutoStyleInStylesDotXml(true);
807 }
808 #endif
809 const QString styleName(mainStyles->insert(*m_currentDrawStyle, "gr"));
810 body->addAttribute("draw:style-name", styleName);
811
812 (void)drawFrameBuf.releaseWriter();
813
814 body->endElement(); // draw:g
815
816 // Properties are set in grpSpPr
817 if (!m_svgProp.isEmpty()) {
818 m_svgProp.pop_back();
819 } else {
820 warnMsooXml << "Element grpSpPr not processed, empty graphic style assigned to draw:g";
821 }
822
823 popCurrentDrawStyle();
824
825 if (m_isLockedCanvas) {
826 READ_EPILOGUE_IF_NS(a)
827 } else {
828 READ_EPILOGUE
829 }
830 }
831
832 #undef CURRENT_EL
833 #define CURRENT_EL grpSpPr
834 //! grpSpPr (Group Shape Properties)
835 //! ECMA-376, 19.3.1.23, p.2837 (PresentationML)
836 //! ECMA-376, 20.1.2.2.22, p.3041 (DrawingML)
837 /*!
838 Parent elements:
839 ----------------
840 PresentationML:
841 - [done] grpSp (§19.3.1.22);
842 - [done] spTree (§19.3.1.45)
843
844 DrawingML:
845 - [done] grpSp (§20.1.2.2.20)
846 - [done] lockedCanvas (§20.3.2.1)
847
848 Child elements:
849 - [done] blipFill (Picture Fill) §20.1.8.14
850 - effectDag (Effect Container) §20.1.8.25
851 - [done] effectLst (Effect Container) §20.1.8.26
852 - extLst (Extension List) §20.1.2.2.15
853 - [done] gradFill (Gradient Fill) §20.1.8.33
854 - grpFill (Group Fill) §20.1.8.35
855 - [done] noFill (No Fill) §20.1.8.44
856 - pattFill (Pattern Fill) §20.1.8.47
857 - scene3d (3D Scene Properties) §20.1.4.1.26
858 - [done] solidFill (Solid Fill) §20.1.8.54
859 - [done] xfrm (2D Transform for Grouped Objects) §20.1.7.5
860 */
read_grpSpPr()861 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_grpSpPr()
862 {
863 if (m_isLockedCanvas) {
864 READ_PROLOGUE_IF_NS(a);
865 } else {
866 READ_PROLOGUE
867 }
868 m_inGrpSpPr = true;
869
870 while (!atEnd()) {
871 readNext();
872 debugMsooXml << *this;
873 if (m_isLockedCanvas) {
874 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
875 } else {
876 BREAK_IF_END_OF(CURRENT_EL)
877 }
878 if (isStartElement()) {
879 TRY_READ_IF_NS(a, xfrm)
880 else if (qualifiedName() == QLatin1String("a:effectLst")) {
881 TRY_READ(effectLst)
882 }
883 else if (qualifiedName() == QLatin1String("a:solidFill")) {
884 TRY_READ(solidFill)
885 // We must set the color immediately, otherwise currentColor may be modified by eg. ln
886 if (m_currentColor != QColor()) {
887 m_currentDrawStyle->addProperty("draw:fill", QLatin1String("solid"));
888 m_currentDrawStyle->addProperty("draw:fill-color", m_currentColor.name());
889 m_currentColor = QColor();
890 }
891 }
892 else if ( qualifiedName() == QLatin1String("a:ln") ) {
893 TRY_READ(ln)
894 }
895 else if (qualifiedName() == QLatin1String("a:noFill")) {
896 m_currentDrawStyle->addProperty("draw:fill", "none");
897 }
898 else if (qualifiedName() == QLatin1String("a:blipFill")) {
899 TRY_READ_IN_CONTEXT(blipFill)
900 if (!m_xlinkHref.isEmpty()) {
901 KoGenStyle fillStyle = KoGenStyle(KoGenStyle::FillImageStyle);
902 fillStyle.addProperty("xlink:href", m_xlinkHref);
903 fillStyle.addProperty("xlink:type", "simple");
904 fillStyle.addProperty("xlink:actuate", "onLoad");
905 const QString imageName = mainStyles->insert(fillStyle);
906 m_currentDrawStyle->addProperty("draw:fill", "bitmap");
907 m_currentDrawStyle->addProperty("draw:fill-image-name", imageName);
908 m_xlinkHref.clear();
909 }
910 }
911 else if (qualifiedName() == QLatin1String("a:gradFill")) {
912 m_currentGradientStyle = KoGenStyle(KoGenStyle::LinearGradientStyle);
913 TRY_READ(gradFill)
914 m_currentDrawStyle->addProperty("draw:fill", "gradient");
915 const QString gradName = mainStyles->insert(m_currentGradientStyle);
916 m_currentDrawStyle->addProperty("draw:fill-gradient-name", gradName);
917 }
918 SKIP_UNKNOWN
919 //! @todo add ELSE_WRONG_FORMAT
920 }
921 }
922
923 GroupProp prop;
924 prop.svgXOld = m_svgX;
925 prop.svgYOld = m_svgY;
926 prop.svgWidthOld = m_svgWidth;
927 prop.svgHeightOld = m_svgHeight;
928 prop.svgXChOld = m_svgChX;
929 prop.svgYChOld = m_svgChY;
930 prop.svgWidthChOld = m_svgChWidth;
931 prop.svgHeightChOld = m_svgChHeight;
932
933 m_svgProp.push_back(prop);
934
935 m_inGrpSpPr = false;
936
937 if (m_isLockedCanvas) {
938 READ_EPILOGUE_IF_NS(a)
939 } else {
940 READ_EPILOGUE
941 }
942 }
943
944 #undef CURRENT_EL
945 #define CURRENT_EL nvCxnSpPr
946 //! nvCxnSpPr (Non-Visual Properties for a Connection Shape)
947 //! ECMA-376, 19.3.1.29 (PresentationML)
948 //! ECMA-376, 20.1.2.2.25 (DrawingML)
949 //! ECMA-376, 20.5.2.19 (SpreadsheetML)
950 /*!
951 Parent Elements:
952 ----------------
953 PresentationML/DrawingML:
954 - [done] cxnSp (§19.3.1.19)/(§20.1.2.2.10)
955
956 Child Elements:
957 ---------------
958 PresentaionML:
959 - cNvCxnSpPr (Non-Visual Connector Shape Drawing Properties) §19.3.1.8
960 - [done] cNvPr (Non-Visual Drawing Properties) §19.3.1.12
961 - [done] nvPr (Non-Visual Properties) §19.3.1.33
962
963 DrawingML:
964 - cNvCxnSpPr (Non-Visual Connector Shape Drawing Properties) §20.1.2.2.4
965 - [done] cNvPr (Non-Visual Drawing Properties) §20.1.2.2.8
966
967 SpreadsheetML:
968 - cNvCxnSpPr (Non-Visual Connector Shape Drawing Properties) §20.5.2.4
969 - [done] cNvPr (Non-Visual Drawing Properties) §20.5.2.8
970 */
read_nvCxnSpPr()971 KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_nvCxnSpPr()
972 {
973 if (m_isLockedCanvas) {
974 READ_PROLOGUE_IF_NS(a);
975 } else {
976 READ_PROLOGUE
977 }
978
979 if (m_isLockedCanvas) {
980 while (!atEnd()) {
981 readNext();
982 debugMsooXml << *this;
983 BREAK_IF_END_OF_WITH_NS(a, CURRENT_EL)
984 if (isStartElement()) {
985 TRY_READ_IF_NS_IN_CONTEXT(a, cNvPr)
986 SKIP_UNKNOWN
987 }
988 }
989 } else {
990 while (!atEnd()) {
991 readNext();
992 debugMsooXml << *this;
993 BREAK_IF_END_OF(CURRENT_EL)
994 if (isStartElement()) {
995 TRY_READ_IF_IN_CONTEXT(cNvPr)
996 #ifdef PPTXXMLSLIDEREADER_CPP
997 ELSE_TRY_READ_IF(nvPr) // only §19.3.1.33
998 #endif
999 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
read_cNvSpPr()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
preReadSp()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
generateFrameSp()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
writeEnhancedGeometry()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 */
read_cxnSp()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
read_sp()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
read_style()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
read_spPr()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 */
read_chart()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 */
read_relIds()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 */
read_lockedCanvas()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 */
read_lnRef()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 */
read_masterClrMapping()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 */
read_overrideClrMapping()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
read_DrawingML_p()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
read_DrawingML_r()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 */
read_DrawingML_br()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 */
read_endParaRPr()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
handleRprAttributes(const QXmlStreamAttributes & attrs)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
read_DrawingML_rPr()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
read_DrawingML_pPr()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 */
read_hlinkClick()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 */
read_custGeom()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
read_xfrm()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
read_off()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
read_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 */
read_ext()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
read_chExt()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
read_blip()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
read_stretch()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
read_biLevel()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
read_grayscl()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
read_lum()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
read_duotone()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
read_tile()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
read_srcRect()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
read_fillRect()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
read_graphic()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
read_graphicData()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
read_blipFill(blipFillCaller caller)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 */
read_txSp()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
algnToODF(const char * odfEl,const QString & ov)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
distToODF(const char * odfEl,const QString & emuValue)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
read_lstStyle()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
read_latin()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
read_DrawingML_highlight()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
read_gradFill()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 */
read_lin()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
read_gradFillRpr()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 */
read_gsLst()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 */
read_gs()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
read_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
read_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
read_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
read_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 */
read_effectLst()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 */
read_outerShdw()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
lvlHelper(const QString & level)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
read_lvl1pPr()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
read_lvl2pPr()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
read_lvl3pPr()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
read_lvl4pPr()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
read_lvl5pPr()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
read_lvl6pPr()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
read_lvl7pPr()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
read_lvl8pPr()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
read_lvl9pPr()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
read_buBlip()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
read_buChar()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 */
read_buClr()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 */
read_buClrTx()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 */
read_buSzPct()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 */
read_buSzPts()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
read_buFont()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
read_buNone()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
read_buAutoNum()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
read_fld()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
read_spcBef()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
read_spcAft()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
read_lnSpc()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 */
read_spcPts()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
read_spcPct()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
read_defRPr()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
read_bodyPr()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 */
read_normAutofit()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 */
read_spAutoFit()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 */
read_DrawingML_txBody(txBodyCaller caller)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
6327