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 }