File indexing completed on 2025-01-19 13:27:35

0001 /*
0002  * This file is part of Office 2007 Filters for Calligra
0003  *
0004  * Copyright (C) 2010 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 "XlsxXmlCommentsReader.h"
0025 #include "XlsxXmlWorksheetReader.h"
0026 #include "XlsxImport.h"
0027 #include <MsooXmlSchemas.h>
0028 
0029 #include <KoXmlWriter.h>
0030 
0031 //#define MSOOXML_CURRENT_NS
0032 #define MSOOXML_CURRENT_CLASS XlsxXmlCommentsReader
0033 #define BIND_READ_CLASS MSOOXML_CURRENT_CLASS
0034 
0035 #include <MsooXmlReader_p.h>
0036 #include <MsooXmlUtils.h>
0037 
0038 #include <memory>
0039 
0040 XlsxComment::XlsxComment(uint authorId)
0041     : m_authorId(authorId)
0042 {
0043 }
0044 
0045 XlsxComments::XlsxComments()
0046 {
0047 }
0048 
0049 XlsxXmlCommentsReaderContext::XlsxXmlCommentsReaderContext(XlsxComments& _comments, MSOOXML::DrawingMLTheme* _themes,
0050     QVector<QString>& _colorIndices)
0051     : comments(&_comments)
0052     , themes(_themes)
0053     , colorIndices(_colorIndices)
0054 {
0055 }
0056 
0057 XlsxXmlCommentsReaderContext::~XlsxXmlCommentsReaderContext()
0058 {
0059 }
0060 
0061 XlsxXmlCommentsReader::XlsxXmlCommentsReader(KoOdfWriters *writers)
0062     : XlsxXmlCommonReader(writers)
0063 {
0064 }
0065 
0066 XlsxXmlCommentsReader::~XlsxXmlCommentsReader()
0067 {
0068 }
0069 
0070 KoFilter::ConversionStatus XlsxXmlCommentsReader::read(MSOOXML::MsooXmlReaderContext* context)
0071 {
0072     m_context = dynamic_cast<XlsxXmlCommentsReaderContext*>(context);
0073     Q_ASSERT(m_context);
0074     m_colorIndices = m_context->colorIndices;
0075     m_themes = m_context->themes;
0076     const KoFilter::ConversionStatus result = readInternal();
0077     m_context = 0;
0078     if (result != KoFilter::OK) {
0079         qCWarning(lcXlsxImport) << "Failure reading the comments";
0080     }
0081     // We're not going to fail reading the whole file because the comments cannot be read
0082     return KoFilter::OK;
0083 }
0084 
0085 KoFilter::ConversionStatus XlsxXmlCommentsReader::readInternal()
0086 {
0087     readNext();
0088     if (!isStartDocument()) {
0089         return KoFilter::WrongFormat;
0090     }
0091 
0092     // comments
0093     readNext();
0094     qCDebug(lcXlsxImport) << *this << namespaceUri();
0095 
0096     if (!expectEl("comments")) {
0097         return KoFilter::WrongFormat;
0098     }
0099     if (!expectNS(MSOOXML::Schemas::spreadsheetml)) {
0100         return KoFilter::WrongFormat;
0101     }
0102 
0103     QXmlStreamNamespaceDeclarations namespaces(namespaceDeclarations());
0104     for (int i = 0; i < namespaces.count(); i++) {
0105         qCDebug(lcXlsxImport) << "NS prefix:" << namespaces[i].prefix() << "uri:" << namespaces[i].namespaceUri();
0106     }
0107 //! @todo find out whether the namespace returned by namespaceUri()
0108 //!       is exactly the same ref as the element of namespaceDeclarations()
0109     if (!namespaces.contains(QXmlStreamNamespaceDeclaration(QString(), MSOOXML::Schemas::spreadsheetml))) {
0110         raiseError(i18n("Namespace \"%1\" not found", QLatin1String(MSOOXML::Schemas::spreadsheetml)));
0111         return KoFilter::WrongFormat;
0112     }
0113 //! @todo expect other namespaces too...
0114 
0115     TRY_READ(comments)
0116 
0117     qCDebug(lcXlsxImport) << "===========finished============";
0118     return KoFilter::OK;
0119 }
0120 
0121 #undef CURRENT_EL
0122 #define CURRENT_EL comments
0123 /*
0124  Parent elements:
0125  - root element
0126 
0127  Child elements:
0128  - [done] authors (Authors) §18.7.2
0129  - [done] commentList (List of Comments) §18.7.4
0130  - extLst (Future Feature Data Storage Area) §18.2.10
0131 
0132 */
0133 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_comments()
0134 {
0135     READ_PROLOGUE
0136     while (!atEnd()) {
0137         readNext();
0138         BREAK_IF_END_OF(CURRENT_EL)
0139         if (isStartElement()) {
0140             TRY_READ_IF(authors)
0141             ELSE_TRY_READ_IF(commentList)
0142 //            ELSE_TRY_READ_IF(extLst)
0143         }
0144     }
0145     READ_EPILOGUE
0146 }
0147 
0148 //! 18.7.2 authors (Authors)
0149 /*
0150  Parent elements:
0151  - [done] comments (§18.7.6)
0152 
0153  Child elements:
0154  - [done] author (Author) §18.7.1
0155 
0156 */
0157 #undef CURRENT_EL
0158 #define CURRENT_EL authors
0159 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_authors()
0160 {
0161     READ_PROLOGUE
0162     while (!atEnd()) {
0163         readNext();
0164         BREAK_IF_END_OF(CURRENT_EL)
0165         if (isStartElement()) {
0166             TRY_READ_IF(author)
0167             ELSE_WRONG_FORMAT
0168         }
0169     }
0170     READ_EPILOGUE
0171 }
0172 
0173 //! 18.7.1 author (Author)
0174 /*
0175  Parent elements:
0176  - [done] authors (§18.7.2)
0177 
0178  Child elements:
0179  - none
0180 */
0181 #undef CURRENT_EL
0182 #define CURRENT_EL author
0183 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_author()
0184 {
0185     READ_PROLOGUE
0186     readNext();
0187     const QString author(text().toString().trimmed());
0188     qCDebug(lcXlsxImport) << "Added author #" << (m_context->comments->count() + 1) << author;
0189     m_context->comments->m_authors.append(author);
0190 
0191     readNext();
0192     READ_EPILOGUE
0193 }
0194 
0195 #undef CURRENT_EL
0196 #define CURRENT_EL commentPr
0197 /*
0198  Parent elements:
0199  - [done] comment (§18.7.3)
0200 
0201  Child elements:
0202  - anchor (Object Cell Anchor) §18.3.1.1
0203 
0204 */
0205 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_commentPr()
0206 {
0207     READ_PROLOGUE
0208     while (!atEnd()) {
0209         readNext();
0210         BREAK_IF_END_OF(CURRENT_EL)
0211         if (isStartElement()) {
0212             //TRY_READ_IF(anchor)
0213             //ELSE_WRONG_FORMAT
0214         }
0215     }
0216     READ_EPILOGUE
0217 }
0218 
0219 #undef CURRENT_EL
0220 #define CURRENT_EL commentList
0221 /*
0222  Parent elements:
0223  - [done] comments (§18.7.6)
0224 
0225  Child elements:
0226  - [done] comment (Comment) §18.7.3
0227 
0228 */
0229 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_commentList()
0230 {
0231     READ_PROLOGUE
0232     while (!atEnd()) {
0233         readNext();
0234         BREAK_IF_END_OF(CURRENT_EL)
0235         if (isStartElement()) {
0236             TRY_READ_IF(comment)
0237             ELSE_WRONG_FORMAT
0238         }
0239     }
0240     READ_EPILOGUE
0241 }
0242 
0243 #undef CURRENT_EL
0244 #define CURRENT_EL comment
0245 /*
0246  Parent elements:
0247  - [done] commentList (§18.7.4)
0248 
0249  Child elements:
0250  - [done] commentPr (Comment Properties) §18.7.5
0251  - [done] text (Comment Text) §18.7.7
0252 
0253 */
0254 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_comment()
0255 {
0256     READ_PROLOGUE
0257     const QXmlStreamAttributes attrs(attributes());
0258     READ_ATTR_WITHOUT_NS(ref)
0259     READ_ATTR_WITHOUT_NS(authorId)
0260     int authorIdInt = -1;
0261     STRING_TO_INT(authorId, authorIdInt, "comment@authorId")
0262     std::auto_ptr<XlsxComment> comment(authorIdInt < 0 ? 0 : new XlsxComment(authorIdInt));
0263     while (!atEnd()) {
0264         readNext();
0265         BREAK_IF_END_OF(CURRENT_EL)
0266         if (isStartElement()) {
0267             TRY_READ_IF(text)
0268             ELSE_TRY_READ_IF(commentPr)
0269             ELSE_WRONG_FORMAT
0270         }
0271     }
0272     if (comment.get()) {
0273         comment.get()->texts = m_currentCommentText;
0274         m_context->comments->insert(ref, comment.release());
0275         qCDebug(lcXlsxImport) << "Added comment for" << ref;
0276     }
0277     READ_EPILOGUE
0278 }
0279 
0280 #undef CURRENT_EL
0281 #define CURRENT_EL text
0282 /*
0283  Parent elements:
0284  - [done] comment (§18.7.3)
0285 
0286  Child elements:
0287  - phoneticPr (Phonetic Properties) §18.4.3
0288  - [done] r (Rich Text Run) §18.4.4
0289  - rPh (Phonetic Run) §18.4.6
0290  - [done] t (Text) §18.4.12
0291 
0292 */
0293 KoFilter::ConversionStatus XlsxXmlCommentsReader::read_text()
0294 {
0295     READ_PROLOGUE
0296 
0297     QByteArray commentData;
0298     QBuffer commentBuffer(&commentData);
0299     commentBuffer.open(QIODevice::WriteOnly);
0300     KoXmlWriter commentWriter(&commentBuffer, 0/*indentation*/);
0301     MSOOXML::Utils::XmlWriteBuffer buf;
0302     body = buf.setWriter(&commentWriter);
0303 
0304     while (!atEnd()) {
0305         readNext();
0306         BREAK_IF_END_OF(CURRENT_EL)
0307         if (isStartElement()) {
0308             TRY_READ_IF(r)
0309             ELSE_TRY_READ_IF(t)
0310             //! @todo ELSE_TRY_READ_IF(rPh)
0311             //! @todo ELSE_TRY_READ_IF(phoneticPr)
0312             //! @todo add ELSE_WRONG_FORMAT
0313         }
0314     }
0315 
0316     body = buf.releaseWriter();
0317     commentBuffer.close();
0318     m_currentCommentText = commentData;
0319 
0320     READ_EPILOGUE
0321 }