include/xmloff/xmltoken.hxx                                 |    1 
 offapi/com/sun/star/text/ReferenceFieldSource.idl           |    5 
 sc/source/ui/view/output2.cxx                               |   14 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |   23 
 sw/inc/fldref.hrc                                           |    1 
 sw/inc/reffld.hxx                                           |   28 
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx                    |    2 
 sw/qa/extras/uiwriter/uiwriter7.cxx                         |   15 
 sw/source/core/access/accpara.cxx                           |    3 
 sw/source/core/crsr/crstrvl.cxx                             |   10 
 sw/source/core/fields/reffld.cxx                            |  497 +++++++++---
 sw/source/core/text/txtfld.cxx                              |   15 
 sw/source/core/unocore/unofield.cxx                         |    2 
 sw/source/filter/ww8/wrtww8.hxx                             |    3 
 sw/source/filter/ww8/ww8atr.cxx                             |   87 +-
 sw/source/filter/ww8/ww8par5.cxx                            |   15 
 sw/source/ui/fldui/fldref.cxx                               |   70 +
 sw/source/ui/fldui/fldref.hxx                               |    1 
 sw/source/uibase/docvw/edtwin2.cxx                          |    2 
 sw/source/uibase/fldui/fldmgr.cxx                           |   16 
 sw/source/uibase/utlui/content.cxx                          |    2 
 writerfilter/source/dmapper/DomainMapper_Impl.cxx           |   55 +
 writerfilter/source/dmapper/FieldTypes.hxx                  |    5 
 xmloff/inc/txtflde.hxx                                      |    1 
 xmloff/source/core/xmltoken.cxx                             |    1 
 xmloff/source/text/txtflde.cxx                              |   32 
 xmloff/source/text/txtfldi.cxx                              |    5 
 xmloff/source/token/tokens.txt                              |    1 
 28 files changed, 753 insertions(+), 159 deletions(-)

New commits:
commit f63e02b99691a0d8c8addba2518ecdf6b4319c52
Author:     Henry Castro <hcas...@collabora.com>
AuthorDate: Wed Oct 11 08:59:59 2023 -0400
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Fri Oct 13 09:48:29 2023 +0200

    sc: ui: fix cell bidi layout strings
    
    The default constructor OutputDevice set the
    layout text to "vcl::text::ComplexTextLayoutFlags::BiDiRtl"
    for all strings, however the each cell string can be
    mixed LTR and RTL.
    
    Set the defaults to auto detect the correct text layout mode.
    
    Signed-off-by: Henry Castro <hcas...@collabora.com>
    Change-Id: I0c451e8014fd13490db4213adca3d83ea4572819
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157831
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index d8dfb064e605..8543f2f517c7 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1481,14 +1481,22 @@ tools::Rectangle ScOutputData::LayoutStrings(bool 
bPixelToLogic, bool bPaint, co
 {
     bool bOrigIsInLayoutStrings = mpDoc->IsInLayoutStrings();
     mpDoc->SetLayoutStrings(true);
-    comphelper::ScopeGuard g([this, bOrigIsInLayoutStrings] {
-        mpDoc->SetLayoutStrings(bOrigIsInLayoutStrings);
-    });
 
     OSL_ENSURE( mpDev == mpRefDevice ||
                 mpDev->GetMapMode().GetMapUnit() == 
mpRefDevice->GetMapMode().GetMapUnit(),
                 "LayoutStrings: different MapUnits ?!?!" );
 
+    vcl::text::ComplexTextLayoutFlags eTextLayout = mpDev->GetLayoutMode();
+    comphelper::ScopeGuard g([this, bOrigIsInLayoutStrings, eTextLayout] {
+        mpDoc->SetLayoutStrings(bOrigIsInLayoutStrings);
+
+        if (mpDev->GetLayoutMode() != eTextLayout)
+            mpDev->SetLayoutMode(eTextLayout);
+    });
+
+    if (mpDev->GetLayoutMode() != vcl::text::ComplexTextLayoutFlags::Default)
+        mpDev->SetLayoutMode(vcl::text::ComplexTextLayoutFlags::Default);
+
     sc::IdleSwitch aIdleSwitch(*mpDoc, false);
 
     // Try to limit interpreting to only visible cells. Calling e.g. IsValue()
commit ffa1798661dab15435190972a98e6277ced05f4e
Author:     Skyler Grey <skyler.g...@collabora.com>
AuthorDate: Thu Sep 14 08:48:16 2023 +0000
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Oct 13 09:16:13 2023 +0200

    tdf#86790: Add support for a word-style styleref
    
    STYLEREF is a field type in Word which changes its content based on
    nearby paragraphs. For example, upon creating a styleref referencing
    "Heading 1" you will see the text of the nearest "Heading 1"-styled
    paragraph that is above the field.
    
    This patch implements STYLEREF in Writer as a cross-reference. By using
    "insert>cross-reference>styles" you'll be presented with a list of
    styles. Selecting one and clicking "insert" will create a field which
    has text from the "most relevant" instance of the style. To find the
    most relevant instance we first search up for paragraphs with the style,
    and if there are any we take the closest. If there weren't any, we
    search down for paragraphs with the style.
    
    This patch also updates our use of STYLEREF for chapters exported to
    docx by using it for all chapters not only those in headers and footers.
    This allows us to approximate more chapter field functionality even when
    moving between Writer and Word.
    
    Still TODO:
    - [  ] Update documentation
    - [  ] Implement reverse-searching (\l) and nondelimiter
           suppression (\t)
           - Probably these 2 will be in a followup patch
    
    Change-Id: I25dd7a6940abee5651a784b9059fe23b32547d6c
    Signed-off-by: Skyler Grey <skyler.g...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156912
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index da28c0f81c03..5bb8528c81e6 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -1898,6 +1898,7 @@ namespace xmloff::token {
         XML_STRUCTURE_PROTECTED,
         XML_STYLE,
         XML_STYLE_NAME,
+        XML_STYLE_REF,
         XML_STYLES,
         XML_STYLESHEET,
         XML_SUB_TABLE,
diff --git a/offapi/com/sun/star/text/ReferenceFieldSource.idl 
b/offapi/com/sun/star/text/ReferenceFieldSource.idl
index 1892fdc04cd8..91295fef2844 100644
--- a/offapi/com/sun/star/text/ReferenceFieldSource.idl
+++ b/offapi/com/sun/star/text/ReferenceFieldSource.idl
@@ -44,6 +44,11 @@ published constants ReferenceFieldSource
     /** The source is an endnote.
     */
     const short ENDNOTE = 4;
+
+    /** The source is a style.
+    @since LibreOffice 24.2
+    */
+    const short STYLE = 5;
 };
 
 
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index c940b6c231ad..5f5040173bb8 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2062,6 +2062,29 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:element>
   </rng:define>
 
+    <!-- TODO no proposal -->
+  <rng:define name="loext-style-reference">
+    <rng:element name="loext:style-ref">
+      <rng:interleave>
+        <rng:ref name="text-common-ref-content"/>
+        <rng:optional>
+          <rng:attribute name="text:reference-format">
+            <rng:choice>
+              <rng:value>text</rng:value>
+              <rng:value>direction</rng:value>
+              <rng:value>number</rng:value>
+              <rng:value>number-no-superior</rng:value>
+              <rng:value>number-all-superior</rng:value>
+            </rng:choice>
+          </rng:attribute>
+        </rng:optional>
+      </rng:interleave>
+    </rng:element>
+  </rng:define>
+  <rng:define name="paragraph-content" combine="choice">
+    <rng:ref name="loext-style-reference"/>
+  </rng:define>
+
   <rng:define name="loext-qrcode">
     <rng:element name="loext:qrcode">
       <rng:attribute name="office:string-value">
diff --git a/sw/inc/fldref.hrc b/sw/inc/fldref.hrc
index 20eae2d31e14..30f3f5ed1554 100644
--- a/sw/inc/fldref.hrc
+++ b/sw/inc/fldref.hrc
@@ -31,6 +31,7 @@ const TranslateId FLD_REF_PAGE_TYPES[] =
     NC_("fldrefpage|liststore1", "Endnotes"),
     NC_("fldrefpage|liststore1", "Headings"),
     NC_("fldrefpage|liststore1", "Numbered Paragraphs"),
+    NC_("fldrefpage|liststore1", "Styles"),
 };
 
 #endif
diff --git a/sw/inc/reffld.hxx b/sw/inc/reffld.hxx
index 931441d27725..28ced8dcc2cb 100644
--- a/sw/inc/reffld.hxx
+++ b/sw/inc/reffld.hxx
@@ -26,8 +26,10 @@
 class SfxPoolItem;
 class SwDoc;
 class SwTextNode;
+class SwContentFrame;
 class SwTextField;
 class SwRootFrame;
+class SwFrame;
 
 bool IsFrameBehind( const SwTextNode& rMyNd, sal_Int32 nMySttPos,
                     const SwTextNode& rBehindNd, sal_Int32 nSttPos );
@@ -39,7 +41,8 @@ enum REFERENCESUBTYPE
     REF_BOOKMARK,
     REF_OUTLINE,
     REF_FOOTNOTE,
-    REF_ENDNOTE
+    REF_ENDNOTE,
+    REF_STYLE
 };
 
 enum REFERENCEMARK
@@ -80,7 +83,8 @@ public:
     static SwTextNode* FindAnchor( SwDoc* pDoc, const OUString& rRefMark,
                                         sal_uInt16 nSubType, sal_uInt16 nSeqNo,
                                         sal_Int32* pStt, sal_Int32* pEnd = 
nullptr,
-                                        SwRootFrame const* pLayout = nullptr);
+                                        SwRootFrame const* pLayout = nullptr,
+                                        SwTextNode* pSelf = nullptr, SwFrame* 
pFrame = nullptr);
     void UpdateGetReferences();
 };
 
@@ -95,15 +99,22 @@ private:
     /// reference to either a SwTextFootnote::m_nSeqNo or a 
SwSetExpField::mnSeqNo
     sal_uInt16 m_nSeqNo;
 
+    SwTextNode* m_pTextNode; ///< a pointer to the text node which contains 
the field
+    SwFrame* m_pFrame; ///< a pointer to the frame which contains the field
+    /* m_pTextNode and m_pFrame are used for STYLEREF, for other subtypes 
these will often be nullptr */
+
     virtual OUString    ExpandImpl(SwRootFrame const* pLayout) const override;
     virtual std::unique_ptr<SwField> Copy() const override;
 
 public:
     SwGetRefField( SwGetRefFieldType*, OUString aSetRef, OUString 
aReferenceLanguage,
-                    sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_uLong nFormat 
);
+                    sal_uInt16 nSubType, sal_uInt16 nSeqNo, sal_uLong nFormat,
+                    SwTextNode* pTextNode, SwFrame* pFrame );
 
     virtual ~SwGetRefField() override;
 
+    void ChangeExpansion(SwFrame* pFrame, const SwTextField* pField);
+
     virtual OUString GetFieldName() const override;
 
     const OUString& GetSetRefName() const { return m_sSetRefName; }
@@ -111,11 +122,13 @@ public:
     // #i81002#
     /** The <SwTextField> instance, which represents the text attribute for the
        <SwGetRefField> instance, has to be passed to the method.
-       This <SwTextField> instance is needed for the reference format type 
REF_UPDOWN
-       and REF_NUMBER.
+       This <SwTextField> instance is needed for the reference format type 
REF_UPDOWN, REF_NUMBER
+       and REF_STYLE.
        Note: This instance may be NULL (field in Undo/Redo). This will cause
        no update for these reference format types. */
     void                UpdateField( const SwTextField* pFieldTextAttr );
+    void                UpdateField( const SwTextField* pFieldTextAttr, const 
SwRootFrame* const pLayout,
+                                     OUString& rText );
 
     void                SetExpand( const OUString& rStr );
 
@@ -126,9 +139,10 @@ public:
     // --> #i81002#
     bool IsRefToHeadingCrossRefBookmark() const;
     bool IsRefToNumItemCrossRefBookmark() const;
-    const SwTextNode* GetReferencedTextNode() const;
+    const SwTextNode* GetReferencedTextNode(SwTextNode* pTextNode) const;
     // #i85090#
     OUString GetExpandedTextOfReferencedTextNode(SwRootFrame const& rLayout) 
const;
+    OUString GetExpandedTextOfReferencedTextNode(SwRootFrame const& rLayout, 
SwTextNode* pTextNode) const;
 
     /// Get/set SequenceNo (of interest only for REF_SEQUENCEFLD).
     sal_uInt16              GetSeqNo() const        { return m_nSeqNo; }
@@ -138,6 +152,8 @@ public:
     virtual OUString    GetPar1() const override;
     virtual void        SetPar1(const OUString& rStr) override;
 
+    void SetText(OUString sText, SwRootFrame* pLayout);
+
     virtual OUString    GetPar2() const override;
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhichId ) 
const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 
nWhichId ) override;
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 5b5001878eb1..4fc4b7a218f8 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -602,7 +602,7 @@ DECLARE_OOXMLEXPORT_TEST(testMultiPageToc, 
"multi-page-toc.docx")
     CPPUNIT_ASSERT_EQUAL(OUString("Table of Contents1"), 
xTextSection->getName());
     // There should be a field in the header as well.
     uno::Reference<text::XText> xHeaderText = getProperty< 
uno::Reference<text::XText> >(getStyles("PageStyles")->getByName("Standard"), 
"HeaderText");
-    CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), 
getProperty<OUString>(getRun(getParagraphOfText(1, xHeaderText), 1), 
"TextPortionType"));
+    CPPUNIT_ASSERT_EQUAL(OUString("TextField"), 
getProperty<OUString>(getRun(getParagraphOfText(1, xHeaderText), 1), 
"TextPortionType"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTextboxTable, "textbox-table.docx")
diff --git a/sw/qa/extras/uiwriter/uiwriter7.cxx 
b/sw/qa/extras/uiwriter/uiwriter7.cxx
index 697a9defa63c..10cb2ace0179 100644
--- a/sw/qa/extras/uiwriter/uiwriter7.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter7.cxx
@@ -780,14 +780,16 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf77342)
     //moving cursor to the starting of document
     pWrtShell->StartOfSection();
     //inserting reference field 1
-    SwGetRefField aField1(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(0), 
REF_CONTENT);
+    SwGetRefField aField1(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(0), 
REF_CONTENT, nullptr,
+                          nullptr);
     pWrtShell->InsertField2(aField1);
     //inserting second footnote
     pWrtShell->InsertFootnote("");
     pWrtShell->StartOfSection();
     pCursor->Move(fnMoveForward);
     //inserting reference field 2
-    SwGetRefField aField2(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(1), 
REF_CONTENT);
+    SwGetRefField aField2(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(1), 
REF_CONTENT, nullptr,
+                          nullptr);
     pWrtShell->InsertField2(aField2);
     //inserting third footnote
     pWrtShell->InsertFootnote("");
@@ -795,7 +797,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf77342)
     pCursor->Move(fnMoveForward);
     pCursor->Move(fnMoveForward);
     //inserting reference field 3
-    SwGetRefField aField3(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(2), 
REF_CONTENT);
+    SwGetRefField aField3(pRefType, "", "", REF_FOOTNOTE, sal_uInt16(2), 
REF_CONTENT, nullptr,
+                          nullptr);
     pWrtShell->InsertField2(aField3);
     //updating the fields
     IDocumentFieldsAccess& rField(pDoc->getIDocumentFieldsAccess());
@@ -1035,7 +1038,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf63553)
     pWrtShell->StartOfSection();
     //inserting reference field 1
     SwGetRefField aGetField1(pRefType, "Illustration", "", REF_SEQUENCEFLD, 
sal_uInt16(0),
-                             REF_CONTENT);
+                             REF_CONTENT, nullptr, nullptr);
     pWrtShell->InsertField2(aGetField1);
     //now we have ref1-seq1
     //moving the cursor
@@ -1048,7 +1051,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf63553)
     pCursor->Move(fnMoveForward);
     //inserting reference field 2
     SwGetRefField aGetField2(pRefType, "Illustration", "", REF_SEQUENCEFLD, 
sal_uInt16(1),
-                             REF_CONTENT);
+                             REF_CONTENT, nullptr, nullptr);
     pWrtShell->InsertField2(aGetField2);
     //now we have ref1-ref2-seq1-seq2
     //moving the cursor
@@ -1062,7 +1065,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf63553)
     pCursor->Move(fnMoveForward);
     //inserting reference field 3
     SwGetRefField aGetField3(pRefType, "Illustration", "", REF_SEQUENCEFLD, 
sal_uInt16(2),
-                             REF_CONTENT);
+                             REF_CONTENT, nullptr, nullptr);
     pWrtShell->InsertField2(aGetField3);
     //now after insertion we have ref1-ref2-ref3-seq1-seq2-seq3
     //updating the fields
diff --git a/sw/source/core/access/accpara.cxx 
b/sw/source/core/access/accpara.cxx
index 7ca30145b1d6..3ea06717835c 100644
--- a/sw/source/core/access/accpara.cxx
+++ b/sw/source/core/access/accpara.cxx
@@ -1229,6 +1229,9 @@ OUString 
SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
                     case REF_SEQUENCEFLD:
                         sEntry = static_cast<const 
SwGetRefField*>(pField)->GetSetRefName();
                         break;
+                    case REF_STYLE:
+                        sEntry = "StyleRef";
+                        break;
                     }
                     //Get format string
                     strTypeName = sEntry;
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index 471e5d989780..3326648b3a5a 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -1409,8 +1409,14 @@ bool SwCursorShell::GotoRefMark( const OUString& 
rRefMark, sal_uInt16 nSubType,
     SwCursorSaveState aSaveState( *m_pCurrentCursor );
 
     sal_Int32 nPos = -1;
-    SwTextNode* pTextNd = SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark,
-                                nSubType, nSeqNo, &nPos, nullptr, GetLayout());
+
+    SwPaM* pCursor = GetCursor();
+    SwPosition* pPos = pCursor->GetPoint();
+    SwTextNode* pRefTextNd = pPos->GetNode().GetTextNode();
+    SwContentFrame* pRefFrame = GetCurrFrame();
+
+    SwTextNode* pTextNd = SwGetRefFieldType::FindAnchor(GetDoc(), rRefMark,
+                                nSubType, nSeqNo, &nPos, nullptr, GetLayout(), 
pRefTextNd, pRefFrame);
     if( !pTextNd || !pTextNd->GetNodes().IsDocNodes() )
         return false;
 
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index c0ed059e2882..9f43ae6b0bca 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -42,6 +42,7 @@
 #include <reffld.hxx>
 #include <expfld.hxx>
 #include <txtfrm.hxx>
+#include <notxtfrm.hxx>
 #include <flyfrm.hxx>
 #include <pagedesc.hxx>
 #include <IMark.hxx>
@@ -65,6 +66,7 @@
 #include <string_view>
 #include <map>
 #include <algorithm>
+#include <deque>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::text;
@@ -348,12 +350,15 @@ static void lcl_formatReferenceLanguage( OUString& 
rRefText,
 /// get references
 SwGetRefField::SwGetRefField( SwGetRefFieldType* pFieldType,
                               OUString aSetRef, OUString 
aSetReferenceLanguage, sal_uInt16 nSubTyp,
-                              sal_uInt16 nSequenceNo, sal_uLong nFormat )
-    : SwField( pFieldType, nFormat ),
-      m_sSetRefName( std::move(aSetRef) ),
-      m_sSetReferenceLanguage( std::move(aSetReferenceLanguage) ),
-      m_nSubType( nSubTyp ),
-      m_nSeqNo( nSequenceNo )
+                              sal_uInt16 nSequenceNo, sal_uLong nFormat, 
SwTextNode* pTextNode,
+                              SwFrame* pFrame )
+    : SwField(pFieldType, nFormat),
+      m_sSetRefName(std::move(aSetRef)),
+      m_sSetReferenceLanguage(std::move(aSetReferenceLanguage)),
+      m_nSubType(nSubTyp),
+      m_nSeqNo(nSequenceNo),
+      m_pTextNode(pTextNode),
+      m_pFrame(pFrame)
 {
 }
 
@@ -361,6 +366,24 @@ SwGetRefField::~SwGetRefField()
 {
 }
 
+void SwGetRefField::ChangeExpansion(SwFrame* pFrame, const SwTextField* pField)
+{
+    m_pFrame = pFrame;
+    m_pTextNode = pField->GetpTextNode();
+}
+
+void SwGetRefField::SetText(OUString sText, SwRootFrame* pLayout)
+{
+    if (pLayout->IsHideRedlines())
+    {
+        m_sTextRLHidden = sText;
+    }
+    else
+    {
+        m_sText = sText;
+    }
+}
+
 OUString SwGetRefField::GetDescription() const
 {
     return SwResId(STR_REFERENCE);
@@ -389,13 +412,14 @@ bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const
         ::sw::mark::CrossRefNumItemBookmark::IsLegalName(m_sSetRefName);
 }
 
-const SwTextNode* SwGetRefField::GetReferencedTextNode() const
+const SwTextNode* SwGetRefField::GetReferencedTextNode(SwTextNode* pTextNode) 
const
 {
     SwGetRefFieldType *pTyp = dynamic_cast<SwGetRefFieldType*>(GetTyp());
     if (!pTyp)
         return nullptr;
     sal_Int32 nDummy = -1;
-    return SwGetRefFieldType::FindAnchor( &pTyp->GetDoc(), m_sSetRefName, 
m_nSubType, m_nSeqNo, &nDummy );
+    return SwGetRefFieldType::FindAnchor( &pTyp->GetDoc(), m_sSetRefName, 
m_nSubType, m_nSeqNo, &nDummy,
+                                          nullptr, nullptr, pTextNode ? 
pTextNode : m_pTextNode, m_pFrame );
 }
 
 // strikethrough for tooltips using Unicode combining character
@@ -414,7 +438,13 @@ static OUString 
lcl_formatStringByCombiningCharacter(std::u16string_view sText,
 OUString SwGetRefField::GetExpandedTextOfReferencedTextNode(
         SwRootFrame const& rLayout) const
 {
-    const SwTextNode* pReferencedTextNode( GetReferencedTextNode() );
+    return GetExpandedTextOfReferencedTextNode(rLayout, m_pTextNode);
+}
+
+OUString SwGetRefField::GetExpandedTextOfReferencedTextNode(
+        SwRootFrame const& rLayout, SwTextNode* pTextNode) const
+{
+    const SwTextNode* pReferencedTextNode( GetReferencedTextNode(pTextNode) );
     if ( !pReferencedTextNode )
         return OUString();
 
@@ -484,36 +514,41 @@ static void FilterText(OUString & rText, LanguageType 
const eLang,
 // #i81002# - parameter <pFieldTextAttr> added
 void SwGetRefField::UpdateField( const SwTextField* pFieldTextAttr )
 {
-    m_sText.clear();
-    m_sTextRLHidden.clear();
+    SwDoc& rDoc = static_cast<SwGetRefFieldType*>(GetTyp())->GetDoc();
+
+    for (SwRootFrame const* const pLay : rDoc.GetAllLayouts())
+    {
+        if (pLay->IsHideRedlines())
+        {
+            UpdateField(pFieldTextAttr, pLay, m_sTextRLHidden);
+        }
+        else
+        {
+            UpdateField(pFieldTextAttr, pLay, m_sText);
+        }
+    }
+}
 
+void SwGetRefField::UpdateField(const SwTextField* pFieldTextAttr, const 
SwRootFrame* const pLayout,
+                                OUString& rText)
+{
     SwDoc& rDoc = static_cast<SwGetRefFieldType*>(GetTyp())->GetDoc();
+
+    rText.clear();
+
     // finding the reference target (the number)
     sal_Int32 nNumStart = -1;
     sal_Int32 nNumEnd = -1;
     SwTextNode* pTextNd = SwGetRefFieldType::FindAnchor(
-        &rDoc, m_sSetRefName, m_nSubType, m_nSeqNo, &nNumStart, &nNumEnd
+        &rDoc, m_sSetRefName, m_nSubType, m_nSeqNo, &nNumStart, &nNumEnd,
+        pLayout, pFieldTextAttr ? &pFieldTextAttr->GetTextNode() : 
m_pTextNode, m_pFrame
     );
     // not found?
     if ( !pTextNd )
     {
-        m_sText = SwViewShell::GetShellRes()->aGetRefField_RefItemNotFound;
-        m_sTextRLHidden = m_sText;
-        return ;
-    }
+        rText = SwViewShell::GetShellRes()->aGetRefField_RefItemNotFound;
 
-    SwRootFrame const* pLayout(nullptr);
-    SwRootFrame const* pLayoutRLHidden(nullptr);
-    for (SwRootFrame const*const pLay : rDoc.GetAllLayouts())
-    {
-        if (pLay->IsHideRedlines())
-        {
-            pLayoutRLHidden = pLay;
-        }
-        else
-        {
-            pLayout = pLay;
-        }
+        return;
     }
 
     // where is the category name (e.g. "Illustration")?
@@ -608,18 +643,21 @@ void SwGetRefField::UpdateField( const SwTextField* 
pFieldTextAttr )
                     SwTextFootnote* const pFootnoteIdx = 
rDoc.GetFootnoteIdxs()[i];
                     if( m_nSeqNo == pFootnoteIdx->GetSeqRefNo() )
                     {
-                        m_sText = 
pFootnoteIdx->GetFootnote().GetViewNumStr(rDoc, nullptr);
-                        m_sTextRLHidden = 
pFootnoteIdx->GetFootnote().GetViewNumStr(rDoc, pLayoutRLHidden);
+                        rText = 
pFootnoteIdx->GetFootnote().GetViewNumStr(rDoc, pLayout);
                         if (!m_sSetReferenceLanguage.isEmpty())
                         {
-                            lcl_formatReferenceLanguage(m_sText, false, 
GetLanguage(), m_sSetReferenceLanguage);
-                            lcl_formatReferenceLanguage(m_sTextRLHidden, 
false, GetLanguage(), m_sSetReferenceLanguage);
+                            lcl_formatReferenceLanguage(rText, false, 
GetLanguage(), m_sSetReferenceLanguage);
                         }
                         break;
                     }
                 }
                 return;
 
+            case REF_STYLE:
+                nStart = 0;
+                nEnd = nLen;
+                break;
+
             case REF_SETREFATTR:
                 nStart = nNumStart;
                 nEnd = nNumEnd;
@@ -631,26 +669,32 @@ void SwGetRefField::UpdateField( const SwTextField* 
pFieldTextAttr )
 
             if( nStart != nEnd ) // a section?
             {
-                m_sText = pTextNd->GetExpandText(pLayout, nStart, nEnd - 
nStart, false, false, false, ExpandMode::HideDeletions);
-                // show the referenced text without the deletions, but if the 
whole text was
-                // deleted, show the original text for the sake of the 
comfortable reviewing
-                // (with strikethrough in tooltip, see 
GetExpandedTextOfReferencedTextNode())
-                if ( m_sText.isEmpty() )
-                    m_sText = pTextNd->GetExpandText(pLayout, nStart, nEnd - 
nStart, false, false, false, ExpandMode(0));
-
-                if (m_nSubType == REF_OUTLINE
-                    || (m_nSubType == REF_SEQUENCEFLD && REF_CONTENT == 
GetFormat()))
+                if (pLayout->IsHideRedlines())
                 {
-                    m_sTextRLHidden = sw::GetExpandTextMerged(
-                        pLayoutRLHidden, *pTextNd, false, false, 
ExpandMode(0));
+                    if (m_nSubType == REF_OUTLINE
+                        || (m_nSubType == REF_SEQUENCEFLD && REF_CONTENT == 
GetFormat()))
+                    {
+                        rText = sw::GetExpandTextMerged(pLayout, *pTextNd, 
false, false,
+                                                        ExpandMode(0));
+                    }
+                    else
+                    {
+                        rText = pTextNd->GetExpandText(pLayout, nStart, nEnd - 
nStart, false, false,
+                                                       false, 
ExpandMode::HideDeletions);
+                    }
                 }
                 else
                 {
-                    m_sTextRLHidden = pTextNd->GetExpandText(pLayoutRLHidden,
-                        nStart, nEnd - nStart, false, false, false, 
ExpandMode::HideDeletions);
+                    rText = pTextNd->GetExpandText(pLayout, nStart, nEnd - 
nStart, false, false,
+                                                   false, 
ExpandMode::HideDeletions);
+                    // show the referenced text without the deletions, but if 
the whole text was
+                    // deleted, show the original text for the sake of the 
comfortable reviewing
+                    // (with strikethrough in tooltip, see 
GetExpandedTextOfReferencedTextNode())
+                    if (rText.isEmpty())
+                        rText = pTextNd->GetExpandText(pLayout, nStart, nEnd - 
nStart, false, false,
+                                                       false, ExpandMode(0));
                 }
                 FilterText(m_sText, GetLanguage(), m_sSetReferenceLanguage);
-                FilterText(m_sTextRLHidden, GetLanguage(), 
m_sSetReferenceLanguage);
             }
         }
         break;
@@ -658,10 +702,7 @@ void SwGetRefField::UpdateField( const SwTextField* 
pFieldTextAttr )
     case REF_PAGE:
     case REF_PAGE_PGDESC:
         {
-          auto const func =
-          [this, pTextNd, nNumStart](OUString & rText, SwRootFrame const*const 
pLay)
-          {
-            SwTextFrame const* pFrame = 
static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLay, nullptr, nullptr));
+            SwTextFrame const* pFrame = 
static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout, nullptr, nullptr));
             SwTextFrame const*const pSave = pFrame;
             if (pFrame)
             {
@@ -688,35 +729,25 @@ void SwGetRefField::UpdateField( const SwTextField* 
pFieldTextAttr )
                 if (!m_sSetReferenceLanguage.isEmpty())
                     lcl_formatReferenceLanguage(rText, false, GetLanguage(), 
m_sSetReferenceLanguage);
             }
-          };
-          // sw_redlinehide: currently only one of these layouts will exist,
-          // so the getLayoutFrame will use the same frame in both cases
-          func(m_sText, pLayout);
-          func(m_sTextRLHidden, pLayoutRLHidden);
         }
         break;
 
     case REF_CHAPTER:
+    {
+        // a bit tricky: search any frame
+        SwFrame const* const pFrame = pTextNd->getLayoutFrame(pLayout);
+        if (pFrame)
         {
-          auto const func =
-          [this, pTextNd](OUString & rText, SwRootFrame const*const pLay)
-          {
-            // a bit tricky: search any frame
-            SwFrame const*const pFrame = pTextNd->getLayoutFrame(pLay);
-            if( pFrame )
-            {
-                SwChapterFieldType aFieldTyp;
-                SwChapterField aField( &aFieldTyp, 0 );
-                aField.SetLevel( MAXLEVEL - 1 );
-                aField.ChangeExpansion( *pFrame, pTextNd, true );
-                rText = aField.GetNumber(pLay);
+            SwChapterFieldType aFieldTyp;
+            SwChapterField aField(&aFieldTyp, 0);
+            aField.SetLevel(MAXLEVEL - 1);
+            aField.ChangeExpansion(*pFrame, pTextNd, true);
 
-                if (!m_sSetReferenceLanguage.isEmpty())
-                    lcl_formatReferenceLanguage(rText, false, GetLanguage(), 
m_sSetReferenceLanguage);
-            }
-          };
-          func(m_sText, pLayout);
-          func(m_sTextRLHidden, pLayoutRLHidden);
+            rText = aField.GetNumber(pLayout);
+
+            if (!m_sSetReferenceLanguage.isEmpty())
+                lcl_formatReferenceLanguage(rText, false, GetLanguage(), 
m_sSetReferenceLanguage);
+        }
         }
         break;
 
@@ -732,22 +763,19 @@ void SwGetRefField::UpdateField( const SwTextField* 
pFieldTextAttr )
             // first a "short" test - in case both are in the same node
             if( pFieldTextAttr->GetpTextNode() == pTextNd )
             {
-                m_sText = nNumStart < pFieldTextAttr->GetStart()
+                rText = nNumStart < pFieldTextAttr->GetStart()
                             ? aLocaleData.getAboveWord()
                             : aLocaleData.getBelowWord();
-                m_sTextRLHidden = m_sText;
                 break;
             }
 
-            m_sText = ::IsFrameBehind( *pFieldTextAttr->GetpTextNode(), 
pFieldTextAttr->GetStart(),
+            rText = ::IsFrameBehind( *pFieldTextAttr->GetpTextNode(), 
pFieldTextAttr->GetStart(),
                                     *pTextNd, nNumStart )
                         ? aLocaleData.getAboveWord()
                         : aLocaleData.getBelowWord();
 
             if (!m_sSetReferenceLanguage.isEmpty())
-                    lcl_formatReferenceLanguage(m_sText, false, GetLanguage(), 
m_sSetReferenceLanguage);
-
-            m_sTextRLHidden = m_sText;
+                    lcl_formatReferenceLanguage(rText, false, GetLanguage(), 
m_sSetReferenceLanguage);
         }
         break;
     // #i81002#
@@ -759,20 +787,12 @@ void SwGetRefField::UpdateField( const SwTextField* 
pFieldTextAttr )
             {
                 auto result =
                     MakeRefNumStr(pLayout, pFieldTextAttr->GetTextNode(), 
*pTextNd, GetFormat());
-                m_sText = result.first;
+                rText = result.first;
                 // for differentiation of Roman numbers and letters in 
Hungarian article handling
                 bool bClosingParenthesis = result.second;
                 if (!m_sSetReferenceLanguage.isEmpty())
                 {
-                    lcl_formatReferenceLanguage(m_sText, bClosingParenthesis, 
GetLanguage(), m_sSetReferenceLanguage);
-                }
-                result =
-                    MakeRefNumStr(pLayoutRLHidden, 
pFieldTextAttr->GetTextNode(), *pTextNd, GetFormat());
-                m_sTextRLHidden = result.first;
-                bClosingParenthesis = result.second;
-                if (!m_sSetReferenceLanguage.isEmpty())
-                {
-                    lcl_formatReferenceLanguage(m_sTextRLHidden, 
bClosingParenthesis, GetLanguage(), m_sSetReferenceLanguage);
+                    lcl_formatReferenceLanguage(rText, bClosingParenthesis, 
GetLanguage(), m_sSetReferenceLanguage);
                 }
             }
         }
@@ -876,7 +896,7 @@ std::unique_ptr<SwField> SwGetRefField::Copy() const
 {
     std::unique_ptr<SwGetRefField> pField( new SwGetRefField( 
static_cast<SwGetRefFieldType*>(GetTyp()),
                                                 m_sSetRefName, 
m_sSetReferenceLanguage, m_nSubType,
-                                                m_nSeqNo, GetFormat() ) );
+                                                m_nSeqNo, GetFormat(), 
m_pTextNode, m_pFrame ) );
     pField->m_sText = m_sText;
     pField->m_sTextRLHidden = m_sTextRLHidden;
     return std::unique_ptr<SwField>(pField.release());
@@ -935,6 +955,7 @@ bool SwGetRefField::QueryValue( uno::Any& rAny, sal_uInt16 
nWhichId ) const
             case  REF_OUTLINE    : OSL_FAIL("not implemented"); break;
             case  REF_FOOTNOTE   : nSource = ReferenceFieldSource::FOOTNOTE; 
break;
             case  REF_ENDNOTE    : nSource = ReferenceFieldSource::ENDNOTE; 
break;
+            case  REF_STYLE      : nSource = ReferenceFieldSource::STYLE; 
break;
             }
             rAny <<= nSource;
         }
@@ -1019,6 +1040,7 @@ bool SwGetRefField::PutValue( const uno::Any& rAny, 
sal_uInt16 nWhichId )
             case ReferenceFieldSource::BOOKMARK       : m_nSubType = 
REF_BOOKMARK   ; break;
             case ReferenceFieldSource::FOOTNOTE       : m_nSubType = 
REF_FOOTNOTE   ; break;
             case ReferenceFieldSource::ENDNOTE        : m_nSubType = 
REF_ENDNOTE    ; break;
+            case ReferenceFieldSource::STYLE          : m_nSubType = REF_STYLE 
     ; break;
             }
         }
         break;
@@ -1167,10 +1189,52 @@ bool IsMarkHintHidden(SwRootFrame const& rLayout,
 
 } // namespace sw
 
-SwTextNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const OUString& 
rRefMark,
-                                        sal_uInt16 nSubType, sal_uInt16 nSeqNo,
-                                        sal_Int32* pStt, sal_Int32* pEnd,
-                                        SwRootFrame const*const pLayout)
+enum StyleRefElementType
+{
+    Default,
+    Reference, /* e.g. footnotes, endnotes */
+    Marginal, /* headers, footers */
+};
+
+namespace
+{
+    /// Picks the first text node with a matching style from a double ended 
queue, starting at the front
+    /// This allows us to use the deque either as a stack or as a queue 
depending on whether we want to search up or down
+    SwTextNode* SearchForStyleAnchor(SwTextNode* pSelf, std::deque<SwNode*> 
pToSearch,
+                                    const OUString& rStyleName, bool 
bCaseSensitive = true)
+    {
+        while (!pToSearch.empty())
+        {
+            SwNode* pCurrent = pToSearch.front();
+            pToSearch.pop_front();
+
+            if (*pCurrent == *pSelf)
+                continue;
+
+            SwTextNode* pTextNode = pCurrent->GetTextNode();
+            if (!pTextNode)
+                continue;
+
+            if (bCaseSensitive)
+            {
+                if (pTextNode->GetFormatColl()->GetName() == rStyleName)
+                    return pTextNode;
+            }
+            else
+            {
+                if 
(pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
+                    return pTextNode;
+            }
+        }
+
+        return nullptr;
+    }
+}
+
+SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& 
rRefMark,
+                                          sal_uInt16 nSubType, sal_uInt16 
nSeqNo, sal_Int32* pStt,
+                                          sal_Int32* pEnd, SwRootFrame const* 
const pLayout,
+                                          SwTextNode* pSelf, SwFrame* 
pContentFrame)
 {
     OSL_ENSURE( pStt, "Why did no one check the StartPos?" );
 
@@ -1285,6 +1349,251 @@ SwTextNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, 
const OUString& rRefMark
                 }
         }
         break;
+        case REF_STYLE:
+            if (!pSelf)
+                break;
+
+            const SwNodes& nodes = pDoc->GetNodes();
+
+            StyleRefElementType elementType = StyleRefElementType::Default;
+            const SwTextNode* pReference = nullptr;
+
+            { /* Check if we're a footnote/endnote */
+                for (SwTextFootnote* pFootnoteIdx : pDoc->GetFootnoteIdxs())
+                {
+                    if (pLayout && pLayout->IsHideRedlines()
+                        && sw::IsFootnoteDeleted(rIDRA, *pFootnoteIdx))
+                    {
+                        continue;
+                    }
+                    const SwNodeIndex* pIdx = pFootnoteIdx->GetStartNode();
+                    if (pIdx)
+                    {
+                        SwNodeIndex aIdx(*pIdx, 1);
+                        SwTextNode* pFootnoteNode = 
aIdx.GetNode().GetTextNode();
+                        if (nullptr == pFootnoteNode)
+                            pFootnoteNode
+                                = 
static_cast<SwTextNode*>(pDoc->GetNodes().GoNext(&aIdx));
+
+                        if (*pSelf == *pFootnoteNode)
+                        {
+                            elementType = StyleRefElementType::Reference;
+                            pReference = &pFootnoteIdx->GetTextNode();
+                        }
+                    }
+                }
+            }
+
+            if (pDoc->IsInHeaderFooter(*pSelf))
+            {
+                elementType = StyleRefElementType::Marginal;
+            }
+
+            if (pReference == nullptr)
+            {
+                pReference = pSelf;
+            }
+
+            switch (elementType)
+            {
+                case Marginal:
+                {
+                    // For marginals, styleref tries to act on the current 
page first
+                    // 1. Get the page we're on, search it from top to bottom
+
+                    Point aPt;
+                    std::pair<Point, bool> const tmp(aPt, false);
+
+                    if (!pContentFrame) 
SAL_WARN("<SwGetRefFieldType::FindAnchor(..)>", "Missing content frame for 
marginal styleref");
+                    const SwPageFrame* pPageFrame = nullptr;
+
+                    if (pContentFrame)
+                        pPageFrame = pContentFrame->FindPageFrame();
+
+                    const SwNode* pPageStart(nullptr);
+                    const SwNode* pPageEnd(nullptr);
+
+                    if (pPageFrame)
+                    {
+                        const SwContentFrame* pPageStartFrame = 
pPageFrame->FindFirstBodyContent();
+                        const SwContentFrame* pPageEndFrame = 
pPageFrame->FindLastBodyContent();
+
+                        if (pPageStartFrame) {
+                            if (pPageStartFrame->IsTextFrame())
+                            {
+                                pPageStart = static_cast<const 
SwTextFrame*>(pPageStartFrame)
+                                                ->GetTextNodeFirst();
+                            }
+                            else
+                            {
+                                pPageStart
+                                    = static_cast<const 
SwNoTextFrame*>(pPageStartFrame)->GetNode();
+                            }
+                        }
+
+                        if (pPageEndFrame) {
+                            if (pPageEndFrame->IsTextFrame())
+                            {
+                                pPageEnd = static_cast<const 
SwTextFrame*>(pPageEndFrame)
+                                            ->GetTextNodeFirst();
+                            }
+                            else
+                            {
+                                pPageEnd = static_cast<const 
SwNoTextFrame*>(pPageEndFrame)->GetNode();
+                            }
+                        }
+                    }
+
+                    if (!pPageStart || !pPageEnd)
+                    {
+                        pPageStart = pReference;
+                        pPageEnd = pReference;
+                    }
+
+                    std::deque<SwNode*> pAbovePage;
+                    std::deque<SwNode*> pInPage;
+                    std::deque<SwNode*> pBelowPage;
+
+                    bool beforeStart = true;
+                    bool beforeEnd = true;
+
+                    for (SwNodeOffset n(0); n < nodes.Count(); n++)
+                    {
+                        if (beforeStart && *pPageStart == *nodes[n])
+                        {
+                            beforeStart = false;
+                        }
+
+                        if (beforeStart)
+                        {
+                            pAbovePage.push_front(nodes[n]);
+                        }
+                        else if (beforeEnd)
+                        {
+                            pInPage.push_back(nodes[n]);
+
+                            if (*pPageEnd == *nodes[n])
+                            {
+                                beforeEnd = false;
+                            }
+                        }
+                        else
+                        {
+                            pBelowPage.push_back(nodes[n]);
+                        }
+                    }
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    // 2. Search up from the top of the page
+                    pTextNd = SearchForStyleAnchor(pSelf, pAbovePage, 
rRefMark);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    // 3. Search down from the bottom of the page
+                    pTextNd = SearchForStyleAnchor(pSelf, pBelowPage, 
rRefMark);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    // Word has case insensitive styles. LO has case sensitive 
styles. If we didn't find
+                    // it yet, maybe we could with a case insensitive search. 
Let's do that
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark,
+                                                   false /* bCaseSensitive */);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pAbovePage, rRefMark,
+                                                   false /* bCaseSensitive */);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pBelowPage, rRefMark,
+                                                   false /* bCaseSensitive */);
+                    break;
+                }
+                case Reference:
+                case Default:
+                {
+                    // Normally, styleref does searches around the field 
position
+                    // For references, styleref acts from the position of the 
reference not the field
+                    // Happily, the previous code saves either one into 
pReference, so the following is generic for both
+
+                    std::deque<SwNode*> pNotBelowElement;
+                    std::deque<SwNode*> pBelowElement;
+
+                    bool beforeElement = true;
+
+                    for (SwNodeOffset n(0); n < nodes.Count(); n++)
+                    {
+                        if (beforeElement)
+                        {
+                            pNotBelowElement.push_front(nodes[n]);
+
+                            if (*pReference == *nodes[n])
+                            {
+                                beforeElement = false;
+                            }
+                        }
+                        else
+                        {
+                            pBelowElement.push_back(nodes[n]);
+                        }
+                    }
+
+                    // 1. Search up until we hit the top of the document
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pNotBelowElement, 
rRefMark);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    // 2. Search down until we hit the bottom of the document
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pBelowElement, 
rRefMark);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    // Again, we need to remember that Word styles are not 
case sensitive
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pNotBelowElement, 
rRefMark,
+                                                   false /* bCaseSensitive */);
+                    if (pTextNd)
+                    {
+                        break;
+                    }
+
+                    pTextNd = SearchForStyleAnchor(pSelf, pBelowElement, 
rRefMark,
+                                                   false /* bCaseSensitive */);
+                    break;
+                }
+                default:
+                    OSL_FAIL("<SwGetRefFieldType::FindAnchor(..)> - unknown 
getref element type");
+            }
+
+            if (pTextNd)
+            {
+                *pStt = 0;
+                if (pEnd)
+                    *pEnd = pTextNd->GetText().getLength();
+            }
+
+            break;
     }
 
     return pTextNd;
diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx
index 5a4e7229334b..aa9cb97ffbad 100644
--- a/sw/source/core/text/txtfld.cxx
+++ b/sw/source/core/text/txtfld.cxx
@@ -244,7 +244,19 @@ SwExpandPortion *SwTextFormatter::NewFieldPortion( 
SwTextFormatInfo &rInf,
             bPlaceHolder = true;
             break;
         case SwFieldIds::GetRef:
+        {
             subType = static_cast<SwGetRefField*>(pField)->GetSubType();
+            if (!bName && subType == REF_STYLE)
+            {
+                SwTextNode* pTextNode = 
pHint->GetFormatField().GetTextField()->GetpTextNode();
+
+                if (pTextNode)
+                    static_cast<SwGetRefField*>(pField)->ChangeExpansion(
+                        pFrame, static_txtattr_cast<SwTextField 
const*>(pHint));
+                static_cast<SwGetRefField*>(pField)->UpdateField(
+                    static_txtattr_cast<SwTextField const*>(pHint));
+            }
+
             {
                 OUString const str( bName
                     ? pField->GetFieldName()
@@ -255,7 +267,8 @@ SwExpandPortion *SwTextFormatter::NewFieldPortion( 
SwTextFormatInfo &rInf,
                 static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = 
ATTR_BOOKMARKFLD;
             else if( subType == REF_SETREFATTR )
                 static_cast<SwFieldPortion*>(pRet)->m_nAttrFieldType = 
ATTR_SETREFATTRFLD;
-            break;
+        }
+        break;
         case SwFieldIds::DateTime:
             subType = static_cast<SwDateTimeField*>(pField)->GetSubType();
             {
diff --git a/sw/source/core/unocore/unofield.cxx 
b/sw/source/core/unocore/unofield.cxx
index f1818c3c088f..76d8a74939f0 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1529,6 +1529,8 @@ void SAL_CALL SwXTextField::attach(
                             m_pImpl->m_pProps->sPar4,
                             0,
                             0,
+                            0,
+                            0,
                             0));
                 if (!m_pImpl->m_pProps->sPar3.isEmpty())
                     
static_cast<SwGetRefField*>(xField.get())->SetExpand(m_pImpl->m_pProps->sPar3);
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 7f20ed491bc2..c30f0a257286 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -642,6 +642,9 @@ public:
     /// Find the bookmark name.
     OUString GetBookmarkName( sal_uInt16 nTyp, const OUString* pName, 
sal_uInt16 nSeqNo );
 
+    /// Find out which style we should use in OOXML
+    OUString GetStyleRefName(const OUString& rName);
+
     /// Use OutputItem() on an item set according to the parameters.
     void OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, bool 
bChpFormat, sal_uInt16 nScript, bool bExportParentItemSet );
 
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 9a561c05dac6..0258ae7f303f 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -128,6 +128,7 @@
 #include <fmthdft.hxx>
 #include <authfld.hxx>
 #include <dbfld.hxx>
+#include <docsh.hxx>
 
 #include "sprmids.hxx"
 
@@ -1045,6 +1046,18 @@ OUString MSWordExportBase::GetBookmarkName( sal_uInt16 
nTyp, const OUString* pNa
     return BookmarkToWord( sRet ); // #i43956# - encode bookmark accordingly
 }
 
+OUString MSWordExportBase::GetStyleRefName(const OUString& rName)
+{
+    SwTextFormatColls* pTextFormatColls = m_rDoc.GetTextFormatColls();
+    SwTextFormatColl* pTextFormat = pTextFormatColls->FindFormatByName(rName);
+
+    if (pTextFormat == nullptr)
+        return "\"" + rName + "\"";
+    // Didn't find the style, just keep the original name
+
+    return "\"" + m_pStyles->GetStyleWWName(pTextFormat) + "\"";
+}
+
 /* File CHRATR.HXX: */
 void WW8AttributeOutput::RTLAndCJKState( bool bIsRTL, sal_uInt16 nScript )
 {
@@ -3293,26 +3306,45 @@ void AttributeOutputBase::TextField( const 
SwFormatField& rField )
                     sStr = FieldString(eField)
                            + GetExport().GetBookmarkName(nSubType, nullptr, 
rRField.GetSeqNo());
                     break;
+                case REF_STYLE:
+                    sStr = FieldString(ww::eSTYLEREF)
+                           + GetExport().GetStyleRefName(pField->GetPar1());
+                    eField = ww::eSTYLEREF;
+                    break;
             }
 
-            if (eField != ww::eNONE)
+            OUString sExtraFlags = "\\h "; // by default, include a hyperlink
+
+            switch (eField)
             {
-                switch (pField->GetFormat())
-                {
-                    case REF_UPDOWN:
-                        sStr += " \\p \\h ";   // with hyperlink
-                        break;
-                    case REF_CHAPTER:
-                        sStr += " \\n \\h ";   // with hyperlink
-                        break;
-                    default:
-                        sStr += " \\h ";       // insert hyperlink
-                        break;
-                }
-                GetExport().OutputField(pField, eField, sStr);
+                case ww::eNONE:
+                    bWriteExpand = true;
+                    break;
+                case ww::eSTYLEREF:
+                    sExtraFlags = ""; // styleref fields do not work if they 
have a hyperlink
+                    [[fallthrough]];
+                default:
+                    switch (pField->GetFormat())
+                    {
+                        case REF_NUMBER:
+                            sStr += " \\r " + sExtraFlags;
+                            break;
+                        case REF_NUMBER_FULL_CONTEXT:
+                            sStr += " \\w " + sExtraFlags;
+                            break;
+                        case REF_UPDOWN:
+                            sStr += " \\p " + sExtraFlags;
+                            break;
+                        case REF_NUMBER_NO_CONTEXT:
+                        case REF_CHAPTER:
+                            sStr += " \\n " + sExtraFlags;
+                            break;
+                        default:
+                            sStr += " " + sExtraFlags;
+                            break;
+                    }
+                    GetExport().OutputField(pField, eField, sStr);
             }
-            else
-                bWriteExpand = true;
         }
         break;
     case SwFieldIds::CombinedChars:
@@ -3362,7 +3394,8 @@ void AttributeOutputBase::TextField( const SwFormatField& 
rField )
         break;
     case SwFieldIds::Chapter:
         bWriteExpand = true;
-        if (GetExport().m_bOutKF && rField.GetTextField())
+
+        if (rField.GetTextField())
         {
             const SwTextNode *pTextNd = GetExport().GetHdFtPageRoot();
             if (!pTextNd)
@@ -3374,10 +3407,22 @@ void AttributeOutputBase::TextField( const 
SwFormatField& rField )
             {
                 SwChapterField aCopy(*static_cast<const 
SwChapterField*>(pField));
                 aCopy.ChangeExpansion(*pTextNd, false);
-                const OUString sStr = FieldString(ww::eSTYLEREF)
-                    + " "
-                    + OUString::number(aCopy.GetLevel() + 1)
-                    + " \\* MERGEFORMAT ";
+
+                OUString sStr;
+                if (GetExport().m_bOutKF) {
+                    // In headers and footers, use the chapter number as the 
style name
+                    sStr = FieldString(ww::eSTYLEREF)
+                        + " "
+                        + OUString::number(aCopy.GetLevel() + 1)
+                        + " \\* MERGEFORMAT ";
+                } else {
+                    // Otherwise, get the style of the text and use it as the 
style name
+                    const SwTextNode* pOutlineNd = 
pTextNd->FindOutlineNodeOfLevel(aCopy.GetLevel());
+
+                    sStr = FieldString(ww::eSTYLEREF)
+                         + 
GetExport().GetStyleRefName(pOutlineNd->GetFormatColl()->GetName());
+                }
+
                 GetExport().OutputField(pField, ww::eSTYLEREF, sStr);
                 bWriteExpand = false;
             }
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 7e7cedd3f4b5..e6dcca3f2cae 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -953,8 +953,7 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* 
pRes)
     bool bHasHandler = aWW8FieldTab[aF.nId] != nullptr;
     if (aF.nId == 10) // STYLEREF
     {
-        // STYLEREF, by default these are not handled.
-        bHasHandler = false;
+        bool bHandledByChapter = false;
         sal_uInt64 nOldPos = m_pStrm->Tell();
         OUString aStr;
         aF.nLCode = m_xSBase->WW8ReadString(*m_pStrm, aStr, 
m_xPlcxMan->GetCpOfs() + aF.nSCode, aF.nLCode, m_eTextCharSet);
@@ -964,9 +963,9 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* 
pRes)
         sal_Int32 nRet = aReadParam.SkipToNextToken();
         if (nRet == -2 && !aReadParam.GetResult().isEmpty())
             // Single numeric argument: this can be handled by SwChapterField.
-            bHasHandler = rtl::isAsciiDigit(aReadParam.GetResult()[0]);
+            bHandledByChapter = rtl::isAsciiDigit(aReadParam.GetResult()[0]);
 
-        if (bHasHandler)
+        if (bHandledByChapter)
         {
             nRet = aReadParam.SkipToNextToken();
             // Handle using SwChapterField only in case there is no \[a-z]
@@ -2158,7 +2157,7 @@ eF_ResT SwWW8ImplReader::Read_F_Ref( WW8FieldDesc*, 
OUString& rStr )
 
     SwGetRefField aField(
         
static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(
 SwFieldIds::GetRef )),
-        sBkmName,"",REF_BOOKMARK,0,eFormat);
+        sBkmName,"",REF_BOOKMARK,0,eFormat,nullptr,nullptr);
 
     if (eFormat == REF_CONTENT)
     {
@@ -2214,14 +2213,14 @@ eF_ResT SwWW8ImplReader::Read_F_NoteReference( 
WW8FieldDesc*, OUString& rStr )
     // (will be corrected in
     SwGetRefField aField( static_cast<SwGetRefFieldType*>(
         m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef 
)), aBkmName, "", REF_FOOTNOTE, 0,
-        REF_ONLYNUMBER );
+        REF_ONLYNUMBER, nullptr, nullptr );
     m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField));
     m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD);
     if (bAboveBelow)
     {
         SwGetRefField aField2( static_cast<SwGetRefFieldType*>(
             m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( 
SwFieldIds::GetRef )),aBkmName, "", REF_FOOTNOTE, 0,
-            REF_UPDOWN );
+            REF_UPDOWN, nullptr, nullptr );
         m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField2));
         m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD);
     }
@@ -2293,7 +2292,7 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, 
OUString& rStr )
         sPageRefBookmarkName = sName;
     }
     SwGetRefField aField( 
static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(
 SwFieldIds::GetRef )),
-                        sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE );
+                        sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE, 
nullptr, nullptr );
     m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, 
SwFormatField( aField ) );
 
     return eF_ResT::OK;
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
index ea8e41414d4a..213143ef8bb6 100644
--- a/sw/source/ui/fldui/fldref.cxx
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -47,6 +47,9 @@
 // #i83479#
 #define REFFLDFLAG_HEADING  0x7100
 #define REFFLDFLAG_NUMITEM  0x7200
+#define REFFLDFLAG_STYLE    0xc000
+/* we skip past 0x8000, 0x9000, 0xa000 and 0xb000 as when we bitwise 'and'
+       with REFFLDFLAG they are false */
 
 static sal_uInt16 nFieldDlgFormatSel = 0;
 
@@ -82,6 +85,7 @@ SwFieldRefPage::SwFieldRefPage(weld::Container* pPage, 
weld::DialogController* p
     // #i83479#
     m_sHeadingText = m_xTypeLB->get_text(3);
     m_sNumItemText = m_xTypeLB->get_text(4);
+    m_sStyleText = m_xTypeLB->get_text(5);
 
     auto nHeight = m_xTypeLB->get_height_rows(8);
     auto nWidth = m_xTypeLB->get_approximate_digit_width() * 
FIELD_COLUMN_WIDTH;
@@ -239,6 +243,9 @@ void SwFieldRefPage::Reset(const SfxItemSet* )
         m_xTypeLB->append(OUString::number(REFFLDFLAG_ENDNOTE), 
m_sEndnoteText);
     }
 
+    // stylerefs
+    m_xTypeLB->append(OUString::number(REFFLDFLAG_STYLE), m_sStyleText);
+
     m_xTypeLB->thaw();
 
     // select old Pos
@@ -274,7 +281,7 @@ void SwFieldRefPage::Reset(const SfxItemSet* )
         }
     }
     TypeHdl(*m_xTypeLB);
-    if (nFormatBoxPosition < m_xFormatLB->n_children())
+    if (!IsFieldEdit() && nFormatBoxPosition < m_xFormatLB->n_children())
     {
         m_xFormatLB->select(nFormatBoxPosition);
     }
@@ -356,6 +363,17 @@ IMPL_LINK_NOARG(SwFieldRefPage, TypeHdl, weld::TreeView&, 
void)
                     nFlag = REFFLDFLAG;
                     break;
                 }
+
+                case REF_STYLE:
+                {
+                    SwGetRefField const*const 
pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+                    if (pRefField)
+                    {
+                        sName = pRefField->GetPar1();
+                    }
+                    nFlag = REFFLDFLAG_STYLE;
+                    break;
+                }
             }
 
             if (m_xTypeLB->find_text(sName) == -1)   // reference to deleted 
mark
@@ -610,7 +628,7 @@ void SwFieldRefPage::UpdateSubType(const OUString& 
filterString)
                     m_xSelectionToolTipLB->append(sId,
                         pIDoc->getOutlineText(nOutlIdx, pSh->GetLayout(), 
true, true, false));
                     if ((IsFieldEdit() && pRefField
-                            && pRefField->GetReferencedTextNode() == 
maOutlineNodes[nOutlIdx])
+                            && pRefField->GetReferencedTextNode(nullptr) == 
maOutlineNodes[nOutlIdx])
                         || mpSavedSelectedTextNode == maOutlineNodes[nOutlIdx])
                     {
                         m_sSelectionToolTipLBId = sId;
@@ -645,7 +663,7 @@ void SwFieldRefPage::UpdateSubType(const OUString& 
filterString)
                     m_xSelectionToolTipLB->append(sId,
                         pIDoc->getListItemText(*maNumItems[nNumItemIdx], 
*pSh->GetLayout()));
                     if ((IsFieldEdit() && pRefField
-                            && pRefField->GetReferencedTextNode() == 
maNumItems[nNumItemIdx]->GetTextNode())
+                            && pRefField->GetReferencedTextNode(nullptr) == 
maNumItems[nNumItemIdx]->GetTextNode())
                         || mpSavedSelectedTextNode == 
maNumItems[nNumItemIdx]->GetTextNode())
                     {
                         m_sSelectionToolTipLBId = sId;
@@ -660,6 +678,32 @@ void SwFieldRefPage::UpdateSubType(const OUString& 
filterString)
                 }
             }
         }
+        else if (nTypeId == REFFLDFLAG_STYLE)
+        {
+            const IDocumentOutlineNodes* 
pIDoc(pSh->getIDocumentOutlineNodesAccess());
+            pIDoc->getOutlineNodes(maOutlineNodes);
+
+            SfxStyleSheetBasePool* pStyleSheetPool
+                = pSh->GetDoc()->GetDocShell()->GetStyleSheetPool();
+            auto stylesheetIterator
+                = pStyleSheetPool->CreateIterator(SfxStyleFamily::Para, 
SfxStyleSearchBits::Used);
+
+            SfxStyleSheetBase* pStyle = stylesheetIterator->First();
+            while (pStyle != nullptr)
+            {
+                bool isSubstring = MatchSubstring(pStyle->GetName(), 
filterString);
+
+                if (isSubstring)
+                {
+                    m_xSelectionLB->append_text(pStyle->GetName());
+                }
+
+                pStyle = stylesheetIterator->Next();
+            }
+
+            if (IsFieldEdit() && pRefField)
+                sOldSel = pRefField->GetPar1();
+        }
         else
         {
             // get the fields to Seq-FieldType:
@@ -803,6 +847,7 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
 
     // reference has less that the annotation
     sal_uInt16 nSize( 0 );
+    sal_uInt16 nOffset( 0 );
     bool bAddCrossRefFormats( false );
     switch (nTypeId)
     {
@@ -818,6 +863,11 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
         case REFFLDFLAG_ENDNOTE:
             nSize = FMT_REF_PAGE_PGDSC_IDX + 1;
             break;
+        case REFFLDFLAG_STYLE:
+            nOffset = FMT_REF_TEXT_IDX;
+            nSize = FMT_REF_UPDOWN_IDX + 1 - nOffset;
+            bAddCrossRefFormats = true;
+            break;
 
         default:
             // #i83479#
@@ -837,7 +887,7 @@ sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
         nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
 
     SwFieldTypesEnum nFieldType = static_cast<SwFieldTypesEnum>(nTypeId);
-    for (sal_uInt16 i = 0; i < nSize; i++)
+    for (sal_uInt16 i = nOffset; i < nSize + nOffset; i++)
     {
         OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i 
)));
         m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nFieldType, i));
@@ -1077,6 +1127,18 @@ bool SwFieldRefPage::FillItemSet(SfxItemSet* )
                 }
             }
         }
+        else if (nTypeId == REFFLDFLAG_STYLE)
+        {
+            int nEntry = m_xSelectionLB->get_selected_index();
+            if (nEntry != -1)
+            {
+                aName = m_xSelectionLB->get_text(nEntry);
+                nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+                nSubType = REF_STYLE;
+            } else {
+                SAL_WARN("<SwFieldRefPage::FillItemSet(..)>", "no entry 
selected in selection listbox!");
+            }
+        }
         else                                // SequenceFields
         {
             // get fields for Seq-FieldType:
diff --git a/sw/source/ui/fldui/fldref.hxx b/sw/source/ui/fldui/fldref.hxx
index 68dc6f6480be..872e6f526bb6 100644
--- a/sw/source/ui/fldui/fldref.hxx
+++ b/sw/source/ui/fldui/fldref.hxx
@@ -34,6 +34,7 @@ class SwFieldRefPage : public SwFieldPage
     // #i83479#
     OUString    m_sHeadingText;
     OUString    m_sNumItemText;
+    OUString    m_sStyleText;
 
     IDocumentOutlineNodes::tSortedOutlineNodeList maOutlineNodes;
     IDocumentListItems::tSortedNodeNumList maNumItems;
diff --git a/sw/source/uibase/docvw/edtwin2.cxx 
b/sw/source/uibase/docvw/edtwin2.cxx
index 04a51cfbc7b2..627bd054d586 100644
--- a/sw/source/uibase/docvw/edtwin2.cxx
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -357,7 +357,7 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt)
                                 if ( 
pRefField->IsRefToHeadingCrossRefBookmark() ||
                                      
pRefField->IsRefToNumItemCrossRefBookmark() )
                                 {
-                                    sText = 
pRefField->GetExpandedTextOfReferencedTextNode(*rSh.GetLayout());
+                                    sText = 
pRefField->GetExpandedTextOfReferencedTextNode(*rSh.GetLayout(), nullptr);
                                     if ( sText.getLength() > 80  )
                                     {
                                         sText = 
OUString::Concat(sText.subView(0, 80)) + "...";
diff --git a/sw/source/uibase/fldui/fldmgr.cxx 
b/sw/source/uibase/fldui/fldmgr.cxx
index 37c58ae0ee84..cd9f99aa2ad7 100644
--- a/sw/source/uibase/fldui/fldmgr.cxx
+++ b/sw/source/uibase/fldui/fldmgr.cxx
@@ -66,6 +66,8 @@
 #include <authfld.hxx>
 #include <flddat.hxx>
 #include <fldmgr.hxx>
+#include <ndtxt.hxx>
+#include <cntfrm.hxx>
 #include <flddropdown.hxx>
 #include <strings.hrc>
 #include <tox.hxx>
@@ -1129,7 +1131,19 @@ bool SwFieldMgr::InsertField(
                 }
                 nFormatId %= SAL_N_ELEMENTS(FMT_REF_ARY);
             }
-            pField.reset(new SwGetRefField(pTyp, rData.m_sPar1, 
sReferenceLanguage, nSubType, nSeqNo, nFormatId));
+
+            SwPaM* pCursor = nullptr;
+            SwPosition* pPos = nullptr;
+            SwTextNode* pTextNode = nullptr;
+            SwContentFrame* pFrame = nullptr;
+            if (nSubType == REF_STYLE) {
+                pCursor = pCurShell->GetCursor();
+                pPos = pCursor->GetPoint();
+                pTextNode = pPos->GetNode().GetTextNode();
+                pFrame = pCurShell->GetCurrFrame();
+            }
+
+            pField.reset(new SwGetRefField(pTyp, rData.m_sPar1, 
sReferenceLanguage, nSubType, nSeqNo, nFormatId, pTextNode, pFrame));
             bExp = true;
             break;
         }
diff --git a/sw/source/uibase/utlui/content.cxx 
b/sw/source/uibase/utlui/content.cxx
index 03d46e4a8cc2..504d17e79ea4 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -704,7 +704,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                     {
                         OUString sExpandedTextOfReferencedTextNode =
                                 pRefField->GetExpandedTextOfReferencedTextNode(
-                                    *m_pWrtShell->GetLayout());
+                                    *m_pWrtShell->GetLayout(), nullptr);
                         if (sExpandedTextOfReferencedTextNode.getLength() > 80)
                         {
                             sExpandedTextOfReferencedTextNode = 
OUString::Concat(
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 7c6c54182854..46caa8f5791d 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -5707,7 +5707,7 @@ static const FieldConversionMap_t & 
lcl_GetFieldConversion()
         {"SEQ",             {"SetExpression",           FIELD_SEQ           }},
         {"SET",             {"SetExpression",           FIELD_SET           }},
 //      {"SKIPIF",          {"",                        FIELD_SKIPIF        }},
-//      {"STYLEREF",        {"",                        FIELD_STYLEREF      }},
+        {"STYLEREF",        {"GetReference",            FIELD_STYLEREF      }},
         {"SUBJECT",         {"DocInfo.Subject",         FIELD_SUBJECT       }},
         {"SYMBOL",          {"",                        FIELD_SYMBOL        }},
         {"TEMPLATE",        {"TemplateName",            FIELD_TEMPLATE      }},
@@ -7373,9 +7373,11 @@ void DomainMapper_Impl::CloseFieldCommand()
                 break;
                 case FIELD_PAGEREF:
                 case FIELD_REF:
+                case FIELD_STYLEREF:
                 if (xFieldProperties.is() && !IsInTOC())
                 {
                     bool bPageRef = aIt->second.eFieldId == FIELD_PAGEREF;
+                    bool bStyleRef = aIt->second.eFieldId == FIELD_STYLEREF;
 
                     // Do we need a GetReference (default) or a GetExpression 
field?
                     uno::Reference< text::XTextFieldsSupplier > 
xFieldsSupplier( GetTextDocument(), uno::UNO_QUERY );
@@ -7385,12 +7387,50 @@ void DomainMapper_Impl::CloseFieldCommand()
                             "com.sun.star.text.FieldMaster.SetExpression."
                             + sFirstParam))
                     {
-                        xFieldProperties->setPropertyValue(
-                            getPropertyName(PROP_REFERENCE_FIELD_SOURCE),
-                            uno::Any( 
sal_Int16(text::ReferenceFieldSource::BOOKMARK)) );
-                        xFieldProperties->setPropertyValue(
-                            getPropertyName(PROP_SOURCE_NAME),
-                            uno::Any(sFirstParam) );
+                        if (bStyleRef)
+                        {
+                            xFieldProperties->setPropertyValue(
+                                getPropertyName(PROP_REFERENCE_FIELD_SOURCE),
+                                
uno::Any(sal_Int16(text::ReferenceFieldSource::STYLE)));
+
+                            OUString sStyleSheetName
+                                = 
GetStyleSheetTable()->ConvertStyleName(sFirstParam, true);
+
+                            uno::Any aStyleDisplayName;
+
+                            uno::Reference<style::XStyleFamiliesSupplier> 
xStylesSupplier(
+                                GetTextDocument(), uno::UNO_QUERY_THROW);
+                            uno::Reference<container::XNameAccess> 
xStyleFamilies
+                                = xStylesSupplier->getStyleFamilies();
+                            uno::Reference<container::XNameAccess> xStyles;
+                            
xStyleFamilies->getByName(getPropertyName(PROP_PARAGRAPH_STYLES))
+                                >>= xStyles;
+                            uno::Reference<css::beans::XPropertySet> xStyle;
+
+                            try
+                            {
+                                xStyles->getByName(sStyleSheetName) >>= xStyle;
+                                aStyleDisplayName = 
xStyle->getPropertyValue("DisplayName");
+                            }
+                            catch (css::container::NoSuchElementException)
+                            {
+                                aStyleDisplayName = uno::Any(sStyleSheetName);
+                            }
+
+                            xFieldProperties->setPropertyValue(
+                                getPropertyName(PROP_SOURCE_NAME), 
aStyleDisplayName);
+                        }
+                        else
+                        {
+                            xFieldProperties->setPropertyValue(
+                                getPropertyName(PROP_REFERENCE_FIELD_SOURCE),
+                                uno::Any( 
sal_Int16(text::ReferenceFieldSource::BOOKMARK)) );
+
+                            xFieldProperties->setPropertyValue(
+                                getPropertyName(PROP_SOURCE_NAME),
+                                uno::Any(sFirstParam));
+                        }
+
                         sal_Int16 nFieldPart = (bPageRef ? 
text::ReferenceFieldPart::PAGE : text::ReferenceFieldPart::TEXT);
                         OUString sValue;
                         if( lcl_FindInCommand( pContext->GetCommand(), 'p', 
sValue ))
@@ -7485,7 +7525,6 @@ void DomainMapper_Impl::CloseFieldCommand()
                     handleFieldSet(pContext, xFieldInterface, 
xFieldProperties);
                 break;
                 case FIELD_SKIPIF       : break;
-                case FIELD_STYLEREF     : break;
                 case FIELD_SUBJECT      :
                 {
                     if (!sFirstParam.isEmpty())
diff --git a/writerfilter/source/dmapper/FieldTypes.hxx 
b/writerfilter/source/dmapper/FieldTypes.hxx
index a907a7af6c22..144d1efe1370 100644
--- a/writerfilter/source/dmapper/FieldTypes.hxx
+++ b/writerfilter/source/dmapper/FieldTypes.hxx
@@ -209,8 +209,9 @@ enum FieldId
      */
     ,FIELD_SKIPIF
     /* STYLEREF stylename \* MERGEFORMAT ->
-     not imported in old ww8 filter
-     todo: add an equivalent field type
+     implemented using GetReference, but some switches are not implemented yet
+     \l isn't implemented
+     \t isn't implemented
      */
     ,FIELD_STYLEREF
     /* SUBJECT subject \* Defaultswitch \* MERGEFORMAT ->
diff --git a/xmloff/inc/txtflde.hxx b/xmloff/inc/txtflde.hxx
index 8670cac40cf6..459dea29f550 100644
--- a/xmloff/inc/txtflde.hxx
+++ b/xmloff/inc/txtflde.hxx
@@ -119,6 +119,7 @@ enum FieldIdEnum {
     FIELD_ID_REF_BOOKMARK,          // get reference field (bookmark)
     FIELD_ID_REF_FOOTNOTE,          // get reference field (footnote)
     FIELD_ID_REF_ENDNOTE,           // get reference field (endnote)
+    FIELD_ID_REF_STYLE,             // styleref field
     FIELD_ID_DDE,                   // DDE field
 
     FIELD_ID_BIBLIOGRAPHY,          // bibliography index entry
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 806d3a6e74e8..6c0eb58b9ef7 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -1911,6 +1911,7 @@ namespace xmloff::token {
         TOKEN( "structure-protected",             XML_STRUCTURE_PROTECTED ),
         TOKEN( "style",                           XML_STYLE ),
         TOKEN( "style-name",                      XML_STYLE_NAME ),
+        TOKEN( "style-ref",                       XML_STYLE_REF ),
         TOKEN( "styles",                          XML_STYLES ),
         TOKEN( "stylesheet",                      XML_STYLESHEET ),
         TOKEN( "sub-table",                       XML_SUB_TABLE ),
diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx
index 853df896f8c0..d27cb0e2f6a7 100644
--- a/xmloff/source/text/txtflde.cxx
+++ b/xmloff/source/text/txtflde.cxx
@@ -564,6 +564,9 @@ enum FieldIdEnum XMLTextFieldExport::MapFieldName(
                 case ReferenceFieldSource::ENDNOTE:
                     nToken = FIELD_ID_REF_ENDNOTE;
                     break;
+                case ReferenceFieldSource::STYLE:
+                    nToken = FIELD_ID_REF_STYLE;
+                    break;
                 default:
                     nToken = FIELD_ID_UNKNOWN;
                     break;
@@ -704,6 +707,7 @@ bool XMLTextFieldExport::IsStringField(
     case FIELD_ID_REF_BOOKMARK:
     case FIELD_ID_REF_FOOTNOTE:
     case FIELD_ID_REF_ENDNOTE:
+    case FIELD_ID_REF_STYLE:
     case FIELD_ID_MACRO:
     case FIELD_ID_TEMPLATE_NAME:
     case FIELD_ID_CHAPTER:
@@ -915,6 +919,7 @@ void XMLTextFieldExport::ExportFieldAutoStyle(
     case FIELD_ID_REF_BOOKMARK:
     case FIELD_ID_REF_FOOTNOTE:
     case FIELD_ID_REF_ENDNOTE:
+    case FIELD_ID_REF_STYLE:
     case FIELD_ID_MACRO:
     case FIELD_ID_REFPAGE_SET:
     case FIELD_ID_REFPAGE_GET:
@@ -1647,6 +1652,30 @@ void XMLTextFieldExport::ExportFieldHelper(
             sPresentation);
         break;
 
+    case FIELD_ID_REF_STYLE:
+    {
+        ProcessString(XML_REFERENCE_FORMAT,
+                      
MapReferenceType(GetInt16Property(gsPropertyReferenceFieldPart, rPropSet)),
+                      XML_TEMPLATE);
+        ProcessString(XML_REF_NAME, GetStringProperty(gsPropertySourceName, 
rPropSet));
+        if (xPropSetInfo->hasPropertyByName(gsPropertyReferenceFieldLanguage)
+            && GetExport().getSaneDefaultVersion() & 
SvtSaveOptions::ODFSVER_EXTENDED)
+        {
+            // export text:reference-language attribute, if not empty
+            ProcessString(XML_REFERENCE_LANGUAGE,
+                          GetStringProperty(gsPropertyReferenceFieldLanguage, 
rPropSet), true,
+                          XML_NAMESPACE_LO_EXT);
+        }
+        SvXMLElementExport aElem(
+            GetExport(),
+            XML_NAMESPACE_LO_EXT,
+            
MapReferenceSource(GetInt16Property(gsPropertyReferenceFieldSource, rPropSet)),
+            false,
+            false);
+        GetExport().Characters(sPresentation);
+        break;
+    }
+
     case FIELD_ID_DDE:
         // name from field master
          ProcessString(XML_CONNECTION_NAME,
@@ -3159,6 +3188,9 @@ enum XMLTokenEnum 
XMLTextFieldExport::MapReferenceSource(sal_Int16 nType)
         case ReferenceFieldSource::ENDNOTE:
             eElement = XML_NOTE_REF;
             break;
+        case ReferenceFieldSource::STYLE:
+            eElement = XML_STYLE_REF;
+            break;
         default:
             OSL_FAIL("unknown reference source");
             break;
diff --git a/xmloff/source/text/txtfldi.cxx b/xmloff/source/text/txtfldi.cxx
index 05d95281ef1b..d51d1fb06316 100644
--- a/xmloff/source/text/txtfldi.cxx
+++ b/xmloff/source/text/txtfldi.cxx
@@ -407,6 +407,7 @@ XMLTextFieldImportContext::CreateTextFieldImportContext(
         case XML_ELEMENT(TEXT, XML_BOOKMARK_REF):
         case XML_ELEMENT(TEXT, XML_NOTE_REF):
         case XML_ELEMENT(TEXT, XML_SEQUENCE_REF):
+        case XML_ELEMENT(TEXT, XML_STYLE_REF):
             pContext = new XMLReferenceFieldImportContext( rImport, rHlp, 
nToken );
             break;
 
@@ -2509,6 +2510,9 @@ void XMLReferenceFieldImportContext::startFastElement(
         case XML_ELEMENT(TEXT, XML_SEQUENCE_REF):
             nSource = ReferenceFieldSource::SEQUENCE_FIELD;
             break;
+        case XML_ELEMENT(TEXT, XML_STYLE_REF):
+            nSource = ReferenceFieldSource::STYLE;
+            break;
         default:
             XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElementToken);
             bTypeOK = false;
@@ -2577,6 +2581,7 @@ void XMLReferenceFieldImportContext::PrepareField(
     {
         case XML_ELEMENT(TEXT, XML_REFERENCE_REF):
         case XML_ELEMENT(TEXT, XML_BOOKMARK_REF):
+        case XML_ELEMENT(LO_EXT, XML_STYLE_REF):
             xPropertySet->setPropertyValue("SourceName", Any(sName));
             break;
 
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index acbdd629d225..50ef5d17f461 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -1811,6 +1811,7 @@ stroke-width
 structure-protected
 style
 style-name
+style-ref
 styles
 stylesheet
 sub-table

Reply via email to