sw/inc/autostyle_helper.hxx                                           |   31 
+++
 sw/qa/extras/ooxmlimport/data/tdf141969-font_in_table_with_style.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport2.cxx                             |   17 +
 sw/source/core/unocore/unoobj.cxx                                     |   52 
+++++
 sw/source/core/unocore/unostyle.cxx                                   |   67 
++++--
 writerfilter/source/dmapper/DomainMapperTableHandler.cxx              |   99 
++++++----
 6 files changed, 213 insertions(+), 53 deletions(-)

New commits:
commit cece082f1b94e448ea807d22a1d177c33635406c
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Jul 4 08:14:02 2023 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Wed Jul 5 07:17:56 2023 +0200

    tdf#141969: use paragraph autostyle to mimic Word's table style
    
    Word's table styles may define paragraph and character properties. They are
    handled in DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle.
    
    When setting such a character property using setPropertyValue, it may apply
    to the text runs inside the paragraph, overriding values from character
    style and direct formatting, which must be kept.
    
    To fix that, this change creates a *paragraph* autostyle first, containing
    the properties; and then applies only this autostyle to the paragraph; the
    autostyle can't apply to runs, so the properties apply at paragraph level.
    
    Sadly, it is impossible to create a useful autostyle in writerfilter using
    UNO, because of the same problem that caused tdf#155945. UNO properties
    may define only parts of complex SfxPoolItem; setting them without having
    already applied values of such SfxPoolItem's would create wrong values for
    properties that weren't set by the UNO properties, but happen to share the
    same SfxPoolItem. To workaround that in writerfilter, a map of UNO names
    to sets of UNO names defining the complex property would be required, and
    then maintained.
    
    Instead, introduce a hidded 'ParaAutoStyleDef' property of SwXTextCursor,
    taking the same PropertyValue sequence as in XAutoStyleFamily::insertStyle.
    Implement it similarly to SwUnoCursorHelper::SetPropertyValues: first,
    build a WhichRangesContainer for specific WIDs needed for the properties;
    then obtain the actual values for these WIDs from the paragraph; and then
    set properties from the PropertyValue sequence.
    
    To create the autostyle properly, the code from 
SwXAutoStyleFamily::insertStyle
    is reused.
    
    There are more "proper" ways to fix this in part or as a whole, e.g.:
    
    * Split all complex SfxPoolItem's to simple ones, as done for one of them
      in commit db115bec9254417ef7a3faf687478fe5424ab378 (tdf#78510 sw,cui:
      split SvxLRSpaceItem for SwTextNode, SwTextFormatColl, 2023-02-24);
    
    * Rewrite writerfilter in sw;
    
    * Implement the missing proper table styles with paragraph and character
      properties, having the same precedence.
    
    But I don't feel crazy enough for any of these :D
    
    Change-Id: I07142cb23e8ec51f0e8ac8609f367ba247d94438
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153947
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit b036e563e699595fa7625888f11ab0c76f1abd66)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153989

diff --git a/sw/inc/autostyle_helper.hxx b/sw/inc/autostyle_helper.hxx
new file mode 100644
index 000000000000..9336085db02e
--- /dev/null
+++ b/sw/inc/autostyle_helper.hxx
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <svl/itemset.hxx>
+
+#include "istyleaccess.hxx"
+#include "swatrset.hxx"
+
+class SwDoc;
+
+std::shared_ptr<SfxItemSet>
+PropValuesToAutoStyleItemSet(SwDoc& rDoc, IStyleAccess::SwAutoStyleFamily 
eFamily,
+                             const 
css::uno::Sequence<css::beans::PropertyValue>& Values,
+                             SfxItemSet& rSet);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git 
a/sw/qa/extras/ooxmlimport/data/tdf141969-font_in_table_with_style.docx 
b/sw/qa/extras/ooxmlimport/data/tdf141969-font_in_table_with_style.docx
new file mode 100644
index 000000000000..6cbb8fb72e9d
Binary files /dev/null and 
b/sw/qa/extras/ooxmlimport/data/tdf141969-font_in_table_with_style.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx 
b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
index 20b190d59af6..a0a4d8051686 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport2.cxx
@@ -1177,6 +1177,23 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf156078)
     CPPUNIT_ASSERT(numberPixelsFound);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf141969)
+{
+    // Given a file with a table with a style setting font height, and a text 
re-defining the height
+    createSwDoc("tdf141969-font_in_table_with_style.docx");
+
+    auto xTable = getParagraphOrTable(2);
+    uno::Reference<text::XText> xCell(getCell(xTable, "A1"), 
uno::UNO_QUERY_THROW);
+    auto xParaOfCell = getParagraphOfText(1, xCell);
+    auto xRun = getRun(xParaOfCell, 1);
+
+    CPPUNIT_ASSERT_EQUAL(OUString("<<link:website>>"), xRun->getString());
+    // Without a fix, this would fail with
+    // - Expected: 8
+    // - Actual  : 11
+    CPPUNIT_ASSERT_EQUAL(8.0f, getProperty<float>(xRun, "CharHeight"));
+}
+
 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in 
ooxmlEXPORT
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/unocore/unoobj.cxx 
b/sw/source/core/unocore/unoobj.cxx
index 221929e4c04b..1d511890c84b 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -25,6 +25,8 @@
 #include <o3tl/safeint.hxx>
 #include <osl/endian.h>
 #include <unotools/collatorwrapper.hxx>
+
+#include <autostyle_helper.hxx>
 #include <swtypes.hxx>
 #include <hintids.hxx>
 #include <cmdid.h>
@@ -2271,6 +2273,56 @@ SwXTextCursor::setPropertyValue(
             m_nAttrMode = SetAttrMode::DEFAULT;
         }
     }
+    else if (rPropertyName == "ParaAutoStyleDef")
+    {
+        // Create an autostyle from passed definition (sequence of 
PropertyValue, same
+        // as in XAutoStyleFamily::insertStyle), using the currently applied 
properties
+        // from the paragraph to not lose their values when creating complex 
properties
+        // like SvxULSpaceItem, when only part of the properties stored there 
is passed;
+        // and apply it to the paragraph.
+        uno::Sequence<beans::PropertyValue> def;
+        if (!(rValue >>= def))
+            throw lang::IllegalArgumentException();
+
+        // See SwUnoCursorHelper::SetPropertyValues
+
+        auto pPropSet = 
aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE);
+
+        // Build set of attributes we want to fetch
+        WhichRangesContainer aRanges;
+        for (auto& rPropVal : def)
+        {
+            SfxItemPropertyMapEntry const* pEntry =
+                pPropSet->getPropertyMap().getByName(rPropVal.Name);
+            if (!pEntry)
+                continue; // PropValuesToAutoStyleItemSet ignores invalid names
+
+            aRanges = aRanges.MergeRange(pEntry->nWID, pEntry->nWID);
+        }
+
+        if (!aRanges.empty())
+        {
+            SfxItemSet aAutoStyleItemSet(rUnoCursor.GetDoc().GetAttrPool(), 
std::move(aRanges));
+            // we need to get up-to-date item set: this makes sure that the 
complex properties,
+            // that are only partially defined by passed definition, do not 
lose the rest of
+            // their already present data (which will become part of the 
autostyle, too).
+            SwUnoCursorHelper::GetCursorAttr(rUnoCursor, aAutoStyleItemSet);
+            // Set normal set ranges before putting into autostyle, to the 
same ranges
+            // that are used for paragraph autostyle in 
SwXAutoStyleFamily::insertStyle
+            aAutoStyleItemSet.SetRanges(aTextNodeSetRange);
+
+            // Fill the prepared item set, containing current paragraph 
property values,
+            // with the passed definition, and create the autostyle.
+            auto pStyle = PropValuesToAutoStyleItemSet(
+                rUnoCursor.GetDoc(), IStyleAccess::AUTO_STYLE_PARA, def, 
aAutoStyleItemSet);
+
+            SwFormatAutoFormat aFormat(RES_AUTO_STYLE);
+            aFormat.SetStyleHandle(pStyle);
+            SfxItemSet rSet(rUnoCursor.GetDoc().GetAttrPool(), RES_AUTO_STYLE, 
RES_AUTO_STYLE);
+            rSet.Put(aFormat);
+            SwUnoCursorHelper::SetCursorAttr(rUnoCursor, rSet, m_nAttrMode);
+        }
+    }
     else
     {
         SwUnoCursorHelper::SetPropertyValue(rUnoCursor,
diff --git a/sw/source/core/unocore/unostyle.cxx 
b/sw/source/core/unocore/unostyle.cxx
index bb78c16244bc..48baa586d4d4 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -50,6 +50,8 @@
 #include <editeng/fhgtitem.hxx>
 #include <editeng/paperinf.hxx>
 #include <editeng/wghtitem.hxx>
+
+#include <autostyle_helper.hxx>
 #include <pagedesc.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
@@ -3519,33 +3521,25 @@ void SwXAutoStyleFamily::Notify(const SfxHint& rHint)
         m_pDocShell = nullptr;
 }
 
-uno::Reference< style::XAutoStyle > SwXAutoStyleFamily::insertStyle(
-    const uno::Sequence< beans::PropertyValue >& Values )
+std::shared_ptr<SfxItemSet>
+PropValuesToAutoStyleItemSet(SwDoc& rDoc, IStyleAccess::SwAutoStyleFamily 
eFamily,
+                             const uno::Sequence<beans::PropertyValue>& 
Values, SfxItemSet& aSet)
 {
-    if (!m_pDocShell)
-    {
-        throw uno::RuntimeException();
-    }
-
-    WhichRangesContainer pRange;
     const SfxItemPropertySet* pPropSet = nullptr;
-    switch( m_eFamily )
+    switch( eFamily )
     {
         case IStyleAccess::AUTO_STYLE_CHAR:
         {
-            pRange = aCharAutoFormatSetRange;
             pPropSet = 
aSwMapProvider.GetPropertySet(PROPERTY_MAP_CHAR_AUTO_STYLE);
             break;
         }
         case IStyleAccess::AUTO_STYLE_RUBY:
         {
-            pRange = WhichRangesContainer(RES_TXTATR_CJK_RUBY, 
RES_TXTATR_CJK_RUBY);
             pPropSet = 
aSwMapProvider.GetPropertySet(PROPERTY_MAP_RUBY_AUTO_STYLE);
             break;
         }
         case IStyleAccess::AUTO_STYLE_PARA:
         {
-            pRange = aTextNodeSetRange; // checked, already added support for 
[XATTR_FILL_FIRST, XATTR_FILL_LAST]
             pPropSet = 
aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARA_AUTO_STYLE);
             break;
         }
@@ -3555,8 +3549,7 @@ uno::Reference< style::XAutoStyle > 
SwXAutoStyleFamily::insertStyle(
     if( !pPropSet)
         throw uno::RuntimeException();
 
-    SwAttrSet aSet( m_pDocShell->GetDoc()->GetAttrPool(), pRange );
-    const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA 
== m_eFamily);
+    const bool bTakeCareOfDrawingLayerFillStyle(IStyleAccess::AUTO_STYLE_PARA 
== eFamily);
 
     if(!bTakeCareOfDrawingLayerFillStyle)
     {
@@ -3581,7 +3574,7 @@ uno::Reference< style::XAutoStyle > 
SwXAutoStyleFamily::insertStyle(
         // set parent to ItemSet to ensure XFILL_NONE as XFillStyleItem
         // to make cases in RES_BACKGROUND work correct; target *is* a style
         // where this is the case
-        
aSet.SetParent(&m_pDocShell->GetDoc()->GetDfltTextFormatColl()->GetAttrSet());
+        aSet.SetParent(&rDoc.GetDfltTextFormatColl()->GetAttrSet());
 
         // here the used DrawingLayer FillStyles are imported when family is
         // equal to IStyleAccess::AUTO_STYLE_PARA, thus we will need to serve 
the
@@ -3622,7 +3615,7 @@ uno::Reference< style::XAutoStyle > 
SwXAutoStyleFamily::insertStyle(
 
                 if(bDoIt)
                 {
-                    const SfxItemPool& rPool = 
m_pDocShell->GetDoc()->GetAttrPool();
+                    const SfxItemPool& rPool = rDoc.GetAttrPool();
                     const MapUnit eMapUnit(rPool.GetMetric(pEntry->nWID));
 
                     if(eMapUnit != MapUnit::Map100thMM)
@@ -3673,7 +3666,7 @@ uno::Reference< style::XAutoStyle > 
SwXAutoStyleFamily::insertStyle(
                 }
                 case RES_BACKGROUND:
                 {
-                    const std::unique_ptr<SvxBrushItem> 
aOriginalBrushItem(getSvxBrushItemFromSourceSet(aSet, RES_BACKGROUND, true, 
m_pDocShell->GetDoc()->IsInXMLImport()));
+                    const std::unique_ptr<SvxBrushItem> 
aOriginalBrushItem(getSvxBrushItemFromSourceSet(aSet, RES_BACKGROUND, true, 
rDoc.IsInXMLImport()));
                     std::unique_ptr<SvxBrushItem> 
aChangedBrushItem(aOriginalBrushItem->Clone());
 
                     aChangedBrushItem->PutValue(aValue, nMemberId);
@@ -3736,10 +3729,44 @@ uno::Reference< style::XAutoStyle > 
SwXAutoStyleFamily::insertStyle(
     // currently in principle only needed when 
bTakeCareOfDrawingLayerFillStyle,
     // but does not hurt and is easily forgotten later eventually, so keep it
     // as common case
-    m_pDocShell->GetDoc()->CheckForUniqueItemForLineFillNameOrIndex(aSet);
+    rDoc.CheckForUniqueItemForLineFillNameOrIndex(aSet);
+
+    return rDoc.GetIStyleAccess().cacheAutomaticStyle(aSet, eFamily);
+}
+
+uno::Reference< style::XAutoStyle > SwXAutoStyleFamily::insertStyle(
+    const uno::Sequence< beans::PropertyValue >& Values )
+{
+    if (!m_pDocShell)
+    {
+        throw uno::RuntimeException();
+    }
+
+    WhichRangesContainer pRange;
+    switch (m_eFamily)
+    {
+    case IStyleAccess::AUTO_STYLE_CHAR:
+    {
+        pRange = aCharAutoFormatSetRange;
+        break;
+    }
+    case IStyleAccess::AUTO_STYLE_RUBY:
+    {
+        pRange = WhichRangesContainer(RES_TXTATR_CJK_RUBY, 
RES_TXTATR_CJK_RUBY);
+        break;
+    }
+    case IStyleAccess::AUTO_STYLE_PARA:
+    {
+        pRange = aTextNodeSetRange; // checked, already added support for 
[XATTR_FILL_FIRST, XATTR_FILL_LAST]
+        break;
+    }
+    default:
+        throw uno::RuntimeException();
+    }
+
+    SwAttrSet aEmptySet(m_pDocShell->GetDoc()->GetAttrPool(), pRange);
+    auto pSet = PropValuesToAutoStyleItemSet(*m_pDocShell->GetDoc(), 
m_eFamily, Values, aEmptySet);
 
-    // AutomaticStyle creation
-    std::shared_ptr<SfxItemSet> pSet = 
m_pDocShell->GetDoc()->GetIStyleAccess().cacheAutomaticStyle( aSet, m_eFamily );
     uno::Reference<style::XAutoStyle> xRet = new 
SwXAutoStyle(m_pDocShell->GetDoc(), pSet, m_eFamily);
 
     return xRet;
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx 
b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index 438036a65ec3..cd77182657c8 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -24,6 +24,9 @@
 #include "DomainMapperTableHandler.hxx"
 #include "DomainMapper_Impl.hxx"
 #include "StyleSheetTable.hxx"
+
+#include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
+#include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
 #include <com/sun/star/style/ParagraphAdjust.hpp>
 #include <com/sun/star/table/TableBorderDistances.hpp>
 #include <com/sun/star/table/TableBorder.hpp>
@@ -1065,10 +1068,28 @@ css::uno::Sequence<css::beans::PropertyValues> 
DomainMapperTableHandler::endTabl
     return aRowProperties;
 }
 
+static bool isAbsent(const std::vector<beans::PropertyValue>& propvals, const 
OUString& name)
+{
+    return std::find_if(propvals.begin(), propvals.end(),
+                        [&name](const beans::PropertyValue& propval)
+                        { return propval.Name == name; })
+           == propvals.end();
+}
+
 // table style has got bigger precedence than docDefault style,
 // but lower precedence than the paragraph styles and direct paragraph 
formatting
 void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParagraph 
rParaProp, std::vector< PropertyIds > aAllTableParaProperties, const 
css::beans::PropertyValues rCellProperties)
 {
+    // Setting paragraph or character properties using setPropertyValue may 
have unwanted
+    // side effects; e.g., setting a paragraph's font size can reset font size 
in a runs
+    // of the paragraph, which have own formatting, which should have highest 
precedence.
+    // Thus we have to collect property values, construct an autostyle, and 
assign it to
+    // the paragraph, to avoid such side effects.
+
+    // 1. Collect all the table-style-defined properties, that aren't 
overridden by the
+    //    paragraph style or direct formatting
+    std::vector<beans::PropertyValue> aProps;
+
     for( auto const& eId : aAllTableParaProperties )
     {
         // apply paragraph and character properties of the table style on 
table paragraphs
@@ -1136,47 +1157,24 @@ void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParag
                 // use table style when no paragraph style setting or a 
docDefault value is applied instead of it
                 if ( aParaStyle == uno::Any() || bDocDefault || 
bCompatOverride ) try
                 {
-                    // check property state of paragraph
                     uno::Reference<text::XParagraphCursor> xParagraph(
                         
rParaProp.m_rEndParagraph->getText()->createTextCursorByRange(rParaProp.m_rEndParagraph),
 uno::UNO_QUERY_THROW );
                     // select paragraph
                     xParagraph->gotoStartOfParagraph( true );
-                    uno::Reference< beans::XPropertyState > xParaProperties( 
xParagraph, uno::UNO_QUERY_THROW );
-                    if ( xParaProperties->getPropertyState(sPropertyName) == 
css::beans::PropertyState_DEFAULT_VALUE )
-                    {
-                        // don't overwrite empty paragraph with table style, 
if it has a direct paragraph formatting
-                        if ( bIsParaLevel && 
xParagraph->getString().getLength() == 0 )
-                            continue;
+                    // don't overwrite empty paragraph with table style, if it 
has a direct paragraph formatting
+                    if ( bIsParaLevel && xParagraph->getString().getLength() 
== 0 )
+                        continue;
 
-                        if ( eId != PROP_FILL_COLOR )
-                        {
-                            // apply style setting when the paragraph doesn't 
modify it
-                            rParaProp.m_rPropertySet->setPropertyValue( 
sPropertyName, pCellProp->Value );
-                        }
-                        else
-                        {
-                            // we need this for complete import of table-style 
based paragraph background color
-                            rParaProp.m_rPropertySet->setPropertyValue( 
"FillColor",  pCellProp->Value );
-                            rParaProp.m_rPropertySet->setPropertyValue( 
"FillStyle",  uno::Any(drawing::FillStyle_SOLID) );
-                        }
+                    if ( eId != PROP_FILL_COLOR )
+                    {
+                        // apply style setting when the paragraph doesn't 
modify it
+                        
aProps.push_back(comphelper::makePropertyValue(sPropertyName, 
pCellProp->Value));
                     }
                     else
                     {
-                        // apply style setting only on text portions without 
direct modification of it
-                        uno::Reference<container::XEnumerationAccess> 
xParaEnumAccess(xParagraph, uno::UNO_QUERY);
-                        uno::Reference<container::XEnumeration> xParaEnum = 
xParaEnumAccess->createEnumeration();
-                        uno::Reference<container::XEnumerationAccess> 
xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
-                        uno::Reference<container::XEnumeration> xRunEnum = 
xRunEnumAccess->createEnumeration();
-                        while ( xRunEnum->hasMoreElements() )
-                        {
-                            uno::Reference<text::XTextRange> 
xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
-                            uno::Reference< beans::XPropertyState > 
xRunProperties( xRun, uno::UNO_QUERY_THROW );
-                            if ( 
xRunProperties->getPropertyState(sPropertyName) == 
css::beans::PropertyState_DEFAULT_VALUE )
-                            {
-                                 uno::Reference< beans::XPropertySet > 
xRunPropertySet( xRun, uno::UNO_QUERY_THROW );
-                                 xRunPropertySet->setPropertyValue( 
sPropertyName, pCellProp->Value );
-                            }
-                        }
+                        // we need this for complete import of table-style 
based paragraph background color
+                        
aProps.push_back(comphelper::makePropertyValue("FillColor",  pCellProp->Value));
+                        
aProps.push_back(comphelper::makePropertyValue("FillStyle",  
uno::Any(drawing::FillStyle_SOLID)));
                     }
                 }
                 catch ( const uno::Exception & )
@@ -1186,6 +1184,41 @@ void 
DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableParag
             }
         }
     }
+
+    if (!aProps.empty())
+    {
+        // 2. Get all properties directly defined in the paragraph
+        uno::Reference<beans::XPropertySetInfo> xPropSetInfo(
+            rParaProp.m_rPropertySet->getPropertySetInfo(), 
uno::UNO_SET_THROW);
+        auto props = xPropSetInfo->getProperties();
+        uno::Sequence<OUString> propNames(props.getLength());
+        std::transform(props.begin(), props.end(), propNames.getArray(),
+                       [](const beans::Property& prop) { return prop.Name; });
+        uno::Reference<beans::XTolerantMultiPropertySet> 
xTolPara(rParaProp.m_rPropertySet,
+                                                                  
uno::UNO_QUERY_THROW);
+        // getDirectPropertyValuesTolerant requires a sorted sequence.
+        // Let's hope XPropertySetInfo::getProperties returns a sorted 
sequence.
+        for (auto& val : xTolPara->getDirectPropertyValuesTolerant(propNames))
+        {
+            // 3. Add them to aProps, unless such properties are already there
+            //    (which means, that 'val' comes from docDefault)
+            if (val.Result == beans::TolerantPropertySetResultType::SUCCESS
+                && val.State == beans::PropertyState_DIRECT_VALUE
+                && isAbsent(aProps, val.Name))
+            {
+                aProps.push_back(comphelper::makePropertyValue(val.Name, 
val.Value));
+            }
+        }
+
+        // 4. Create an autostyle, and assign it to the paragraph. The hidden 
ParaAutoStyleDef
+        //    property is handled in SwXTextCursor::setPropertyValue.
+        uno::Reference<beans::XPropertySet> xCursorProps(
+            rParaProp.m_rEndParagraph->getText()->createTextCursorByRange(
+                rParaProp.m_rEndParagraph),
+            uno::UNO_QUERY_THROW);
+        xCursorProps->setPropertyValue("ParaAutoStyleDef",
+                                       
uno::Any(comphelper::containerToSequence(aProps)));
+    }
 }
 
 // convert formula range identifier ABOVE, BELOW, LEFT and RIGHT

Reply via email to