[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.4' - sw/qa writerfilter/CustomTarget_source.mk writerfilter/inc writerfilter/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 20 13:03:40 UTC 2021


 sw/qa/extras/ooxmlexport/ooxmlexport15.cxx            |   19 +++++
 writerfilter/CustomTarget_source.mk                   |    1 
 writerfilter/inc/dmapper/CommentProperties.hxx        |   21 +++++
 writerfilter/inc/dmapper/resourcemodel.hxx            |    3 
 writerfilter/inc/ooxml/OOXMLDocument.hxx              |    2 
 writerfilter/source/dmapper/DomainMapper.cxx          |   13 +++
 writerfilter/source/dmapper/DomainMapper.hxx          |    2 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx     |   21 +++++
 writerfilter/source/dmapper/DomainMapper_Impl.hxx     |    7 +
 writerfilter/source/dmapper/PropertyMap.hxx           |    4 +
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx       |   11 +++
 writerfilter/source/ooxml/OOXMLDocumentImpl.hxx       |    4 +
 writerfilter/source/ooxml/OOXMLFactory.hxx            |    3 
 writerfilter/source/ooxml/OOXMLFastContextHandler.cxx |   36 ++++++++++
 writerfilter/source/ooxml/OOXMLFastContextHandler.hxx |   16 ++++
 writerfilter/source/ooxml/OOXMLStreamImpl.cxx         |    5 +
 writerfilter/source/ooxml/model.xml                   |   64 ++++++++++++++++++
 17 files changed, 230 insertions(+), 2 deletions(-)

New commits:
commit 942ed1856769aeb9da6ba82f0bbcdd366ef3235b
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Fri Apr 16 14:30:28 2021 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Tue Apr 20 15:02:59 2021 +0200

    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 at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114329
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 6dbef482ef25..8b29a9adaf6c 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -198,6 +198,25 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133473_shadowSize, "tdf133473.docx")
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(200000), nSize1);
 }
 
+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: resolved
+    CPPUNIT_ASSERT(xFields->hasMoreElements());
+    css::uno::Any aComment = xFields->nextElement();
+    css::uno::Reference<css::beans::XPropertySet> xComment(aComment, css::uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(true, xComment->getPropertyValue("Resolved").get<bool>());
+
+    // Second comment: unresolved
+    CPPUNIT_ASSERT(xFields->hasMoreElements());
+    aComment = xFields->nextElement();
+    xComment.set(aComment, css::uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(false, 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 bd528d1a1e59..44e659235845 100644
--- a/writerfilter/inc/dmapper/resourcemodel.hxx
+++ b/writerfilter/inc/dmapper/resourcemodel.hxx
@@ -56,6 +56,7 @@
 typedef sal_uInt32 Id;
 
 namespace writerfilter {
+struct CommentProperties;
 
 /**
     Reference to a resource that generates events and sends them to a
@@ -303,6 +304,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 7856a6a4dced..57654b624d63 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -75,7 +75,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 2c47effafd45..c6d718790763 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1221,6 +1221,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);
     }
@@ -4014,7 +4021,13 @@ void DomainMapper::finishParagraph(const bool bRemove)
     m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH), bRemove);
 }
 
+void DomainMapper::commentProps(const OUString& sId, const CommentProperties& rProps)
+{
+    m_pImpl->commentProps(sId, rProps);
+}
+
 } //namespace dmapper
+
 } //namespace writerfilter
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/dmapper/DomainMapper.hxx b/writerfilter/source/dmapper/DomainMapper.hxx
index 55f9a20e0373..b2c2ba63d9a0 100644
--- a/writerfilter/source/dmapper/DomainMapper.hxx
+++ b/writerfilter/source/dmapper/DomainMapper.hxx
@@ -129,6 +129,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 c180a1250945..82c13df4f7ef 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -1902,6 +1902,17 @@ void DomainMapper_Impl::finishParagraph( const PropertyMapPtr& pPropertyMap, con
     }
     m_previousRedline.clear();
 
+    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;
 
@@ -2618,6 +2629,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())
         {
@@ -2666,6 +2680,7 @@ void DomainMapper_Impl::PopAnnotation()
 
     m_xAnnotationField.clear();
     m_nAnnotationId = -1;
+    m_bAnnotationResolved = false;
 }
 
 void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > & xShape )
@@ -7158,6 +7173,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 00621c1db263..668461bc978a 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -38,6 +38,8 @@
 
 #include <ooxml/resourceids.hxx>
 
+#include <dmapper/CommentProperties.hxx>
+
 #include "DomainMapper.hxx"
 #include "DomainMapperTableManager.hxx"
 #include "DomainMapperTableHandler.hxx"
@@ -569,6 +571,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);
@@ -1074,6 +1077,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
@@ -1087,6 +1092,8 @@ private:
     /// Current paragraph in a table is first paragraph of a cell
     bool m_bFirstParagraphInCell;
     bool m_bSaveFirstParagraphInCell;
+
+    std::unordered_map<OUString, CommentProperties> m_aCommentProps;
 };
 
 } //namespace dmapper
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx
index 923581fcfb86..5d1074b24c1c 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -413,6 +413,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
@@ -491,6 +492,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 b5ef23464f8f..2df01a68f27c 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -317,9 +317,20 @@ void OOXMLDocumentImpl::resolveEndnote(Stream & rStream,
     resolveFastSubStreamWithId(rStream, pStream, 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 6b290bc489d9..20015dc6e923 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -69,6 +69,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);
@@ -90,6 +92,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 04a71bbc92f4..a08229c0a597 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.hxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.hxx
@@ -55,7 +55,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 2d3ea9f328a9..68bfdf63a1a2 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>
 
 static const sal_Unicode uCR = 0xd;
 static const sal_Unicode uFtnEdnRef = 0x2;
@@ -384,6 +385,19 @@ 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());
+                }
+            }
         }
     }
 }
@@ -2161,6 +2175,28 @@ void OOXMLFastContextHandlerMath::process()
     }
 }
 
+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 4f2a070c85de..de3f3b7a61f9 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -589,6 +589,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;
+};
+
 }}
 #endif // INCLUDED_WRITERFILTER_SOURCE_OOXML_OOXMLFASTCONTEXTHANDLER_HXX
 
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 2b773e02cf5e..81e75a29b627 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -148,6 +148,7 @@ bool OOXMLStreamImpl::lcl_getTarget(const uno::Reference<embed::XRelationshipAcc
     static const char sFooterType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer";
     static const char sHeaderType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
     static const char sOleObjectType[] = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
+    static const char sCommentsExtendedType[] = "http://schemas.microsoft.com/office/2011/relationships/commentsExtended";
     // OOXML strict
     static const char sDocumentTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument";
     static const char sStylesTypeStrict[] = "http://purl.oclc.org/ooxml/officeDocument/relationships/styles";
@@ -251,6 +252,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 4ac953bacb1d..969eca1d84e3 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"
@@ -5353,6 +5354,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 -->
@@ -14186,6 +14235,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"/>
@@ -14206,6 +14267,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"/>
@@ -14516,6 +14578,7 @@
         <attribute name="rsidTr">
           <data type="string"/>
         </attribute>
+        <ref name="AG_Parids"/>
       </define>
       <define name="ST_TblLayout">
         <choice>
@@ -18290,6 +18353,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"/>


More information about the Libreoffice-commits mailing list