summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oox/source/export/vmlexport.cxx5
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport17.cxx25
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport5.cxx2
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx6
-rw-r--r--sw/source/filter/ww8/attributeoutputbase.hxx2
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx16
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx2
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx2
-rw-r--r--writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx30
-rw-r--r--writerfilter/qa/cppunittests/dmapper/data/sdt-run-plain-text.docxbin0 -> 4179 bytes
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx20
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx5
-rw-r--r--writerfilter/source/dmapper/SdtHelper.cxx1
-rw-r--r--writerfilter/source/dmapper/SdtHelper.hxx4
14 files changed, 100 insertions, 20 deletions
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 47a196908a4d..1bfc59ee13db 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -1008,12 +1008,9 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
default:
#if OSL_DEBUG_LEVEL > 0
const size_t opt_nProp_size(opt.nProp.size());
- const sal_uInt8 opt_nProp_empty(0);
SAL_WARN( "oox.vml", "TODO VMLExport::Commit(), unimplemented id: " << nId
<< ", value: " << opt.nPropValue
- << ", data: [" << opt_nProp_size << ", "
- << (0 == opt_nProp_size ? &opt_nProp_empty : opt.nProp.data())
- << "]");
+ << ", data: [" << opt_nProp_size << "]");
if ( opt.nProp.size() )
{
const sal_uInt8 *pIt = opt.nProp.data();
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index f139837b822a..ee5b0dd19b14 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -676,15 +676,26 @@ DECLARE_OOXMLEXPORT_TEST(testTdf123642_BookmarkAtDocEnd, "tdf123642.docx")
DECLARE_OOXMLEXPORT_TEST(testTdf148361, "tdf148361.docx")
{
- // Refresh fields and ensure cross-reference to numbered para is okay
- uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
- uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+ if (mbExported)
+ {
+ // Block SDT is turned into run SDT on export, so the next import will have this as content
+ // control, not as a field.
+ OUString aActual = getParagraph(1)->getString();
+ // This was "itadmin".
+ CPPUNIT_ASSERT_EQUAL(OUString("itadmin"), aActual);
+ }
+ else
+ {
+ // Refresh fields and ensure cross-reference to numbered para is okay
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
- uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
- CPPUNIT_ASSERT(xFields->hasMoreElements());
+ uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+ CPPUNIT_ASSERT(xFields->hasMoreElements());
- uno::Reference<text::XTextField> xTextField1(xFields->nextElement(), uno::UNO_QUERY);
- CPPUNIT_ASSERT_EQUAL(OUString("itadmin"), xTextField1->getPresentation(false));
+ uno::Reference<text::XTextField> xTextField1(xFields->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("itadmin"), xTextField1->getPresentation(false));
+ }
OUString aActual = getParagraph(2)->getString();
// This was "itadmin".
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index cd405b196cba..d34e5ce957f0 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -1095,7 +1095,7 @@ CPPUNIT_TEST_FIXTURE(Test, testSdt2Run)
xmlDocUniquePtr pXmlDoc = parseExport();
// The problem was that <w:sdt> was closed after "first", not after "second", so the second assert failed.
- assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r", 1);
+ assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:t", "firstsecond");
// Make sure the third portion is still outside <w:sdt>.
assertXPathContent(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/w:t", "third");
}
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index d5fd1691c2a3..43a7c2a67ce4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -587,7 +587,8 @@ CPPUNIT_TEST_FIXTURE(Test, testfdo82123)
xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
// make sure there is only one run inside first SDT after RT as in the Original file.
- assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:p/w:sdt[1]/w:sdtContent/w:r",1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:p/w:sdt[1]/w:sdtContent/w:r/w:t", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:p/w:r/w:drawing", 1);
}
CPPUNIT_TEST_FIXTURE(Test, testSdtBeforeField)
@@ -612,7 +613,8 @@ CPPUNIT_TEST_FIXTURE(Test, testfdo82492)
xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
// make sure there is only one run inside first SDT after RT as in the Original file.
- assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt[1]/w:sdtContent/w:r",1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt[1]/w:sdtContent/w:r/w:t", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent", 1);
}
CPPUNIT_TEST_FIXTURE(Test, testSdtHeader)
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index a9331c9b628b..35ac50057786 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -373,7 +373,7 @@ public:
virtual void StartContentControl(const SwFormatContentControl& /*rFormatContentControl*/) {}
/// Output content control end.
- virtual void EndContentControl() {}
+ virtual void EndContentControl( const SwTextNode& /*rNode*/, sal_Int32 /*nPos*/ ) {}
protected:
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index f525aadf460f..9bf73a95ff9a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -368,9 +368,16 @@ void DocxAttributeOutput::StartContentControl(const SwFormatContentControl& rFor
m_pContentControl = rFormatContentControl.GetContentControl();
}
-void DocxAttributeOutput::EndContentControl()
+void DocxAttributeOutput::EndContentControl(const SwTextNode& rNode, sal_Int32 nPos)
{
- ++m_nCloseContentControlInThisRun;
+ if (rNode.GetTextAttrForCharAt(nPos, RES_TXTATR_FLYCNT) || rNode.GetTextAttrForCharAt(nPos, RES_TXTATR_CONTENTCONTROL))
+ {
+ ++m_nCloseContentControlInPreviousRun;
+ }
+ else
+ {
+ ++m_nCloseContentControlInThisRun;
+ }
}
static void checkAndWriteFloatingTables(DocxAttributeOutput& rDocxAttributeOutput)
@@ -2331,6 +2338,11 @@ void DocxAttributeOutput::WriteContentControlStart()
return;
}
+ if (m_bAnchorLinkedToNode)
+ {
+ return;
+ }
+
m_pSerializer->startElementNS(XML_w, XML_sdt);
m_pSerializer->startElementNS(XML_w, XML_sdtPr);
if (!m_pContentControl->GetPlaceholderDocPart().isEmpty())
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 877e8ded562a..c25c4ad1225a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -408,7 +408,7 @@ public:
void StartContentControl(const SwFormatContentControl& rFormatContentControl) override;
/// See AttributeOutputBase::EndContentControl().
- void EndContentControl() override;
+ void EndContentControl( const SwTextNode& rNode, sal_Int32 nPos ) override;
private:
/// Initialize the structures where we are going to collect some of the paragraph properties.
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 7bd841d727b5..4b42fc63e2e3 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -1407,7 +1407,7 @@ int SwWW8AttrIter::OutAttrWithRange(const SwTextNode& rNode, sal_Int32 nPos)
pEnd = pHt->End();
if (nPos == *pEnd && nPos != pHt->GetStart())
{
- m_rExport.AttrOutput().EndContentControl();
+ m_rExport.AttrOutput().EndContentControl(rNode, nPos);
--nRet;
}
break;
diff --git a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
index b2e7f1058f88..6b568619785e 100644
--- a/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
+++ b/writerfilter/qa/cppunittests/dmapper/SdtHelper.cxx
@@ -88,6 +88,36 @@ CPPUNIT_TEST_FIXTURE(Test, testSdtRunRichText)
CPPUNIT_ASSERT_EQUAL(24.f, fCharheight);
}
+CPPUNIT_TEST_FIXTURE(Test, testSdtRunPlainText)
+{
+ // Given a document with a plain text inline/run SDT:
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "sdt-run-plain-text.docx";
+
+ // When loading the document:
+ getComponent() = loadFromDesktop(aURL);
+
+ // Then make sure that the text inside the SDT is not rich:
+ uno::Reference<text::XTextDocument> xTextDocument(getComponent(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
+ uno::Reference<container::XEnumerationAccess> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xPortionEnum = xPara->createEnumeration();
+ uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), uno::UNO_QUERY);
+ OUString aTextPortionType;
+ xPortion->getPropertyValue("TextPortionType") >>= aTextPortionType;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: ContentControl
+ // - Actual : TextField
+ // i.e. the SDT was imported as a text field, not as a content control.
+ CPPUNIT_ASSERT_EQUAL(OUString("ContentControl"), aTextPortionType);
+ uno::Reference<beans::XPropertySet> xContentControl;
+ xPortion->getPropertyValue("ContentControl") >>= xContentControl;
+ bool bPlainText{};
+ xContentControl->getPropertyValue("PlainText") >>= bPlainText;
+ CPPUNIT_ASSERT(bPlainText);
+}
+
CPPUNIT_TEST_FIXTURE(Test, testSdtRunCheckbox)
{
// Given a document with a checkbox inline/run SDT:
diff --git a/writerfilter/qa/cppunittests/dmapper/data/sdt-run-plain-text.docx b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-plain-text.docx
new file mode 100644
index 000000000000..127d81fd966b
--- /dev/null
+++ b/writerfilter/qa/cppunittests/dmapper/data/sdt-run-plain-text.docx
Binary files differ
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index c3742cdbaa47..826404d640be 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1067,6 +1067,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
break;
case NS_ooxml::LN_CT_SdtBlock_sdtContent:
case NS_ooxml::LN_CT_SdtRun_sdtContent:
+ m_pImpl->m_pSdtHelper->SetSdtType(nName);
if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::unknown)
{
// Still not determined content type? and it is even not unsupported? Then it is plain text field
@@ -1107,6 +1108,15 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
default:
break;
}
+
+ 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->SetSdt(false);
@@ -2754,6 +2764,14 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
case NS_ooxml::LN_CT_SdtPr_text:
{
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;
+ }
+ }
enableInteropGrabBag("ooxml:CT_SdtPr_text");
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if (pProperties)
@@ -3753,7 +3771,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len)
return;
}
}
- else if (m_pImpl->m_pSdtHelper->getControlType() == SdtControlType::plainText)
+ 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)
{
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 f37e7c2d9032..ba66d5c340f7 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -978,6 +978,11 @@ void DomainMapper_Impl::PopSdt()
uno::Any(m_pSdtHelper->getDate().makeStringAndClear()));
}
+ if (m_pSdtHelper->getControlType() == SdtControlType::plainText)
+ {
+ xContentControlProps->setPropertyValue("PlainText", uno::Any(true));
+ }
+
xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true);
m_pSdtHelper->clear();
diff --git a/writerfilter/source/dmapper/SdtHelper.cxx b/writerfilter/source/dmapper/SdtHelper.cxx
index 8f5e809efdec..0301264bbaef 100644
--- a/writerfilter/source/dmapper/SdtHelper.cxx
+++ b/writerfilter/source/dmapper/SdtHelper.cxx
@@ -443,6 +443,7 @@ void SdtHelper::clear()
m_aDropDownItems.clear();
m_aDropDownDisplayTexts.clear();
setControlType(SdtControlType::unknown);
+ m_nSdtType = 0;
m_sDataBindingPrefixMapping.clear();
m_sDataBindingXPath.clear();
m_sDataBindingStoreItemID.clear();
diff --git a/writerfilter/source/dmapper/SdtHelper.hxx b/writerfilter/source/dmapper/SdtHelper.hxx
index c817285095e7..441fa927b045 100644
--- a/writerfilter/source/dmapper/SdtHelper.hxx
+++ b/writerfilter/source/dmapper/SdtHelper.hxx
@@ -66,6 +66,7 @@ class SdtHelper final : public virtual SvRefBase
std::vector<OUString> m_aDropDownDisplayTexts;
/// Type of sdt control
SdtControlType m_aControlType;
+ sal_uInt32 m_nSdtType = 0;
/// Pieces of the default text -- currently used only by the dropdown control.
OUStringBuffer m_aSdtTexts;
/// Date ISO string contained in the w:date element, used by the date control.
@@ -169,6 +170,9 @@ public:
SdtControlType getControlType() { return m_aControlType; }
void setControlType(SdtControlType aType) { m_aControlType = aType; }
+ void SetSdtType(sal_uInt32 nSdtType) { m_nSdtType = nSdtType; }
+ sal_uInt32 GetSdtType() const { return m_nSdtType; }
+
/// Create drop-down control from w:sdt's w:dropDownList.
void createDropDownControl();
/// Create date control from w:sdt's w:date.