summaryrefslogtreecommitdiff
path: root/writerfilter
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-04-16 14:30:28 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2021-04-16 23:10:34 +0300
commit3adf3fa04e5644dcc68996caa621b07b642e9829 (patch)
tree804c0ef7acec8cfa9164cf660c0c03d771f834e2 /writerfilter
parent21ac373fdfc7842a77f5cb1b5504dd73afac311b (diff)
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>
Diffstat (limited to 'writerfilter')
-rw-r--r--writerfilter/CustomTarget_source.mk1
-rw-r--r--writerfilter/inc/dmapper/CommentProperties.hxx21
-rw-r--r--writerfilter/inc/dmapper/resourcemodel.hxx4
-rw-r--r--writerfilter/inc/ooxml/OOXMLDocument.hxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx12
-rw-r--r--writerfilter/source/dmapper/DomainMapper.hxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx21
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx7
-rw-r--r--writerfilter/source/dmapper/PropertyMap.hxx4
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.cxx11
-rw-r--r--writerfilter/source/ooxml/OOXMLDocumentImpl.hxx4
-rw-r--r--writerfilter/source/ooxml/OOXMLFactory.hxx3
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.cxx37
-rw-r--r--writerfilter/source/ooxml/OOXMLFastContextHandler.hxx16
-rw-r--r--writerfilter/source/ooxml/OOXMLStreamImpl.cxx5
-rw-r--r--writerfilter/source/ooxml/model.xml64
16 files changed, 212 insertions, 2 deletions
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 5ea1512fb1ba..7ecb82335d23 100644
--- a/writerfilter/inc/dmapper/resourcemodel.hxx
+++ b/writerfilter/inc/dmapper/resourcemodel.hxx
@@ -55,6 +55,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 72aa04493d1b..f85507bb53aa 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -73,7 +73,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 fd9fd7f4bce7..ea3657d94dc2 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1239,6 +1239,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);
}
@@ -4080,6 +4087,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 4d405c764f7f..d3c779a10b6c 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -2093,6 +2093,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;
@@ -2853,6 +2864,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())
{
@@ -2901,6 +2915,7 @@ void DomainMapper_Impl::PopAnnotation()
m_xAnnotationField.clear();
m_nAnnotationId = -1;
+ m_bAnnotationResolved = false;
}
void DomainMapper_Impl::PushPendingShape( const uno::Reference< drawing::XShape > & xShape )
@@ -7538,6 +7553,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 2fb996ccd9ff..8da791182f6e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -32,6 +32,8 @@
#include <vector>
#include <optional>
+#include <dmapper/CommentProperties.hxx>
+
#include "DomainMapper.hxx"
#include "DomainMapperTableManager.hxx"
#include "DomainMapperTableHandler.hxx"
@@ -572,6 +574,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);
@@ -1103,6 +1106,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
@@ -1119,6 +1124,8 @@ private:
bool m_bSaveFirstParagraphInCell;
/// Current paragraph had at least one inline object in it.
bool m_bParaWithInlineObject;
+
+ 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 f8c976abd388..d25e87671efb 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 fba694b5b77b..72671cb93c1e 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -310,9 +310,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 1848f8971766..657f3317c1d9 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 bf92bd6e2a51..5446e1907b64 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.hxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.hxx
@@ -49,7 +49,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 3b62c912967e..7c01b7f2f29e 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>
@@ -406,6 +407,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());
+ }
+ }
+
}
}
@@ -2198,6 +2213,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 ac8346d3dad2..8074b5ccf5bd 100644
--- a/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
+++ b/writerfilter/source/ooxml/OOXMLFastContextHandler.hxx
@@ -600,6 +600,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 7d48f1c08fce..9c7baecc6bfc 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 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";
@@ -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"/>