include/xmloff/xmlstyle.hxx                                 |    2 +
 include/xmloff/xmltoken.hxx                                 |    2 +
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |    9 ++++
 sw/qa/extras/odfexport/data/style-link.fodt                 |   15 +++++++
 sw/qa/extras/odfexport/odfexport2.cxx                       |   21 ++++++++++
 xmloff/source/core/xmltoken.cxx                             |    2 +
 xmloff/source/style/prstylei.cxx                            |   24 ++++++++++++
 xmloff/source/style/styleexp.cxx                            |   13 ++++++
 xmloff/source/style/xmlstyle.cxx                            |    3 +
 xmloff/source/token/tokens.txt                              |    1 
 10 files changed, 92 insertions(+)

New commits:
commit 05f863844d9a5613250e8d787e32752b270ec4d3
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Sep 28 09:37:10 2021 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Sep 28 10:27:20 2021 +0200

    sw: paragraph styles: add ODT filter for a linked character style
    
    And the same in the other direction: link a para style from a char
    style.
    
    With this, the ODT filter is on par with the DOCX one for this feature.
    
    Change-Id: Idd994b933672ab47a5f87a75c92abc137d3c73b2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122753
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/include/xmloff/xmlstyle.hxx b/include/xmloff/xmlstyle.hxx
index 184fd19eb379..04a74b841a15 100644
--- a/include/xmloff/xmlstyle.hxx
+++ b/include/xmloff/xmlstyle.hxx
@@ -44,6 +44,7 @@ class XMLOFF_DLLPUBLIC SvXMLStyleContext : public 
SvXMLImportContext
     OUString     maAutoName;
     OUString     maParentName;// Will be moved to XMLPropStyle soon!!!!
     OUString     maFollow;    // Will be moved to XMLPropStyle soon!!!!
+    OUString     maLinked;
     bool         mbHidden;
 
     XmlStyleFamily mnFamily;
@@ -79,6 +80,7 @@ public:
     const OUString&  GetAutoName() const { return maAutoName; }
     const OUString&  GetParentName() const { return maParentName; }
     const OUString&  GetFollow() const { return maFollow; }
+    const OUString&  GetLinked() const { return maLinked; }
 
     XmlStyleFamily GetFamily() const { return mnFamily; }
 
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index e4b2314527f0..c8dedd84b4b2 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -3437,6 +3437,8 @@ namespace xmloff::token {
         XML_RTL,
         XML_SYMMETRIC,
 
+        XML_LINKED_STYLE_NAME,
+
         XML_TOKEN_END
     };
 
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index a0f8711d092b..0c467fdc3780 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2731,4 +2731,13 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+  <!-- TODO no proposal -->
+  <rng:define name="style-style-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:linked-style-name">
+        <rng:ref name="styleNameRef"/>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
 </rng:grammar>
diff --git a/sw/qa/extras/odfexport/data/style-link.fodt 
b/sw/qa/extras/odfexport/data/style-link.fodt
new file mode 100644
index 000000000000..76c36c698845
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/style-link.fodt
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
 office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+  <office:styles>
+    <style:style style:name="List_20_Paragraph" style:display-name="List 
Paragraph" style:family="paragraph" 
loext:linked-style-name="List_20_Paragraph_20_Char"/>
+    <style:style style:name="List_20_Paragraph_20_Char" 
style:display-name="List Paragraph Char" style:family="text" 
loext:linked-style-name="List_20_Paragraph"/>
+  </office:styles>
+  <office:master-styles>
+    <style:master-page style:name="Standard"/>
+  </office:master-styles>
+  <office:body>
+    <office:text>
+      <text:p/>
+    </office:text>
+  </office:body>
+</office:document>
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx 
b/sw/qa/extras/odfexport/odfexport2.cxx
index bb05521f08fc..c73dc611db04 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -184,6 +184,27 @@ DECLARE_ODFEXPORT_TEST(testListFormatOdt, "listformat.odt")
     }
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testStyleLink)
+{
+    // Given a document with a para and a char style that links each other, 
when loading that
+    // document:
+    load(mpTestDocumentPath, "style-link.fodt");
+
+    // Then make sure the char style links the para one:
+    uno::Any aCharStyle = getStyles("CharacterStyles")->getByName("List 
Paragraph Char");
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: List Paragraph
+    // - Actual  :
+    // i.e. the linked style was lost on import.
+    CPPUNIT_ASSERT_EQUAL(OUString("List Paragraph"), 
getProperty<OUString>(aCharStyle, "LinkStyle"));
+    uno::Any aParaStyle = getStyles("ParagraphStyles")->getByName("List 
Paragraph");
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: List Paragraph Char
+    // - Actual  :
+    // i.e. the linked style was lost on import.
+    CPPUNIT_ASSERT_EQUAL(OUString("List Paragraph Char"), 
getProperty<OUString>(aParaStyle, "LinkStyle"));
+}
+
 // This test started in LO 7.2. Use the odfexport.cxx if you intend to 
backport to 7.1.
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 1e682a39fcb1..52ecd9038cbb 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -3440,6 +3440,8 @@ namespace xmloff::token {
         TOKEN("rtl",                 XML_RTL ),
         TOKEN("symmetric",           XML_SYMMETRIC ),
 
+        TOKEN("linked-style-name",   XML_LINKED_STYLE_NAME ),
+
 
 #if OSL_DEBUG_LEVEL > 0
         { 0, nullptr, std::nullopt,               XML_TOKEN_END }
diff --git a/xmloff/source/style/prstylei.cxx b/xmloff/source/style/prstylei.cxx
index e9ca87595f2b..5cd856b209e8 100644
--- a/xmloff/source/style/prstylei.cxx
+++ b/xmloff/source/style/prstylei.cxx
@@ -509,6 +509,30 @@ void XMLPropStyleContext::Finish( bool bOverwrite )
         }
     }
 
+    // Connect linked style.
+    OUString aLinked(GetLinked());
+    if (!aLinked.isEmpty())
+    {
+        if (GetFamily() == XmlStyleFamily::TEXT_PARAGRAPH)
+        {
+            aLinked = 
GetImport().GetStyleDisplayName(XmlStyleFamily::TEXT_TEXT, aLinked);
+        }
+        else if (GetFamily() == XmlStyleFamily::TEXT_TEXT)
+        {
+            aLinked = 
GetImport().GetStyleDisplayName(XmlStyleFamily::TEXT_PARAGRAPH, aLinked);
+        }
+    }
+    if (!aLinked.isEmpty() && xPropSetInfo->hasPropertyByName("LinkStyle"))
+    {
+        uno::Any aAny = xPropSet->getPropertyValue("LinkStyle");
+        OUString aCurrentLinked;
+        aAny >>= aCurrentLinked;
+        if (aCurrentLinked != aLinked)
+        {
+            xPropSet->setPropertyValue("LinkStyle", uno::Any(aLinked));
+        }
+    }
+
     if ( xPropSetInfo->hasPropertyByName( "Hidden" ) )
     {
         xPropSet->setPropertyValue( "Hidden", uno::makeAny( IsHidden( ) ) );
diff --git a/xmloff/source/style/styleexp.cxx b/xmloff/source/style/styleexp.cxx
index 2c628ffbda4d..1a3a81f10c95 100644
--- a/xmloff/source/style/styleexp.cxx
+++ b/xmloff/source/style/styleexp.cxx
@@ -237,6 +237,19 @@ bool XMLStyleExport::exportStyle(
         }
     }
 
+    // style:linked-style-name="..." (SW paragraph and character styles only)
+    if (xPropSetInfo->hasPropertyByName("LinkStyle"))
+    {
+        aAny = xPropSet->getPropertyValue("LinkStyle");
+        OUString sLinkName;
+        aAny >>= sLinkName;
+        if (!sLinkName.isEmpty())
+        {
+            GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, 
XML_LINKED_STYLE_NAME,
+                                     GetExport().EncodeStyleName(sLinkName));
+        }
+    }
+
     // style:auto-update="..." (SW only)
     if( xPropSetInfo->hasPropertyByName( gsIsAutoUpdate ) )
     {
diff --git a/xmloff/source/style/xmlstyle.cxx b/xmloff/source/style/xmlstyle.cxx
index 38ec932fe132..00afedf82a39 100644
--- a/xmloff/source/style/xmlstyle.cxx
+++ b/xmloff/source/style/xmlstyle.cxx
@@ -88,6 +88,9 @@ void SvXMLStyleContext::SetAttribute( sal_Int32 nElement,
         case XML_ELEMENT(STYLE, XML_NEXT_STYLE_NAME):
             maFollow = rValue;
             break;
+        case XML_ELEMENT(LO_EXT, XML_LINKED_STYLE_NAME):
+            maLinked = rValue;
+            break;
         case XML_ELEMENT(STYLE, XML_HIDDEN):
             mbHidden = rValue.toBoolean();
             break;
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index f52e9c492db9..395dffe62cf1 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -3185,4 +3185,5 @@ movablelimits
 rspace
 rtl
 symmetric
+linked-style-name
 TOKEN_END_DUMMY

Reply via email to