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 }