summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Melenchuk <vasily.melenchuk@cib.de>2021-11-16 18:12:39 +0300
committerThorsten Behrens <thorsten.behrens@allotropia.de>2021-12-21 12:48:14 +0100
commitc635dcd89a62a015daddd2976eaef1db771a0ab8 (patch)
tree46d30ebc1902eb82ade5a6a03c390ab27c74dab3
parentwriterfilter: extend SdtHelper for better support control types (diff)
downloadcore-c635dcd89a62a015daddd2976eaef1db771a0ab8.tar.gz
core-c635dcd89a62a015daddd2976eaef1db771a0ab8.zip
sw: refactoring for docx sdt blocks output
Previous approach with almost duplicate storage and processing for paragraph-level and run-level sdt blocks was very bulky. Especially this became visible once supported std elements list start to grow. Paragraph-level sdt block and run-level sdt block data are almost identical, so they can be kept in one standard class (SdtBlockHelper) and use the same methods for collecting data from grabbags and writing to output without passing huge amount of parameters. Change-Id: I4e1183eddf20317e954cb8aca72e97a4fc45ac68 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125372 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> Reviewed-by: Vasily Melenchuk <vasily.melenchuk@cib.de> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127158 Tested-by: Thorsten Behrens <thorsten.behrens@allotropia.de> Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx765
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx73
2 files changed, 356 insertions, 482 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 78673d876df9..31c05f3a7efb 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -301,6 +301,28 @@ static bool lcl_isOnelinerSdt(const OUString& rName)
return rName == "Title" || rName == "Subtitle" || rName == "Company";
}
+static void AddToAttrList(rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrs, ...)
+{
+ if (!pAttrList.is())
+ pAttrList = FastSerializerHelper::createAttrList();
+
+ va_list args;
+ va_start(args, nAttrs);
+ for (sal_Int32 i = 0; i < nAttrs; i++)
+ {
+ sal_Int32 nName = va_arg(args, sal_Int32);
+ const char* pValue = va_arg(args, const char*);
+ if (pValue)
+ pAttrList->add(nName, pValue);
+ }
+ va_end(args);
+}
+
+static void AddToAttrList(rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrName, const char* sAttrValue)
+{
+ AddToAttrList(pAttrList, 1, nAttrName, sAttrValue);
+}
+
// write a floating table directly to docx without the surrounding frame
void DocxAttributeOutput::WriteFloatingTable(ww8::Frame const* pParentFrame)
{
@@ -438,7 +460,7 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
// would normally arrive, it would be too late (would be after the
// paragraph start has been written).
bool bEndParaSdt = false;
- if (m_bStartedParaSdt)
+ if (m_aParagraphSdt.m_bStartedSdt)
{
SwTextNode* pTextNode = m_rExport.m_pCurPam->GetNode().GetTextNode();
if (pTextNode && pTextNode->GetpSwAttrSet())
@@ -448,17 +470,16 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
{
const SfxGrabBagItem& rParaGrabBag = static_cast<const SfxGrabBagItem&>(*pItem);
const std::map<OUString, css::uno::Any>& rMap = rParaGrabBag.GetGrabBag();
- bEndParaSdt = m_bStartedParaSdt && rMap.find("ParaSdtEndBefore") != rMap.end();
+ bEndParaSdt = m_aParagraphSdt.m_bStartedSdt && rMap.find("ParaSdtEndBefore") != rMap.end();
}
}
}
// TODO also avoid multiline paragraphs in those SDT types for shape text
- bool bOneliner = m_bStartedParaSdt && !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen() && lcl_isOnelinerSdt(m_aStartedParagraphSdtPrAlias);
- if (bEndParaSdt || (m_bStartedParaSdt && m_bHadSectPr) || bOneliner)
+ bool bOneliner = m_aParagraphSdt.m_bStartedSdt && !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen() && lcl_isOnelinerSdt(m_aStartedParagraphSdtPrAlias);
+ if (bEndParaSdt || (m_aParagraphSdt.m_bStartedSdt && m_bHadSectPr) || bOneliner)
{
// This is the common case: "close sdt before the current paragraph" was requested by the next paragraph.
- EndSdtBlock();
- m_bStartedParaSdt = false;
+ m_aParagraphSdt.EndSdtBlock(m_pSerializer);
m_aStartedParagraphSdtPrAlias.clear();
}
m_bHadSectPr = false;
@@ -551,24 +572,265 @@ static OString convertToOOXMLHoriOrientRel(sal_Int16 nOrientRel)
}
}
-static void lcl_deleteAndResetTheLists(
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTokenChildren,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrDataBindingAttrs,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTextAttrs,
- OUString& rSdtPrAlias, OUString& rSdtPrPlaceholderDocPart, OUString& rColor)
+void SdtBlockHelper::DeleteAndResetTheLists()
{
- if( pSdtPrTokenChildren.is() )
- pSdtPrTokenChildren.clear();
- if( pSdtPrDataBindingAttrs.is() )
- pSdtPrDataBindingAttrs.clear();
- if (pSdtPrTextAttrs.is())
- pSdtPrTextAttrs.clear();
- if (!rSdtPrAlias.isEmpty())
- rSdtPrAlias.clear();
- if (!rSdtPrPlaceholderDocPart.isEmpty())
- rSdtPrPlaceholderDocPart.clear();
- if (!rColor.isEmpty())
- rColor.clear();
+ if (m_pTokenChildren.is() )
+ m_pTokenChildren.clear();
+ if (m_pDataBindingAttrs.is() )
+ m_pDataBindingAttrs.clear();
+ if (m_pTextAttrs.is())
+ m_pTextAttrs.clear();
+ if (!m_aAlias.isEmpty())
+ m_aAlias.clear();
+ if (!m_aPlaceHolderDocPart.isEmpty())
+ m_aPlaceHolderDocPart.clear();
+ if (!m_aColor.isEmpty())
+ m_aColor.clear();
+ m_bHasId = false;
+}
+
+void SdtBlockHelper::WriteSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer, bool bRunTextIsOn, bool bParagraphHasDrawing)
+{
+ if (m_nSdtPrToken <= 0 && !m_pDataBindingAttrs.is() && !m_bHasId)
+ return;
+
+ // sdt start mark
+ pSerializer->mark(Tag_WriteSdtBlock);
+
+ pSerializer->startElementNS(XML_w, XML_sdt);
+
+ // output sdt properties
+ pSerializer->startElementNS(XML_w, XML_sdtPr);
+
+ if (m_nSdtPrToken > 0 && m_pTokenChildren.is())
+ {
+ if (!m_pTokenAttributes.is())
+ pSerializer->startElement(m_nSdtPrToken);
+ else
+ {
+ XFastAttributeListRef xAttrList( m_pTokenAttributes.get() );
+ m_pTokenAttributes.clear();
+ pSerializer->startElement(m_nSdtPrToken, xAttrList);
+ }
+
+ if (m_nSdtPrToken == FSNS(XML_w, XML_date) || m_nSdtPrToken == FSNS(XML_w, XML_docPartObj) || m_nSdtPrToken == FSNS(XML_w, XML_docPartList) || m_nSdtPrToken == FSNS(XML_w14, XML_checkbox)) {
+ const uno::Sequence<xml::FastAttribute> aChildren = m_pTokenChildren->getFastAttributes();
+ for (const auto& rChild : aChildren)
+ pSerializer->singleElement(rChild.Token, FSNS(XML_w, XML_val), rChild.Value.toUtf8() );
+ }
+
+ pSerializer->endElement(m_nSdtPrToken);
+ }
+ else if ((m_nSdtPrToken > 0) && m_nSdtPrToken != FSNS(XML_w, XML_id) && !(bRunTextIsOn && bParagraphHasDrawing))
+ {
+ if (!m_pTokenAttributes.is())
+ pSerializer->singleElement(m_nSdtPrToken);
+ else
+ {
+ XFastAttributeListRef xAttrList( m_pTokenAttributes.get() );
+ m_pTokenAttributes.clear();
+ pSerializer->singleElement(m_nSdtPrToken, xAttrList);
+ }
+ }
+
+ if (m_nSdtPrToken == FSNS(XML_w, XML_id) || m_bHasId)
+ //Word won't open a document with an empty id tag, we fill it with a random number
+ pSerializer->singleElementNS(XML_w, XML_id, FSNS(XML_w, XML_val),
+ OString::number(comphelper::rng::uniform_int_distribution(0, std::numeric_limits<int>::max())));
+
+ if (m_pDataBindingAttrs.is() && !bParagraphHasDrawing)
+ {
+ XFastAttributeListRef xAttrList( m_pDataBindingAttrs.get() );
+ m_pDataBindingAttrs.clear();
+ pSerializer->singleElementNS(XML_w, XML_dataBinding, xAttrList);
+ }
+
+ if (m_pTextAttrs.is())
+ {
+ XFastAttributeListRef xAttrList( m_pTextAttrs.get() );
+ m_pTextAttrs.clear();
+ pSerializer->singleElementNS(XML_w, XML_text, xAttrList);
+ }
+
+ if (!m_aPlaceHolderDocPart.isEmpty())
+ {
+ pSerializer->startElementNS(XML_w, XML_placeholder);
+ pSerializer->singleElementNS(XML_w, XML_docPart, FSNS(XML_w, XML_val), m_aPlaceHolderDocPart.toUtf8() );
+ pSerializer->endElementNS(XML_w, XML_placeholder);
+ }
+ if (!m_aColor.isEmpty())
+ {
+ pSerializer->singleElementNS(XML_w15, XML_color, FSNS(XML_w, XML_val), m_aColor.toUtf8() );
+ }
+
+ if (!m_aAlias.isEmpty())
+ pSerializer->singleElementNS(XML_w, XML_alias, FSNS(XML_w, XML_val), m_aAlias.toUtf8() );
+
+ pSerializer->endElementNS(XML_w, XML_sdtPr);
+
+ // sdt contents start tag
+ pSerializer->startElementNS(XML_w, XML_sdtContent);
+
+ // prepend the tags since the sdt start mark before the paragraph
+ pSerializer->mergeTopMarks(Tag_WriteSdtBlock, sax_fastparser::MergeMarks::PREPEND);
+
+ // write the ending tags after the paragraph
+ m_bStartedSdt = true;
+
+ // clear sdt status
+ m_nSdtPrToken = 0;
+ m_pTokenChildren.clear();
+ m_pDataBindingAttrs.clear();
+ m_pTextAttrs.clear();
+ m_aAlias.clear();
+ m_bHasId = false;
+}
+
+void SdtBlockHelper::EndSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer)
+{
+ pSerializer->endElementNS(XML_w, XML_sdtContent);
+ pSerializer->endElementNS(XML_w, XML_sdt);
+ m_bStartedSdt = false;
+}
+
+void SdtBlockHelper::GetSdtParamsFromGrabBag(const uno::Sequence<beans::PropertyValue>& aGrabBagSdt)
+{
+ for (const beans::PropertyValue& aPropertyValue : aGrabBagSdt)
+ {
+ if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
+ {
+ m_nSdtPrToken = FSNS(XML_w14, XML_checkbox);
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ OUString sValue = rProp.Value.get<OUString>();
+ if (rProp.Name == "ooxml:CT_SdtCheckbox_checked")
+ AddToAttrList(m_pTokenChildren,
+ FSNS(XML_w14, XML_checked),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ else if (rProp.Name == "ooxml:CT_SdtCheckbox_checkedState")
+ AddToAttrList(m_pTokenChildren,
+ FSNS(XML_w14, XML_checkedState),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ else if (rProp.Name == "ooxml:CT_SdtCheckbox_uncheckedState")
+ AddToAttrList(m_pTokenChildren,
+ FSNS(XML_w14, XML_uncheckedState),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding" && !m_pDataBindingAttrs.is())
+ {
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ OUString sValue = rProp.Value.get<OUString>();
+ if (rProp.Name == "ooxml:CT_DataBinding_prefixMappings")
+ AddToAttrList( m_pDataBindingAttrs,
+ FSNS( XML_w, XML_prefixMappings ),
+ OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (rProp.Name == "ooxml:CT_DataBinding_xpath")
+ AddToAttrList( m_pDataBindingAttrs,
+ FSNS( XML_w, XML_xpath ),
+ OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ else if (rProp.Name == "ooxml:CT_DataBinding_storeItemID")
+ AddToAttrList( m_pDataBindingAttrs,
+ FSNS( XML_w, XML_storeItemID ),
+ OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
+ {
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ if (aGrabBag.hasElements())
+ {
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ OUString sValue = rProp.Value.get<OUString>();
+ if (rProp.Name == "ooxml:CT_SdtText_multiLine")
+ AddToAttrList(m_pTextAttrs,
+ FSNS(XML_w, XML_multiLine),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ else
+ {
+ // We still have w:text, but no attrs
+ m_nSdtPrToken = FSNS(XML_w, XML_text);
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPlaceholder_docPart")
+ {
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ OUString sValue = rProp.Value.get<OUString>();
+ if (rProp.Name == "ooxml:CT_SdtPlaceholder_docPart_val")
+ m_aPlaceHolderDocPart = sValue;
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_color")
+ {
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ OUString sValue = rProp.Value.get<OUString>();
+ if (rProp.Name == "ooxml:CT_SdtColor_val")
+ m_aColor = sValue;
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_alias" && m_aAlias.isEmpty())
+ {
+ if (!(aPropertyValue.Value >>= m_aAlias))
+ SAL_WARN("sw.ww8", "DocxAttributeOutput::GrabBag: unexpected sdt alias value");
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id")
+ m_bHasId = true;
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
+ m_nSdtPrToken = FSNS(XML_w, XML_citation);
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
+ aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
+ {
+ if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
+ m_nSdtPrToken = FSNS(XML_w, XML_docPartObj);
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
+ m_nSdtPrToken = FSNS(XML_w, XML_docPartList);
+
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aPropertyValue.Value >>= aGrabBag;
+ for (const auto& rProp : std::as_const(aGrabBag))
+ {
+ OUString sValue = rProp.Value.get<OUString>();
+ if (rProp.Name == "ooxml:CT_SdtDocPart_docPartGallery")
+ AddToAttrList(m_pTokenChildren,
+ FSNS(XML_w, XML_docPartGallery),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ else if (rProp.Name == "ooxml:CT_SdtDocPart_docPartCategory")
+ AddToAttrList(m_pTokenChildren,
+ FSNS(XML_w, XML_docPartCategory),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ else if (rProp.Name == "ooxml:CT_SdtDocPart_docPartUnique")
+ {
+ if (sValue.isEmpty())
+ sValue = "true";
+ AddToAttrList(m_pTokenChildren, FSNS(XML_w, XML_docPartUnique),
+ OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+ }
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
+ m_nSdtPrToken = FSNS(XML_w, XML_equation);
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
+ m_nSdtPrToken = FSNS(XML_w, XML_picture);
+ else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
+ m_nSdtPrToken = FSNS(XML_w, XML_group);
+ else
+ SAL_WARN("sw.ww8", "GetSdtParamsFromGrabBag unhandled SdtPr grab bag property " << aPropertyValue.Name);
+ }
}
void DocxAttributeOutput::PopulateFrameProperties(const SwFrameFormat* pFrameFormat, const Size& rSize)
@@ -646,7 +908,7 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
++m_nTextFrameLevel;
if( m_nTextFrameLevel == 1 && !m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen() )
{
- comphelper::FlagRestorationGuard aStartedParaSdtGuard(m_bStartedParaSdt, false);
+ comphelper::FlagRestorationGuard aStartedParaSdtGuard(m_aParagraphSdt.m_bStartedSdt, false);
assert(!m_pPostponedCustomShape);
m_pPostponedCustomShape.reset(new std::vector<PostponedDrawing>);
@@ -658,11 +920,10 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
if (!TextBoxIsFramePr(rFrameFormat) || m_bWritingHeaderFooter)
{
- if (m_bStartedCharSdt)
+ if (m_aRunSdt.m_bStartedSdt)
{
// Run-level SDT still open? Close it before AlternateContent.
- EndSdtBlock();
- m_bStartedCharSdt = false;
+ m_aRunSdt.EndSdtBlock(m_pSerializer);
}
m_pSerializer->startElementNS(XML_w, XML_r);
m_pSerializer->startElementNS(XML_mc, XML_AlternateContent);
@@ -748,11 +1009,10 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
m_nHyperLinkCount = 0;
}
- if (m_bStartedCharSdt)
+ if (m_aRunSdt.m_bStartedSdt)
{
// Run-level SDT still open? Close it now.
- EndSdtBlock();
- m_bStartedCharSdt = false;
+ m_aRunSdt.EndSdtBlock(m_pSerializer);
}
if (m_bPageBreakAfter)
@@ -764,21 +1024,25 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
m_pSerializer->endElementNS( XML_w, XML_p );
// on export sdt blocks are never nested ATM
- if( !m_bAnchorLinkedToNode && !m_bStartedParaSdt )
- WriteSdtBlock(m_nParagraphSdtPrToken, m_pParagraphSdtPrTokenChildren,
- m_pParagraphSdtPrTokenAttributes, m_pParagraphSdtPrDataBindingAttrs,
- m_pParagraphSdtPrTextAttrs, m_aParagraphSdtPrAlias,
- m_aParagraphSdtPrPlaceHolderDocPart, m_aParagraphSdtPrColor, /*bPara=*/true);
+ if (!m_bAnchorLinkedToNode && !m_aParagraphSdt.m_bStartedSdt)
+ {
+ m_aParagraphSdt.WriteSdtBlock(m_pSerializer, m_bRunTextIsOn, m_rExport.SdrExporter().IsParagraphHasDrawing());
+
+ if (m_aParagraphSdt.m_bStartedSdt)
+ {
+ if (m_tableReference->m_bTableCellOpen)
+ m_tableReference->m_bTableCellParaSdtOpen = true;
+ if (m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen())
+ m_rExport.SdrExporter().setParagraphSdtOpen(true);
+ }
+ }
else
{
//These should be written out to the actual Node and not to the anchor.
//Clear them as they will be repopulated when the node is processed.
- m_nParagraphSdtPrToken = 0;
- m_bParagraphSdtHasId = false;
- lcl_deleteAndResetTheLists(m_pParagraphSdtPrTokenChildren,
- m_pParagraphSdtPrDataBindingAttrs, m_pParagraphSdtPrTextAttrs,
- m_aParagraphSdtPrAlias, m_aParagraphSdtPrPlaceHolderDocPart,
- m_aParagraphSdtPrColor);
+ m_aParagraphSdt.m_nSdtPrToken = 0;
+ m_aParagraphSdt.m_bHasId = false;
+ m_aParagraphSdt.DeleteAndResetTheLists();
}
//sdtcontent is written so Set m_bParagraphHasDrawing to false
@@ -806,129 +1070,6 @@ void DocxAttributeOutput::EndParagraph( ww8::WW8TableNodeInfoInner::Pointer_t pT
m_aBookmarksOfParagraphEnd.clear();
}
-void DocxAttributeOutput::WriteSdtBlock( sal_Int32& nSdtPrToken,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTokenChildren,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTokenAttributes,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrDataBindingAttrs,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTextAttrs,
- OUString& rSdtPrAlias,
- OUString& rSdtPrPlaceholderDocPart,
- OUString& rColor,
- bool bPara )
-{
- if( nSdtPrToken <= 0 && !pSdtPrDataBindingAttrs.is() && !m_bParagraphSdtHasId)
- return;
-
- // sdt start mark
- m_pSerializer->mark(Tag_WriteSdtBlock);
-
- m_pSerializer->startElementNS(XML_w, XML_sdt);
-
- // output sdt properties
- m_pSerializer->startElementNS(XML_w, XML_sdtPr);
-
- if( nSdtPrToken > 0 && pSdtPrTokenChildren.is() )
- {
- if (!pSdtPrTokenAttributes.is())
- m_pSerializer->startElement(nSdtPrToken);
- else
- {
- XFastAttributeListRef xAttrList(pSdtPrTokenAttributes.get());
- pSdtPrTokenAttributes.clear();
- m_pSerializer->startElement(nSdtPrToken, xAttrList);
- }
-
- if (nSdtPrToken == FSNS( XML_w, XML_date ) || nSdtPrToken == FSNS( XML_w, XML_docPartObj ) || nSdtPrToken == FSNS( XML_w, XML_docPartList ) || nSdtPrToken == FSNS( XML_w14, XML_checkbox )) {
- const uno::Sequence<xml::FastAttribute> aChildren = pSdtPrTokenChildren->getFastAttributes();
- for( const auto& rChild : aChildren )
- m_pSerializer->singleElement( rChild.Token,
- FSNS(XML_w, XML_val), rChild.Value.toUtf8() );
- }
-
- m_pSerializer->endElement( nSdtPrToken );
- }
- else if( (nSdtPrToken > 0) && nSdtPrToken != FSNS( XML_w, XML_id ) && !(m_bRunTextIsOn && m_rExport.SdrExporter().IsParagraphHasDrawing()))
- {
- if (!pSdtPrTokenAttributes.is())
- m_pSerializer->singleElement(nSdtPrToken);
- else
- {
- XFastAttributeListRef xAttrList(pSdtPrTokenAttributes.get());
- pSdtPrTokenAttributes.clear();
- m_pSerializer->singleElement(nSdtPrToken, xAttrList);
- }
- }
-
- if( nSdtPrToken == FSNS( XML_w, XML_id ) || ( bPara && m_bParagraphSdtHasId ) )
- //Word won't open a document with an empty id tag, we fill it with a random number
- m_pSerializer->singleElementNS(XML_w, XML_id, FSNS(XML_w, XML_val),
- OString::number(comphelper::rng::uniform_int_distribution(0, std::numeric_limits<int>::max())));
-
- if( pSdtPrDataBindingAttrs.is() && !m_rExport.SdrExporter().IsParagraphHasDrawing())
- {
- XFastAttributeListRef xAttrList( pSdtPrDataBindingAttrs.get() );
- pSdtPrDataBindingAttrs.clear();
- m_pSerializer->singleElementNS(XML_w, XML_dataBinding, xAttrList);
- }
-
- if (pSdtPrTextAttrs.is())
- {
- XFastAttributeListRef xAttrList( pSdtPrTextAttrs.get() );
- pSdtPrTextAttrs.clear();
- m_pSerializer->singleElementNS(XML_w, XML_text, xAttrList);
- }
-
- if (!rSdtPrPlaceholderDocPart.isEmpty())
- {
- m_pSerializer->startElementNS(XML_w, XML_placeholder);
- m_pSerializer->singleElementNS(XML_w, XML_docPart, FSNS(XML_w, XML_val), rSdtPrPlaceholderDocPart.toUtf8());
- m_pSerializer->endElementNS(XML_w, XML_placeholder);
- }
- if (!rColor.isEmpty())
- {
- m_pSerializer->singleElementNS(XML_w15, XML_color, FSNS(XML_w, XML_val), rColor.toUtf8());
- }
-
- if (!rSdtPrAlias.isEmpty())
- m_pSerializer->singleElementNS(XML_w, XML_alias, FSNS(XML_w, XML_val),
- rSdtPrAlias.toUtf8());
-
- m_pSerializer->endElementNS( XML_w, XML_sdtPr );
-
- // sdt contents start tag
- m_pSerializer->startElementNS(XML_w, XML_sdtContent);
-
- // prepend the tags since the sdt start mark before the paragraph
- m_pSerializer->mergeTopMarks(Tag_WriteSdtBlock, sax_fastparser::MergeMarks::PREPEND);
-
- // write the ending tags after the paragraph
- if (bPara)
- {
- m_bStartedParaSdt = true;
- if (m_tableReference->m_bTableCellOpen)
- m_tableReference->m_bTableCellParaSdtOpen = true;
- if (m_rExport.SdrExporter().IsDMLAndVMLDrawingOpen())
- m_rExport.SdrExporter().setParagraphSdtOpen(true);
- }
- else
- // Support multiple runs inside a run-level SDT: don't close the SDT block yet.
- m_bStartedCharSdt = true;
-
- // clear sdt status
- nSdtPrToken = 0;
- pSdtPrTokenChildren.clear();
- pSdtPrDataBindingAttrs.clear();
- pSdtPrTextAttrs.clear();
- rSdtPrAlias.clear();
- m_bParagraphSdtHasId = false;
-}
-
-void DocxAttributeOutput::EndSdtBlock()
-{
- m_pSerializer->endElementNS( XML_w, XML_sdtContent );
- m_pSerializer->endElementNS( XML_w, XML_sdt );
-}
-
#define MAX_CELL_IN_WORD 62
void DocxAttributeOutput::SyncNodelessCells(ww8::WW8TableNodeInfoInner::Pointer_t const & pInner, sal_Int32 nCell, sal_uInt32 nRow)
@@ -1398,12 +1539,11 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
// if another sdt starts in this run, then wait
// as closing the sdt now, might cause nesting of sdts
- if (m_nRunSdtPrToken > 0)
+ if (m_aRunSdt.m_nSdtPrToken > 0)
bCloseEarlierSDT = true;
else
- EndSdtBlock();
+ m_aRunSdt.EndSdtBlock(m_pSerializer);
m_bEndCharSdt = false;
- m_bStartedCharSdt = false;
}
if ( m_closeHyperlinkInPreviousRun )
@@ -1561,27 +1701,22 @@ void DocxAttributeOutput::EndRun(const SwTextNode* pNode, sal_Int32 nPos, bool /
// enclose in a sdt block, if necessary: if one is already started, then don't do it for now
// (so on export sdt blocks are never nested ATM)
- if ( !m_bAnchorLinkedToNode && !m_bStartedCharSdt )
+ if ( !m_bAnchorLinkedToNode && !m_aRunSdt.m_bStartedSdt)
{
- rtl::Reference<sax_fastparser::FastAttributeList> pRunSdtPrTokenAttributes;
- WriteSdtBlock(m_nRunSdtPrToken, m_pRunSdtPrTokenChildren, pRunSdtPrTokenAttributes,
- m_pRunSdtPrDataBindingAttrs, m_pRunSdtPrTextAttrs, m_aRunSdtPrAlias,
- m_aRunSdtPrPlaceHolderDocPart, m_aRunSdtPrColor, /*bPara=*/false);
+ m_aRunSdt.WriteSdtBlock(m_pSerializer, m_bRunTextIsOn, m_rExport.SdrExporter().IsParagraphHasDrawing());
}
else
{
//These should be written out to the actual Node and not to the anchor.
//Clear them as they will be repopulated when the node is processed.
- m_nRunSdtPrToken = 0;
- lcl_deleteAndResetTheLists(m_pRunSdtPrTokenChildren, m_pRunSdtPrDataBindingAttrs,
- m_pRunSdtPrTextAttrs, m_aRunSdtPrAlias,
- m_aRunSdtPrPlaceHolderDocPart, m_aRunSdtPrColor);
+ m_aRunSdt.m_nSdtPrToken = 0;
+ m_aRunSdt.DeleteAndResetTheLists();
}
if (bCloseEarlierSDT)
{
m_pSerializer->mark(Tag_EndRun_2);
- EndSdtBlock();
+ m_aRunSdt.EndSdtBlock(m_pSerializer);
m_pSerializer->mergeTopMarks(Tag_EndRun_2, sax_fastparser::MergeMarks::PREPEND);
}
@@ -2730,7 +2865,7 @@ void DocxAttributeOutput::GetSdtEndBefore(const SdrObject* pSdrObj)
auto pProp = std::find_if(aGrabBag.begin(), aGrabBag.end(),
[this](const beans::PropertyValue& rProp) {
- return "SdtEndBefore" == rProp.Name && m_bStartedCharSdt && !m_bEndCharSdt; });
+ return "SdtEndBefore" == rProp.Name && m_aRunSdt.m_bStartedSdt && !m_bEndCharSdt; });
if (pProp != aGrabBag.end())
pProp->Value >>= m_bEndCharSdt;
}
@@ -5829,8 +5964,8 @@ void DocxAttributeOutput::pushToTableExportContext(DocxTableExportContext& rCont
rContext.m_nTableDepth = m_tableReference->m_nTableDepth;
m_tableReference->m_nTableDepth = 0;
- rContext.m_bStartedParaSdt = m_bStartedParaSdt;
- m_bStartedParaSdt = false;
+ rContext.m_bStartedParaSdt = m_aParagraphSdt.m_bStartedSdt;
+ m_aParagraphSdt.m_bStartedSdt = false;
}
void DocxAttributeOutput::popFromTableExportContext(DocxTableExportContext const & rContext)
@@ -5838,7 +5973,7 @@ void DocxAttributeOutput::popFromTableExportContext(DocxTableExportContext const
m_rExport.m_pTableInfo = rContext.m_pTableInfo;
m_tableReference->m_bTableCellOpen = rContext.m_bTableCellOpen;
m_tableReference->m_nTableDepth = rContext.m_nTableDepth;
- m_bStartedParaSdt = rContext.m_bStartedParaSdt;
+ m_aParagraphSdt.m_bStartedSdt = rContext.m_bStartedParaSdt;
}
void DocxAttributeOutput::WriteTextBox(uno::Reference<drawing::XShape> xShape)
@@ -6169,11 +6304,10 @@ void DocxAttributeOutput::SectionBreak( sal_uInt8 nC, bool bBreakAfter, const WW
void DocxAttributeOutput::EndParaSdtBlock()
{
- if (m_bStartedParaSdt)
+ if (m_aParagraphSdt.m_bStartedSdt)
{
// Paragraph-level SDT still open? Close it now.
- EndSdtBlock();
- m_bStartedParaSdt = false;
+ m_aParagraphSdt.EndSdtBlock(m_pSerializer);
}
}
@@ -9008,143 +9142,8 @@ void DocxAttributeOutput::ParaGrabBag(const SfxGrabBagItem& rItem)
{
const uno::Sequence<beans::PropertyValue> aGrabBagSdt =
rGrabBagElement.second.get< uno::Sequence<beans::PropertyValue> >();
- for (const beans::PropertyValue& aPropertyValue : aGrabBagSdt)
- {
- if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj" ||
- aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
- {
- if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartObj")
- m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartObj );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_docPartList")
- m_nParagraphSdtPrToken = FSNS( XML_w, XML_docPartList );
-
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtDocPart_docPartGallery")
- AddToAttrList( m_pParagraphSdtPrTokenChildren,
- FSNS( XML_w, XML_docPartGallery ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_SdtDocPart_docPartCategory")
- AddToAttrList( m_pParagraphSdtPrTokenChildren,
- FSNS( XML_w, XML_docPartCategory ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_SdtDocPart_docPartUnique")
- {
- if (sValue.isEmpty())
- sValue = "true";
- AddToAttrList( m_pParagraphSdtPrTokenChildren, FSNS( XML_w, XML_docPartUnique ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- }
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_equation")
- m_nParagraphSdtPrToken = FSNS( XML_w, XML_equation );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_picture")
- m_nParagraphSdtPrToken = FSNS( XML_w, XML_picture );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
- m_nParagraphSdtPrToken = FSNS( XML_w, XML_citation );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_group")
- m_nParagraphSdtPrToken = FSNS( XML_w, XML_group );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- if (aGrabBag.hasElements())
- {
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtText_multiLine")
- AddToAttrList(m_pParagraphSdtPrTextAttrs,
- FSNS(XML_w, XML_multiLine),
- OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
- }
- }
- else
- {
- // We still have w:text, but no attrs
- m_nParagraphSdtPrToken = FSNS(XML_w, XML_text);
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding" && !m_pParagraphSdtPrDataBindingAttrs.is())
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_DataBinding_prefixMappings")
- AddToAttrList( m_pParagraphSdtPrDataBindingAttrs,
- FSNS( XML_w, XML_prefixMappings ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_DataBinding_xpath")
- AddToAttrList( m_pParagraphSdtPrDataBindingAttrs,
- FSNS( XML_w, XML_xpath ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_DataBinding_storeItemID")
- AddToAttrList( m_pParagraphSdtPrDataBindingAttrs,
- FSNS( XML_w, XML_storeItemID ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPlaceholder_docPart")
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtPlaceholder_docPart_val")
- m_aParagraphSdtPrPlaceHolderDocPart = sValue;
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_color")
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtColor_val")
- m_aParagraphSdtPrColor = sValue;
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_alias" && m_aParagraphSdtPrAlias.isEmpty())
- {
- if (!(aPropertyValue.Value >>= m_aParagraphSdtPrAlias))
- SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unexpected sdt alias value");
- m_aStartedParagraphSdtPrAlias = m_aParagraphSdtPrAlias;
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
- {
- m_nParagraphSdtPrToken = FSNS( XML_w14, XML_checkbox );
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtCheckbox_checked")
- AddToAttrList( m_pParagraphSdtPrTokenChildren,
- FSNS( XML_w14, XML_checked ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_SdtCheckbox_checkedState")
- AddToAttrList( m_pParagraphSdtPrTokenChildren,
- FSNS( XML_w14, XML_checkedState ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_SdtCheckbox_uncheckedState")
- AddToAttrList( m_pParagraphSdtPrTokenChildren,
- FSNS( XML_w14, XML_uncheckedState ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id")
- m_bParagraphSdtHasId = true;
- else
- SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled SdtPr grab bag property " << aPropertyValue.Name);
- }
+ m_aParagraphSdt.GetSdtParamsFromGrabBag(aGrabBagSdt);
+ m_aStartedParagraphSdtPrAlias = m_aParagraphSdt.m_aAlias;
}
else if (rGrabBagElement.first == "ParaCnfStyle")
{
@@ -9275,107 +9274,14 @@ void DocxAttributeOutput::CharGrabBag( const SfxGrabBagItem& rItem )
}
else if (rGrabBagElement.first == "SdtEndBefore")
{
- if (m_bStartedCharSdt)
+ if (m_aRunSdt.m_bStartedSdt)
m_bEndCharSdt = true;
}
else if (rGrabBagElement.first == "SdtPr" && FLY_NOT_PROCESSED != m_nStateOfFlyFrame )
{
const uno::Sequence<beans::PropertyValue> aGrabBagSdt =
rGrabBagElement.second.get< uno::Sequence<beans::PropertyValue> >();
- for (const beans::PropertyValue& aPropertyValue : aGrabBagSdt)
- {
- if (aPropertyValue.Name == "ooxml:CT_SdtPr_checkbox")
- {
- m_nRunSdtPrToken = FSNS( XML_w14, XML_checkbox );
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtCheckbox_checked")
- AddToAttrList( m_pRunSdtPrTokenChildren,
- FSNS( XML_w14, XML_checked ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_SdtCheckbox_checkedState")
- AddToAttrList( m_pRunSdtPrTokenChildren,
- FSNS( XML_w14, XML_checkedState ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_SdtCheckbox_uncheckedState")
- AddToAttrList( m_pRunSdtPrTokenChildren,
- FSNS( XML_w14, XML_uncheckedState ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text")
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtText_multiLine")
- AddToAttrList(m_pRunSdtPrTextAttrs,
- FSNS(XML_w, XML_multiLine),
- OUStringToOString(sValue, RTL_TEXTENCODING_UTF8).getStr());
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_dataBinding" && !m_pRunSdtPrDataBindingAttrs.is())
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_DataBinding_prefixMappings")
- AddToAttrList( m_pRunSdtPrDataBindingAttrs,
- FSNS( XML_w, XML_prefixMappings ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_DataBinding_xpath")
- AddToAttrList( m_pRunSdtPrDataBindingAttrs,
- FSNS( XML_w, XML_xpath ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- else if (rProp.Name == "ooxml:CT_DataBinding_storeItemID")
- AddToAttrList( m_pRunSdtPrDataBindingAttrs,
- FSNS( XML_w, XML_storeItemID ),
- OUStringToOString( sValue, RTL_TEXTENCODING_UTF8 ).getStr() );
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPlaceholder_docPart")
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtPlaceholder_docPart_val")
- m_aRunSdtPrPlaceHolderDocPart = sValue;
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_color")
- {
- uno::Sequence<beans::PropertyValue> aGrabBag;
- aPropertyValue.Value >>= aGrabBag;
- for (const auto& rProp : std::as_const(aGrabBag))
- {
- OUString sValue = rProp.Value.get<OUString>();
- if (rProp.Name == "ooxml:CT_SdtColor_val")
- m_aRunSdtPrColor = sValue;
- }
- }
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_alias" && m_aRunSdtPrAlias.isEmpty())
- {
- if (!(aPropertyValue.Value >>= m_aRunSdtPrAlias))
- SAL_WARN("sw.ww8", "DocxAttributeOutput::CharGrabBag: unexpected sdt alias value");
- }
- //do not overwrite the parent node.
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_text" && !m_pRunSdtPrTokenChildren.is())
- m_nRunSdtPrToken = FSNS( XML_w, XML_text );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_id" && m_nRunSdtPrToken == 0)
- // only write id token as a marker if no other exist
- m_nRunSdtPrToken = FSNS( XML_w, XML_id );
- else if (aPropertyValue.Name == "ooxml:CT_SdtPr_citation")
- m_nRunSdtPrToken = FSNS( XML_w, XML_citation );
- }
+ m_aRunSdt.GetSdtParamsFromGrabBag(aGrabBagSdt);
}
else
SAL_INFO("sw.ww8", "DocxAttributeOutput::CharGrabBag: unhandled grab bag property " << rGrabBagElement.first);
@@ -9388,8 +9294,6 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr
m_pSerializer( pSerializer ),
m_rDrawingML( *pDrawingML ),
m_bEndCharSdt(false),
- m_bStartedCharSdt(false),
- m_bStartedParaSdt(false),
m_endPageRef( false ),
m_pFootnotesList( new ::docx::FootnotesList() ),
m_pEndnotesList( new ::docx::FootnotesList() ),
@@ -9435,10 +9339,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, const FSHelperPtr
m_nParaBeforeSpacing(0),
m_nParaAfterSpacing(0),
m_setFootnote(false)
- , m_nParagraphSdtPrToken(0)
- , m_nRunSdtPrToken(0)
, m_nStateOfFlyFrame( FLY_NOT_PROCESSED )
- , m_bParagraphSdtHasId(false)
{
// Push initial items to the RelId cache. In case the document contains no
// special streams (headers, footers, etc.) then these items are used
@@ -9501,26 +9402,4 @@ void DocxAttributeOutput::BulletDefinition(int nId, const Graphic& rGraphic, Siz
m_pSerializer->endElementNS(XML_w, XML_numPicBullet);
}
-void DocxAttributeOutput::AddToAttrList( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue )
-{
- AddToAttrList( pAttrList, 1, nAttrName, sAttrValue );
-}
-
-void DocxAttributeOutput::AddToAttrList( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrs, ... )
-{
- if( !pAttrList.is() )
- pAttrList = FastSerializerHelper::createAttrList();
-
- va_list args;
- va_start( args, nAttrs );
- for( sal_Int32 i = 0; i<nAttrs; i++)
- {
- sal_Int32 nName = va_arg( args, sal_Int32 );
- const char* pValue = va_arg( args, const char* );
- if( pValue )
- pAttrList->add( nName, pValue );
- }
- va_end( args );
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 415a7944e5f5..84c63957c208 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -119,6 +119,36 @@ struct TableReference
}
};
+class SdtBlockHelper
+{
+public:
+ SdtBlockHelper()
+ : m_bHasId(false)
+ , m_bStartedSdt(false)
+ , m_nSdtPrToken(0)
+ {}
+
+ bool m_bHasId;
+ bool m_bStartedSdt;
+ rtl::Reference<sax_fastparser::FastAttributeList> m_pTokenChildren;
+ rtl::Reference<sax_fastparser::FastAttributeList> m_pTokenAttributes;
+ rtl::Reference<sax_fastparser::FastAttributeList> m_pTextAttrs;
+ rtl::Reference<sax_fastparser::FastAttributeList> m_pDataBindingAttrs;
+ OUString m_aColor;
+ OUString m_aPlaceHolderDocPart;
+ OUString m_aAlias;
+ sal_Int32 m_nSdtPrToken;
+
+ void DeleteAndResetTheLists();
+
+ void WriteSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer, bool bRunTextIsOn, bool bParagraphHasDrawing);
+
+ /// Closes a currently open SDT block.
+ void EndSdtBlock(::sax_fastparser::FSHelperPtr& pSerializer);
+
+ void GetSdtParamsFromGrabBag(const uno::Sequence<beans::PropertyValue>& aGrabBagSdt);
+};
+
/// The class that has handlers for various resource types when exporting as DOCX.
class DocxAttributeOutput : public AttributeOutputBase, public oox::vml::VMLTextExport, public oox::drawingml::DMLTextExport
{
@@ -708,18 +738,6 @@ private:
void WritePostponedDMLDrawing();
void WritePostponedCustomShape();
- void WriteSdtBlock(sal_Int32& nSdtPrToken,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTokenChildren,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTokenAttributes,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrDataBindingAttrs,
- rtl::Reference<sax_fastparser::FastAttributeList>& pSdtPrTextAttrs,
- OUString& rSdtPrAlias,
- OUString& rSdtPrPlaceholderDocPart,
- OUString& rColor,
- bool bPara);
- /// Closes a currently open SDT block.
- void EndSdtBlock();
-
void WriteFormDateStart(const OUString& sFullDate, const OUString& sDateFormat, const OUString& sLang);
void WriteSdtDropDownStart(OUString const& rName, OUString const& rSelected, uno::Sequence<OUString> const& rListItems);
void WriteSdtDropDownEnd(OUString const& rSelected, uno::Sequence<OUString> const& rListItems);
@@ -732,9 +750,6 @@ private:
void EndField_Impl( const SwTextNode* pNode, sal_Int32 nPos, FieldInfos& rInfos );
void DoWriteFieldRunProperties( const SwTextNode* pNode, sal_Int32 nPos, bool bWriteCombChars = false );
- static void AddToAttrList( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nAttrName, const sal_Char* sAttrValue );
- static void AddToAttrList( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, sal_Int32 nArgs, ... );
-
rtl::Reference<sax_fastparser::FastAttributeList> m_pFontsAttrList;
rtl::Reference<sax_fastparser::FastAttributeList> m_pEastAsianLayoutAttrList;
rtl::Reference<sax_fastparser::FastAttributeList> m_pCharLangAttrList;
@@ -743,10 +758,6 @@ private:
rtl::Reference<sax_fastparser::FastAttributeList> m_pHyperlinkAttrList;
/// If the current SDT around runs should be ended before the current run.
bool m_bEndCharSdt;
- /// If an SDT around runs is currently open.
- bool m_bStartedCharSdt;
- /// If an SDT around paragraphs is currently open.
- bool m_bStartedParaSdt;
/// Attributes of the run color
rtl::Reference<sax_fastparser::FastAttributeList> m_pColorAttrList;
/// Attributes of the paragraph background
@@ -957,30 +968,14 @@ private:
/// RelId <-> BitmapChecksum cache, similar to m_aRelIdCache, but used for non-Writer graphics, handled in oox.
std::stack< std::map<BitmapChecksum, OUString> > m_aSdrRelIdCache;
- /// members to control the existence of grabbagged SDT properties in the paragraph
- sal_Int32 m_nParagraphSdtPrToken;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pParagraphSdtPrTokenChildren;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pParagraphSdtPrTokenAttributes;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pParagraphSdtPrDataBindingAttrs;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pParagraphSdtPrTextAttrs;
- /// members to control the existence of grabbagged SDT properties in the text run
- sal_Int32 m_nRunSdtPrToken;
+ SdtBlockHelper m_aParagraphSdt;
+ SdtBlockHelper m_aRunSdt;
+
/// State of the Fly at current position
FlyProcessingState m_nStateOfFlyFrame;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pRunSdtPrTokenChildren;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pRunSdtPrDataBindingAttrs;
- rtl::Reference<sax_fastparser::FastAttributeList> m_pRunSdtPrTextAttrs;
- /// Value of the <w:alias> paragraph SDT element.
- OUString m_aParagraphSdtPrAlias;
- OUString m_aParagraphSdtPrPlaceHolderDocPart;
- OUString m_aParagraphSdtPrColor;
+
/// Same as m_aParagraphSdtPrAlias, but its content is available till the SDT is closed.
OUString m_aStartedParagraphSdtPrAlias;
- OUString m_aRunSdtPrAlias;
- OUString m_aRunSdtPrPlaceHolderDocPart;
- OUString m_aRunSdtPrColor;
- /// Currently paragraph SDT has a <w:id> child element.
- bool m_bParagraphSdtHasId;
std::map<SvxBoxItemLine, css::table::BorderLine2> m_aTableStyleConf;