diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-04-16 14:30:28 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-04-16 18:41:47 +0200 |
commit | d8c0b63355af6caf3f0145dd1c10a93d63134a88 (patch) | |
tree | 7a4b312e9eb198400eef9ba045c364f97b6887d1 | |
parent | tdf#122222: add DOCX export of resolved comments as "done" (diff) | |
download | core-d8c0b63355af6caf3f0145dd1c10a93d63134a88.tar.gz core-d8c0b63355af6caf3f0145dd1c10a93d63134a88.zip |
tdf#122222: add DOCX import of resolved comments as "done"
Change-Id: Id596d18965de2d8c98853c281188fe8d749055f4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114204
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport16.cxx | 56 | ||||
-rw-r--r-- | writerfilter/CustomTarget_source.mk | 1 | ||||
-rw-r--r-- | writerfilter/inc/dmapper/CommentProperties.hxx | 21 | ||||
-rw-r--r-- | writerfilter/inc/dmapper/resourcemodel.hxx | 4 | ||||
-rw-r--r-- | writerfilter/inc/ooxml/OOXMLDocument.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 12 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 21 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 7 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.hxx | 4 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 11 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 4 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFactory.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.cxx | 37 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLFastContextHandler.hxx | 16 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 5 | ||||
-rw-r--r-- | writerfilter/source/ooxml/model.xml | 64 |
17 files changed, 257 insertions, 13 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx index 1c4bb106a0ec..722eb4f96606 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx @@ -18,6 +18,7 @@ #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/text/XEndnotesSupplier.hpp> #include <com/sun/star/text/XFootnotesSupplier.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <com/sun/star/text/XTextTable.hpp> #include <com/sun/star/text/XTextTablesSupplier.hpp> @@ -312,18 +313,8 @@ DECLARE_OOXMLEXPORT_TEST(testTdf140137, "tdf140137.docx") // Don't throw exception during load } -DECLARE_OOXMLEXPORT_TEST(testCommentDone, "CommentDone.docx") +DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testCommentDone, "CommentDone.docx") { - if (!mbExported) - { - // This manually toggles (enables) the resolved state of the first comment now, while - // import is not yet implemented (TODO) - uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence( - { { "Id", uno::makeAny(OUString("1")) } }); - dispatchCommand(mxComponent, ".uno:ResolveComment", aPropertyValues); - return; - } - xmlDocUniquePtr pXmlComm = parseExport("word/comments.xml"); assertXPath(pXmlComm, "/w:comments/w:comment[1]/w:p", 2); OUString idLastPara = getXPath(pXmlComm, "/w:comments/w:comment[1]/w:p[2]", "paraId"); @@ -335,6 +326,49 @@ DECLARE_OOXMLEXPORT_TEST(testCommentDone, "CommentDone.docx") assertXPath(pXmlCommExt, "/w15:commentsEx/w15:commentEx", "done", "1"); } +DECLARE_OOXMLEXPORT_TEST(testCommentDoneModel, "CommentDone.docx") +{ + css::uno::Reference<css::text::XTextFieldsSupplier> xTextFieldsSupplier( + mxComponent, css::uno::UNO_QUERY_THROW); + auto xFields(xTextFieldsSupplier->getTextFields()->createEnumeration()); + + // First comment: initially resolved, toggled to unresolved on import, unresolved on roundtrip + CPPUNIT_ASSERT(xFields->hasMoreElements()); + css::uno::Any aComment = xFields->nextElement(); + css::uno::Reference<css::beans::XPropertySet> xComment(aComment, css::uno::UNO_QUERY_THROW); + + if (!mbExported) + { + // Check that it's resolved when initially read + CPPUNIT_ASSERT_EQUAL(true, xComment->getPropertyValue("Resolved").get<bool>()); + // Set to unresolved + xComment->setPropertyValue("Resolved", css::uno::Any(false)); + } + else + { + // After the roundtrip, it keeps the "unresolved" state set above + CPPUNIT_ASSERT_EQUAL(false, xComment->getPropertyValue("Resolved").get<bool>()); + } + + // Second comment: initially unresolved, toggled to resolved on import, resolved on roundtrip + CPPUNIT_ASSERT(xFields->hasMoreElements()); + aComment = xFields->nextElement(); + xComment.set(aComment, css::uno::UNO_QUERY_THROW); + + if (!mbExported) + { + // Check that it's unresolved when initially read + CPPUNIT_ASSERT_EQUAL(false, xComment->getPropertyValue("Resolved").get<bool>()); + // Set to resolved + xComment->setPropertyValue("Resolved", css::uno::Any(true)); + } + else + { + // After the roundtrip, it keeps the "resolved" state set above + CPPUNIT_ASSERT_EQUAL(true, xComment->getPropertyValue("Resolved").get<bool>()); + } +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/CustomTarget_source.mk b/writerfilter/CustomTarget_source.mk index 8d7b3d22b690..d0085654a146 100644 --- a/writerfilter/CustomTarget_source.mk +++ b/writerfilter/CustomTarget_source.mk @@ -41,6 +41,7 @@ writerfilter_OOXMLNAMESPACES= \ vml-wordprocessingDrawing \ wp14 \ w14 \ + w15 \ a14 \ wml diff --git a/writerfilter/inc/dmapper/CommentProperties.hxx b/writerfilter/inc/dmapper/CommentProperties.hxx new file mode 100644 index 000000000000..1cba6930d4c6 --- /dev/null +++ b/writerfilter/inc/dmapper/CommentProperties.hxx @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +namespace writerfilter +{ +struct CommentProperties +{ + bool bDone; + // TODO: a reference to a parent comment (paraIdParent: [MS-DOCX] sect. 2.5.3.1 CT_CommentEx) +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/writerfilter/inc/dmapper/resourcemodel.hxx b/writerfilter/inc/dmapper/resourcemodel.hxx index fce90839d520..1a525b12296f 100644 --- a/writerfilter/inc/dmapper/resourcemodel.hxx +++ b/writerfilter/inc/dmapper/resourcemodel.hxx @@ -54,6 +54,8 @@ typedef sal_uInt32 Id; namespace writerfilter { +struct CommentProperties; + /** Reference to a resource that generates events and sends them to a handler. @@ -297,6 +299,8 @@ public: /// Receives end mark for glossary document entry. virtual void endGlossaryEntry() = 0; + virtual void commentProps(const OUString& /*sId*/, const CommentProperties& /*rProps*/) {} + protected: ~Stream() override {} }; diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index 1110fa84b1e0..de0a8a7134de 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -72,7 +72,7 @@ class OOXMLStream : public virtual SvRefBase { public: enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, WEBSETTINGS, FONTTABLE, NUMBERING, - FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER, VBADATA }; + FOOTNOTES, ENDNOTES, COMMENTS, COMMENTS_EXTENDED, THEME, CUSTOMXML, CUSTOMXMLPROPS, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER, VBADATA }; typedef tools::SvRef<OOXMLStream> Pointer_t; /** diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 2561120adb2d..9d163f2e671e 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1219,6 +1219,13 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) m_pImpl->HandleAltChunk(sStringValue); } break; + case NS_ooxml::LN_AG_Parids_paraId: + if (ParagraphPropertyMap* pParaContext + = dynamic_cast<ParagraphPropertyMap*>(m_pImpl->GetTopContext().get())) + { + pParaContext->SetParaId(sStringValue); + } + break; default: SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName); } @@ -4103,6 +4110,11 @@ void DomainMapper::finishParagraph(const bool bRemove, const bool bNoNumbering) m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove, bNoNumbering); } +void DomainMapper::commentProps(const OUString& sId, const CommentProperties& rProps) +{ + m_pImpl->commentProps(sId, rProps); +} + } //namespace writerfilter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper.hxx b/writerfilter/source/dmapper/DomainMapper.hxx index 4e47dd70a441..94b91460a6f9 100644 --- a/writerfilter/source/dmapper/DomainMapper.hxx +++ b/writerfilter/source/dmapper/DomainMapper.hxx @@ -131,6 +131,8 @@ public: void HandleRedline( Sprm& rSprm ); + virtual void commentProps(const OUString& sId, const CommentProperties& rProps) override; + private: // Stream virtual void lcl_startSectionGroup() override; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 914836944486..b0ef95e0a785 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -2120,6 +2120,17 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con m_previousRedline.clear(); m_bParaChanged = false; + if (m_bIsInComments && pParaContext) + { + if (const OUString sParaId = pParaContext->GetParaId(); !sParaId.isEmpty()) + { + if (const auto& item = m_aCommentProps.find(sParaId); item != m_aCommentProps.end()) + { + m_bAnnotationResolved = item->second.bDone; + } + } + } + if (m_bIsFirstParaInShape) m_bIsFirstParaInShape = false; @@ -3037,6 +3048,9 @@ void DomainMapper_Impl::PopAnnotation() try { + if (m_bAnnotationResolved) + m_xAnnotationField->setPropertyValue("Resolved", css::uno::Any(true)); + // See if the annotation will be a single position or a range. if (m_nAnnotationId == -1 || !m_aAnnotationPositions[m_nAnnotationId].m_xStart.is() || !m_aAnnotationPositions[m_nAnnotationId].m_xEnd.is()) { @@ -3085,6 +3099,7 @@ void DomainMapper_Impl::PopAnnotation() m_xAnnotationField.clear(); m_nAnnotationId = -1; + m_bAnnotationResolved = false; } void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > & xShape ) @@ -7700,6 +7715,12 @@ void DomainMapper_Impl::substream(Id rName, assert(m_aPropertyStacks[i].size() == propSize[i]); } } + +void DomainMapper_Impl::commentProps(const OUString& sId, const CommentProperties& rProps) +{ + m_aCommentProps[sId] = rProps; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index c4d9b5014c04..c12d75e201fa 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -33,6 +33,8 @@ #include <vector> #include <optional> +#include <dmapper/CommentProperties.hxx> + #include "DomainMapper.hxx" #include "DomainMapperTableManager.hxx" #include "DomainMapperTableHandler.hxx" @@ -590,6 +592,7 @@ private: //annotation import css::uno::Reference< css::beans::XPropertySet > m_xAnnotationField; sal_Int32 m_nAnnotationId; + bool m_bAnnotationResolved = false; std::unordered_map< sal_Int32, AnnotationPosition > m_aAnnotationPositions; void GetCurrentLocale(css::lang::Locale& rLocale); @@ -1128,6 +1131,8 @@ public: /// Handles <w:altChunk>. void HandleAltChunk(const OUString& rStreamName); + void commentProps(const OUString& sId, const CommentProperties& rProps); + private: void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType); // Start a new index section; if needed, finish current paragraph @@ -1146,6 +1151,8 @@ private: bool m_bParaWithInlineObject; /// SAXException was seen so document will be abandoned bool m_bSaxError; + + std::unordered_map<OUString, CommentProperties> m_aCommentProps; }; } //namespace writerfilter::dmapper diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index d5282991f1b5..d4f981c5db91 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -429,6 +429,7 @@ private: sal_Int32 m_yAlign; // from ST_YAlign bottom, center, inline, inside, outside, top sal_Int8 m_nDropCapLength; // number of characters OUString m_sParaStyleName; + OUString m_sParaId; // [MS-DOCX] sect. 2.2.4 "p and tr Extensions" css::uno::Reference< css::text::XTextRange > m_xStartingRange; // start of a frame css::uno::Reference< css::text::XTextRange > m_xEndingRange; // end of the frame @@ -507,6 +508,9 @@ public: const OUString& GetParaStyleName() const { return m_sParaStyleName; } void SetParaStyleName( const OUString& rSet ) { m_sParaStyleName = rSet; } + const OUString& GetParaId() const { return m_sParaId; } + void SetParaId(const OUString& rSet) { m_sParaId = rSet; } + void ResetFrameProperties(); }; diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 8d959dc0119f..0331d3539508 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -310,9 +310,20 @@ void OOXMLDocumentImpl::resolveEndnote(Stream & rStream, resolveFastSubStreamWithId(rStream, mpXNoteStream, nId); } +void OOXMLDocumentImpl::resolveCommentsExtendedStream(Stream& rStream) +{ + resolveFastSubStream(rStream, OOXMLStream::COMMENTS_EXTENDED); +} + void OOXMLDocumentImpl::resolveComment(Stream & rStream, const sal_Int32 nId) { + if (!mbCommentsExtendedResolved) + { + resolveCommentsExtendedStream(rStream); + mbCommentsExtendedResolved = true; + } + writerfilter::Reference<Stream>::Pointer_t pStream = getXNoteStream(OOXMLStream::COMMENTS, nId); diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index 93259997515b..ed9db125cbe8 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -67,6 +67,8 @@ class OOXMLDocumentImpl : public OOXMLDocument /// Graphic mapper css::uno::Reference<css::graphic::XGraphicMapper> mxGraphicMapper; + bool mbCommentsExtendedResolved = false; + private: void resolveFastSubStream(Stream & rStream, OOXMLStream::StreamType_t nType); @@ -88,6 +90,8 @@ private: void resolveCustomXmlStream(Stream & rStream); void resolveGlossaryStream(Stream & rStream); void resolveEmbeddingsStream(const OOXMLStream::Pointer_t& pStream); + void resolveCommentsExtendedStream(Stream & rStream); + public: OOXMLDocumentImpl(OOXMLStream::Pointer_t const & pStream, const css::uno::Reference<css::task::XStatusIndicator>& xStatusIndicator, bool bSkipImages, const css::uno::Sequence<css::beans::PropertyValue>& rDescriptor); virtual ~OOXMLDocumentImpl() override; diff --git a/writerfilter/source/ooxml/OOXMLFactory.hxx b/writerfilter/source/ooxml/OOXMLFactory.hxx index 79c375f2863e..4f3c82f1b070 100644 --- a/writerfilter/source/ooxml/OOXMLFactory.hxx +++ b/writerfilter/source/ooxml/OOXMLFactory.hxx @@ -48,7 +48,8 @@ enum class ResourceType { TwipsMeasure_asSigned, TwipsMeasure_asZero, HpsMeasure, - MeasurementOrPercent + MeasurementOrPercent, + CommentEx, }; struct AttributeInfo diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx index 2c48f121b066..efd097405c90 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.cxx @@ -34,6 +34,7 @@ #include "OOXMLFastContextHandler.hxx" #include "OOXMLFactory.hxx" #include "Handler.hxx" +#include <dmapper/CommentProperties.hxx> #include <dmapper/PropertyIds.hxx> #include <comphelper/propertysequence.hxx> #include <comphelper/sequenceashashmap.hxx> @@ -421,6 +422,20 @@ void OOXMLFastContextHandler::startParagraphGroup() { mpStream->startParagraphGroup(); mpParserState->setInParagraphGroup(true); + + if (const auto& pPropSet = getPropertySet()) + { + OOXMLPropertySetEntryToString aHandler(NS_ooxml::LN_AG_Parids_paraId); + pPropSet->resolve(aHandler); + if (const OUString& sText = aHandler.getString(); !sText.isEmpty()) + { + OOXMLStringValue::Pointer_t pVal = new OOXMLStringValue(sText); + OOXMLPropertySet::Pointer_t pPropertySet(new OOXMLPropertySet); + pPropertySet->add(NS_ooxml::LN_AG_Parids_paraId, pVal, OOXMLProperty::ATTRIBUTE); + mpStream->props(pPropertySet.get()); + } + } + } } @@ -2215,6 +2230,28 @@ void OOXMLFastContextHandlerMath::process() mpStream->props( pProps.get() ); } +OOXMLFastContextHandlerCommentEx::OOXMLFastContextHandlerCommentEx( + OOXMLFastContextHandler* pContext) + : OOXMLFastContextHandler(pContext) +{ +} + +void OOXMLFastContextHandlerCommentEx::lcl_endFastElement(Token_t /*Element*/) +{ + mpStream->commentProps(m_sParaId, { m_bDone }); +} + +void OOXMLFastContextHandlerCommentEx::att_paraId(const OOXMLValue::Pointer_t& pValue) +{ + m_sParaId = pValue->getString(); +} + +void OOXMLFastContextHandlerCommentEx::att_done(const OOXMLValue::Pointer_t& pValue) +{ + if (pValue->getInt()) + m_bDone = true; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx index aa67decdb55b..6aa2bd2ed6c2 100644 --- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx +++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx @@ -599,6 +599,22 @@ protected: virtual void process() override; }; +class OOXMLFastContextHandlerCommentEx : public OOXMLFastContextHandler +{ +public: + explicit OOXMLFastContextHandlerCommentEx(OOXMLFastContextHandler* pContext); + + virtual std::string getType() const override { return "CommentEx"; } + virtual void lcl_endFastElement(Token_t Element) override; + + void att_paraId(const OOXMLValue::Pointer_t& pValue); + void att_done(const OOXMLValue::Pointer_t& pValue); + +private: + OUString m_sParaId; + bool m_bDone = false; +}; + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index 1d54ffde00d1..67fa826957e9 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx @@ -145,6 +145,7 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc static const OUStringLiteral sFooterType = u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer"; static const OUStringLiteral sHeaderType = u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header"; static const OUStringLiteral sOleObjectType = u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"; + static const OUStringLiteral sCommentsExtendedType = u"http://schemas.microsoft.com/office/2011/relationships/commentsExtended"; // OOXML strict static const OUStringLiteral sDocumentTypeStrict = u"http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument"; static const OUStringLiteral sStylesTypeStrict = u"http://purl.oclc.org/ooxml/officeDocument/relationships/styles"; @@ -248,6 +249,10 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc sStreamType = sHeaderType; sStreamTypeStrict = sHeaderTypeStrict; break; + case COMMENTS_EXTENDED: + sStreamType = sCommentsExtendedType; + sStreamTypeStrict = sCommentsExtendedType; + break; default: break; } diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 3f45394d5d88..77dce046fb3d 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -26,6 +26,7 @@ xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" + xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" @@ -5359,6 +5360,54 @@ <element name="cntxtAlts" tokenid="ooxml:cntxtAlts_cntxtAlts"/> </resource> </namespace> + <namespace name="w15"> + <start name="commentsEx"/> + <grammar xmlns="http://relaxng.org/ns/structure/1.0" ns="http://schemas.microsoft.com/office/word/2012/wordml" attributeFormDefault="qualified"> + <define name="commentsEx"> + <element name="commentsEx"> + <ref name="CT_CommentsEx"/> + </element> + </define> + <define name="CT_CommentsEx"> + <element name="commentEx"> + <ref name="CT_CommentEx"/> + </element> + </define> + <define name="CT_CommentEx"> + <attribute name="paraId"> + <ref name="ST_LongHexNumber"/> + </attribute> + <!-- Not yet used + <attribute name="paraIdParent"> + <ref name="ST_LongHexNumber"/> + </attribute> + --> + <attribute name="done"> + <ref name="ST_OnOff"/> + </attribute> + </define> + <define name="ST_LongHexNumber"> + <data type="hexBinary"/> + </define> + <define name="ST_OnOff"> + <choice> + <value>true</value> + <value>false</value> + <value>0</value> + <value>1</value> + </choice> + </define> + </grammar> + <resource name="CT_CommentsEx" resource="Stream"> + <element name="commentEx" tokenid="ooxml:CT_CommentsEx_commentEx"/> + </resource> + <resource name="CT_CommentEx" resource="CommentEx"> + <attribute name="paraId" tokenid="ooxml:CT_CommentEx_paraId" action="att_paraId"/> + <attribute name="done" tokenid="ooxml:CT_CommentEx_done" action="att_done"/> + </resource> + <resource name="ST_LongHexNumber" resource="String"/> + <resource name="ST_OnOff" resource="Boolean"/> + </namespace> <namespace name="a14"> <grammar xmlns="http://relaxng.org/ns/structure/1.0" ns="http://schemas.microsoft.com/office/drawing/2010/main"> <!-- Simple types --> @@ -14197,6 +14246,18 @@ </element> </choice> </define> + <!-- [MS-DOCX] sect. 2.2.4 "p and tr Extensions" --> + <!-- Should rather be in w14 namespace, but I don't see how to reference things from there --> + <define name="AG_Parids"> + <attribute name="w14:paraId"> + <data type="string"/> + </attribute> + <!-- Not yet used + <attribute name="textId"> + <ref name="ST_LongHexNumber"/> + </attribute> + --> + </define> <define name="CT_P"> <element name="pPr"> <ref name="CT_PPr"/> @@ -14217,6 +14278,7 @@ <attribute name="rsidRDefault"> <data type="string"/> </attribute> + <ref name="AG_Parids"/> <!-- tdf#108714 : allow <w:br> at paragraph level (despite this is illegal according to ECMA-376-1:2016) - bug-to-bug compatibility with Word --> <element name="br"> <ref name="CT_Br_OutOfOrder"/> @@ -14522,6 +14584,7 @@ <attribute name="rsidTr"> <data type="string"/> </attribute> + <ref name="AG_Parids"/> </define> <define name="ST_TblLayout"> <choice> @@ -18296,6 +18359,7 @@ <element name="subDoc" tokenid="ooxml:EG_PContent_subDoc"/> </resource> <resource name="CT_P" resource="Stream"> + <attribute name="w14:paraId" tokenid="ooxml:AG_Parids_paraId"/> <action name="start" action="handleLastParagraphInSection"/> <action name="start" action="startParagraphGroup"/> <action name="start" action="setHandle"/> |