Warning, file /office/calligra/filters/sheets/xlsx/XlsxXmlCommonReader.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * This file is part of Office 2007 Filters for Calligra 0003 * 0004 * SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies). 0005 * 0006 * Contact: Suresh Chande suresh.chande@nokia.com 0007 * 0008 * SPDX-License-Identifier: LGPL-2.1-only 0009 * 0010 */ 0011 0012 #include "XlsxUtils.h" 0013 #include "XlsxXmlCommonReader.h" 0014 0015 #include <math.h> 0016 0017 #include <MsooXmlSchemas.h> 0018 #include <MsooXmlUtils.h> 0019 #include <KoXmlWriter.h> 0020 #include <KoCharacterStyle.h> 0021 0022 #undef MSOOXML_CURRENT_NS 0023 #define MSOOXML_CURRENT_CLASS XlsxXmlCommonReader 0024 #define BIND_READ_CLASS MSOOXML_CURRENT_CLASS 0025 0026 #include <MsooXmlReader_p.h> 0027 0028 class XlsxXmlCommonReader::Private 0029 { 0030 public: 0031 Private() { 0032 } 0033 ~Private() { 0034 } 0035 private: 0036 }; 0037 0038 XlsxXmlCommonReader::XlsxXmlCommonReader(KoOdfWriters *writers) 0039 : MSOOXML::MsooXmlReader(writers) 0040 , d(new Private) 0041 { 0042 init(); 0043 } 0044 0045 XlsxXmlCommonReader::~XlsxXmlCommonReader() 0046 { 0047 delete d; 0048 } 0049 0050 void XlsxXmlCommonReader::init() 0051 { 0052 m_currentTextStyleProperties = 0; 0053 } 0054 0055 QColor XlsxXmlCommonReader::tintedColor(const QColor& color, qreal tint) 0056 { 0057 const int HLSMAX = 255; // Used for computing tint 0058 if (tint == 0.0 || !color.isValid()) { 0059 return color; 0060 } 0061 int h, l, s; 0062 color.getHsl(&h, &l, &s); 0063 if (tint < 0.0) { 0064 l = floor( l * (1.0 + tint) ); 0065 } 0066 else { 0067 l = floor( l * (1.0 - tint) + (HLSMAX - HLSMAX * (1.0 - tint)) ); 0068 } 0069 int r, g, b; 0070 color.getRgb(&r, &g, &b); 0071 return QColor(r, g, b, color.alpha()); 0072 } 0073 0074 #undef CURRENT_EL 0075 #define CURRENT_EL t 0076 //! t handler (Text) 0077 /*! ECMA-376, 18.4.12, p. 1914. 0078 This element represents the text content shown as part of a string. 0079 0080 No child elements. 0081 Parent elements: 0082 - is (§18.3.1.53) 0083 - [done] r (§18.4.4) 0084 - rPh (§18.4.6) 0085 - [done] si (§18.4.8) 0086 - text (§18.7.7) 0087 0088 @todo support all child elements 0089 */ 0090 KoFilter::ConversionStatus XlsxXmlCommonReader::read_t() 0091 { 0092 READ_PROLOGUE 0093 while (!atEnd()) { 0094 readNext(); 0095 qCDebug(lcXlsxImport) << *this; 0096 if (isCharacters()) { 0097 body->addTextSpan(text().toString()); 0098 } 0099 BREAK_IF_END_OF(CURRENT_EL) 0100 } 0101 READ_EPILOGUE 0102 } 0103 0104 #undef CURRENT_EL 0105 #define CURRENT_EL r 0106 //! r handler (Rich Text Run) 0107 /*! ECMA-376, 18.4.12, p. 1909. 0108 This element represents a run of rich text. A rich text run is a region of text that share a common set of 0109 properties, such as formatting properties. The properties are defined in the rPr element, and the text displayed 0110 to the user is defined in the Text (t) element. 0111 0112 Parent elements: 0113 - is (§18.3.1.53) 0114 - [done] si (§18.4.8) 0115 - text (§18.7.7) 0116 0117 Child elements: 0118 - [done] rPr (§18.4.7) 0119 - [done] t (§18.4.12) 0120 0121 @todo support all elements 0122 */ 0123 KoFilter::ConversionStatus XlsxXmlCommonReader::read_r() 0124 { 0125 READ_PROLOGUE 0126 0127 m_currentTextStyle = KoGenStyle(KoGenStyle::TextAutoStyle, "text"); 0128 0129 MSOOXML::Utils::XmlWriteBuffer rBuf; 0130 body = rBuf.setWriter(body); 0131 0132 while (!atEnd()) { 0133 readNext(); 0134 BREAK_IF_END_OF(CURRENT_EL) 0135 if (isStartElement()) { 0136 TRY_READ_IF(rPr) 0137 ELSE_TRY_READ_IF(t) 0138 ELSE_WRONG_FORMAT 0139 } 0140 } 0141 0142 body = rBuf.originalWriter(); 0143 0144 body->startElement("text:span", false); 0145 if (!m_currentTextStyle.isEmpty() || !m_currentTextStyle.parentName().isEmpty()) { 0146 const QString currentTextStyleName(mainStyles->insert(m_currentTextStyle)); 0147 body->addAttribute("text:style-name", currentTextStyleName); 0148 } 0149 0150 (void)rBuf.releaseWriter(); 0151 0152 body->endElement(); //text:span 0153 0154 READ_EPILOGUE 0155 } 0156 0157 #undef CURRENT_EL 0158 #define CURRENT_EL rPr 0159 //! rPr handler (Run Properties) 0160 /*! ECMA-376, 18.4.7, p. 1911. 0161 This element represents a set of properties to apply to the contents of this rich text run. 0162 0163 Parent elements: 0164 - [done] r (§18.4.4) 0165 0166 Child elements: 0167 - [done] b §18.8.2 0168 - charset §18.4.1 0169 - [done] color §18.3.1.15 0170 - condense §18.8.12 0171 - extend §18.8.17 0172 - family §18.8.18 0173 - [done] i §18.8.26 0174 - [done] outline §18.4.2 0175 - [done] rFont §18.4.5 0176 - [done] scheme §18.8.35 0177 - shadow §18.8.36 0178 - [done] strike §18.4.10 0179 - [done] sz §18.4.11 0180 - [done] u §18.4.13 0181 - [done] vertAlign §18.4.14 0182 0183 @todo support all child elements 0184 */ 0185 KoFilter::ConversionStatus XlsxXmlCommonReader::read_rPr() 0186 { 0187 READ_PROLOGUE 0188 m_currentTextStyleProperties = new KoCharacterStyle; 0189 0190 m_currentColor = QColor(); 0191 0192 while (!atEnd()) { 0193 readNext(); 0194 BREAK_IF_END_OF(CURRENT_EL) 0195 if (isStartElement()) { 0196 TRY_READ_IF(vertAlign) 0197 ELSE_TRY_READ_IF(sz) 0198 ELSE_TRY_READ_IF(rFont) 0199 ELSE_TRY_READ_IF(color) 0200 ELSE_TRY_READ_IF(u) 0201 ELSE_TRY_READ_IF(i) 0202 ELSE_TRY_READ_IF(b) 0203 ELSE_TRY_READ_IF(strike) 0204 ELSE_TRY_READ_IF(outline) 0205 SKIP_UNKNOWN 0206 //! @todo add ELSE_WRONG_FORMAT 0207 } 0208 } 0209 0210 if (m_currentColor.isValid()) { 0211 m_currentTextStyleProperties->setForeground(QBrush(m_currentColor)); 0212 } 0213 0214 m_currentTextStyleProperties->saveOdf(m_currentTextStyle); 0215 delete m_currentTextStyleProperties; 0216 m_currentTextStyleProperties = 0; 0217 READ_EPILOGUE 0218 } 0219 0220 #undef CURRENT_EL 0221 #define CURRENT_EL vertAlign 0222 //! vertAlign handler (Vertical Alignment) 0223 /*! ECMA-376, 18.4.7, p. 1914. 0224 This element adjusts the vertical position of the text relative to the text's default appearance for this run. 0225 It is used to get 'superscript' or 'subscript' texts, and shall reduce the font size 0226 (if a smaller size is available) accordingly. 0227 0228 Parent elements: 0229 - [done] font (§18.8.22) 0230 - [done] rPr (§18.4.7) 0231 0232 No child elements. 0233 0234 @todo support all elements 0235 */ 0236 KoFilter::ConversionStatus XlsxXmlCommonReader::read_vertAlign() 0237 { 0238 READ_PROLOGUE 0239 const QXmlStreamAttributes attrs(attributes()); 0240 TRY_READ_ATTR_WITHOUT_NS(val) 0241 if (val == "subscript") { 0242 m_currentTextStyleProperties->setVerticalAlignment(QTextCharFormat::AlignSubScript); 0243 } 0244 else if (val == "superscript") { 0245 m_currentTextStyleProperties->setVerticalAlignment(QTextCharFormat::AlignSuperScript); 0246 } 0247 0248 readNext(); 0249 READ_EPILOGUE 0250 } 0251 0252 #undef CURRENT_EL 0253 #define CURRENT_EL sz 0254 //! fontSize 0255 /* 0256 Parent elements: 0257 - [done] font (§18.8.22); 0258 - [done] rPr (§18.4.7) 0259 0260 Child elements: 0261 - none 0262 */ 0263 KoFilter::ConversionStatus XlsxXmlCommonReader::read_sz() 0264 { 0265 READ_PROLOGUE 0266 const QXmlStreamAttributes attrs(attributes()); 0267 TRY_READ_ATTR_WITHOUT_NS(val) 0268 0269 if (!val.isEmpty()) { 0270 m_currentTextStyleProperties->setFontPointSize(val.toDouble()); 0271 } 0272 0273 readNext(); 0274 READ_EPILOGUE 0275 } 0276 0277 #undef CURRENT_EL 0278 #define CURRENT_EL rFont 0279 //! font 0280 /* 0281 Parent elements: 0282 - [done] rPr (§18.4.7) 0283 0284 Child elements: 0285 - none 0286 */ 0287 KoFilter::ConversionStatus XlsxXmlCommonReader::read_rFont() 0288 { 0289 READ_PROLOGUE 0290 const QXmlStreamAttributes attrs(attributes()); 0291 TRY_READ_ATTR_WITHOUT_NS(val) 0292 0293 if (!val.isEmpty()) { 0294 m_currentTextStyle.addProperty("fo:font-family", val); 0295 } 0296 0297 readNext(); 0298 READ_EPILOGUE 0299 } 0300 0301 #undef CURRENT_EL 0302 #define CURRENT_EL i 0303 //! i handler (Italic) 0304 /*! ECMA-376, 18.8.26, p. 1969. 0305 Displays characters in italic font style. 0306 0307 Parent elements: 0308 - [done] font (§18.8.22) 0309 - [done] rPr (§18.4.7) 0310 0311 Child elements: 0312 - none 0313 */ 0314 KoFilter::ConversionStatus XlsxXmlCommonReader::read_i() 0315 { 0316 READ_PROLOGUE 0317 const QXmlStreamAttributes attrs(attributes()); 0318 TRY_READ_ATTR_WITHOUT_NS(val) 0319 const bool italic = MSOOXML::Utils::convertBooleanAttr(val, true); 0320 m_currentTextStyleProperties->setFontItalic(italic); 0321 0322 readNext(); 0323 READ_EPILOGUE 0324 } 0325 0326 #undef CURRENT_EL 0327 #define CURRENT_EL scheme 0328 //! scheme handler (Scheme) 0329 /*! 0330 0331 Parent elements: 0332 - [done] font (§18.8.22) 0333 - [done] rPr (§18.4.7) 0334 0335 Child elements: 0336 - none 0337 */ 0338 KoFilter::ConversionStatus XlsxXmlCommonReader::read_scheme() 0339 { 0340 READ_PROLOGUE 0341 0342 const QXmlStreamAttributes attrs(attributes()); 0343 TRY_READ_ATTR_WITHOUT_NS(val) 0344 QString font; 0345 0346 if (val == "major") { 0347 font = m_themes->fontScheme.majorFonts.latinTypeface; 0348 m_currentTextStyle.addProperty("fo:font-family", font); 0349 } else if (val == "minor") { 0350 font = m_themes->fontScheme.minorFonts.latinTypeface; 0351 m_currentTextStyle.addProperty("fo:font-family", font); 0352 } 0353 0354 readNext(); 0355 READ_EPILOGUE 0356 } 0357 0358 #undef CURRENT_EL 0359 #define CURRENT_EL b 0360 //! b handler (Bold) 0361 /*! ECMA-376, 18.8.2, p. 1947. 0362 Displays characters in bold face font style. 0363 0364 Parent elements: 0365 - [done] font (§18.8.22) 0366 - [done] rPr (§18.4.7) 0367 0368 Child elements: 0369 - none 0370 */ 0371 KoFilter::ConversionStatus XlsxXmlCommonReader::read_b() 0372 { 0373 READ_PROLOGUE 0374 0375 const QXmlStreamAttributes attrs(attributes()); 0376 TRY_READ_ATTR_WITHOUT_NS(val) 0377 const bool bold = MSOOXML::Utils::convertBooleanAttr(val, true); 0378 m_currentTextStyleProperties->setFontWeight(bold ? QFont::Bold : QFont::Normal); 0379 0380 readNext(); 0381 READ_EPILOGUE 0382 } 0383 0384 #undef CURRENT_EL 0385 #define CURRENT_EL outline 0386 //! outline handler (Outline) 0387 /*! 0388 0389 Parent elements: 0390 - [done] font (§18.8.22) 0391 - [done] rPr (§18.4.7) 0392 0393 Child elements: 0394 - none 0395 */ 0396 KoFilter::ConversionStatus XlsxXmlCommonReader::read_outline() 0397 { 0398 READ_PROLOGUE 0399 0400 const QXmlStreamAttributes attrs(attributes()); 0401 TRY_READ_ATTR_WITHOUT_NS(val) 0402 if (val == "1") { 0403 m_currentTextStyleProperties->setTextOutline(QPen(Qt::SolidLine)); 0404 } 0405 0406 readNext(); 0407 READ_EPILOGUE 0408 } 0409 0410 #undef CURRENT_EL 0411 #define CURRENT_EL strike 0412 //! strike handler (Strike Through) 0413 /*! ECMA-376, 18.4.10, p. 1913. 0414 This element draws a strikethrough line through the horizontal middle of the text. 0415 0416 Parent elements: 0417 - [done] font (§18.8.22) 0418 - [done] rPr (§18.4.7) 0419 0420 Child elements: 0421 - none 0422 */ 0423 KoFilter::ConversionStatus XlsxXmlCommonReader::read_strike() 0424 { 0425 READ_PROLOGUE 0426 0427 m_currentTextStyleProperties->setStrikeOutStyle(KoCharacterStyle::SolidLine); 0428 m_currentTextStyleProperties->setStrikeOutType(KoCharacterStyle::SingleLine); 0429 0430 readNext(); 0431 READ_EPILOGUE 0432 } 0433 0434 #undef CURRENT_EL 0435 #define CURRENT_EL u 0436 //! u handler (Underline) 0437 /*! ECMA-376, 18.4.13, p. 1914. 0438 This element represents the underline formatting style. 0439 0440 Parent elements: 0441 - [done] font (§18.8.22) 0442 - [done] rPr (§18.4.7) 0443 0444 Child elements: 0445 - none 0446 */ 0447 KoFilter::ConversionStatus XlsxXmlCommonReader::read_u() 0448 { 0449 READ_PROLOGUE 0450 const QXmlStreamAttributes attrs(attributes()); 0451 0452 TRY_READ_ATTR_WITHOUT_NS(val) 0453 if (!val.isEmpty()) { 0454 MSOOXML::Utils::setupUnderLineStyle(val, m_currentTextStyleProperties); 0455 } 0456 0457 readNext(); 0458 READ_EPILOGUE 0459 } 0460 0461 #undef CURRENT_EL 0462 #define CURRENT_EL color 0463 //! color 0464 /* 0465 Parent elements: 0466 - [done] font (§18.8.22); 0467 - [done] rPr (§18.4.7) 0468 0469 Child elements: 0470 - none 0471 */ 0472 KoFilter::ConversionStatus XlsxXmlCommonReader::read_color() 0473 { 0474 READ_PROLOGUE 0475 const QXmlStreamAttributes attrs(attributes()); 0476 0477 TRY_READ_ATTR_WITHOUT_NS(indexed) 0478 TRY_READ_ATTR_WITHOUT_NS(rgb) 0479 TRY_READ_ATTR_WITHOUT_NS(theme) 0480 TRY_READ_ATTR_WITHOUT_NS(tint) 0481 0482 if (!indexed.isEmpty()) { 0483 int index = indexed.toInt(); 0484 if (index >= 0 && index < 64) { 0485 m_currentColor = QString("#%1").arg(m_colorIndices.at(index)); 0486 } 0487 } 0488 if (!rgb.isEmpty()) { 0489 m_currentColor = QString("#" + rgb.right(rgb.length()-2)); 0490 } 0491 if (!theme.isEmpty()) { 0492 // Xlsx seems to switch these indices 0493 if (theme == "0" ) { 0494 theme = "1"; 0495 } 0496 else if (theme == "1" ) { 0497 theme = "0"; 0498 } 0499 else if (theme == "2") { 0500 theme = "3"; 0501 } 0502 else if (theme == "3") { 0503 theme = "2"; 0504 } 0505 MSOOXML::DrawingMLColorSchemeItemBase *colorItemBase = m_themes->colorScheme.value(theme); 0506 if (colorItemBase) { 0507 m_currentColor = colorItemBase->value(); 0508 } 0509 } 0510 if (!tint.isEmpty()) { 0511 m_currentColor = tintedColor(m_currentColor, tint.toDouble()); 0512 } 0513 0514 readNext(); 0515 READ_EPILOGUE 0516 }