From 4fc84b0ee4e696a1010b1ba4b8bcf7ed14454569 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Tue, 13 Apr 2021 09:06:52 +0300 Subject: tdf#122222: add DOCX export of resolved comments as "done" Since implementation of tdf#119228, Writer comments may have "Resolved" state, which is the equivalent of Word's internal "done" flag. This relies on [MS-DOCX] extensions available since Word 2013. DOCX import will be implemented in a follow-up commit. [MS-DOCX]: https://docs.microsoft.com/en-us/openspecs/office_standards/ms-docx Change-Id: I3be1e8a096bdec41c8268974fe81328480eb0704 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114023 Tested-by: Jenkins Reviewed-by: Mike Kaganski Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114328 Reviewed-by: Miklos Vajna Tested-by: Jenkins CollaboraOffice --- include/oox/token/relationship.hxx | 1 + include/sax/tools/converter.hxx | 14 +++++ oox/source/token/namespaces-strict.txt | 1 + oox/source/token/namespaces.txt | 1 + oox/source/token/relationship.inc | 1 + oox/source/token/tokens.txt | 5 ++ sax/source/tools/converter.cxx | 15 ++++++ sw/qa/extras/ooxmlexport/data/CommentDone.docx | Bin 0 -> 20946 bytes sw/qa/inc/swmodeltestbase.hxx | 1 + sw/source/filter/ww8/attributeoutputbase.hxx | 2 +- sw/source/filter/ww8/docxattributeoutput.cxx | 69 +++++++++++++++++++++---- sw/source/filter/ww8/docxattributeoutput.hxx | 17 ++++-- sw/source/filter/ww8/docxexport.cxx | 30 +++++++++-- sw/source/filter/ww8/docxexport.hxx | 2 +- sw/source/filter/ww8/rtfattributeoutput.cxx | 4 +- sw/source/filter/ww8/rtfattributeoutput.hxx | 3 +- sw/source/filter/ww8/wrtw8nds.cxx | 2 +- sw/source/filter/ww8/ww8attributeoutput.hxx | 2 +- 18 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/CommentDone.docx diff --git a/include/oox/token/relationship.hxx b/include/oox/token/relationship.hxx index adc25f4a73b6..40253558c799 100644 --- a/include/oox/token/relationship.hxx +++ b/include/oox/token/relationship.hxx @@ -22,6 +22,7 @@ enum class Relationship CHART, COMMENTS, COMMENTAUTHORS, + COMMENTSEXTENDED, CONTROL, CTRLPROP, CUSTOMXML, diff --git a/include/sax/tools/converter.hxx b/include/sax/tools/converter.hxx index b15288e51062..6cbeffd2f770 100644 --- a/include/sax/tools/converter.hxx +++ b/include/sax/tools/converter.hxx @@ -20,6 +20,10 @@ #ifndef INCLUDED_SAX_TOOLS_CONVERTER_HXX #define INCLUDED_SAX_TOOLS_CONVERTER_HXX +#include + +#include + #include #include @@ -213,6 +217,16 @@ public: OUStringBuffer& rsType , const css::uno::Any& rValue); + /** convert specified byte sequence to xsd:hexBinary string **/ + static void convertBytesToHexBinary(OUStringBuffer& rBuffer, const void* pBytes, + sal_Int32 nBytes); + + template , int> = 0> + static void convertNumberToHexBinary(OUStringBuffer& rBuffer, T n) + { + convertBytesToHexBinary(rBuffer, &n, sizeof(n)); + } + }; } diff --git a/oox/source/token/namespaces-strict.txt b/oox/source/token/namespaces-strict.txt index d6990e5bdf91..36841732372e 100644 --- a/oox/source/token/namespaces-strict.txt +++ b/oox/source/token/namespaces-strict.txt @@ -84,6 +84,7 @@ p14 http://schemas.microsoft.com/office/powerpoint/2010/main # MSO 2012/2013 extensions --------------------------------------------------------- +w15 http://schemas.microsoft.com/office/word/2012/wordml p15 http://schemas.microsoft.com/office/powerpoint/2012/main x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac diff --git a/oox/source/token/namespaces.txt b/oox/source/token/namespaces.txt index 604541129469..20d283415069 100644 --- a/oox/source/token/namespaces.txt +++ b/oox/source/token/namespaces.txt @@ -84,6 +84,7 @@ p14 http://schemas.microsoft.com/office/powerpoint/2010/main # MSO 2012/2013 extensions --------------------------------------------------------- +w15 http://schemas.microsoft.com/office/word/2012/wordml p15 http://schemas.microsoft.com/office/powerpoint/2012/main x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac diff --git a/oox/source/token/relationship.inc b/oox/source/token/relationship.inc index 2b973ded1653..31d46cdd7d71 100644 --- a/oox/source/token/relationship.inc +++ b/oox/source/token/relationship.inc @@ -2,6 +2,7 @@ {Relationship::CHART, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"}, {Relationship::COMMENTS, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"}, {Relationship::COMMENTAUTHORS, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors"}, +{Relationship::COMMENTSEXTENDED, "http://schemas.microsoft.com/office/2011/relationships/commentsExtended"}, {Relationship::CONTROL, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"}, {Relationship::CTRLPROP, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp"}, {Relationship::CUSTOMXML, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"}, diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index 3929d8c93808..9f7b815e53c2 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -1314,12 +1314,14 @@ comma command commandType comment +commentEx commentList commentPr commentRangeEnd commentRangeStart commentReference comments +commentsEx comp compact compactData @@ -1901,6 +1903,7 @@ doNotValidateAgainstSchema doNotVertAlignCellWithSp doNotVertAlignInTxbx doNotWrapTextWithPunct +done doc docDefaults docEnd @@ -3850,6 +3853,7 @@ parTrans parTransId parTxLTRAlign parTxRTLAlign +paraId paragraph parallel parallelogram @@ -5672,6 +5676,7 @@ vt w w10 w14 +w15 wAfter wArH wBefore diff --git a/sax/source/tools/converter.cxx b/sax/source/tools/converter.cxx index 8ee00c63be1f..b73aef090e13 100644 --- a/sax/source/tools/converter.cxx +++ b/sax/source/tools/converter.cxx @@ -2439,6 +2439,21 @@ bool Converter::convertAny(OUStringBuffer& rsValue, return bConverted; } +void Converter::convertBytesToHexBinary(OUStringBuffer& rBuffer, const void* pBytes, + sal_Int32 nBytes) +{ + rBuffer.setLength(0); + rBuffer.ensureCapacity(nBytes * 2); + auto pChars = static_cast(pBytes); + for (sal_Int32 i = 0; i < nBytes; ++i) + { + sal_Int32 c = *pChars++; + if (c < 16) + rBuffer.append('0'); + rBuffer.append(c, 16); + } +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/data/CommentDone.docx b/sw/qa/extras/ooxmlexport/data/CommentDone.docx new file mode 100644 index 000000000000..1ce5993d440b Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/CommentDone.docx differ diff --git a/sw/qa/inc/swmodeltestbase.hxx b/sw/qa/inc/swmodeltestbase.hxx index 077a6e0a4205..e92b75aadce5 100644 --- a/sw/qa/inc/swmodeltestbase.hxx +++ b/sw/qa/inc/swmodeltestbase.hxx @@ -964,6 +964,7 @@ protected: xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("pic"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/picture")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("rels"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w14"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordml")); + xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w15"), BAD_CAST("http://schemas.microsoft.com/office/word/2012/wordml")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("m"), BAD_CAST("http://schemas.openxmlformats.org/officeDocument/2006/math")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("ContentType"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("lc"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas")); diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index 3d8daa633daa..da23f8ba3a7c 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -155,7 +155,7 @@ public: virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) = 0; /// Start of the paragraph. - virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) = 0; + virtual sal_Int32 StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, bool bGenerateParaId ) = 0; /// End of the paragraph. virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) = 0; diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index c2776d461c89..7310e7d5f395 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -290,6 +291,15 @@ class FieldMarkParamsHelper return bResult; } }; + +// [ISO/IEC29500-1:2016] 17.18.50 ST_LongHexNumber (Eight Digit Hexadecimal Value) +static OUString NumberToHexBinary(sal_Int32 n) +{ + OUStringBuffer aBuf; + sax::Converter::convertNumberToHexBinary(aBuf, n); + return aBuf.makeStringAndClear(); +} + void DocxAttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 /*nScript*/ ) { if (bIsRTL) @@ -379,7 +389,8 @@ static void checkAndWriteFloatingTables(DocxAttributeOutput& rDocxAttributeOutpu } } -void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) +sal_Int32 DocxAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, + bool bGenerateParaId) { // look ahead for floating tables that were put into a frame during import // floating tables in shapes are not supported: exclude this case @@ -468,7 +479,16 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText // We will only know if we have to do that later. m_pSerializer->mark(Tag_StartParagraph_1); - m_pSerializer->startElementNS(XML_w, XML_p); + const char* pParaId = nullptr; + OString aParaId; + sal_Int32 nParaId = 0; + if (bGenerateParaId) + { + nParaId = m_nNextParaId++; + aParaId = OUStringToOString(NumberToHexBinary(nParaId), RTL_TEXTENCODING_UTF8); + pParaId = aParaId.getStr(); + } + m_pSerializer->startElementNS(XML_w, XML_p, FSNS(XML_w14, XML_paraId), pParaId); // postpone the output of the run (we get it before the paragraph // properties, but must write it after them) @@ -479,6 +499,8 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText m_bParagraphOpened = true; m_bIsFirstParagraph = false; + + return nParaId; } static OString convertToOOXMLVertOrient(sal_Int16 nOrient) @@ -5794,7 +5816,7 @@ void DocxAttributeOutput::WriteOutliner(const OutlinerParaObject& rParaObj) sal_Int32 nCurrentPos = 0; sal_Int32 nEnd = aStr.getLength(); - StartParagraph(ww8::WW8TableNodeInfo::Pointer_t()); + StartParagraph(ww8::WW8TableNodeInfo::Pointer_t(), false); // Write paragraph properties. StartParagraphProperties(); @@ -7515,14 +7537,14 @@ void DocxAttributeOutput::PostitField( const SwField* pField ) else // Otherwise get a new one. nId = m_nNextAnnotationMarkId++; - m_postitFields.emplace_back(pPostItField, nId); + m_postitFields.emplace_back(pPostItField, PostItDOCXData{ nId }); } void DocxAttributeOutput::WritePostitFieldReference() { while( m_postitFieldsMaxId < m_postitFields.size()) { - OString idstr = OString::number(m_postitFields[m_postitFieldsMaxId].second); + OString idstr = OString::number(m_postitFields[m_postitFieldsMaxId].second.id); // In case this file is inside annotation marks, we want to write the // comment reference after the annotation mark is closed, not here. @@ -7534,27 +7556,39 @@ void DocxAttributeOutput::WritePostitFieldReference() } } -void DocxAttributeOutput::WritePostitFields() +DocxAttributeOutput::hasResolved DocxAttributeOutput::WritePostitFields() { - for (const auto& rPair : m_postitFields) + hasResolved eResult = hasResolved::no; + for (auto& [f, data] : m_postitFields) { - OString idstr = OString::number( rPair.second); - const SwPostItField* f = rPair.first; + OString idstr = OString::number(data.id); m_pSerializer->startElementNS( XML_w, XML_comment, FSNS( XML_w, XML_id ), idstr, FSNS( XML_w, XML_author ), f->GetPar1().toUtf8(), FSNS( XML_w, XML_date ), DateTimeToOString(f->GetDateTime()), FSNS( XML_w, XML_initials ), f->GetInitials().toUtf8() ); + const bool bNeedParaId = f->GetResolved(); + if (bNeedParaId) + eResult = hasResolved::yes; + if (f->GetTextObject() != nullptr) { // richtext - GetExport().WriteOutliner(*f->GetTextObject(), TXT_ATN); + data.lastParaId = GetExport().WriteOutliner(*f->GetTextObject(), TXT_ATN, bNeedParaId); } else { // just plain text - eg. when the field was created via the // .uno:InsertAnnotation API - m_pSerializer->startElementNS(XML_w, XML_p); + const char* pParaId = nullptr; + OString aParaId; + if (bNeedParaId) + { + data.lastParaId = m_nNextParaId++; + aParaId = OUStringToOString(NumberToHexBinary(data.lastParaId), RTL_TEXTENCODING_UTF8); + pParaId = aParaId.getStr(); + } + m_pSerializer->startElementNS(XML_w, XML_p, FSNS(XML_w14, XML_paraId), pParaId); m_pSerializer->startElementNS(XML_w, XML_r); RunText(f->GetText()); m_pSerializer->endElementNS(XML_w, XML_r); @@ -7563,6 +7597,19 @@ void DocxAttributeOutput::WritePostitFields() m_pSerializer->endElementNS( XML_w, XML_comment ); } + return eResult; +} + +void DocxAttributeOutput::WritePostItFieldsResolved() +{ + for (auto& [f, data] : m_postitFields) + { + if (!f->GetResolved()) + continue; + OString idstr = OUStringToOString(NumberToHexBinary(data.lastParaId), RTL_TEXTENCODING_UTF8); + m_pSerializer->singleElementNS(XML_w15, XML_commentEx, FSNS(XML_w15, XML_paraId), idstr, + FSNS(XML_w15, XML_done), "1"); + } } bool DocxAttributeOutput::DropdownField( const SwField* pField ) diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index 6655b180bb2b..dd91f1668e10 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -127,7 +127,8 @@ public: virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) override; /// Start of the paragraph. - virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo ) override; + virtual sal_Int32 StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, + bool bGenerateParaId) override; /// End of the paragraph. virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) override; @@ -787,6 +788,9 @@ private: sal_Int32 m_nNextBookmarkId; sal_Int32 m_nNextAnnotationMarkId; + /// [MS-DOCX] section 2.6.2.3 + sal_Int32 m_nNextParaId = 1; // MUST be greater than 0 + OUString m_sRawText; /// Bookmarks to output @@ -915,8 +919,13 @@ private: std::vector m_aPostponedFormControls; std::vector m_aPostponedActiveXControls; const SwField* pendingPlaceholder; + + struct PostItDOCXData{ + sal_Int32 id; + sal_Int32 lastParaId = 0; // [MS-DOCX] 2.5.3.1 CT_CommentEx needs paraId attribute + }; /// Maps postit fields to ID's, used in commentRangeStart/End, commentReference and comment.xml. - std::vector< std::pair > m_postitFields; + std::vector> m_postitFields; /// Number of postit fields which already have a commentReference written. unsigned int m_postitFieldsMaxId; int m_anchorId; @@ -1009,7 +1018,9 @@ public: static void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & fs, int tag, const SwEndNoteInfo& info, int listtag ); bool HasPostitFields() const; - void WritePostitFields(); + enum class hasResolved { no, yes }; + hasResolved WritePostitFields(); + void WritePostItFieldsResolved(); /// VMLTextExport virtual void WriteOutliner(const OutlinerParaObject& rParaObj) override; diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index ad5104b6dd7f..4e26362f6ed3 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -737,9 +737,29 @@ void DocxExport::WritePostitFields() pPostitFS->startElementNS( XML_w, XML_comments, MainXmlNamespaces()); m_pAttrOutput->SetSerializer( pPostitFS ); - m_pAttrOutput->WritePostitFields(); + const auto eHasResolved = m_pAttrOutput->WritePostitFields(); m_pAttrOutput->SetSerializer( m_pDocumentFS ); pPostitFS->endElementNS( XML_w, XML_comments ); + + if (eHasResolved != DocxAttributeOutput::hasResolved::yes) + return; + + m_pFilter->addRelation(m_pDocumentFS->getOutputStream(), + oox::getRelationship(Relationship::COMMENTSEXTENDED), + "commentsExtended.xml"); + + pPostitFS = m_pFilter->openFragmentStreamWithSerializer( + "word/commentsExtended.xml", + "application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml"); + + pPostitFS->startElementNS(XML_w15, XML_commentsEx, // Add namespaces manually now + FSNS(XML_xmlns, XML_mc), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(mce)), RTL_TEXTENCODING_UTF8), + FSNS(XML_xmlns, XML_w15), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(w15)), RTL_TEXTENCODING_UTF8), + FSNS(XML_mc, XML_Ignorable), "w15"); + m_pAttrOutput->SetSerializer(pPostitFS); + m_pAttrOutput->WritePostItFieldsResolved(); + m_pAttrOutput->SetSerializer(m_pDocumentFS); + pPostitFS->endElementNS(XML_w15, XML_commentsEx); } } @@ -1619,18 +1639,21 @@ bool DocxExport::ignoreAttributeForStyleDefaults( sal_uInt16 nWhich ) const return MSWordExportBase::ignoreAttributeForStyleDefaults( nWhich ); } -void DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTyp) +sal_Int32 DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTyp, + bool bNeedsLastParaId) { const EditTextObject& rEditObj = rParaObj.GetTextObject(); MSWord_SdrAttrIter aAttrIter( *this, rEditObj, nTyp ); sal_Int32 nPara = rEditObj.GetParagraphCount(); + sal_Int32 nParaId = 0; for( sal_Int32 n = 0; n < nPara; ++n ) { if( n ) aAttrIter.NextPara( n ); - AttrOutput().StartParagraph( ww8::WW8TableNodeInfo::Pointer_t()); + nParaId = AttrOutput().StartParagraph(ww8::WW8TableNodeInfo::Pointer_t(), + bNeedsLastParaId && n == nPara - 1); rtl_TextEncoding eChrSet = aAttrIter.GetNodeCharSet(); OUString aStr( rEditObj.GetText( n )); sal_Int32 nCurrentPos = 0; @@ -1665,6 +1688,7 @@ void DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt8 nTy // aAttrIter.OutParaAttr(false); AttrOutput().EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t()); } + return nParaId; } void DocxExport::SetFS( ::sax_fastparser::FSHelperPtr const & pFS ) diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index f659cd1244f4..93482cc8344d 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -191,7 +191,7 @@ public: /// Writes the shape using drawingML syntax. void OutputDML( css::uno::Reference< css::drawing::XShape > const & xShape ); - void WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp); + sal_Int32 WriteOutliner(const OutlinerParaObject& rOutliner, sal_uInt8 nTyp, bool bNeedsLastParaId); virtual ExportFormat GetExportFormat() const override { return ExportFormat::DOCX; } diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 53fffd032a17..b8a2fdcaf680 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -209,7 +209,8 @@ void RtfAttributeOutput::RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript) m_bControlLtrRtl = true; } -void RtfAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo) +sal_Int32 RtfAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, + bool /*bGenerateParaId*/) { if (m_bIsBeforeFirstParagraph && m_rExport.m_nTextTyp != TXT_HDFT) m_bIsBeforeFirstParagraph = false; @@ -265,6 +266,7 @@ void RtfAttributeOutput::StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNo } OSL_ENSURE(m_aRun.getLength() == 0, "m_aRun is not empty"); + return 0; } void RtfAttributeOutput::EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner) diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 791fdf8d2678..879ec751266c 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -48,7 +48,8 @@ public: void RTLAndCJKState(bool bIsRTL, sal_uInt16 nScript) override; /// Start of the paragraph. - void StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo) override; + sal_Int32 StartParagraph(ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, + bool bGenerateParaId) override; /// End of the paragraph. void EndParagraph(ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner) override; diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 2d31a2f52aed..f0d40dcb3ecc 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -2297,7 +2297,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) if( softBreakList.size() > 1 ) // not for empty paragraph ++aBreakIt; - AttrOutput().StartParagraph( pTextNodeInfo ); + AttrOutput().StartParagraph(pTextNodeInfo, false); const SwSection* pTOXSect = nullptr; if( m_bInWriteTOX ) diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx index 7e3f2a31ff20..9e50b953369b 100644 --- a/sw/source/filter/ww8/ww8attributeoutput.hxx +++ b/sw/source/filter/ww8/ww8attributeoutput.hxx @@ -32,7 +32,7 @@ public: virtual void RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript ) override; /// Start of the paragraph. - virtual void StartParagraph( ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/ ) override {} + virtual sal_Int32 StartParagraph( ww8::WW8TableNodeInfo::Pointer_t /*pTextNodeInfo*/, bool /*bGenerateParaId*/ ) override { return 0; } /// End of the paragraph. virtual void EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner ) override; -- cgit