1 /*
2 * This file is part of Office 2007 Filters for Calligra
3 *
4 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
5 *
6 * Contact: Suresh Chande suresh.chande@nokia.com
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * version 2.1 as published by the Free Software Foundation.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24 #include "MsooXmlThemesReader.h"
25 #include "MsooXmlSchemas.h"
26 #include "MsooXmlTheme.h"
27 #include "MsooXmlUtils.h"
28 #include "MsooXmlUnits.h"
29
30 #include <KoOdfGraphicStyles.h>
31 #include <MsooXmlRelationships.h>
32
33 #define MSOOXML_CURRENT_NS "a"
34 #define MSOOXML_CURRENT_CLASS MsooXmlThemesReader
35 #define MSOOXML_THEMESREADER_CPP
36
37 #include "MsooXmlReader_p.h"
38
39 #include <QPalette>
40
41 #include <memory>
42 #include <math.h>
43
44 #ifndef M_PI
45 #define M_PI 3.1415926535897932384626
46 #endif
47
48 using namespace MSOOXML;
49
DrawingMLGradientFill(const QVector<qreal> & shadeModifier,const QVector<qreal> & tintModifier,const QVector<qreal> & satModifier,const QVector<int> & alphaModifier,const QVector<int> & gradPositions,const QString & gradAngle)50 DrawingMLGradientFill::DrawingMLGradientFill(const QVector<qreal> &shadeModifier, const QVector<qreal> &tintModifier, const QVector<qreal> &satModifier,
51 const QVector<int> &alphaModifier, const QVector<int> &gradPositions, const QString &gradAngle)
52 : m_shadeModifier(shadeModifier),m_tintModifier(tintModifier), m_satModifier(satModifier),
53 m_alphaModifier(alphaModifier), m_gradPosition(gradPositions), m_gradAngle(gradAngle)
54 {
55 }
56
writeStyles(KoGenStyles & styles,KoGenStyle * graphicStyle,const QColor & color)57 void DrawingMLGradientFill::writeStyles(KoGenStyles& styles, KoGenStyle *graphicStyle, const QColor &color)
58 {
59 KoGenStyle gradientStyle = KoGenStyle(KoGenStyle::LinearGradientStyle);
60
61 qreal angle = -m_gradAngle.toDouble() / 60000.0 / 180.0 * M_PI;
62 gradientStyle.addAttribute("svg:x1", QString("%1%").arg(50 - 50 * cos(angle)));
63 gradientStyle.addAttribute("svg:y1", QString("%1%").arg(50 + 50 * sin(angle)));
64 gradientStyle.addAttribute("svg:x2", QString("%1%").arg(50 + 50 * cos(angle)));
65 gradientStyle.addAttribute("svg:y2", QString("%1%").arg(50 - 50 * sin(angle)));
66
67 int index = 0;
68 while (index < m_alphaModifier.size()) {
69 QColor gradColor = color;
70 MSOOXML::Utils::modifyColor(gradColor, m_tintModifier.at(index), m_shadeModifier.at(index), m_satModifier.at(index));
71 QString contents = QString("<svg:stop svg:offset=\"%1\" svg:stop-color=\"%2\" svg:stop-opacity=\"1\"/>").arg(m_gradPosition.at(index)/100.0).arg(gradColor.name());
72 QString name = QString("%1").arg(index);
73 gradientStyle.addChildElement(name, contents);
74 ++index;
75 }
76
77 graphicStyle->addProperty("draw:fill", "gradient");
78 const QString gradName = styles.insert(gradientStyle);
79 graphicStyle->addProperty("draw:fill-gradient-name", gradName);
80 }
81
DrawingMLBlipFill(const QString & filePath)82 DrawingMLBlipFill::DrawingMLBlipFill(const QString &filePath) : m_filePath(filePath)
83 {
84 }
85
writeStyles(KoGenStyles & styles,KoGenStyle * graphicStyle,const QColor & color)86 void DrawingMLBlipFill::writeStyles(KoGenStyles& styles, KoGenStyle *graphicStyle, const QColor &color)
87 {
88 Q_UNUSED(color)
89
90 KoGenStyle fillImageStyle(KoGenStyle::FillImageStyle);
91 fillImageStyle.addAttribute("xlink:href", m_filePath);
92 fillImageStyle.addAttribute("xlink:type", "simple");
93 fillImageStyle.addAttribute("xlink:show", "embed");
94 fillImageStyle.addAttribute("xlink:actuate", "onLoad");
95 QString fillImageName = styles.insert(fillImageStyle);
96
97 graphicStyle->addProperty("draw:fill", "bitmap");
98 graphicStyle->addProperty("draw:fill-image-name", fillImageName);
99 }
100
writeStyles(KoGenStyles & styles,KoGenStyle * graphicStyle,const QColor & color)101 void DrawingMLSolidFill::writeStyles(KoGenStyles& styles, KoGenStyle *graphicStyle, const QColor &color)
102 {
103 if (color.isValid()) {
104 QBrush brush(color, Qt::SolidPattern);
105 KoOdfGraphicStyles::saveOdfFillStyle(*graphicStyle, styles, brush);
106 }
107 }
108
DrawingMLColorSchemeItem()109 DrawingMLColorSchemeItem::DrawingMLColorSchemeItem()
110 {
111 }
112
DrawingMLColorSchemeSystemItem()113 DrawingMLColorSchemeSystemItem::DrawingMLColorSchemeSystemItem()
114 {
115 }
116
value() const117 QColor DrawingMLColorSchemeSystemItem::value() const
118 {
119 // Prefer lastColor
120 if (lastColor.isValid()) {
121 return lastColor;
122 }
123
124 //TODO: use the style:use-window-font-color attribute
125
126 //! 20.1.10.58 ST_SystemColorVal (System Color Value)
127 if ( systemColor == QLatin1String("windowText") ||
128 systemColor == QLatin1String("menuText"))
129 {
130 return QPalette().color(QPalette::Active, QPalette::WindowText);
131 }
132 else if ( systemColor == QLatin1String("window") ||
133 systemColor == QLatin1String("menu") ||
134 systemColor == QLatin1String("menuBar"))
135 {
136 return QPalette().color(QPalette::Active, QPalette::Window);
137 }
138 else if (systemColor == QLatin1String("highlightText")) {
139 return QPalette().color(QPalette::Active, QPalette::HighlightedText);
140 }
141 else if (systemColor == QLatin1String("highlight")) {
142 return QPalette().color(QPalette::Active, QPalette::Highlight);
143 }
144 else if (systemColor == QLatin1String("grayText")) {
145 return QPalette().color(QPalette::Disabled, QPalette::WindowText);
146 }
147 else if (systemColor == QLatin1String("btnText")) {
148 return QPalette().color(QPalette::Active, QPalette::ButtonText);
149 }
150 else if (systemColor == QLatin1String("btnFace")) {
151 return QPalette().color(QPalette::Active, QPalette::Button);
152 }
153 else if (systemColor == QLatin1String("btnHighlight")) {
154 return QPalette().color(QPalette::Active, QPalette::Light);
155 }
156 else if (systemColor == QLatin1String("btnShadow")) {
157 return QPalette().color(QPalette::Active, QPalette::Dark);
158 }
159
160 //! @todo Use more of systemColor
161 return QColor(Qt::black); // TODO; better default?
162 }
163
DrawingMLColorSchemeItemBase()164 DrawingMLColorSchemeItemBase::DrawingMLColorSchemeItemBase()
165 {
166 }
167
~DrawingMLColorSchemeItemBase()168 DrawingMLColorSchemeItemBase::~DrawingMLColorSchemeItemBase()
169 {
170 }
171
toColorItem()172 DrawingMLColorSchemeItem* DrawingMLColorSchemeItemBase::toColorItem()
173 {
174 return dynamic_cast<DrawingMLColorSchemeItem*>(this);
175 }
176
toSystemItem()177 DrawingMLColorSchemeSystemItem* DrawingMLColorSchemeItemBase::toSystemItem()
178 {
179 return dynamic_cast<DrawingMLColorSchemeSystemItem*>(this);
180 }
181
DrawingMLColorScheme()182 DrawingMLColorScheme::DrawingMLColorScheme()
183 {
184 }
185
~DrawingMLColorScheme()186 DrawingMLColorScheme::~DrawingMLColorScheme()
187 {
188 QSet<DrawingMLColorSchemeItemBase*> set(values().toSet()); // use set because values can be duplicated
189 qDeleteAll(set);
190 }
191
operator =(const DrawingMLColorScheme & scheme)192 DrawingMLColorScheme& DrawingMLColorScheme::operator=(const DrawingMLColorScheme& scheme)
193 {
194 QHashIterator<QString, DrawingMLColorSchemeItemBase*> i(scheme);
195 while (i.hasNext()) {
196 i.next();
197 insert(i.key(), i.value()->clone());
198 }
199
200 return *this;
201 }
202
DrawingMLColorScheme(const DrawingMLColorScheme & scheme)203 DrawingMLColorScheme::DrawingMLColorScheme(const DrawingMLColorScheme& scheme) : QHash<QString, DrawingMLColorSchemeItemBase*>()
204 {
205 QHashIterator<QString, DrawingMLColorSchemeItemBase*> i(scheme);
206 while (i.hasNext()) {
207 i.next();
208 insert(i.key(), i.value()->clone());
209 }
210 }
211
value(int index) const212 DrawingMLColorSchemeItemBase* DrawingMLColorScheme::value(int index) const
213 {
214 return DrawingMLColorSchemeItemHash::value( QString::number(index) );
215 }
216
DrawingMLFontScheme()217 DrawingMLFontScheme::DrawingMLFontScheme()
218 {
219 }
220
DrawingMLFontSet()221 DrawingMLFontSet::DrawingMLFontSet()
222 {
223 }
224
~DrawingMLFillBase()225 DrawingMLFillBase::~DrawingMLFillBase()
226 {
227 }
228
~DrawingMLFormatScheme()229 DrawingMLFormatScheme::~DrawingMLFormatScheme()
230 {
231 qDeleteAll(fillStyles);
232 }
233
DrawingMLFormatScheme()234 DrawingMLFormatScheme::DrawingMLFormatScheme()
235 {
236 }
237
DrawingMLFormatScheme(const DrawingMLFormatScheme & format)238 DrawingMLFormatScheme::DrawingMLFormatScheme(const DrawingMLFormatScheme& format)
239 {
240 QMapIterator<int, DrawingMLFillBase*> i(format.fillStyles);
241 while (i.hasNext()) {
242 i.next();
243 fillStyles.insert(i.key(), i.value()->clone());
244 }
245 lnStyleLst = format.lnStyleLst;
246 }
247
operator =(const DrawingMLFormatScheme & format)248 DrawingMLFormatScheme& DrawingMLFormatScheme::operator=(const DrawingMLFormatScheme& format)
249 {
250 QMapIterator<int, DrawingMLFillBase*> i(format.fillStyles);
251 while (i.hasNext()) {
252 i.next();
253 fillStyles.insert(i.key(), i.value()->clone());
254 }
255 lnStyleLst = format.lnStyleLst;
256
257 return *this;
258 }
259
DrawingMLTheme()260 DrawingMLTheme::DrawingMLTheme()
261 {
262 }
263
264 // ---------------------------------------------------
265
MsooXmlThemesReaderContext(DrawingMLTheme & t,MSOOXML::MsooXmlRelationships * rel,MSOOXML::MsooXmlImport * imp,const QString & pathName,const QString & fileName)266 MsooXmlThemesReaderContext::MsooXmlThemesReaderContext(DrawingMLTheme& t, MSOOXML::MsooXmlRelationships* rel,
267 MSOOXML::MsooXmlImport* imp, const QString &pathName, const QString &fileName)
268 : MsooXmlReaderContext()
269 , theme(&t), relationships(rel), import(imp), path(pathName), file(fileName)
270 {
271 }
272
273 // ---------------------------------------------------
274
MsooXmlThemesReader(KoOdfWriters * writers)275 MsooXmlThemesReader::MsooXmlThemesReader(KoOdfWriters *writers)
276 : MsooXmlCommonReader(writers)
277 , m_currentColor_local(0)
278 , m_context(0)
279 {
280 init();
281 }
282
~MsooXmlThemesReader()283 MsooXmlThemesReader::~MsooXmlThemesReader()
284 {
285 }
286
init()287 void MsooXmlThemesReader::init()
288 {
289 m_clrScheme_initialized = false;
290 m_color_initialized = false;
291 }
292
read(MsooXmlReaderContext * context)293 KoFilter::ConversionStatus MsooXmlThemesReader::read(MsooXmlReaderContext* context)
294 {
295 m_context = dynamic_cast<MsooXmlThemesReaderContext*>(context);
296 Q_ASSERT(m_context);
297 m_import = m_context->import;
298 m_path = m_context->path;
299 m_file = m_context->file;
300 m_relationships = m_context->relationships;
301 *m_context->theme = DrawingMLTheme(); //clear
302 const KoFilter::ConversionStatus result = readInternal();
303 m_context = 0;
304 if (result == KoFilter::OK)
305 return KoFilter::OK;
306 *dynamic_cast<MsooXmlThemesReaderContext*>(context)->theme = DrawingMLTheme(); //clear
307 return result;
308 }
309
readInternal()310 KoFilter::ConversionStatus MsooXmlThemesReader::readInternal()
311 {
312 //debugMsooXml << "=============================";
313 readNext();
314 if (!isStartDocument()) {
315 return KoFilter::WrongFormat;
316 }
317
318 readNext();
319 //debugMsooXml << *this;
320 if (isStartElement()) {
321 TRY_READ_IF(theme)
322 ELSE_WRONG_FORMAT
323 } else {
324 return KoFilter::WrongFormat;
325 }
326 //debugMsooXml << "===========finished============";
327 return KoFilter::OK;
328 }
329
330 #undef CURRENT_EL
331 #define CURRENT_EL theme
332 //! theme (Theme)
333 /*! ECMA-376, 20.1.6.9, p.3180.
334 No parent elements.
335 Child elements:
336 - custClrLst (Custom Color List) §20.1.6.3
337 - extLst (Extension List) §20.1.2.2.15
338 - extraClrSchemeLst (Extra Color Scheme List) §20.1.6.5
339 - objectDefaults (Object Defaults) §20.1.6.7
340 - themeElements [done] (Theme Elements) §20.1.6.10
341 CASE #850
342 */
read_theme()343 KoFilter::ConversionStatus MsooXmlThemesReader::read_theme()
344 {
345 READ_PROLOGUE
346 //debugMsooXml << namespaceUri();
347
348 if (!expectNS(Schemas::drawingml::main)) {
349 return KoFilter::WrongFormat;
350 }
351
352 const QXmlStreamAttributes attrs(attributes());
353 READ_ATTR_WITHOUT_NS_INTO(name, m_context->theme->name)
354 //debugMsooXml << "name:" << m_context->theme->name;
355
356 QXmlStreamNamespaceDeclarations namespaces(namespaceDeclarations());
357 //for (int i = 0; i < namespaces.count(); i++) {
358 //debugMsooXml << "NS prefix:" << namespaces[i].prefix() << "uri:" << namespaces[i].namespaceUri();
359 //}
360 //! @todo find out whether the namespace returned by namespaceUri()
361 //! is exactly the same ref as the element of namespaceDeclarations()
362 if (!namespaces.contains(QXmlStreamNamespaceDeclaration(MSOOXML_CURRENT_NS, Schemas::drawingml::main))) {
363 raiseError(i18n("Namespace \"%1\" not found", QLatin1String(Schemas::drawingml::main)));
364 return KoFilter::WrongFormat;
365 }
366 //! @todo expect other namespaces too...
367
368 while (!atEnd()) {
369 readNext();
370 //debugMsooXml << *this;
371 BREAK_IF_END_OF(CURRENT_EL)
372 if (isStartElement()) {
373 TRY_READ_IF(themeElements)
374 ELSE_TRY_READ_IF(custClrLst)
375 ELSE_TRY_READ_IF(extLst)
376 ELSE_TRY_READ_IF(extraClrSchemeLst)
377 ELSE_TRY_READ_IF(objectDefaults)
378 ELSE_TRY_READ_IF(custClrLst)
379 ELSE_WRONG_FORMAT
380 }
381 }
382 READ_EPILOGUE
383 }
384
385 #undef CURRENT_EL
386 #define CURRENT_EL themeElements
387 //! themeElements (Theme Elements)
388 /*! ECMA-376, 20.1.6.10, p.3181.
389 Parent elements:
390 - theme
391 Child elements:
392 - clrScheme (Color Scheme) §20.1.6.2
393 - extLst (Extension List) §20.1.2.2.15
394 - fmtScheme (Format Scheme) §20.1.4.1.14
395 - fontScheme (Font Scheme) §20.1.4.1.18
396 CASE #850
397 */
read_themeElements()398 KoFilter::ConversionStatus MsooXmlThemesReader::read_themeElements()
399 {
400 READ_PROLOGUE
401 while (!atEnd()) {
402 readNext();
403 //debugMsooXml << *this;
404 BREAK_IF_END_OF(CURRENT_EL)
405 if (isStartElement()) {
406 TRY_READ_IF(clrScheme)
407 ELSE_TRY_READ_IF(extLst)
408 ELSE_TRY_READ_IF(fmtScheme)
409 ELSE_TRY_READ_IF(fontScheme)
410 ELSE_WRONG_FORMAT
411 }
412 }
413 READ_EPILOGUE
414 }
415
416 #undef CURRENT_EL
417 #define CURRENT_EL objectDefaults
418 //! objectDefaults (Object Defaults)
419 /*! ECMA-376, 20.1.6.7, p.3178.
420
421 This element allows for the definition of default shape, line, and textbox formatting properties. An application
422 can use this information to format a shape (or text) initially on insertion into a document.
423
424 Parent elements:
425 - [done] theme
426 Child elements:
427 - extLst (Extension List) §20.1.2.2.15
428 - lnDef (Line Default) §20.1.4.1.20
429 - spDef (Shape Default) §20.1.4.1.27
430 - txDef (Text Default) §20.1.4.1.28
431
432 @todo
433 */
read_objectDefaults()434 KoFilter::ConversionStatus MsooXmlThemesReader::read_objectDefaults()
435 {
436 SKIP_EVERYTHING_AND_RETURN
437 }
438
439 #undef CURRENT_EL
440 #define CURRENT_EL custClrLst
441 //! custClrLst (Custom Color List))
442 /*! ECMA-376, 20.1.6.3, p.3175.
443
444 @todo
445 */
read_custClrLst()446 KoFilter::ConversionStatus MsooXmlThemesReader::read_custClrLst()
447 {
448 SKIP_EVERYTHING_AND_RETURN
449 }
450
451 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
452
453 #undef CURRENT_EL
454 #define CURRENT_EL clrMap
read_clrMap()455 KoFilter::ConversionStatus MsooXmlThemesReader::read_clrMap()
456 {
457 READ_PROLOGUE
458 const QXmlStreamAttributes attrs(attributes());
459
460 SKIP_EVERYTHING
461
462 READ_EPILOGUE
463 }
464
465 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
466 #undef CURRENT_EL
467 #define CURRENT_EL extraClrSchemeLst
468 //! extraClrSchemeLst (Extra Color Scheme List)
469 /*! ECMA-376, 20.1.6.5, p.3177.
470
471 @todo implement
472 */
read_extraClrSchemeLst()473 KoFilter::ConversionStatus MsooXmlThemesReader::read_extraClrSchemeLst()
474 {
475 READ_PROLOGUE
476
477 while (!atEnd()) {
478 readNext();
479 //debugMsooXml << *this;
480 BREAK_IF_END_OF(CURRENT_EL)
481 if (isStartElement()) {
482 TRY_READ_IF(extraClrScheme)
483 }
484 }
485 READ_EPILOGUE
486 }
487
488 #undef CURRENT_EL
489 #define CURRENT_EL extraClrScheme
490 //! extraClrScheme (Extra Color Scheme)
491 /*!
492
493 @todo implement
494 */
read_extraClrScheme()495 KoFilter::ConversionStatus MsooXmlThemesReader::read_extraClrScheme()
496 {
497 READ_PROLOGUE
498
499 while (!atEnd()) {
500 readNext();
501 //debugMsooXml << *this;
502 BREAK_IF_END_OF(CURRENT_EL)
503 if (isStartElement()) {
504 }
505 }
506 READ_EPILOGUE
507 }
508
509 #define INIT_COLOR_ITEM(name, index) \
510 BIND_READ_METHOD(name, color) \
511 m_colorSchemeIndices.insert(name, QLatin1String(STRINGIFY(index)));
512
513 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
514 #undef CURRENT_EL
515 #define CURRENT_EL clrScheme
516 //! clrScheme (Color Scheme)
517 /*! ECMA-376, 20.1.6.2, p.3173.
518 Parent elements:
519 - extraClrScheme (§20.1.6.4)
520 - [done] themeElements (§20.1.6.10)
521 - themeOverride (§20.1.6.12)
522 Child elements:
523 - accent1 (Accent 1) §20.1.4.1.1
524 - accent2 (Accent 2) §20.1.4.1.2
525 - accent3 (Accent 3) §20.1.4.1.3
526 - accent4 (Accent 4) §20.1.4.1.4
527 - accent5 (Accent 5) §20.1.4.1.5
528 - accent6 (Accent 6) §20.1.4.1.6
529 - dk1 (Dark 1) §20.1.4.1.9
530 - dk2 (Dark 2) §20.1.4.1.10
531 - extLst (Extension List) §20.1.2.2.15
532 - folHlink (Followed Hyperlink) §20.1.4.1.15
533 - hlink (Hyperlink) §20.1.4.1.19
534 - lt1 (Light 1) §20.1.4.1.22
535 - lt2 (Light 2) §20.1.4.1.23
536 */
read_clrScheme()537 KoFilter::ConversionStatus MsooXmlThemesReader::read_clrScheme()
538 {
539 READ_PROLOGUE
540
541 if (!m_clrScheme_initialized) {
542 m_clrScheme_initialized = true;
543 INIT_COLOR_ITEM("dk1", 0)
544 INIT_COLOR_ITEM("lt1", 1)
545 INIT_COLOR_ITEM("dk2", 2)
546 INIT_COLOR_ITEM("lt2", 3)
547 INIT_COLOR_ITEM("accent1", 4)
548 INIT_COLOR_ITEM("accent2", 5)
549 INIT_COLOR_ITEM("accent3", 6)
550 INIT_COLOR_ITEM("accent4", 7)
551 INIT_COLOR_ITEM("accent5", 8)
552 INIT_COLOR_ITEM("accent6", 9)
553 INIT_COLOR_ITEM("hlink", 10)
554 INIT_COLOR_ITEM("folHlink", 11)
555 }
556
557 const QXmlStreamAttributes attrs(attributes());
558 READ_ATTR_WITHOUT_NS_INTO(name, m_context->theme->colorScheme.name)
559
560 while (!atEnd()) {
561 readNext();
562 //debugMsooXml << *this;
563 BREAK_IF_END_OF(CURRENT_EL)
564 if (isStartElement()) {
565 ReadMethod readMethod = m_readMethods.value(this->name().toString());
566 if (readMethod) {
567 Q_ASSERT(!m_currentColor_local);
568 RETURN_IF_ERROR( (this->*readMethod)() )
569 Q_ASSERT(m_currentColor_local);
570 if (!m_currentColor_local) {
571 return KoFilter::InternalError;
572 }
573 const QString colorName( this->name().toString() );
574 //debugMsooXml << "inserting color for" << colorName;
575 m_context->theme->colorScheme.insert(colorName, m_currentColor_local);
576 const QString colorIndex(m_colorSchemeIndices.value(colorName));
577 if (!colorIndex.isEmpty()) {
578 m_context->theme->colorScheme.insert(colorIndex, m_currentColor_local);
579 }
580
581 m_currentColor_local = 0;
582 }
583 ELSE_WRONG_FORMAT_DEBUG("!readMethod")
584 }
585 }
586 READ_EPILOGUE
587 }
588 #undef INIT_COLOR_ITEM
589
590 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
591 #undef CURRENT_EL
592 //! accent[1-6] (Accent [1-6]), dk1/2, lt1/2
593 /*! ECMA-376, 20.1.4.1.1-6, p.3098, etc.
594
595 Parent elements:
596 - [done] clrScheme (§20.1.6.2)
597
598 Child elements:
599 - hslClr (Hue, Saturation, Luminance Color Model) §20.1.2.3.13
600 - prstClr (Preset Color) §20.1.2.3.22
601 - [unsupported by MSO] schemeClr (Scheme Color) §20.1.2.3.29
602 - scrgbClr (RGB Color Model - Percentage Variant) §20.1.2.3.30
603 - srgbClr (RGB Color Model - Hex Variant) §20.1.2.3.32
604 - sysClr (System Color) §20.1.2.3.33
605 */
read_color()606 KoFilter::ConversionStatus MsooXmlThemesReader::read_color()
607 {
608 const QString qn(qualifiedName().toString());
609
610 if (!m_color_initialized) {
611 m_color_initialized = true;
612 //! @todo remove _SKIP
613 BIND_READ_SKIP(hslClr)
614 //! @todo remove _SKIP
615 BIND_READ_SKIP(prstClr)
616 //! @todo remove _SKIP
617 BIND_READ_SKIP(schemeClr)
618 //! @todo remove _SKIP
619 BIND_READ_SKIP(scrgbClr)
620
621 BIND_READ(srgbClr_local)
622 BIND_READ(sysClr_local)
623 }
624
625 while (!atEnd()) {
626 readNext();
627 //debugMsooXml << *this;
628 BREAK_IF_END_OF_QSTRING(qn)
629 if (isStartElement()) {
630 QString name = this->name().toString();
631
632 //using local versions at the moment
633 if (name == "srgbClr") {
634 name = "srgbClr_local";
635 } else if (name == "sysClr") {
636 name = "sysClr_local";
637 }
638
639 ReadMethod readMethod = m_readMethods.value(name);
640 if (readMethod) {
641 RETURN_IF_ERROR( (this->*readMethod)() )
642 }
643 ELSE_WRONG_FORMAT_DEBUG("!readMethod")
644 }
645 }
646
647 if (!expectElEnd(qn)) {
648 return KoFilter::WrongFormat;
649 }
650 return KoFilter::OK;
651 }
652
653
654 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
655 #undef CURRENT_EL
656 #define CURRENT_EL srgbClr
657 //! srgbClr (RGB Color Model - Hex Variant)
658 //! ECMA-376 20.1.2.3.32, p. 3085.
659 /*!
660 Parent elements:
661 [done] accent1 (§20.1.4.1.1); accent2 (§20.1.4.1.2); accent3 (§20.1.4.1.3); accent4 (§20.1.4.1.4);
662 [done] accent5 (§20.1.4.1.5); accent6 (§20.1.4.1.6);
663 [done] dk1 (§20.1.4.1.9); dk2 (§20.1.4.1.10);
664 [done] lt1 (§20.1.4.1.22); lt2 (§20.1.4.1.23);
665 [done] folHlink (§20.1.4.1.15); hlink (§20.1.4.1.19);
666
667 TODO:
668 alphaInv (§20.1.8.4);
669 bgClr (§20.1.8.10);
670 bgRef (§19.3.1.3);
671 buClr (§21.1.2.4.4);
672 clrFrom (§20.1.8.17);
673 clrMru (§19.2.1.4);
674 clrRepl (§20.1.8.18);
675 clrTo (§20.1.8.19);
676 clrVal (§19.5.27);
677 contourClr (§20.1.5.6);
678 custClr (§20.1.4.1.8);
679 duotone (§20.1.8.23);
680 effectClrLst (§21.4.4.7);
681 effectRef (§20.1.4.2.8);
682 extrusionClr (§20.1.5.7);
683 fgClr (§20.1.8.27);
684 fillClrLst (§21.4.4.8);
685 fillRef (§20.1.4.2.10);
686 fontRef (§20.1.4.1.17);
687 from (§19.5.43);
688 glow (§20.1.8.32);
689 gs (§20.1.8.36);
690 highlight (§21.1.2.3.4);
691 innerShdw (§20.1.8.40);
692 linClrLst (§21.4.4.9);
693 lnRef (§20.1.4.2.19);
694 outerShdw (§20.1.8.45);
695 penClr (§19.2.1.23);
696 prstShdw (§20.1.8.49);
697 solidFill (§20.1.8.54);
698 tcTxStyle (§20.1.4.2.30);
699 to (§19.5.90);
700 txEffectClrLst (§21.4.4.12);
701 txFillClrLst (§21.4.4.13);
702 txLinClrLst (§21.4.4.14)
703
704 Child elements:
705 alpha (Alpha) §20.1.2.3.1
706 alphaMod (Alpha Modulation) §20.1.2.3.2
707 alphaOff (Alpha Offset) §20.1.2.3.3
708 blue (Blue) §20.1.2.3.4
709 blueMod (Blue Modification) §20.1.2.3.5
710 blueOff (Blue Offset) §20.1.2.3.6
711 comp (Complement) §20.1.2.3.7
712 gamma (Gamma) §20.1.2.3.8
713 gray (Gray) §20.1.2.3.9
714 green (Green) §20.1.2.3.10
715 greenMod (Green Modification) §20.1.2.3.11
716 greenOff (Green Offset) §20.1.2.3.12
717 hue (Hue) §20.1.2.3.14
718 hueMod (Hue Modulate) §20.1.2.3.15
719 hueOff (Hue Offset) §20.1.2.3.16
720 inv (Inverse) §20.1.2.3.17
721 invGamma (Inverse Gamma) §20.1.2.3.18
722 lum (Luminance) §20.1.2.3.19
723 lumMod (Luminance Modulation) §20.1.2.3.20
724 lumOff (Luminance Offset) §20.1.2.3.21
725 red (Red) §20.1.2.3.23
726 redMod (Red Modulation) §20.1.2.3.24
727 redOff (Red Offset) §20.1.2.3.25
728 sat (Saturation) §20.1.2.3.26
729 satMod (Saturation Modulation) §20.1.2.3.27
730 satOff (Saturation Offset) §20.1.2.3.28
731 shade (Shade) §20.1.2.3.31
732 tint (Tint) §20.1.2.3.34
733
734 TODO: these child elements are common for all *Clr() methods, so
735 create common function for parsing them
736 */
read_srgbClr_local()737 KoFilter::ConversionStatus MsooXmlThemesReader::read_srgbClr_local()
738 {
739 std::auto_ptr<DrawingMLColorSchemeItem> color(new DrawingMLColorSchemeItem);
740 m_currentColor_local = 0;
741 READ_PROLOGUE
742 const QXmlStreamAttributes attrs(attributes());
743
744 READ_ATTR_WITHOUT_NS(val)
745 color.get()->color = Utils::ST_HexColorRGB_to_QColor(val);
746 //debugMsooXml << color.get()->color;
747
748 readNext();
749 READ_EPILOGUE_WITHOUT_RETURN
750 m_currentColor_local = color.release();
751
752 return KoFilter::OK;
753 }
754
755 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
756 #undef CURRENT_EL
757 #define CURRENT_EL sysClr
758 /*! ECMA-376
759 - sysClr (System Color) §20.1.2.3.33
760
761 Parent elements:
762 [done] accent1 (§20.1.4.1.1);
763 accent2 (§20.1.4.1.2);
764 accent3 (§20.1.4.1.3);
765 accent4 (§20.1.4.1.4);
766 [done] accent5 (§20.1.4.1.5);
767 accent6 (§20.1.4.1.6);
768 [done] dk1 (§20.1.4.1.9);
769 dk2 (§20.1.4.1.10);
770 [done] lt1 (§20.1.4.1.22);
771 lt2 (§20.1.4.1.23);
772 [done] folHlink (§20.1.4.1.15);
773 hlink (§20.1.4.1.19);
774
775 TODO:
776 alphaInv (§20.1.8.4);
777 bgClr (§20.1.8.10);
778 bgRef (§19.3.1.3);
779 buClr (§21.1.2.4.4);
780 clrFrom (§20.1.8.17);
781 clrMru (§19.2.1.4);
782 clrRepl (§20.1.8.18);
783 clrTo (§20.1.8.19);
784 clrVal (§19.5.27);
785 contourClr (§20.1.5.6);
786 custClr (§20.1.4.1.8);
787 duotone (§20.1.8.23);
788 effectClrLst (§21.4.4.7);
789 effectRef (§20.1.4.2.8);
790 extrusionClr (§20.1.5.7);
791 fgClr (§20.1.8.27);
792 fillClrLst (§21.4.4.8);
793 fillRef (§20.1.4.2.10);
794 fontRef (§20.1.4.1.17);
795 from (§19.5.43);
796 glow (§20.1.8.32);
797 gs (§20.1.8.36);
798 highlight (§21.1.2.3.4);
799 innerShdw (§20.1.8.40);
800 linClrLst (§21.4.4.9);
801 lnRef (§20.1.4.2.19);
802 outerShdw (§20.1.8.45);
803 penClr (§19.2.1.23);
804 prstShdw (§20.1.8.49);
805 solidFill (§20.1.8.54);
806 tcTxStyle (§20.1.4.2.30);
807 to (§19.5.90);
808 txEffectClrLst (§21.4.4.12);
809 txFillClrLst (§21.4.4.13);
810 xLinClrLst (§21.4.4.14)
811
812 Child elements:
813 alpha (Alpha) §20.1.2.3.1
814 alphaMod (Alpha Modulation) §20.1.2.3.2
815 alphaOff (Alpha Offset) §20.1.2.3.3
816 blue (Blue) §20.1.2.3.4
817 blueMod (Blue Modification) §20.1.2.3.5
818 blueOff (Blue Offset) §20.1.2.3.6
819 comp (Complement) §20.1.2.3.7
820 gamma (Gamma) §20.1.2.3.8
821 gray (Gray) §20.1.2.3.9
822 green (Green) §20.1.2.3.10
823 greenMod (Green Modification) §20.1.2.3.11
824 greenOff (Green Offset) §20.1.2.3.12
825 hue (Hue) §20.1.2.3.14
826 hueMod (Hue Modulate) §20.1.2.3.15
827 hueOff (Hue Offset) §20.1.2.3.16
828 inv (Inverse) §20.1.2.3.17
829 invGamma (Inverse Gamma) §20.1.2.3.18
830 lum (Luminance) §20.1.2.3.19
831 lumMod (Luminance Modulation) §20.1.2.3.20
832 lumOff (Luminance Offset) §20.1.2.3.21
833 red (Red) §20.1.2.3.23
834 redMod (Red Modulation) §20.1.2.3.24
835 redOff (Red Offset) §20.1.2.3.25
836 sat (Saturation) §20.1.2.3.26
837 satMod (Saturation Modulation) §20.1.2.3.27
838 satOff (Saturation Offset) §20.1.2.3.28
839 shade (Shade) §20.1.2.3.31
840 tint (Tint) §20.1.2.3.34
841 */
read_sysClr_local()842 KoFilter::ConversionStatus MsooXmlThemesReader::read_sysClr_local()
843 {
844 std::auto_ptr<DrawingMLColorSchemeSystemItem> color(new DrawingMLColorSchemeSystemItem);
845 m_currentColor_local = 0;
846 READ_PROLOGUE
847 const QXmlStreamAttributes attrs(attributes());
848
849 READ_ATTR_WITHOUT_NS(lastClr)
850 color.get()->lastColor = Utils::ST_HexColorRGB_to_QColor(lastClr);
851 // debugMsooXml << "lastClr:" << color.get()->lastColor.name();
852
853 // System color value. This color is based upon the value that this color
854 // currently has within the system on which the document is being viewed.
855 READ_ATTR_WITHOUT_NS_INTO(val, color.get()->systemColor)
856 // debugMsooXml << "val:" << color.get()->systemColor;
857
858 readNext();
859 READ_EPILOGUE_WITHOUT_RETURN
860 m_currentColor_local = color.release();
861
862 return KoFilter::OK;
863 }
864
865 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
866 #undef CURRENT_EL
867 #define CURRENT_EL fmtScheme
868 //! fmtScheme (Format Scheme)
869 /*! ECMA-376, 20.1.4.1.14, p.3110.
870 Parent elements:
871 - [done] themeElements (§20.1.6.10)
872 - themeOverride (§20.1.6.12)
873 Child elements:
874 - [done] bgFillStyleLst (Background Fill Style List) §20.1.4.1.7
875 - effectStyleLst (Effect Style List) §20.1.4.1.12
876 - [done] fillStyleLst (Fill Style List) §20.1.4.1.13
877 - [done] lnStyleLst (Line Style List) §20.1.4.1.21*/
read_fmtScheme()878 KoFilter::ConversionStatus MsooXmlThemesReader::read_fmtScheme()
879 {
880 READ_PROLOGUE
881 while (!atEnd()) {
882 readNext();
883 BREAK_IF_END_OF(CURRENT_EL)
884 if (isStartElement()) {
885 TRY_READ_IF(bgFillStyleLst)
886 ELSE_TRY_READ_IF(fillStyleLst)
887 ELSE_TRY_READ_IF(lnStyleLst)
888 SKIP_UNKNOWN
889 }
890 }
891 READ_EPILOGUE
892 }
893
894 #undef CURRENT_EL
895 #define CURRENT_EL lnStyleLst
896 //! lnStyleLst (Line style list)
897 //! ECMA-376, 20.1.4.1.21, p.3115
898 /*!
899 This element defines a list of three line styles for use within a
900 theme. The three line styles are arranged in order from subtle to
901 moderate to intense versions of lines. This list makes up part of
902 the style matrix.
903
904 Parent elements:
905 - [done] fmtScheme (§20.1.4.1.14)
906
907 Child elements:
908 - [done] ln (Outline) (§20.1.2.2.24)
909 */
read_lnStyleLst()910 KoFilter::ConversionStatus MsooXmlThemesReader::read_lnStyleLst()
911 {
912 READ_PROLOGUE
913
914 QList<KoGenStyle> *list = &m_context->theme->formatScheme.lnStyleLst;
915
916 while (!atEnd()) {
917 readNext();
918 BREAK_IF_END_OF(CURRENT_EL)
919 if (isStartElement()) {
920 pushCurrentDrawStyle(new KoGenStyle(KoGenStyle::GraphicAutoStyle, "graphic"));
921 TRY_READ_IF(ln)
922 list->append(*m_currentDrawStyle);
923 popCurrentDrawStyle();
924 }
925 }
926
927 READ_EPILOGUE
928 }
929
fillStyleReadHelper(int & index)930 KoFilter::ConversionStatus MsooXmlThemesReader::fillStyleReadHelper(int& index)
931 {
932 QXmlStreamAttributes attrs;
933
934 if (isStartElement()) {
935 QString element = qualifiedName().toString();
936 if (element == "a:gradFill") {
937 QVector<qreal> shadeModifiers;
938 QVector<qreal> tintModifiers;
939 QVector<qreal> satModifiers;
940 QVector<int> alphaModifiers;
941 QVector<int> gradPositions;
942 QString gradAngle = "16200000"; // 270 degrees as the default, that is, from up to down
943 while (!atEnd()) {
944 readNext();
945 if (isEndElement() && qualifiedName() == "a:gradFill") {
946 break;
947 }
948 else if (isStartElement() && qualifiedName() == "a:lin") {
949 attrs = attributes();
950 TRY_READ_ATTR_WITHOUT_NS(ang)
951 gradAngle = ang;
952 }
953 else if (isStartElement() && qualifiedName() == "a:gsLst") {
954 while (!atEnd()) {
955 readNext();
956 if (isEndElement() && qualifiedName() == "a:gsLst") {
957 break;
958 }
959 else if (isStartElement() && qualifiedName() == "a:gs") {
960 attrs = attributes();
961 TRY_READ_ATTR_WITHOUT_NS(pos)
962 int gradPosition = pos.toInt() / 1000;
963 qreal shadeModifier = 0;
964 qreal tintModifier = 0;
965 qreal satModifier = 0;
966 int alphaModifier = 0;
967 while (!atEnd()) {
968 readNext();
969 if (isEndElement() && qualifiedName() == "a:gs") {
970 break;
971 }
972 else if (isStartElement() && qualifiedName() == "a:schemeClr") {
973 while (!atEnd()) {
974 readNext();
975 if (isEndElement() && qualifiedName() == "a:schemeClr") {
976 break;
977 }
978 else if (isStartElement()) {
979 attrs = attributes();
980 TRY_READ_ATTR_WITHOUT_NS(val)
981 if (qualifiedName() == "a:tint") {
982 tintModifier = val.toInt()/100000.0;
983 }
984 else if (qualifiedName() == "a:shade") {
985 shadeModifier = val.toInt()/100000.0;
986 }
987 else if (qualifiedName() == "a:satMod") {
988 satModifier = val.toDouble()/100000.0;
989 }
990 else if (qualifiedName() == "a:alpha") {
991 alphaModifier = val.toInt()/1000;
992 }
993 }
994 }
995 }
996 }
997 gradPositions.push_back(gradPosition);
998 tintModifiers.push_back(tintModifier);
999 shadeModifiers.push_back(shadeModifier);
1000 satModifiers.push_back(satModifier),
1001 alphaModifiers.push_back(alphaModifier);
1002 }
1003 }
1004 }
1005 }
1006 m_context->theme->formatScheme.fillStyles[index] = new DrawingMLGradientFill(shadeModifiers, tintModifiers,
1007 satModifiers, alphaModifiers, gradPositions, gradAngle);
1008 }
1009 // Commented out for now, until there's a nice implementation for duotone effect
1010 /*else if (element == "a:blipFill") {
1011 readNext(); // Going to a:blip
1012 attrs = attributes();
1013 TRY_READ_ATTR_WITH_NS(r, embed)
1014 if (!r_embed.isEmpty()) {
1015 const QString sourceName(m_relationships->target(m_path, m_file, r_embed));
1016 QString destinationName = "Pictures/" + sourceName.mid(sourceName.lastIndexOf('/') + 1);
1017 RETURN_IF_ERROR( m_import->copyFile(sourceName, destinationName, false) )
1018 addManifestEntryForFile(destinationName);
1019 addManifestEntryForPicturesDir();
1020 m_context->theme->formatScheme.fillStyles[index] = new DrawingMLBlipFill(destinationName);
1021 }
1022 while (!atEnd()) {
1023 readNext();
1024 if (isEndElement() && qualifiedName() == element) {
1025 break;
1026 }
1027 }
1028 }*/
1029 else { //if (element == "a:solidFill") { //For now, let's have this as default
1030 m_context->theme->formatScheme.fillStyles[index] = new DrawingMLSolidFill;
1031 skipCurrentElement();
1032 } // todo, handle rest
1033 ++index;
1034 }
1035
1036 return KoFilter::OK;
1037 }
1038
1039 #undef CURRENT_EL
1040 #define CURRENT_EL fillStyleLst
1041 //! fillStyleLst (fill style list)
read_fillStyleLst()1042 KoFilter::ConversionStatus MsooXmlThemesReader::read_fillStyleLst()
1043 {
1044 READ_PROLOGUE
1045
1046 int index = 1; // The first style goes to 1
1047
1048 while (!atEnd()) {
1049 readNext();
1050 BREAK_IF_END_OF(CURRENT_EL)
1051 fillStyleReadHelper(index);
1052 }
1053 READ_EPILOGUE
1054 }
1055
1056 #undef CURRENT_EL
1057 #define CURRENT_EL bgFillStyleLst
1058 //! bgFillStyleLst (background fill style list)
read_bgFillStyleLst()1059 KoFilter::ConversionStatus MsooXmlThemesReader::read_bgFillStyleLst()
1060 {
1061 READ_PROLOGUE
1062
1063 int index = 1001; // The first style goes to 1001
1064
1065 while (!atEnd()) {
1066 readNext();
1067 BREAK_IF_END_OF(CURRENT_EL)
1068 fillStyleReadHelper(index);
1069 }
1070 READ_EPILOGUE
1071 }
1072
1073 //! @todo !!!!!!!!!!!!!MERGE with Document Reader!!!!!!!!!!!!!
1074 #undef CURRENT_EL
1075 #define CURRENT_EL fontScheme
1076 //! fontScheme (Font Scheme)
1077 /*! ECMA-376, 20.1.4.1.18, p.3114.
1078 Parent elements:
1079 - [done] themeElements (§20.1.6.10)
1080 - themeOverride (§20.1.6.12)
1081 Child elements:
1082 - extLst (Extension List) §20.1.2.2.15
1083 - [done] majorFont (Major Font) §20.1.4.1.24
1084 - [done] minorFont (Minor fonts) §20.1.4.1.25*/
read_fontScheme()1085 KoFilter::ConversionStatus MsooXmlThemesReader::read_fontScheme()
1086 {
1087 READ_PROLOGUE
1088 while (!atEnd()) {
1089 readNext();
1090 BREAK_IF_END_OF(CURRENT_EL)
1091 if (isStartElement()) {
1092 TRY_READ_IF(majorFont)
1093 ELSE_TRY_READ_IF(minorFont)
1094 SKIP_UNKNOWN
1095 }
1096 }
1097 READ_EPILOGUE
1098 }
1099
1100 #undef CURRENT_EL
1101 #define CURRENT_EL majorFont
1102 //! majorFont (Major Font)
read_majorFont()1103 KoFilter::ConversionStatus MsooXmlThemesReader::read_majorFont()
1104 {
1105 READ_PROLOGUE
1106 while (!atEnd()) {
1107 readNext();
1108 BREAK_IF_END_OF(CURRENT_EL)
1109 if (isStartElement()) {
1110 if (qualifiedName() == "a:latin") {
1111 const QXmlStreamAttributes attrs(attributes());
1112 TRY_READ_ATTR_WITHOUT_NS(typeface)
1113 m_context->theme->fontScheme.majorFonts.latinTypeface = typeface;
1114 }
1115 else if (qualifiedName() == "a:ea") {
1116 const QXmlStreamAttributes attrs(attributes());
1117 TRY_READ_ATTR_WITHOUT_NS(typeface)
1118 m_context->theme->fontScheme.minorFonts.eaTypeface = typeface;
1119 }
1120 else if (qualifiedName() == "a:cs") {
1121 const QXmlStreamAttributes attrs(attributes());
1122 TRY_READ_ATTR_WITHOUT_NS(typeface)
1123 m_context->theme->fontScheme.minorFonts.csTypeface = typeface;
1124 }
1125 SKIP_UNKNOWN
1126 }
1127 }
1128 READ_EPILOGUE
1129 }
1130
1131 #undef CURRENT_EL
1132 #define CURRENT_EL minorFont
1133 //! minorFont (Minor Font)
read_minorFont()1134 KoFilter::ConversionStatus MsooXmlThemesReader::read_minorFont()
1135 {
1136 READ_PROLOGUE
1137 while (!atEnd()) {
1138 readNext();
1139 BREAK_IF_END_OF(CURRENT_EL)
1140 if (isStartElement()) {
1141 if (qualifiedName() == "a:latin") {
1142 const QXmlStreamAttributes attrs(attributes());
1143 TRY_READ_ATTR_WITHOUT_NS(typeface)
1144 m_context->theme->fontScheme.minorFonts.latinTypeface = typeface;
1145 }
1146 else if (qualifiedName() == "a:ea") {
1147 const QXmlStreamAttributes attrs(attributes());
1148 TRY_READ_ATTR_WITHOUT_NS(typeface)
1149 m_context->theme->fontScheme.minorFonts.eaTypeface = typeface;
1150 }
1151 else if (qualifiedName() == "a:cs") {
1152 const QXmlStreamAttributes attrs(attributes());
1153 TRY_READ_ATTR_WITHOUT_NS(typeface)
1154 m_context->theme->fontScheme.minorFonts.csTypeface = typeface;
1155 }
1156 SKIP_UNKNOWN
1157 }
1158 }
1159 READ_EPILOGUE
1160 }
1161
read_SKIP()1162 KoFilter::ConversionStatus MsooXmlThemesReader::read_SKIP()
1163 {
1164 SKIP_EVERYTHING_AND_RETURN
1165 }
1166
1167 #include "MsooXmlDrawingMLSharedImpl.h"
1168