diff options
-rw-r--r-- | sw/inc/txatbase.hxx | 2 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx | 43 | ||||
-rw-r--r-- | sw/source/filter/ww8/attributeoutputbase.hxx | 8 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 86 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.hxx | 11 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 2 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.cxx | 3 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.hxx | 3 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtw8nds.cxx | 29 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 4 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8attributeoutput.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 15 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 8 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SdtHelper.hxx | 4 |
14 files changed, 93 insertions, 127 deletions
diff --git a/sw/inc/txatbase.hxx b/sw/inc/txatbase.hxx index 183e254f8817..00e2f9b51470 100644 --- a/sw/inc/txatbase.hxx +++ b/sw/inc/txatbase.hxx @@ -132,7 +132,7 @@ public: virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; }; -class SAL_DLLPUBLIC_RTTI SwTextAttrEnd : public virtual SwTextAttr +class SW_DLLPUBLIC SwTextAttrEnd : public virtual SwTextAttr { protected: sal_Int32 m_nEnd; diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx index 073918d31c48..f5db919b4c7e 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx @@ -596,7 +596,8 @@ CPPUNIT_TEST_FIXTURE(Test, testSdtBeforeField) loadAndReload("sdt-before-field.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); // Make sure the field doesn't sneak inside the SDT: the SDT should contain only a single run (there were 6 ones). - assertXPath(pXmlDoc, "//w:sdt/w:sdtContent/w:r", 1); + assertXPath(pXmlDoc, "//w:p/w:sdt/w:sdtContent/w:r/w:t", 1); + assertXPath(pXmlDoc, "//w:p/w:r/w:fldChar", 3); } CPPUNIT_TEST_FIXTURE(Test, testfdo81946) @@ -901,36 +902,26 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf104823) OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf104823.docx"; loadURL(aURL, nullptr); - css::uno::Reference<css::text::XTextFieldsSupplier> xTextFieldsSupplier( - mxComponent, css::uno::UNO_QUERY_THROW); - auto xFields(xTextFieldsSupplier->getTextFields()->createEnumeration()); - - // FIXME: seems order of fields is different than in source document - // so feel free to modify testcase if order is changed - - // First field: content from core properties - uno::Reference<text::XTextField> xField1(xFields->nextElement(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xFields->hasMoreElements()); + // First paragraph: content from core properties + uno::Reference<text::XTextRange> xParagraph1 = getParagraph(1); + auto xContentControl1 = getProperty<uno::Reference<text::XText>>(getRun(xParagraph1, 2), "ContentControl"); // Check field value (it should be value from data source) and set new - CPPUNIT_ASSERT_EQUAL(OUString("True Core Property Value"), xField1->getPresentation(false)); - uno::Reference<beans::XPropertySet> xField1Props(xField1, uno::UNO_QUERY); - xField1Props->setPropertyValue("Content", uno::Any(OUString("New Core Property Value"))); + CPPUNIT_ASSERT_EQUAL(OUString("True Core Property Value"), xContentControl1->getString()); + xContentControl1->setString("New Core Property Value"); - // Third field: content from custom properties - uno::Reference<text::XTextField> xField2(xFields->nextElement(), uno::UNO_QUERY); - CPPUNIT_ASSERT(xFields->hasMoreElements()); + // Third paragraph: content from custom properties + uno::Reference<text::XTextRange> xParagraph3 = getParagraph(3); + auto xContentControl3 = getProperty<uno::Reference<text::XText>>(getRun(xParagraph3, 2), "ContentControl"); // Check field value (it should be value from data source) and set new - CPPUNIT_ASSERT_EQUAL(OUString("True Custom XML Value"), xField2->getPresentation(false)); - uno::Reference<beans::XPropertySet> xField2Props(xField2, uno::UNO_QUERY); - xField2Props->setPropertyValue("Content", uno::Any(OUString("New Custom XML Value"))); + CPPUNIT_ASSERT_EQUAL(OUString("True Custom XML Value"), xContentControl3->getString()); + xContentControl3->setString("New Custom XML Value"); - // Second field: content from extended properties - uno::Reference<text::XTextField> xField3(xFields->nextElement(), uno::UNO_QUERY); - CPPUNIT_ASSERT(!xFields->hasMoreElements()); + // Second paragraph: content from extended properties + uno::Reference<text::XTextRange> xParagraph2 = getParagraph(2); + auto xContentControl2 = getProperty<uno::Reference<text::XText>>(getRun(xParagraph2, 2), "ContentControl"); // Check field value (it should be value from data source) and set new - CPPUNIT_ASSERT_EQUAL(OUString("True Extended Property Value"), xField3->getPresentation(false)); - uno::Reference<beans::XPropertySet> xField3Props(xField3, uno::UNO_QUERY); - xField3Props->setPropertyValue("Content", uno::Any(OUString("New Extended Property Value"))); + CPPUNIT_ASSERT_EQUAL(OUString("True Extended Property Value"), xContentControl2->getString()); + xContentControl2->setString("New Extended Property Value"); // Save and check saved data save("Office Open XML Text", maTempFile); diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx index a7740970347d..d8a8be3e8f7f 100644 --- a/sw/source/filter/ww8/attributeoutputbase.hxx +++ b/sw/source/filter/ww8/attributeoutputbase.hxx @@ -173,7 +173,7 @@ public: virtual void StartRun( const SwRedlineData* pRedlineData, sal_Int32 nPos, bool bSingleEmptyRun = false ) = 0; /// End of the text run. - virtual void EndRun( const SwTextNode* pNode, sal_Int32 nPos, bool bLastRun = false ) = 0; + virtual void EndRun( const SwTextNode* pNode, sal_Int32 nPos, sal_Int32 nLen, bool bLastRun = false ) = 0; /// Called before we start outputting the attributes. virtual void StartRunProperties() = 0; @@ -370,12 +370,6 @@ public: const OUString &rNumberingString, const SvxBrushItem* pBrush) = 0; // #i120928 export graphic of bullet - /// Output content control start. - virtual void StartContentControl(const SwFormatContentControl& /*rFormatContentControl*/) {} - - /// Output content control end. - virtual void EndContentControl( const SwTextNode& /*rNode*/, sal_Int32 /*nPos*/ ) {} - protected: static void GetNumberPara( OUString& rStr, const SwField& rField ); diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 49ac7c64a9cf..f8fc5429fb97 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -136,6 +136,7 @@ #include <frmatr.hxx> #include <txtatr.hxx> #include <frameformats.hxx> +#include <textcontentcontrol.hxx> #include <o3tl/string_view.hxx> #include <o3tl/unit_conversion.hxx> @@ -363,23 +364,6 @@ void DocxAttributeOutput::WriteFloatingTable(ww8::Frame const* pParentFrame) m_rExport.SetFloatingTableFrame(nullptr); } -void DocxAttributeOutput::StartContentControl(const SwFormatContentControl& rFormatContentControl) -{ - m_pContentControl = rFormatContentControl.GetContentControl(); -} - -void DocxAttributeOutput::EndContentControl(const SwTextNode& rNode, sal_Int32 nPos) -{ - if (rNode.GetTextAttrForCharAt(nPos, RES_TXTATR_CONTENTCONTROL)) - { - ++m_nCloseContentControlInPreviousRun; - } - else - { - ++m_nCloseContentControlInThisRun; - } -} - static void checkAndWriteFloatingTables(DocxAttributeOutput& rDocxAttributeOutput) { const auto& rExport = rDocxAttributeOutput.GetExport(); @@ -1584,7 +1568,7 @@ void DocxAttributeOutput::StartRun( const SwRedlineData* pRedlineData, sal_Int32 m_pSerializer->mark(Tag_StartRun_3); // let's call it "postponed text" } -void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /*bLastRun*/) +void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_Int32 nLen, bool /*bLastRun*/) { int nFieldsInPrevHyperlink = m_nFieldsInHyperlink; // Reset m_nFieldsInHyperlink if a new hyperlink is about to start @@ -1641,12 +1625,6 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / m_bEndCharSdt = false; } - for (; m_nCloseContentControlInPreviousRun > 0; --m_nCloseContentControlInPreviousRun) - { - // Not the last run of this paragraph. - WriteContentControlEnd(); - } - if ( m_closeHyperlinkInPreviousRun ) { if ( m_startedHyperlink ) @@ -1744,8 +1722,6 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / m_nHyperLinkCount++; } - WriteContentControlStart(); - // if there is some redlining in the document, output it StartRedline( m_pRedlineData ); @@ -1791,6 +1767,17 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / DoWriteBookmarkStartIfExist(nPos); + if (nLen != -1) + { + SwTextAttr* pAttr = pNode->GetTextAttrAt(nPos, RES_TXTATR_CONTENTCONTROL, SwTextNode::DEFAULT); + if (pAttr && pAttr->GetStart() == nPos) + { + auto pTextContentControl = static_txtattr_cast<SwTextContentControl*>(pAttr); + m_pContentControl = pTextContentControl->GetContentControl().GetContentControl(); + WriteContentControlStart(); + } + } + m_pSerializer->startElementNS(XML_w, XML_r); if(GetExport().m_bTabInTOC && m_pHyperlinkAttrList.is()) { @@ -1809,6 +1796,16 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / // append the actual run end m_pSerializer->endElementNS( XML_w, XML_r ); + if (nLen != -1) + { + sal_Int32 nEnd = nPos + nLen; + SwTextAttr* pAttr = pNode->GetTextAttrAt(nPos, RES_TXTATR_CONTENTCONTROL, SwTextNode::DEFAULT); + if (pAttr && *pAttr->GetEnd() == nEnd) + { + WriteContentControlEnd(); + } + } + // if there is some redlining in the document, output it // (except in the case of fields with multiple runs) EndRedline( m_pRedlineData ); @@ -1856,12 +1853,6 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool / m_pRedlineData = nullptr; } - for (; m_nCloseContentControlInThisRun > 0; --m_nCloseContentControlInThisRun) - { - // Last run of this paragraph. - WriteContentControlEnd(); - } - if ( m_closeHyperlinkInThisRun ) { if ( m_startedHyperlink ) @@ -2445,6 +2436,26 @@ void DocxAttributeOutput::WriteContentControlStart() m_pSerializer->endElementNS(XML_w, XML_sdtPr); m_pSerializer->startElementNS(XML_w, XML_sdtContent); + + const OUString& rPrefixMapping = m_pContentControl->GetDataBindingPrefixMappings(); + const OUString& rXpath = m_pContentControl->GetDataBindingXpath(); + if (!rXpath.isEmpty()) + { + // This content control has a data binding, update the data source. + SwTextContentControl* pTextAttr = m_pContentControl->GetTextAttr(); + SwTextNode* pTextNode = m_pContentControl->GetTextNode(); + SwPosition aPoint(*pTextNode, pTextAttr->GetStart()); + SwPosition aMark(*pTextNode, *pTextAttr->GetEnd()); + SwPaM aPam(aMark, aPoint); + OUString aSnippet = aPam.GetText(); + static sal_Unicode const aForbidden[] = { + CH_TXTATR_BREAKWORD, + 0 + }; + aSnippet = comphelper::string::removeAny(aSnippet, aForbidden); + m_rExport.AddSdtData(rPrefixMapping, rXpath, aSnippet); + } + m_pContentControl = nullptr; } @@ -3387,11 +3398,6 @@ void DocxAttributeOutput::RunText( const OUString& rText, rtl_TextEncoding /*eCh { m_closeHyperlinkInPreviousRun = true; } - if (m_nCloseContentControlInThisRun > 0) - { - ++m_nCloseContentControlInPreviousRun; - --m_nCloseContentControlInThisRun; - } m_bRunTextIsOn = true; // one text can be split into more <w:t>blah</w:t>'s by line breaks etc. const sal_Unicode *pBegin = rText.getStr(); @@ -3463,7 +3469,7 @@ void DocxAttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 nPos, co { WW8Ruby aWW8Ruby( rNode, rRuby, GetExport() ); SAL_INFO("sw.ww8", "TODO DocxAttributeOutput::StartRuby( const SwTextNode& rNode, const SwFormatRuby& rRuby )" ); - EndRun( &rNode, nPos ); // end run before starting ruby to avoid nested runs, and overlap + EndRun( &rNode, nPos, -1 ); // end run before starting ruby to avoid nested runs, and overlap assert(!m_closeHyperlinkInThisRun); // check that no hyperlink overlaps ruby assert(!m_closeHyperlinkInPreviousRun); m_pSerializer->startElementNS(XML_w, XML_r); @@ -3507,7 +3513,7 @@ void DocxAttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 nPos, co EndRunProperties( nullptr ); RunText( rRuby.GetText( ) ); - EndRun( &rNode, nPos ); + EndRun( &rNode, nPos, -1 ); m_pSerializer->endElementNS( XML_w, XML_rt ); m_pSerializer->startElementNS(XML_w, XML_rubyBase); @@ -3517,7 +3523,7 @@ void DocxAttributeOutput::StartRuby( const SwTextNode& rNode, sal_Int32 nPos, co void DocxAttributeOutput::EndRuby(const SwTextNode& rNode, sal_Int32 nPos) { SAL_INFO("sw.ww8", "TODO DocxAttributeOutput::EndRuby()" ); - EndRun( &rNode, nPos ); + EndRun( &rNode, nPos, -1 ); m_pSerializer->endElementNS( XML_w, XML_rubyBase ); m_pSerializer->endElementNS( XML_w, XML_ruby ); m_pSerializer->endElementNS( XML_w, XML_r ); diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx index b1b5d22ff456..9de8f6fed332 100644 --- a/sw/source/filter/ww8/docxattributeoutput.hxx +++ b/sw/source/filter/ww8/docxattributeoutput.hxx @@ -185,7 +185,7 @@ public: virtual void StartRun( const SwRedlineData* pRedlineData, sal_Int32 nPos, bool bSingleEmptyRun = false ) override; /// End of the text run. - virtual void EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool bLastRun = false) override; + virtual void EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_Int32 nLen, bool bLastRun = false) override; /// Called before we start outputting the attributes. virtual void StartRunProperties() override; @@ -404,12 +404,6 @@ public: void WriteFloatingTable(ww8::Frame const* pParentFrame); - /// See AttributeOutputBase::StartContentControl(). - void StartContentControl(const SwFormatContentControl& rFormatContentControl) override; - - /// See AttributeOutputBase::EndContentControl(). - void EndContentControl( const SwTextNode& rNode, sal_Int32 nPos ) override; - private: /// Initialize the structures where we are going to collect some of the paragraph properties. /// @@ -914,9 +908,6 @@ private: o3tl::sorted_vector<const SwFrameFormat*> m_aFloatingTablesOfParagraph; sal_Int32 m_nTextFrameLevel; - sal_Int32 m_nCloseContentControlInThisRun = 0; - sal_Int32 m_nCloseContentControlInPreviousRun = 0; - // close of hyperlink needed bool m_closeHyperlinkInThisRun; bool m_closeHyperlinkInPreviousRun; diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 52090fc74891..a8ec459c79a5 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -1969,7 +1969,7 @@ sal_Int32 DocxExport::WriteOutliner(const OutlinerParaObject& rParaObj, sal_uInt eChrSet = eNextChrSet; aAttrIter.NextPos(); - AttrOutput().EndRun( nullptr, 0 ); + AttrOutput().EndRun( nullptr, 0, -1 ); } while( nCurrentPos < nEnd ); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index a7f7086f0657..4c3c2c5a74af 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -419,7 +419,8 @@ void RtfAttributeOutput::StartRun(const SwRedlineData* pRedlineData, sal_Int32 / OSL_ENSURE(m_aRunText.getLength() == 0, "m_aRunText is not empty"); } -void RtfAttributeOutput::EndRun(const SwTextNode* /*pNode*/, sal_Int32 /*nPos*/, bool /*bLastRun*/) +void RtfAttributeOutput::EndRun(const SwTextNode* /*pNode*/, sal_Int32 /*nPos*/, sal_Int32 /*nLen*/, + bool /*bLastRun*/) { m_aRun->append(SAL_NEWLINE_STRING); m_aRun.appendAndClear(m_aRunText); diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 17de105ed4f6..a20719df6777 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -75,7 +75,8 @@ public: bool bSingleEmptyRun = false) override; /// End of the text run. - void EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool bLastRun = false) override; + void EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_Int32 nLen, + bool bLastRun = false) override; /// Called before we start outputting the attributes. void StartRunProperties() override; diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 692086fa709d..a9ff9a6b9b56 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -1402,14 +1402,6 @@ int SwWW8AttrIter::OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos) --nRet; } break; - case RES_TXTATR_CONTENTCONTROL: - pEnd = pHt->End(); - if (nPos == *pEnd && nPos != pHt->GetStart()) - { - m_rExport.AttrOutput().EndContentControl(rNode, nPos); - --nRet; - } - break; } if (nPos < pHt->GetAnyEnd()) break; // sorted by end @@ -1464,17 +1456,6 @@ int SwWW8AttrIter::OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos) --nRet; } break; - case RES_TXTATR_CONTENTCONTROL: - if (nPos == pHt->GetStart()) - { - auto pFormatContentControl - = static_cast<const SwFormatContentControl*>(pItem); - m_rExport.AttrOutput().StartContentControl(*pFormatContentControl); - ++nRet; - } - // We know that the content control is never empty as it has a dummy character - // at least. - break; } if (nPos < pHt->GetStart()) break; // sorted by start @@ -2427,7 +2408,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) { if( AttrOutput().FootnoteEndnoteRefTag() ) { - AttrOutput().EndRun( &rNode, nCurrentPos, nNextAttr == nEnd ); + AttrOutput().EndRun( &rNode, nCurrentPos, -1, nNextAttr == nEnd ); AttrOutput().StartRun( pRedlineData, nCurrentPos, bSingleEmptyRun ); } } @@ -2481,7 +2462,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) && nStateOfFlyFrame == FLY_PROCESSED) { // write flys in a separate run before field character - AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd); + AttrOutput().EndRun(&rNode, nCurrentPos, -1, nNextAttr == nEnd); AttrOutput().StartRun(pRedlineData, nCurrentPos, bSingleEmptyRun); } @@ -2778,7 +2759,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) { if (FLY_PROCESSED == nStateOfFlyFrame || FLY_NONE == nStateOfFlyFrame) { - AttrOutput().EndRun(&rNode, nCurrentPos, /*bLastRun=*/false); + AttrOutput().EndRun(&rNode, nCurrentPos, -1, /*bLastRun=*/false); if (!aSavedSnippet.isEmpty()) bStartedPostponedRunProperties = false; @@ -2796,10 +2777,10 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) AttrOutput().WritePostitFieldReference(); } AttrOutput().RunText( aSavedSnippet, eChrSet ); - AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd); + AttrOutput().EndRun(&rNode, nCurrentPos, nLen, nNextAttr == nEnd); } else - AttrOutput().EndRun(&rNode, nCurrentPos, nNextAttr == nEnd); + AttrOutput().EndRun(&rNode, nCurrentPos, nLen, nNextAttr == nEnd); nCurrentPos = nNextAttr; UpdatePosition( &aAttrIter, nCurrentPos ); diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index 5afd5b0c8de2..3fce91b9b436 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -1099,7 +1099,7 @@ void WW8AttributeOutput::OnTOXEnding() mbOnTOXEnding = true; } -void WW8AttributeOutput::EndRun( const SwTextNode* /*pNode*/, sal_Int32 nPos, bool bLastRun ) +void WW8AttributeOutput::EndRun( const SwTextNode* /*pNode*/, sal_Int32 nPos, sal_Int32 /*nLen*/, bool bLastRun ) { /// Insert bookmarks ended after this run auto aRange = m_aBookmarksOfParagraphEnd.equal_range(nPos); @@ -2573,7 +2573,7 @@ void AttributeOutputBase::StartTOX( const SwSection& rSect ) FieldFlags::CmdEnd ); if (GetExport().GetExportFormat() == MSWordExportBase::ExportFormat::RTF) { - EndRun(nullptr, -42, true); + EndRun(nullptr, -42, -1, true); } } } diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx index 9ea43ef885b5..32ad12cdadb3 100644 --- a/sw/source/filter/ww8/ww8attributeoutput.hxx +++ b/sw/source/filter/ww8/ww8attributeoutput.hxx @@ -58,7 +58,7 @@ public: /// End of the text run. /// /// No-op for binary filters. - virtual void EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool bLastRun = false) override; + virtual void EndRun(const SwTextNode* pNode, sal_Int32 nPos, sal_Int32 nLen, bool bLastRun = false) override; /// Before we start outputting the attributes. virtual void StartRunProperties() override; diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 9fa547675c8a..9286f6261287 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -1111,11 +1111,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText) { - // The plain text && data binding case needs more work before it can be enabled. - if (m_pImpl->m_pSdtHelper->GetDataBindingPrefixMapping().isEmpty()) - { - m_pImpl->PopSdt(); - } + m_pImpl->PopSdt(); } } @@ -2781,11 +2777,8 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext ) m_pImpl->m_pSdtHelper->setControlType(SdtControlType::plainText); if (m_pImpl->m_pSdtHelper->GetSdtType() == NS_ooxml::LN_CT_SdtRun_sdtContent) { - if (m_pImpl->m_pSdtHelper->GetDataBindingPrefixMapping().isEmpty()) - { - m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); - break; - } + m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); + break; } enableInteropGrabBag("ooxml:CT_SdtPr_text"); writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); @@ -3786,7 +3779,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) return; } } - else if ((m_pImpl->m_pSdtHelper->GetSdtType() != NS_ooxml::LN_CT_SdtRun_sdtContent || !m_pImpl->m_pSdtHelper->GetDataBindingPrefixMapping().isEmpty()) && m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText) + else if (m_pImpl->m_pSdtHelper->GetSdtType() != NS_ooxml::LN_CT_SdtRun_sdtContent && m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText) { m_pImpl->m_pSdtHelper->getSdtTexts().append(sText); if (bNewLine) diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 8966e096dd59..22c75bfb7800 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -892,6 +892,14 @@ void DomainMapper_Impl::PopSdt() xCursor->goRight(1, /*bExpand=*/false); } xCursor->gotoRange(xEnd, /*bExpand=*/true); + + std::optional<OUString> oData = m_pSdtHelper->getValueFromDataBinding(); + if (oData.has_value() && m_pSdtHelper->getControlType() != SdtControlType::datePicker) + { + // Data binding has a value for us, prefer that over the in-document value. + xCursor->setString(*oData); + } + uno::Reference<text::XTextContent> xContentControl( m_xTextFactory->createInstance("com.sun.star.text.ContentControl"), uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xContentControlProps(xContentControl, uno::UNO_QUERY); diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx index 7be862cd45f4..1db71cdc9a92 100644 --- a/writerfilter/source/dmapper/SdtHelper.hxx +++ b/writerfilter/source/dmapper/SdtHelper.hxx @@ -116,8 +116,6 @@ class SdtHelper final : public virtual SvRefBase css::uno::Reference<css::awt::XControlModel> const& xControlModel, const css::uno::Sequence<css::beans::PropertyValue>& rGrabBag); - std::optional<OUString> getValueFromDataBinding(); - void loadPropertiesXMLs(); /// <w:placeholder>'s <w:docPart w:val="...">. @@ -204,6 +202,8 @@ public: void SetColor(const OUString& rColor); const OUString& GetColor() const; + + std::optional<OUString> getValueFromDataBinding(); }; } // namespace writerfilter::dmapper |