[Libreoffice-commits] core.git: sw/inc sw/source writerfilter/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 27 10:21:51 UTC 2021


 sw/inc/charfmt.hxx                              |    2 -
 sw/source/filter/ww8/attributeoutputbase.hxx    |    2 -
 sw/source/filter/ww8/docxattributeoutput.cxx    |   13 +++----
 sw/source/filter/ww8/docxattributeoutput.hxx    |    2 -
 sw/source/filter/ww8/rtfattributeoutput.cxx     |    4 +-
 sw/source/filter/ww8/rtfattributeoutput.hxx     |    2 -
 sw/source/filter/ww8/wrtw8sty.cxx               |   27 +++++++++++----
 sw/source/filter/ww8/wrtww8.hxx                 |    2 -
 sw/source/filter/ww8/ww8attributeoutput.hxx     |    2 -
 writerfilter/source/dmapper/StyleSheetTable.cxx |   43 ++++++++++++++++++++----
 writerfilter/source/dmapper/StyleSheetTable.hxx |    1 
 11 files changed, 73 insertions(+), 27 deletions(-)

New commits:
commit 9ef18582310d6f397a811dc5cc3c2cc1c64076ac
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Sep 27 11:10:13 2021 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Mon Sep 27 12:21:16 2021 +0200

    sw: paragraph styles: add DOCX filter for a linked character style
    
    And the same in the other direction: link a para style from a char
    style.
    
    This gets the info out of the grab-bag, so later we can store it also in
    ODF.
    
    No new tests, the existing testStyleInheritance in
    CppunitTest_sw_ooxmlexport3 covers this refactor.
    
    Change-Id: I5ada7ea471a253204984ae0466bd0f8ad70046e2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122681
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/charfmt.hxx b/sw/inc/charfmt.hxx
index 45b03fc701fa..e08d2f5f3a3f 100644
--- a/sw/inc/charfmt.hxx
+++ b/sw/inc/charfmt.hxx
@@ -23,7 +23,7 @@
 #include "hintids.hxx"
 
 /// Represents the style of a text portion.
-class SwCharFormat final : public SwFormat
+class SW_DLLPUBLIC SwCharFormat final : public SwFormat
 {
     friend class SwDoc;
     friend class SwTextFormatColl;
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 1be43833b109..1694b9335cb5 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -274,7 +274,7 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const OUString& rName, StyleType eType,
-            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nWwId, sal_uInt16 nId,
+            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nId,
             bool bAutoUpdate ) = 0;
 
     /// End of a style in the styles table.
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index a78211445782..1d230b108cb3 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6569,10 +6569,10 @@ static bool lcl_guessQFormat(const OUString& rName, sal_uInt16 nWwId)
 }
 
 void DocxAttributeOutput::StartStyle( const OUString& rName, StyleType eType,
-        sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nWwId, sal_uInt16 nId, bool bAutoUpdate )
+        sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nId, bool bAutoUpdate )
 {
     bool bQFormat = false, bUnhideWhenUsed = false, bSemiHidden = false, bLocked = false, bDefault = false, bCustomStyle = false;
-    OUString aLink, aRsid, aUiPriority;
+    OUString aRsid, aUiPriority;
     rtl::Reference<FastAttributeList> pStyleAttributeList = FastSerializerHelper::createAttrList();
     uno::Any aAny;
     if (eType == STYLE_TYPE_PARA || eType == STYLE_TYPE_CHAR)
@@ -6593,8 +6593,6 @@ void DocxAttributeOutput::StartStyle( const OUString& rName, StyleType eType,
             aUiPriority = rProp.Value.get<OUString>();
         else if (rProp.Name == "qFormat")
             bQFormat = true;
-        else if (rProp.Name == "link")
-            aLink = rProp.Value.get<OUString>();
         else if (rProp.Name == "rsid")
             aRsid = rProp.Value.get<OUString>();
         else if (rProp.Name == "unhideWhenUsed")
@@ -6646,8 +6644,11 @@ void DocxAttributeOutput::StartStyle( const OUString& rName, StyleType eType,
                 FSNS( XML_w, XML_val ), m_rExport.m_pStyles->GetStyleId(nNext) );
     }
 
-    if (!aLink.isEmpty())
-        m_pSerializer->singleElementNS(XML_w, XML_link, FSNS(XML_w, XML_val), aLink);
+    if (nLink != 0x0FFF && (eType == STYLE_TYPE_PARA || eType == STYLE_TYPE_CHAR))
+    {
+        m_pSerializer->singleElementNS(XML_w, XML_link, FSNS(XML_w, XML_val),
+                                       m_rExport.m_pStyles->GetStyleId(nLink));
+    }
 
     if ( bAutoUpdate )
         m_pSerializer->singleElementNS(XML_w, XML_autoRedefine);
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index e8b47febbefa..c315422536ce 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -252,7 +252,7 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const OUString& rName, StyleType eType,
-            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nWwId, sal_uInt16 nId,
+            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nId,
             bool bAutoUpdate ) override;
 
     /// End of a style in the styles table.
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index c52781e84814..907c035b5ffc 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1148,8 +1148,8 @@ void RtfAttributeOutput::EndStyles(sal_uInt16 /*nNumberOfStyles*/)
 void RtfAttributeOutput::DefaultStyle() { /* noop, the default style is always 0 in RTF */}
 
 void RtfAttributeOutput::StartStyle(const OUString& rName, StyleType eType, sal_uInt16 nBase,
-                                    sal_uInt16 nNext, sal_uInt16 /*nWwId*/, sal_uInt16 nId,
-                                    bool bAutoUpdate)
+                                    sal_uInt16 nNext, sal_uInt16 /*nLink*/, sal_uInt16 /*nWwId*/,
+                                    sal_uInt16 nId, bool bAutoUpdate)
 {
     SAL_INFO("sw.rtf", __func__ << ", rName = '" << rName << "'");
 
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 3a4bb5a18d9c..c07f3e525501 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -147,7 +147,7 @@ public:
 
     /// Start of a style in the styles table.
     void StartStyle(const OUString& rName, StyleType eType, sal_uInt16 nBase, sal_uInt16 nNext,
-                    sal_uInt16 nWwId, sal_uInt16 nId, bool bAutoUpdate) override;
+                    sal_uInt16 nLink, sal_uInt16 nWwId, sal_uInt16 nId, bool bAutoUpdate) override;
 
     /// End of a style in the styles table.
     void EndStyle() override;
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index 7ebb20c0f3ca..f181e5b83571 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -403,7 +403,7 @@ void WW8AttributeOutput::EndStyle()
 }
 
 void WW8AttributeOutput::StartStyle( const OUString& rName, StyleType eType, sal_uInt16 nWwBase,
-    sal_uInt16 nWwNext, sal_uInt16 nWwId, sal_uInt16 /*nId*/, bool bAutoUpdate )
+    sal_uInt16 nWwNext, sal_uInt16 /*nWwLink*/, sal_uInt16 nWwId, sal_uInt16 /*nId*/, bool bAutoUpdate )
 {
     sal_uInt8 aWW8_STD[ sizeof( WW8_STD ) ] = {};
     sal_uInt8* pData = aWW8_STD;
@@ -549,7 +549,7 @@ void WW8AttributeOutput::EndStyleProperties( bool /*bParProp*/ )
     ShortToSVBT16( nLen, pUpxLen );                 // add default length
 }
 
-void MSWordStyles::GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext )
+void MSWordStyles::GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext, sal_uInt16& nLink )
 {
     bFormatColl = pFormat->Which() == RES_TXTFMTCOLL || pFormat->Which() == RES_CONDTXTFMTCOLL;
 
@@ -561,12 +561,26 @@ void MSWordStyles::GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt1
         nBase = GetSlot( pFormat->DerivedFrom() );
 
     SwFormat* pNext;
+    const SwFormat* pLink = nullptr;
     if ( bFormatColl )
-        pNext = &static_cast<SwTextFormatColl*>(pFormat)->GetNextTextFormatColl();
+    {
+        auto pFormatColl = static_cast<SwTextFormatColl*>(pFormat);
+        pNext = &pFormatColl->GetNextTextFormatColl();
+        pLink = pFormatColl->GetLinkedCharFormat();
+    }
     else
+    {
         pNext = pFormat; // CharFormat: next CharFormat == self
+        auto pCharFormat = static_cast<SwCharFormat*>(pFormat);
+        pLink = pCharFormat->GetLinkedParaFormat();
+    }
 
     nNext = GetSlot( pNext );
+
+    if (pLink)
+    {
+        nLink = GetSlot(pLink);
+    }
 }
 
 void WW8AttributeOutput::DefaultStyle()
@@ -577,7 +591,7 @@ void WW8AttributeOutput::DefaultStyle()
 void MSWordStyles::OutputStyle(const SwNumRule* pNumRule, sal_uInt16 nPos)
 {
     m_rExport.AttrOutput().StartStyle( pNumRule->GetName(), STYLE_TYPE_LIST,
-            /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWWId =*/ 0, nPos,
+            /*nBase =*/ 0, /*nWwNext =*/ 0, /*nWwLink =*/ 0, /*nWWId =*/ 0, nPos,
             /*bAutoUpdateFormat =*/ false );
 
     m_rExport.AttrOutput().EndStyle();
@@ -592,8 +606,9 @@ void MSWordStyles::OutputStyle( SwFormat* pFormat, sal_uInt16 nPos )
     {
         bool bFormatColl;
         sal_uInt16 nBase, nWwNext;
+        sal_uInt16 nWwLink = 0x0FFF;
 
-        GetStyleData( pFormat, bFormatColl, nBase, nWwNext );
+        GetStyleData(pFormat, bFormatColl, nBase, nWwNext, nWwLink);
 
         OUString aName = pFormat->GetName();
         // We want to map LO's default style to Word's "Normal" style.
@@ -641,7 +656,7 @@ void MSWordStyles::OutputStyle( SwFormat* pFormat, sal_uInt16 nPos )
         }
 
         m_rExport.AttrOutput().StartStyle( aName, (bFormatColl ? STYLE_TYPE_PARA : STYLE_TYPE_CHAR),
-                nBase, nWwNext, GetWWId( *pFormat ), nPos,
+                nBase, nWwNext, nWwLink, GetWWId( *pFormat ), nPos,
                 pFormat->IsAutoUpdateFormat() );
 
         if ( bFormatColl )
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 2cf9a82df7a0..d65a16126f44 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -1590,7 +1590,7 @@ class MSWordStyles
     sal_uInt16 BuildGetSlot( const SwNumRule& /*rNumRule*/ ) { return m_nUsedSlots++;}
 
     /// Return information about one style.
-    void GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext );
+    void GetStyleData( SwFormat* pFormat, bool& bFormatColl, sal_uInt16& nBase, sal_uInt16& nNext, sal_uInt16& nLink );
 
     /// Outputs attributes of one style.
     void WriteProperties( const SwFormat* pFormat, bool bPap, sal_uInt16 nPos, bool bInsDefCharSiz );
diff --git a/sw/source/filter/ww8/ww8attributeoutput.hxx b/sw/source/filter/ww8/ww8attributeoutput.hxx
index aee7ce33f2f0..9bd1b425d39e 100644
--- a/sw/source/filter/ww8/ww8attributeoutput.hxx
+++ b/sw/source/filter/ww8/ww8attributeoutput.hxx
@@ -126,7 +126,7 @@ public:
 
     /// Start of a style in the styles table.
     virtual void StartStyle( const OUString& rName, StyleType eType,
-            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nWwIdi, sal_uInt16 nId,
+            sal_uInt16 nBase, sal_uInt16 nNext, sal_uInt16 nLink, sal_uInt16 nWwIdi, sal_uInt16 nId,
             bool bAutoUpdate ) override;
 
     /// End of a style in the styles table.
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx
index f1d1df4496b5..1464f3ae4082 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -75,6 +75,7 @@ TableStyleSheetEntry::TableStyleSheetEntry( StyleSheetEntry const & rEntry )
     nStyleTypeCode = STYLE_TYPE_TABLE;
     sBaseStyleIdentifier = rEntry.sBaseStyleIdentifier;
     sNextStyleIdentifier = rEntry.sNextStyleIdentifier;
+    sLinkStyleIdentifier = rEntry.sLinkStyleIdentifier;
     sStyleName = rEntry.sStyleName;
     sStyleIdentifierD = rEntry.sStyleIdentifierD;
 }
@@ -556,6 +557,9 @@ void StyleSheetTable::lcl_sprm(Sprm & rSprm)
                 pTableEntry->AppendInteropGrabBag(aValue);
             }
             break;
+        case NS_ooxml::LN_CT_Style_link:
+            m_pImpl->m_pCurrentEntry->sLinkStyleIdentifier = sStringValue;
+            break;
         case NS_ooxml::LN_CT_Style_next:
             m_pImpl->m_pCurrentEntry->sNextStyleIdentifier = sStringValue;
             break;
@@ -591,7 +595,6 @@ void StyleSheetTable::lcl_sprm(Sprm & rSprm)
         case NS_ooxml::LN_CT_Style_semiHidden:
         case NS_ooxml::LN_CT_Style_unhideWhenUsed:
         case NS_ooxml::LN_CT_Style_uiPriority:
-        case NS_ooxml::LN_CT_Style_link:
         case NS_ooxml::LN_CT_Style_locked:
             if (m_pImpl->m_pCurrentEntry->nStyleTypeCode != STYLE_TYPE_UNKNOWN)
             {
@@ -626,12 +629,6 @@ void StyleSheetTable::lcl_sprm(Sprm & rSprm)
                     aValue.Value <<= OUString::number(nIntValue);
                 }
                 break;
-                case NS_ooxml::LN_CT_Style_link:
-                {
-                    aValue.Name = "link";
-                    aValue.Value <<= sStringValue;
-                }
-                break;
                 case NS_ooxml::LN_CT_Style_locked:
                     aValue.Name = "locked";
                 break;
@@ -1006,6 +1003,7 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable )
         {
             std::vector< ::std::pair<OUString, uno::Reference<style::XStyle>> > aMissingParent;
             std::vector< ::std::pair<OUString, uno::Reference<style::XStyle>> > aMissingFollow;
+            std::vector<std::pair<OUString, uno::Reference<style::XStyle>>> aMissingLink;
             std::vector<beans::PropertyValue> aTableStylesVec;
             for( auto& pEntry : m_pImpl->m_aStyleSheetEntries )
             {
@@ -1015,6 +1013,7 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable )
                 if( pEntry->nStyleTypeCode == STYLE_TYPE_CHAR || pEntry->nStyleTypeCode == STYLE_TYPE_PARA || pEntry->nStyleTypeCode == STYLE_TYPE_LIST )
                 {
                     bool bParaStyle = pEntry->nStyleTypeCode == STYLE_TYPE_PARA;
+                    bool bCharStyle = pEntry->nStyleTypeCode == STYLE_TYPE_CHAR;
                     bool bListStyle = pEntry->nStyleTypeCode == STYLE_TYPE_LIST;
                     bool bInsert = false;
                     uno::Reference< container::XNameContainer > xStyles = bParaStyle ? xParaStyles : (bListStyle ? xNumberingStyles : xCharStyles);
@@ -1137,6 +1136,19 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable )
 
                     auto aPropValues = comphelper::sequenceToContainer< std::vector<beans::PropertyValue> >(pEntry->pProperties->GetPropertyValues());
 
+                    if (bParaStyle || bCharStyle)
+                    {
+                        // delay adding LinkStyle property: all styles need to be created first
+                        if (!pEntry->sLinkStyleIdentifier.isEmpty())
+                        {
+                            StyleSheetEntryPtr pLinkStyle
+                                = FindStyleSheetByISTD(pEntry->sLinkStyleIdentifier);
+                            if (pLinkStyle && !pLinkStyle->sStyleName.isEmpty())
+                                aMissingLink.emplace_back(ConvertStyleName(pLinkStyle->sStyleName),
+                                                          xStyle);
+                        }
+                    }
+
                     if( bParaStyle )
                     {
                         // delay adding FollowStyle property: all styles need to be created first
@@ -1320,6 +1332,23 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable )
                 catch( uno::Exception & ) {}
             }
 
+            // Update the styles that were created before their linked styles.
+            for (auto const& rLinked : aMissingLink)
+            {
+                try
+                {
+                    uno::Reference<beans::XPropertySet> xPropertySet(rLinked.second,
+                                                                     uno::UNO_QUERY);
+                    xPropertySet->setPropertyValue("LinkStyle", uno::makeAny(rLinked.first));
+                }
+                catch (uno::Exception&)
+                {
+                    TOOLS_WARN_EXCEPTION(
+                        "writerfilter",
+                        "StyleSheetTable::ApplyStyleSheets: failed to set LinkStyle");
+                }
+            }
+
             if (!aTableStylesVec.empty())
             {
                 // If we had any table styles, add a new document-level InteropGrabBag entry for them.
diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx b/writerfilter/source/dmapper/StyleSheetTable.hxx
index b0dd24fa6efa..5dcf84b789bb 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.hxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.hxx
@@ -58,6 +58,7 @@ public:
     StyleType       nStyleTypeCode; //sgc
     OUString sBaseStyleIdentifier;
     OUString sNextStyleIdentifier;
+    OUString sLinkStyleIdentifier;
     OUString sStyleName;
     const tools::SvRef<StyleSheetPropertyMap> pProperties;
     OUString sConvertedStyleName;


More information about the Libreoffice-commits mailing list