sw/qa/extras/ooxmlexport/data/tdf48459.fodt          |   66 +++++++++++++++++++
 sw/qa/extras/ooxmlexport/ooxmlexport20.cxx           |   11 +++
 sw/source/filter/ww8/docxattributeoutput.cxx         |   31 +++++++-
 sw/source/filter/ww8/docxattributeoutput.hxx         |    2 
 sw/source/filter/ww8/writerhelper.cxx                |   16 +++-
 sw/source/filter/ww8/wrtw8nds.cxx                    |   31 ++------
 sw/source/filter/ww8/wrtww8.cxx                      |    2 
 sw/source/filter/ww8/wrtww8.hxx                      |    1 
 sw/source/writerfilter/dmapper/DomainMapper.cxx      |    1 
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx |   12 ++-
 10 files changed, 136 insertions(+), 37 deletions(-)

New commits:
commit 49765a9e7be41d4908729ff7d838755276b244cb
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Oct 30 17:11:26 2024 +0100
Commit:     László Németh <nem...@numbertext.org>
CommitDate: Fri Nov 1 10:23:49 2024 +0100

    tdf#48459 tdf#131728 sw inline heading: new frame style: fix DOCX export
    
    Export Inline Heading frame style as OOXML style separator,
    fixing interoperability of the newly created inline headings.
    
    Remove frame grab-bagging, use the new Inline Heading
    style for round-trip of DOCX documents. Note: paragraph
    grab-bagging is used only for the case, where no frame
    created for the inline heading (second or more inline
    heading paragraphs in the same paragraph layout).
    
    Now the DOCX import uses anchoring as character, fixing layout
    problems of short paragraphs with big size headings anchored
    *to character* previously.
    
    Follow-up to commit 7a35f3dc7419d833b8f47069c4df63e900ccb880
    "tdf#48459 sw inline heading: apply it on the selected words",
    commit d87cf67f8f3346a1e380383917a3a4552fd9248e
    "tdf#131728 sw inline heading: fix missing/broken DOCX export"
    and commit a1dcbd1d1ce6071d48bb5df26d7839aeb21b75a8
    "tdf48459 sw inline heading: add Inline Heading frame style".
    
    Change-Id: Idc5f366c7a34f6e018683744475fc87aed0a3d14
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175835
    Reviewed-by: László Németh <nem...@numbertext.org>
    Tested-by: Jenkins

diff --git a/sw/qa/extras/ooxmlexport/data/tdf48459.fodt 
b/sw/qa/extras/ooxmlexport/data/tdf48459.fodt
new file mode 100644
index 000000000000..30db0fd1ada4
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf48459.fodt
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/"; 
xmlns:grddl="http://www.w3.org/2003/g/data-view#"; 
xmlns:xhtml="http://www.w3.org/1999/xhtml"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; 
xmlns:xforms="http://www.w3.org/2002/xforms"; 
xmlns:dom="http://www.w3.org/2001/xml-events"; 
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" 
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" 
xmlns:math="http://www.w3.org/1998/Math/MathML"; 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:ooow="http://openoffice.org/2004/writer"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:drawooo="http://openoffice.org/2010/draw"; 
xmlns:oooc="http://openoffice.org/2004/calc"; 
xmlns:dc="http://purl.org/dc/elements/1.1/"; xmlns:c
 alcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" 
xmlns:tableooo="http://openoffice.org/2009/table"; 
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" 
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" 
xmlns:rpt="http://openoffice.org/2005/report"; 
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
 xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" 
xmlns:officeooo="http://openoffice.org/2009/office"; 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" 
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" 
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:
 meta:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Sans" 
svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" 
style:font-pitch="variable"/>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="graphic">
+   <style:graphic-properties svg:stroke-color="#3465a4" 
draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" 
draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" 
draw:start-line-spacing-vertical="0.283cm" 
draw:end-line-spacing-horizontal="0.283cm" 
draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+   <style:paragraph-properties style:text-autospace="ideograph-alpha" 
style:line-break="strict" loext:tab-stop-distance="0cm" 
style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+    <style:tab-stops/>
+   </style:paragraph-properties>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="US" style:letter-kerning="true"/>
+  </style:default-style>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:orphans="2" fo:widows="2" 
fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" 
loext:hyphenation-keep-type="column" style:text-autospace="ideograph-alpha" 
style:punctuation-wrap="hanging" style:line-break="strict" 
style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="en" fo:country="US" style:letter-kerning="true" 
fo:hyphenate="false" fo:hyphenation-remain-char-count="2" 
fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" 
loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" 
loext:hyphenation-zone="no-limit"/>
+  </style:default-style>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text"/>
+  <style:style style:name="Text_20_body" style:display-name="Text body" 
style:family="paragraph" style:parent-style-name="Standard" style:class="text">
+   <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.247cm" 
style:contextual-spacing="false" fo:line-height="115%"/>
+  </style:style>
+  <style:style style:name="Frame_20_contents" style:display-name="Frame 
contents" style:family="paragraph" style:parent-style-name="Standard" 
style:class="extra"/>
+  <style:style style:name="Heading_20_4" style:display-name="Heading 4" 
style:family="paragraph" style:parent-style-name="Heading" 
style:next-style-name="Text_20_body" style:default-outline-level="4" 
style:class="chapter">
+   <style:paragraph-properties fo:margin-top="0.212cm" 
fo:margin-bottom="0.212cm" style:contextual-spacing="false"/>
+   <style:text-properties fo:font-size="12pt" fo:font-style="normal" 
fo:font-weight="bold"/>
+  </style:style>
+  <style:style style:name="Frame" style:family="graphic">
+   <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" 
svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" 
fo:margin-top="0.201cm" fo:margin-bottom="0.201cm" style:wrap="parallel" 
style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" 
style:vertical-pos="top" style:vertical-rel="paragraph-content" 
style:horizontal-pos="center" style:horizontal-rel="paragraph-content" 
draw:fill="none" fo:padding="0.15cm" fo:border="0.06pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Inline_20_Heading" style:display-name="Inline 
Heading" style:family="graphic">
+   <style:graphic-properties fo:min-width="0cm" fo:min-height="0cm" 
text:anchor-type="as-char" svg:y="0cm" fo:margin-left="0cm" 
fo:margin-right="0cm" style:vertical-pos="middle" style:vertical-rel="text" 
draw:fill="none"/>
+  </style:style>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties officeooo:rsid="001a5dde" 
officeooo:paragraph-rsid="001a5dde"/>
+  </style:style>
+  <style:style style:name="P2" style:family="paragraph" 
style:parent-style-name="Heading_20_4">
+   <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0cm" 
style:contextual-spacing="false"/>
+  </style:style>
+  <style:style style:name="fr1" style:family="graphic" 
style:parent-style-name="Inline_20_Heading">
+   <style:graphic-properties style:vertical-pos="middle" 
style:vertical-rel="text"/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:page-layout-properties fo:page-width="21.001cm" 
fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" 
fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" 
fo:margin-right="2cm" style:writing-mode="lr-tb" 
style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+    <style:footnote-sep style:width="0.018cm" 
style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" 
style:line-style="solid" style:adjustment="left" style:rel-width="25%" 
style:color="#000000"/>
+   </style:page-layout-properties>
+   <style:header-style/>
+   <style:footer-style/>
+  </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:p text:style-name="P1"><draw:frame draw:style-name="fr1" 
draw:name="Frame1" text:anchor-type="as-char" draw:z-index="0">
+     <draw:text-box fo:min-height="0cm" fo:min-width="0cm">
+      <text:h text:style-name="P2" text:outline-level="4">Heading</text:h>
+     </draw:text-box>
+    </draw:frame><text:s/>and paragraph</text:p>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx
index d05f809098bd..bfb777448fc3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport20.cxx
@@ -263,6 +263,17 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf131728)
     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:rPr/w:specVanish", 7);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf48459)
+{
+    loadAndSave("tdf48459.fodt");
+    // export Inline Heading frame style as style separator
+    xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr);
+
+    // This was 0 (no style separator)
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:rPr/w:vanish", 1);
+    assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:rPr/w:specVanish", 1);
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testFdo77129)
 {
     loadAndSave("fdo77129.docx");
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index e5f7e071f3fe..ff0e00475cf6 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -165,6 +165,7 @@
 #include <IDocumentDeviceAccess.hxx>
 #include <sfx2/printer.hxx>
 #include <unotxdoc.hxx>
+#include <poolfmt.hxx>
 
 using ::editeng::SvxBorderLine;
 
@@ -1448,6 +1449,7 @@ void DocxAttributeOutput::StartParagraphProperties()
     m_pSerializer->mark(Tag_StartParagraphProperties);
 
     m_pSerializer->startElementNS(XML_w, XML_pPr);
+    m_bOpenedParaPr = true;
 
     // and output the section break now (if it appeared)
     if (m_pSectionInfo && m_rExport.m_nTextTyp == TXT_MAINTEXT)
@@ -1751,6 +1753,8 @@ void DocxAttributeOutput::EndParagraphProperties(const 
SfxItemSet& rParagraphMar
     // merge the properties _before_ the run (strictly speaking, just
     // after the start of the paragraph)
     m_pSerializer->mergeTopMarks(Tag_StartParagraphProperties, 
sax_fastparser::MergeMarks::PREPEND);
+
+    m_bOpenedParaPr = false;
 }
 
 void DocxAttributeOutput::SetStateOfFlyFrame( FlyProcessingState 
nStateOfFlyFrame )
@@ -3643,11 +3647,12 @@ void DocxAttributeOutput::WriteCollectedRunProperties()
     }
     m_aTextEffectsGrabBag.clear();
     m_aTextFillGrabBag.clear();
-
-    if ( m_bParaInlineHeading )
+    // export vanish and specVanish for the newly created inline headings
+    if ( m_bOpenedParaPr && m_rExport.m_bParaInlineHeading )
     {
+        m_pSerializer->singleElementNS(XML_w, XML_vanish);
         m_pSerializer->singleElementNS(XML_w, XML_specVanish);
-        m_bParaInlineHeading = false;
+        m_rExport.m_bParaInlineHeading = false;
     }
 }
 
@@ -6393,6 +6398,11 @@ void DocxAttributeOutput::WriteFlyFrame(const 
ww8::Frame& rFrame)
                 if 
(m_aFloatingTablesOfParagraph.find(&rFrame.GetFrameFormat()) != 
m_aFloatingTablesOfParagraph.end())
                     break;
 
+                // skip also inline headings already exported before
+                const SwFormat* pParent = 
rFrame.GetFrameFormat().DerivedFrom();
+                if ( pParent && pParent->GetPoolFormatId() == 
RES_POOLFRM_INLINE_HEADING )
+                    break;
+
                 // The frame output is postponed to the end of the anchor 
paragraph
                 bool bDuplicate = false;
                 const OUString& rName = rFrame.GetFrameFormat().GetName();
@@ -8321,7 +8331,16 @@ void DocxAttributeOutput::CharRelief( const 
SvxCharReliefItem& rRelief )
 void DocxAttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden )
 {
     if ( rHidden.GetValue() )
+    {
         m_pSerializer->singleElementNS(XML_w, XML_vanish);
+        // export specVanish for inline headings
+        if (m_bOpenedParaPr && m_rExport.m_bParaInlineHeading)
+        {
+            m_pSerializer->singleElementNS(XML_w, XML_specVanish);
+            // don't export extra vanish/specVanish
+            m_rExport.m_bParaInlineHeading = false;
+        }
+    }
     else
         m_pSerializer->singleElementNS(XML_w, XML_vanish, FSNS(XML_w, 
XML_val), "false");
 }
@@ -10202,7 +10221,7 @@ void DocxAttributeOutput::ParaGrabBag(const 
SfxGrabBagItem& rItem)
             // Handled already in StartParagraph().
         }
         else if (rGrabBagElement.first == "ParaInlineHeading")
-            m_bParaInlineHeading = true;
+            m_rExport.m_bParaInlineHeading = true;
         else
             SAL_WARN("sw.ww8", "DocxAttributeOutput::ParaGrabBag: unhandled 
grab bag property " << rGrabBagElement.first );
     }
@@ -10327,6 +10346,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport 
&rExport, const FSHelperPtr
       m_nRedlineId( 0 ),
       m_bOpenedSectPr( false ),
       m_bHadSectPr(false),
+      m_bOpenedParaPr( false ),
       m_bRunTextIsOn( false ),
       m_bWritingHeaderFooter( false ),
       m_bAnchorLinkedToNode(false),
@@ -10358,8 +10378,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport 
&rExport, const FSHelperPtr
       m_bParaBeforeAutoSpacing(false),
       m_bParaAfterAutoSpacing(false),
       m_nParaBeforeSpacing(0),
-      m_nParaAfterSpacing(0),
-      m_bParaInlineHeading(false)
+      m_nParaAfterSpacing(0)
     , m_nStateOfFlyFrame( FLY_NOT_PROCESSED )
 {
     m_nHyperLinkCount.push_back(0);
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx 
b/sw/source/filter/ww8/docxattributeoutput.hxx
index 02b8190ad31d..385ce344c21d 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -858,6 +858,8 @@ private:
     bool m_bOpenedSectPr;
     /// Did we have a section break in this paragraph? Set by StartSection(), 
reset by the next StartParagraph().
     bool m_bHadSectPr;
+    /// Flag indicating that the paragraph properties are being written
+    bool m_bOpenedParaPr;
 
     /// Flag indicating that the Run Text is being written
     bool m_bRunTextIsOn;
diff --git a/sw/source/filter/ww8/writerhelper.cxx 
b/sw/source/filter/ww8/writerhelper.cxx
index 0d71b51f10b5..4bc9faf385c1 100644
--- a/sw/source/filter/ww8/writerhelper.cxx
+++ b/sw/source/filter/ww8/writerhelper.cxx
@@ -59,6 +59,7 @@
 #include <IDocumentMarkAccess.hxx>
 #include <IMark.hxx>
 #include <grfatr.hxx>
+#include <poolfmt.hxx>
 
 using namespace com::sun::star;
 
@@ -113,8 +114,17 @@ namespace
         for(const auto& rFly : rFlys)
         {
             const SwFrameFormat &rEntry = rFly.GetFormat();
-
-            if (const SwNode* pAnchor = rEntry.GetAnchor().GetAnchorNode())
+            const SwFormat* pParent = rEntry.DerivedFrom();
+            const SwFormatAnchor& rAnchor = rEntry.GetAnchor();
+            // keep only Inline Heading frames from the frames anchored as 
characters
+            bool bAsChar = rAnchor.GetAnchorId() ==
+                    
static_cast<RndStdIds>(css::text::TextContentAnchorType_AS_CHARACTER);
+            if ( bAsChar &&
+                    !(pParent && pParent->GetPoolFormatId() == 
RES_POOLFRM_INLINE_HEADING) )
+            {
+                continue;
+            }
+            if (const SwNode* pAnchor = rAnchor.GetAnchorNode())
             {
                 // the anchor position will be invalidated by SetRedlineFlags
                 // so set a dummy position and fix it in UpdateFramePositions
@@ -474,7 +484,7 @@ namespace sw
            */
         ww8::Frames GetFrames(const SwDoc &rDoc, SwPaM const *pPaM /*, bool 
bAll*/)
         {
-            SwPosFlyFrames aFlys(rDoc.GetAllFlyFormats(pPaM, true));
+            SwPosFlyFrames aFlys(rDoc.GetAllFlyFormats(pPaM, 
/*bDrawAlso=*/true, /*bAsCharAlso=*/true));
             ww8::Frames aRet(SwPosFlyFramesToFrames(aFlys));
             return aRet;
         }
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index b4451803bb28..260bd38fc6ad 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -111,6 +111,7 @@
 #include <ndole.hxx>
 #include <formatflysplit.hxx>
 #include <annotationmark.hxx>
+#include <poolfmt.hxx>
 
 #include <cstdio>
 
@@ -181,30 +182,8 @@ lcl_getLinkChainName(const 
uno::Reference<beans::XPropertySet>& rPropertySet,
 
 static bool lcl_IsInlineHeading(const ww8::Frame &rFrame)
 {
-    const SwFrameFormat& rFrameFormat = rFrame.GetFrameFormat();
-
-    uno::Reference<drawing::XShape> xShape;
-    const SdrObject* pSdrObj = rFrameFormat.FindRealSdrObject();
-    if (pSdrObj)
-        xShape.set(const_cast<SdrObject*>(pSdrObj)->getUnoShape(), 
uno::UNO_QUERY);
-    uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
-    uno::Reference<beans::XPropertySetInfo> xPropSetInfo;
-    if (xPropertySet.is())
-        xPropSetInfo = xPropertySet->getPropertySetInfo();
-
-    if (xPropSetInfo.is() && 
xPropSetInfo->hasPropertyByName(u"FrameInteropGrabBag"_ustr))
-    {
-        uno::Sequence<beans::PropertyValue> propList;
-        xPropertySet->getPropertyValue(u"FrameInteropGrabBag"_ustr) >>= 
propList;
-        auto pProp = std::find_if(std::cbegin(propList), std::cend(propList),
-                                  [](const beans::PropertyValue& rProp) {
-                                      return rProp.Name == 
"FrameInlineHeading";
-                                  });
-        if (pProp != std::cend(propList))
-            return true;
-    }
-
-    return false;
+    const SwFormat* pParent = rFrame.GetFrameFormat().DerivedFrom();
+    return pParent && pParent->GetPoolFormatId() == RES_POOLFRM_INLINE_HEADING;
 }
 
 MSWordAttrIter::MSWordAttrIter( MSWordExportBase& rExport )
@@ -2358,7 +2337,11 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode 
)
             SwTextNode *pTextNode =
                 
const_cast<SwTextNode*>(pInlineHeading->GetContent()->GetTextNode());
             if (pTextNode)
+            {
+                m_bParaInlineHeading = true;
                 OutputTextNode(*pTextNode);
+                m_bParaInlineHeading = false;
+            }
         }
     }
 
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 5019c8c5f329..b809a47acbdd 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3431,6 +3431,7 @@ ErrCode MSWordExportBase::ExportDocument( bool bWriteAll )
     m_bFootnoteAtTextEnd = m_bEndAtTextEnd = true;
 
     m_pParentFrame = nullptr;
+    m_bParaInlineHeading = false;
     m_pFlyOffset = nullptr;
     m_eNewAnchorType = RndStdIds::FLY_AT_PAGE;
     m_nTextTyp = TXT_MAINTEXT;
@@ -3969,6 +3970,7 @@ MSWordExportBase::MSWordExportBase( SwDoc& rDocument, 
std::shared_ptr<SwUnoCurso
     , m_bFirstTOCNodeWithSection(false)
     , m_pChpIter(nullptr)
     , m_pParentFrame(nullptr)
+    , m_bParaInlineHeading(false)
     , m_pFlyOffset(nullptr)
     , m_eNewAnchorType(RndStdIds::FLY_AS_CHAR)
     , m_pStyAttr(nullptr)
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index a4e85ebc7c1b..bd07c5b155c9 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -521,6 +521,7 @@ public:
 
     const ww8::Frame *m_pParentFrame; // If set we are exporting content inside
                                     // a frame, e.g. a graphic node
+    bool m_bParaInlineHeading;        // exporting paragraph of inline heading
 
     Point* m_pFlyOffset;              // for adjusting of character-bound Fly 
in the Writer,
     RndStdIds m_eNewAnchorType;       // that is paragraph-bound in the WW.
diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper.cxx
index 8fee3500a043..9d8654c06f4a 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx
@@ -2143,6 +2143,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const 
PropertyMapPtr& rContext )
         {
             // put inline heading inside a text frame to get the same layout 
with ToC/PDF bookmark support
             m_pImpl->m_StreamStateStack.top().bIsInlineParagraph = true;
+            // grab-bag it for multiple inline headings in the same paragraph
             m_pImpl->GetTopContext()->Insert( PROP_INLINE_HEADING, uno::Any( 
true ), false, PARA_GRAB_BAG );
         }
         break;
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index 14e1149356bf..c2b4e3782d36 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -2776,7 +2776,6 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                         comphelper::SequenceAsHashMap aFrameGrabBag;
                         aFrameGrabBag[u"FrameInlineHeading"_ustr] <<= true;
 
-                        // TODO anchor as character
                         std::vector<beans::PropertyValue> aFrameProperties
                         {
                             comphelper::makePropertyValue(u"TextWrap"_ustr, 
css::text::WrapTextMode_RIGHT),
@@ -2786,15 +2785,20 @@ void DomainMapper_Impl::finishParagraph( const 
PropertyMapPtr& pPropertyMap, con
                             
comphelper::makePropertyValue(getPropertyName(PROP_OPAQUE), false),
                             
comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), 
text::SizeType::MIN),
                             
comphelper::makePropertyValue(getPropertyName(PROP_SIZE_TYPE), 
text::SizeType::MIN),
-                            
comphelper::makePropertyValue(u"FrameInteropGrabBag"_ustr,
-                                            
aFrameGrabBag.getAsConstPropertyValueList())
                         };
 
                         fillEmptyFrameProperties(aFrameProperties, false);
 
                         uno::Reference<text::XTextAppendAndConvert> 
xBodyText(xRangeStart->getText(), uno::UNO_QUERY);
 
-                        xBodyText->convertToTextFrame(xRangeStart, xRangeEnd, 
comphelper::containerToSequence(aFrameProperties));
+                        uno::Reference<text::XTextContent> xFrame = 
xBodyText->convertToTextFrame(xRangeStart, xRangeEnd, 
comphelper::containerToSequence(aFrameProperties));
+                        uno::Reference<beans::XPropertySet> 
xFrameProps(xFrame, uno::UNO_QUERY);
+                        // set frame style now to avoid losing text content 
(convertToTextFrame() doesn't work
+                        // with frame styles anchored "as character")
+                        xFrameProps->setPropertyValue(u"FrameStyleName"_ustr, 
uno::Any(u"Inline Heading"_ustr));
+                        // set anchoring because setting frame style doesn't 
modify the anchoring to
+                        // its default "anchored as character" setting
+                        
xFrameProps->setPropertyValue(getPropertyName(PROP_ANCHOR_TYPE), 
uno::Any(text::TextContentAnchorType_AS_CHARACTER));
 
                         m_StreamStateStack.top().bIsInlineParagraph = false;
                         m_StreamStateStack.top().bIsPreviousInlineParagraph = 
true;

Reply via email to