File indexing completed on 2025-01-19 13:27:36
0001 /* 0002 * This file is part of Office 2007 Filters for Calligra 0003 * 0004 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 0005 * 0006 * Contact: Suresh Chande suresh.chande@nokia.com 0007 * 0008 * This library is free software; you can redistribute it and/or 0009 * modify it under the terms of the GNU Lesser General Public License 0010 * version 2.1 as published by the Free Software Foundation. 0011 * 0012 * This library is distributed in the hope that it will be useful, but 0013 * WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 0020 * 02110-1301 USA 0021 * 0022 */ 0023 0024 #include "XlsxUtils.h" 0025 #include "XlsxXmlSharedStringsReader.h" 0026 0027 #include <MsooXmlSchemas.h> 0028 #include <MsooXmlUtils.h> 0029 #include <KoXmlWriter.h> 0030 0031 #undef MSOOXML_CURRENT_NS 0032 #define MSOOXML_CURRENT_CLASS XlsxXmlSharedStringsReader 0033 #define BIND_READ_CLASS MSOOXML_CURRENT_CLASS 0034 0035 #include <MsooXmlReader_p.h> 0036 0037 // ------------------------------------------------------------- 0038 0039 XlsxXmlSharedStringsReaderContext::XlsxXmlSharedStringsReaderContext(QVector<QString>& _strings, MSOOXML::DrawingMLTheme* _themes, 0040 QVector<QString>& _colorIndices) 0041 : strings(&_strings), themes(_themes), colorIndices(_colorIndices) 0042 { 0043 } 0044 0045 class XlsxXmlSharedStringsReader::Private 0046 { 0047 public: 0048 Private() { 0049 } 0050 ~Private() { 0051 } 0052 private: 0053 }; 0054 0055 XlsxXmlSharedStringsReader::XlsxXmlSharedStringsReader(KoOdfWriters *writers) 0056 : XlsxXmlCommonReader(writers) 0057 , m_context(0) 0058 , d(new Private) 0059 { 0060 init(); 0061 } 0062 0063 XlsxXmlSharedStringsReader::~XlsxXmlSharedStringsReader() 0064 { 0065 delete d; 0066 } 0067 0068 void XlsxXmlSharedStringsReader::init() 0069 { 0070 m_defaultNamespace = ""; 0071 m_index = 0; 0072 } 0073 0074 KoFilter::ConversionStatus XlsxXmlSharedStringsReader::read(MSOOXML::MsooXmlReaderContext* context) 0075 { 0076 m_context = dynamic_cast<XlsxXmlSharedStringsReaderContext*>(context); 0077 Q_ASSERT(m_context); 0078 m_colorIndices = m_context->colorIndices; 0079 m_themes = m_context->themes; 0080 const KoFilter::ConversionStatus result = readInternal(); 0081 m_context = 0; 0082 if (result == KoFilter::OK) 0083 return KoFilter::OK; 0084 return result; 0085 } 0086 0087 KoFilter::ConversionStatus XlsxXmlSharedStringsReader::readInternal() 0088 { 0089 qCDebug(lcXlsxImport) << "============================="; 0090 readNext(); 0091 if (!isStartDocument()) { 0092 return KoFilter::WrongFormat; 0093 } 0094 0095 // sst 0096 readNext(); 0097 qCDebug(lcXlsxImport) << *this << namespaceUri(); 0098 0099 if (!expectEl("sst")) { 0100 return KoFilter::WrongFormat; 0101 } 0102 if (!expectNS(MSOOXML::Schemas::spreadsheetml)) { 0103 return KoFilter::WrongFormat; 0104 } 0105 0106 QXmlStreamNamespaceDeclarations namespaces(namespaceDeclarations()); 0107 for (int i = 0; i < namespaces.count(); i++) { 0108 qCDebug(lcXlsxImport) << "NS prefix:" << namespaces[i].prefix() << "uri:" << namespaces[i].namespaceUri(); 0109 } 0110 //! @todo find out whether the namespace returned by namespaceUri() 0111 //! is exactly the same ref as the element of namespaceDeclarations() 0112 if (!namespaces.contains(QXmlStreamNamespaceDeclaration(QString(), MSOOXML::Schemas::spreadsheetml))) { 0113 raiseError(i18n("Namespace \"%1\" not found", QLatin1String(MSOOXML::Schemas::spreadsheetml))); 0114 return KoFilter::WrongFormat; 0115 } 0116 //! @todo expect other namespaces too... 0117 0118 TRY_READ(sst) 0119 qCDebug(lcXlsxImport) << "===========finished============"; 0120 return KoFilter::OK; 0121 } 0122 0123 #undef CURRENT_EL 0124 #define CURRENT_EL sst 0125 //! workbook handler (Shared String Table) 0126 /*! ECMA-376, 18.4.9, p. 1912. 0127 Root element. 0128 */ 0129 KoFilter::ConversionStatus XlsxXmlSharedStringsReader::read_sst() 0130 { 0131 READ_PROLOGUE 0132 0133 const QXmlStreamAttributes attrs(attributes()); 0134 TRY_READ_ATTR_WITHOUT_NS(count) 0135 //! @todo use uniqueCount attr? 0136 // TRY_READ_ATTR_WITHOUT_NS(uniqueCount) 0137 bool ok = true; 0138 const uint countNumber = count.isEmpty() ? 0 : count.toUInt(&ok); 0139 if (!ok) { 0140 raiseUnexpectedAttributeValueError(count, "sst@count"); 0141 return KoFilter::WrongFormat; 0142 } 0143 m_context->strings->resize(countNumber); 0144 m_index = 0; 0145 0146 while (!atEnd()) { 0147 readNext(); 0148 BREAK_IF_END_OF(CURRENT_EL) 0149 if (isStartElement()) { 0150 TRY_READ_IF(si) 0151 ELSE_WRONG_FORMAT 0152 } 0153 } 0154 0155 READ_EPILOGUE 0156 } 0157 0158 #undef CURRENT_EL 0159 #define CURRENT_EL si 0160 //! si handler (String Item) 0161 /*! ECMA-376, 18.2.20, p. 1911. 0162 This element is the representation of an individual string in the Shared String table. 0163 0164 Child elements: 0165 - phoneticPr (Phonetic Properties) §18.4.3 0166 - [done] r (Rich Text Run) §18.4.4 0167 - rPh (Phonetic Run) §18.4.6 0168 - [done] t (Text) §18.4.12 0169 0170 Parent elements: 0171 - [done] sst (§18.4.9) 0172 0173 @todo support all child elements 0174 */ 0175 KoFilter::ConversionStatus XlsxXmlSharedStringsReader::read_si() 0176 { 0177 READ_PROLOGUE 0178 0179 qCDebug(lcXlsxImport) << "#" << m_index << text().toString(); 0180 if (m_index >= (uint)m_context->strings->size()) { 0181 raiseError(i18n("Declared number of shared strings too small (%1)", m_context->strings->size())); 0182 return KoFilter::WrongFormat; 0183 } 0184 0185 QByteArray siData; 0186 QBuffer siBuffer(&siData); 0187 siBuffer.open(QIODevice::WriteOnly); 0188 KoXmlWriter siWriter(&siBuffer, 0/*indentation*/); 0189 MSOOXML::Utils::XmlWriteBuffer buf; 0190 body = buf.setWriter(&siWriter); 0191 0192 while (!atEnd()) { 0193 readNext(); 0194 qCDebug(lcXlsxImport) << *this; 0195 BREAK_IF_END_OF(CURRENT_EL) 0196 if (isStartElement()) { 0197 TRY_READ_IF(t) 0198 ELSE_TRY_READ_IF(r) 0199 SKIP_UNKNOWN 0200 //! @todo support phoneticPr 0201 //! @todo support rPh 0202 //ELSE_WRONG_FORMAT 0203 } 0204 } 0205 0206 body = buf.releaseWriter(); 0207 siBuffer.close(); 0208 (*m_context->strings)[m_index] = QString::fromUtf8(siData); 0209 0210 m_index++; 0211 READ_EPILOGUE 0212 }