sw/inc/dbfld.hxx                             |   10 -
 sw/inc/docufld.hxx                           |   18 +-
 sw/inc/expfld.hxx                            |   16 +-
 sw/inc/fldbas.hxx                            |    6 
 sw/inc/flddat.hxx                            |    4 
 sw/inc/reffld.hxx                            |    4 
 sw/inc/usrfld.hxx                            |    4 
 sw/qa/extras/uiwriter/uiwriter8.cxx          |   18 +-
 sw/source/core/access/accpara.cxx            |   20 +-
 sw/source/core/doc/DocumentFieldsManager.cxx |  200 +++++++++++++--------------
 sw/source/core/doc/docfld.cxx                |    9 -
 sw/source/core/fields/dbfld.cxx              |    4 
 sw/source/core/fields/docufld.cxx            |    4 
 sw/source/core/fields/fldbas.cxx             |  142 ++++++++++++++++---
 sw/source/core/txtnode/atrfld.cxx            |    2 
 sw/source/core/unocore/unofield.cxx          |   41 +++--
 sw/source/filter/html/htmlfldw.cxx           |   20 +-
 sw/source/filter/ww8/docxattributeoutput.cxx |   13 -
 sw/source/filter/ww8/rtfattributeoutput.cxx  |    4 
 sw/source/filter/ww8/ww8atr.cxx              |  124 ++++++++--------
 sw/source/filter/ww8/ww8par.cxx              |   14 +
 sw/source/ui/dbui/dbinsdlg.cxx               |    4 
 sw/source/ui/fldui/flddb.cxx                 |    8 -
 sw/source/ui/fldui/flddinf.cxx               |    8 -
 sw/source/ui/fldui/flddok.cxx                |    6 
 sw/source/ui/fldui/fldedt.cxx                |    9 -
 sw/source/ui/fldui/fldpage.cxx               |    6 
 sw/source/ui/fldui/fldref.cxx                |   22 --
 sw/source/ui/fldui/fldvar.cxx                |   11 +
 sw/source/uibase/docvw/edtwin2.cxx           |   28 +++
 sw/source/uibase/fldui/fldmgr.cxx            |   13 -
 sw/source/uibase/utlui/content.cxx           |    7 
 32 files changed, 477 insertions(+), 322 deletions(-)

New commits:
commit 9257e94e5d1b6b29aaadef42ffad6888fb77df6b
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Sat Jul 5 16:35:17 2025 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Mon Jul 7 21:10:47 2025 +0200

    move m_nSubType field in SwField down to subclasses
    
    because it is really different types depending which subclass
    it belongs to.
    Here I do not try to apply correct types to all of the fields
    that are created in the subclasses, only a couple of the
    obvious ones.
    Unfortunately, some of the code is just too awkward to
    fully re-structure, so I add some SwField::GetUntypedSubtype()
    method to allow some code to get/set untyped format values.
    
    Change-Id: I7f03d8de91606116f152ead64a28aa50d09e896b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187490
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sw/inc/dbfld.hxx b/sw/inc/dbfld.hxx
index 42e96d29f9b4..04f4a2783372 100644
--- a/sw/inc/dbfld.hxx
+++ b/sw/inc/dbfld.hxx
@@ -66,7 +66,7 @@ class SW_DLLPUBLIC SwDBField final : public SwValueField
     virtual std::unique_ptr<SwField> Copy() const override;
 
 public:
-    SwDBField(SwDBFieldType*, sal_uInt32 nFormat = 0);
+    SwDBField(SwDBFieldType*, sal_uInt32 nFormat = 0, sal_uInt16 nSubType = 0);
     virtual ~SwDBField() override;
 
     virtual SwFieldType*    ChgTyp( SwFieldType* ) override;
@@ -74,8 +74,8 @@ public:
     /// Current text.
     inline  void        SetExpansion(const OUString& rStr);
 
-    virtual sal_uInt16      GetSubType() const override;
-    virtual void        SetSubType(sal_uInt16 nType) override;
+    sal_uInt16 GetSubType() const;
+    void SetSubType(sal_uInt16 nType);
 
     virtual OUString    GetFieldName() const override;
 
@@ -145,8 +145,8 @@ public:
 
     virtual bool            QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich 
) const override;
     virtual bool            PutValue( const css::uno::Any& rVal, sal_uInt16 
nWhich ) override;
-    virtual sal_uInt16      GetSubType() const override;
-    virtual void            SetSubType(sal_uInt16 nType) override;
+    sal_uInt16              GetSubType() const;
+    void                    SetSubType(sal_uInt16 nType);
 };
 
 // Database field next record.
diff --git a/sw/inc/docufld.hxx b/sw/inc/docufld.hxx
index 417ad4adcad1..5506ee45e0cd 100644
--- a/sw/inc/docufld.hxx
+++ b/sw/inc/docufld.hxx
@@ -178,7 +178,8 @@ public:
     virtual OUString GetPar2() const override;
     virtual void        SetPar2(const OUString& rStr) override;
 
-    virtual sal_uInt16  GetSubType() const override;
+    sal_uInt16          GetSubType() const;
+    void                SetSubType(sal_uInt16 n) { m_nSubType = n; }
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) 
const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich 
) override;
 
@@ -302,8 +303,8 @@ public:
     virtual OUString    ExpandImpl(SwRootFrame const* pLayout) const override;
     virtual std::unique_ptr<SwField> Copy() const override;
 
-    virtual sal_uInt16      GetSubType() const override;
-    virtual void        SetSubType(sal_uInt16 nSub) override;
+    sal_uInt16          GetSubType() const;
+    void                SetSubType(sal_uInt16 nSub);
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) 
const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich 
) override;
 };
@@ -367,7 +368,8 @@ public:
     virtual void        SetPar2(const OUString& rStr) override;
     virtual OUString    GetPar2() const override;
 
-    virtual sal_uInt16  GetSubType() const override;
+    SwFieldTypesEnum    GetSubType() const;
+    void SetSubType(SwFieldTypesEnum n) { m_nSubType = n; }
 
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) 
const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich 
) override;
@@ -582,8 +584,8 @@ public:
     SwDocInfoField(SwDocInfoFieldType*, sal_uInt16 nSub, const OUString& 
rName, sal_uInt32 nFormat=0);
     SwDocInfoField(SwDocInfoFieldType*, sal_uInt16 nSub, const OUString& 
rName, const OUString& rValue, sal_uInt32 nFormat=0);
 
-    virtual void            SetSubType(sal_uInt16) override;
-    virtual sal_uInt16      GetSubType() const override;
+    void                    SetSubType(sal_uInt16);
+    sal_uInt16              GetSubType() const;
     virtual void            SetLanguage(LanguageType nLng) override;
     virtual OUString        GetFieldName() const override;
     const OUString&         GetName() const { return m_aName; }
@@ -618,8 +620,8 @@ public:
     virtual OUString    ExpandImpl(SwRootFrame const* pLayout) const override;
     virtual std::unique_ptr<SwField> Copy() const override;
 
-    virtual sal_uInt16      GetSubType() const override;
-    virtual void        SetSubType(sal_uInt16 nSub) override;
+    SW_DLLPUBLIC sal_uInt16 GetSubType() const;
+    void SetSubType(sal_uInt16 nSub);
 
     void         SetExpansion(const OUString& rStr) { m_aContent = rStr; }
 
diff --git a/sw/inc/expfld.hxx b/sw/inc/expfld.hxx
index 5560b176e93b..917374888aa3 100644
--- a/sw/inc/expfld.hxx
+++ b/sw/inc/expfld.hxx
@@ -124,8 +124,8 @@ public:
     virtual OUString GetPar2() const override;
     virtual void        SetPar2(const OUString& rStr) override;
 
-    virtual sal_uInt16  GetSubType() const override;
-    virtual void        SetSubType(sal_uInt16 nType) override;
+    sal_uInt16          GetSubType() const;
+    void                SetSubType(sal_uInt16 nType);
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) 
const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich 
) override;
 
@@ -237,8 +237,8 @@ public:
 
     virtual OUString            GetFieldName() const override;
 
-    virtual sal_uInt16              GetSubType() const override;
-    virtual void                SetSubType(sal_uInt16 nType) override;
+    sal_uInt16                  GetSubType() const;
+    void                        SetSubType(sal_uInt16 nType);
 
     inline bool                 IsSequenceField() const;
 
@@ -336,8 +336,8 @@ public:
     const OUString&         GetToolTip() const;
     void                    SetToolTip(const OUString & rStr);
 
-    virtual sal_uInt16      GetSubType() const override;
-    virtual void            SetSubType(sal_uInt16 nSub) override;
+    sal_uInt16          GetSubType() const;
+    void                SetSubType(sal_uInt16 nSub);
     virtual bool        QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) 
const override;
     virtual bool        PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich 
) override;
 };
@@ -394,8 +394,8 @@ public:
                 sal_uInt16 nSubType, sal_uLong nFormat);
 
     virtual void        SetValue( const double& rVal ) override;
-    virtual sal_uInt16  GetSubType() const override;
-    virtual void        SetSubType(sal_uInt16 nType) override;
+    sal_uInt16          GetSubType() const;
+    void                SetSubType(sal_uInt16 nType);
 
     void                ChgExpStr(const OUString& rStr) { m_sExpand = rStr; }
 
diff --git a/sw/inc/fldbas.hxx b/sw/inc/fldbas.hxx
index 447c36cf4bc8..cc3ee5321a3b 100644
--- a/sw/inc/fldbas.hxx
+++ b/sw/inc/fldbas.hxx
@@ -318,8 +318,10 @@ public:
 
     // TYP_ID
     SwFieldTypesEnum    GetTypeId() const;
-    virtual sal_uInt16      GetSubType() const;
-    virtual void        SetSubType(sal_uInt16);
+
+    // for code that is still passing around untyped values
+    sal_uInt16 GetUntypedSubType() const;
+    void SetUntypedSubType(sal_uInt16);
 
     /// Language at field position.
     inline LanguageType GetLanguage() const;
diff --git a/sw/inc/flddat.hxx b/sw/inc/flddat.hxx
index 39c00f68a235..4b8cafdb4056 100644
--- a/sw/inc/flddat.hxx
+++ b/sw/inc/flddat.hxx
@@ -54,8 +54,8 @@ public:
         SwDateTimeField(SwDateTimeFieldType* pType, sal_uInt16 nSubType = 
DATEFLD,
                     sal_uLong nFormat = 0, LanguageType nLng = 
LANGUAGE_SYSTEM);
 
-        virtual sal_uInt16      GetSubType() const override;
-        virtual void            SetSubType(sal_uInt16 nSub) override;
+        sal_uInt16              GetSubType() const;
+        void                    SetSubType(sal_uInt16 nSub);
 
         virtual double          GetValue() const override;
 
diff --git a/sw/inc/reffld.hxx b/sw/inc/reffld.hxx
index 8b93239bc52c..601adc4d8555 100644
--- a/sw/inc/reffld.hxx
+++ b/sw/inc/reffld.hxx
@@ -160,8 +160,8 @@ public:
     void                SetExpand( const OUString& rStr );
 
     /// Get/set sub type.
-    virtual sal_uInt16      GetSubType() const override;
-    SW_DLLPUBLIC virtual void SetSubType( sal_uInt16 n ) override;
+    SW_DLLPUBLIC sal_uInt16 GetSubType() const;
+    SW_DLLPUBLIC void SetSubType( sal_uInt16 n );
 
     // --> #i81002#
     SW_DLLPUBLIC bool IsRefToHeadingCrossRefBookmark() const;
diff --git a/sw/inc/usrfld.hxx b/sw/inc/usrfld.hxx
index b389af3c1bd9..be213de2276c 100644
--- a/sw/inc/usrfld.hxx
+++ b/sw/inc/usrfld.hxx
@@ -112,8 +112,8 @@ class SW_DLLPUBLIC SwUserField final : public SwValueField
 public:
     SwUserField(SwUserFieldType*, sal_uInt16 nSub, sal_uInt32 nFormat);
 
-    virtual sal_uInt16      GetSubType() const override;
-    virtual void            SetSubType(sal_uInt16 nSub) override;
+    sal_uInt16              GetSubType() const;
+    void                    SetSubType(sal_uInt16 nSub);
 
     virtual double          GetValue() const override;
     virtual void            SetValue( const double& rVal ) override;
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx 
b/sw/qa/extras/uiwriter/uiwriter8.cxx
index 1214cc920117..653e9c1b5431 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -2845,36 +2845,42 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf128106)
         CPPUNIT_ASSERT(pA == pB || &pHintA->GetTextNode() != 
&pHintB->GetTextNode());
         return pHintA->GetTextNode().GetIndex() < 
pHintB->GetTextNode().GetIndex();
     });
-    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), 
fields[0]->GetField()->GetSubType());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK),
+                         
static_cast<SwGetRefField*>(fields[0]->GetField())->GetSubType());
     CPPUNIT_ASSERT_EQUAL(
         u"bookmarkchapter1_text"_ustr,
         static_cast<SwGetRefField 
const*>(fields[0]->GetField())->GetSetRefName().toString());
     CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
                          static_cast<SwGetRefField 
const*>(fields[0]->GetField())
                              
->GetExpandedTextOfReferencedTextNode(*pWrtShell->GetLayout()));
-    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), 
fields[1]->GetField()->GetSubType());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK),
+                         
static_cast<SwGetRefField*>(fields[1]->GetField())->GetSubType());
     CPPUNIT_ASSERT(
         static_cast<SwGetRefField 
const*>(fields[1]->GetField())->IsRefToHeadingCrossRefBookmark());
     CPPUNIT_ASSERT_EQUAL(u"Chapter 2"_ustr,
                          static_cast<SwGetRefField 
const*>(fields[1]->GetField())->GetPar2());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), 
fields[2]->GetField()->GetSubType());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK),
+                         
static_cast<SwGetRefField*>(fields[2]->GetField())->GetSubType());
     CPPUNIT_ASSERT_EQUAL(
         u"Bookmarkchapter1"_ustr,
         static_cast<SwGetRefField 
const*>(fields[2]->GetField())->GetSetRefName().toString());
     CPPUNIT_ASSERT_EQUAL(u"Chapter 1"_ustr,
                          static_cast<SwGetRefField 
const*>(fields[2]->GetField())->GetPar2());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), 
fields[3]->GetField()->GetSubType());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK),
+                         
static_cast<SwGetRefField*>(fields[3]->GetField())->GetSubType());
     CPPUNIT_ASSERT_EQUAL(
         u"bookmarkchapter1_text"_ustr,
         static_cast<SwGetRefField 
const*>(fields[3]->GetField())->GetSetRefName().toString());
     CPPUNIT_ASSERT_EQUAL(u"Text"_ustr,
                          static_cast<SwGetRefField 
const*>(fields[3]->GetField())->GetPar2());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), 
fields[4]->GetField()->GetSubType());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK),
+                         
static_cast<SwGetRefField*>(fields[4]->GetField())->GetSubType());
     CPPUNIT_ASSERT(
         static_cast<SwGetRefField 
const*>(fields[4]->GetField())->IsRefToHeadingCrossRefBookmark());
     CPPUNIT_ASSERT_EQUAL(u"Chapter 1.1"_ustr,
                          static_cast<SwGetRefField 
const*>(fields[4]->GetField())->GetPar2());
-    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK), 
fields[5]->GetField()->GetSubType());
+    CPPUNIT_ASSERT_EQUAL(sal_uInt16(REF_BOOKMARK),
+                         
static_cast<SwGetRefField*>(fields[5]->GetField())->GetSubType());
     CPPUNIT_ASSERT(
         static_cast<SwGetRefField 
const*>(fields[5]->GetField())->IsRefToHeadingCrossRefBookmark());
     CPPUNIT_ASSERT_EQUAL(u"Chapter 2"_ustr,
diff --git a/sw/source/core/access/accpara.cxx 
b/sw/source/core/access/accpara.cxx
index c507fc2d4a0e..97374ab8f562 100644
--- a/sw/source/core/access/accpara.cxx
+++ b/sw/source/core/access/accpara.cxx
@@ -1027,14 +1027,14 @@ OUString 
SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
         break;
     case SwFieldIds::GetRef:
         {
-            switch( pField->GetSubType() )
+            const SwGetRefField* pRefField = static_cast<const 
SwGetRefField*>(pField);
+            switch( pRefField->GetSubType() )
             {
             case REF_BOOKMARK:
                 {
-                    const SwGetRefField* pRefField = dynamic_cast<const 
SwGetRefField*>(pField);
-                    if ( pRefField && 
pRefField->IsRefToHeadingCrossRefBookmark() )
+                    if (  pRefField->IsRefToHeadingCrossRefBookmark() )
                         sEntry = "Headings";
-                    else if ( pRefField && 
pRefField->IsRefToNumItemCrossRefBookmark() )
+                    else if (  pRefField->IsRefToNumItemCrossRefBookmark() )
                         sEntry = "Numbered Paragraphs";
                     else
                         sEntry = "Bookmarks";
@@ -1050,7 +1050,7 @@ OUString 
SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
                 sEntry = "Insert Reference";
                 break;
             case REF_SEQUENCEFLD:
-                sEntry = static_cast<const 
SwGetRefField*>(pField)->GetSetRefName().toString();
+                sEntry = pRefField->GetSetRefName().toString();
                 break;
             case REF_STYLE:
                 sEntry = "StyleRef";
@@ -1100,8 +1100,11 @@ OUString 
SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
         }
         break;
     case SwFieldIds::DocInfo:
-        subType = pField->GetSubType();
-        subType &= 0x00ff;
+        {
+            const SwDocInfoField* pDocInfoField = static_cast<const 
SwDocInfoField*>(pField);
+            subType = pDocInfoField->GetSubType();
+            subType &= 0x00ff;
+        }
         break;
     case SwFieldIds::RefPageSet:
         {
@@ -1135,7 +1138,8 @@ OUString 
SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
             {
                 strTypeName = sEntry;
                 sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), 
false);
-                const sal_uInt16 nExSub = pField->GetSubType() & 0xff00;
+                auto pDocInfoField = static_cast<const 
SwDocInfoField*>(pField);
+                const sal_uInt16 nExSub = pDocInfoField->GetSubType() & 0xff00;
                 if (nSize > 0 && nExSub > 0)
                 {
                     //Get extra subtype string
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx 
b/sw/source/core/doc/DocumentFieldsManager.cxx
index e2c2abefc2a0..3ac7341378f3 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -133,12 +133,13 @@ namespace
 
         if( SwFieldIds::SetExp == nFieldWhich )
         {
+            auto pSetExpField = static_cast<const SwSetExpField*>(pField);
             SwSbxValue aValue;
-            if( nsSwGetSetExpType::GSE_EXPR & pField->GetSubType() )
-                aValue.PutDouble( static_cast<const 
SwSetExpField*>(pField)->GetValue(pLayout) );
+            if( nsSwGetSetExpType::GSE_EXPR & pSetExpField->GetSubType() )
+                aValue.PutDouble( pSetExpField->GetValue(pLayout) );
             else
                 // Extension to calculate with Strings
-                aValue.PutString( static_cast<const 
SwSetExpField*>(pField)->GetExpStr(pLayout) );
+                aValue.PutString( pSetExpField->GetExpStr(pLayout) );
 
             // set the new value in Calculator
             rCalc.VarChange( pField->GetTyp()->GetName().toString(), aValue );
@@ -1066,108 +1067,101 @@ void DocumentFieldsManager::UpdateExpFieldsImpl(
         }
         break;
         case SwFieldIds::GetExp:
-        case SwFieldIds::SetExp:
         {
-            if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )        
// replace String
+            SwGetExpField* pGField = 
const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
+            if( nsSwGetSetExpType::GSE_STRING & pGField->GetSubType() )        
// replace String
             {
-                if( SwFieldIds::GetExp == nWhich )
+                if( (!pUpdateField || pUpdateField == pTextField )
+                    && pGField->IsInBodyText() )
                 {
-                    SwGetExpField* pGField = 
const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
-
-                    if( (!pUpdateField || pUpdateField == pTextField )
-                        && pGField->IsInBodyText() )
-                    {
-                        OUString aNew = LookString( aHashStrTable, 
pGField->GetFormula() );
-                        pGField->ChgExpStr( aNew, pLayout );
-                    }
+                    OUString aNew = LookString( aHashStrTable, 
pGField->GetFormula() );
+                    pGField->ChgExpStr( aNew, pLayout );
                 }
-                else
+            }
+            else            // recalculate formula
+            {
+                if( (!pUpdateField || pUpdateField == pTextField )
+                    && pGField->IsInBodyText() )
                 {
-                    SwSetExpField* pSField = 
const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
-                    // is the "formula" a field?
-                    OUString aNew = LookString( aHashStrTable, 
pSField->GetFormula() );
+                    SwSbxValue aValue = aCalc.Calculate(
+                                    pGField->GetFormula());
+                    if(!aValue.IsVoidValue())
+                        pGField->SetValue(aValue.GetDouble(), pLayout);
+                }
+            }
+        }
+        break;
+        case SwFieldIds::SetExp:
+        {
+            SwSetExpField* pSField = 
const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
+            if( nsSwGetSetExpType::GSE_STRING & pSField->GetSubType() )        
// replace String
+            {
+                // is the "formula" a field?
+                OUString aNew = LookString( aHashStrTable, 
pSField->GetFormula() );
 
-                    if( aNew.isEmpty() )               // nothing found then 
the formula is the new value
-                        aNew = pSField->GetFormula();
+                if( aNew.isEmpty() )               // nothing found then the 
formula is the new value
+                    aNew = pSField->GetFormula();
 
-                    // only update one field
-                    if( !pUpdateField || pUpdateField == pTextField )
-                        pSField->ChgExpStr( aNew, pLayout );
+                // only update one field
+                if( !pUpdateField || pUpdateField == pTextField )
+                    pSField->ChgExpStr( aNew, pLayout );
 
-                    // lookup the field's name
-                    aNew = 
static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName().toString();
-                    // Entry present?
-                    auto pFnd = aHashStrTable.find( aNew );
-                    if( pFnd != aHashStrTable.end() )
-                        // Modify entry in the hash table
-                        pFnd->second = pSField->GetExpStr(pLayout);
-                    else
-                        // insert new entry
-                        pFnd = aHashStrTable.insert( { aNew, 
pSField->GetExpStr(pLayout) } ).first;
+                // lookup the field's name
+                aNew = 
static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName().toString();
+                // Entry present?
+                auto pFnd = aHashStrTable.find( aNew );
+                if( pFnd != aHashStrTable.end() )
+                    // Modify entry in the hash table
+                    pFnd->second = pSField->GetExpStr(pLayout);
+                else
+                    // insert new entry
+                    pFnd = aHashStrTable.insert( { aNew, 
pSField->GetExpStr(pLayout) } ).first;
 
-                    // Extension for calculation with Strings
-                    SwSbxValue aValue;
-                    aValue.PutString( pFnd->second );
-                    aCalc.VarChange( aNew, aValue );
-                }
+                // Extension for calculation with Strings
+                SwSbxValue aValue;
+                aValue.PutString( pFnd->second );
+                aCalc.VarChange( aNew, aValue );
             }
             else            // recalculate formula
             {
-                if( SwFieldIds::GetExp == nWhich )
-                {
-                    SwGetExpField* pGField = 
const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
+                SwSetExpFieldType* pSFieldTyp = 
static_cast<SwSetExpFieldType*>(pField->GetTyp());
+                OUString aNew = pSFieldTyp->GetName().toString();
 
-                    if( (!pUpdateField || pUpdateField == pTextField )
-                        && pGField->IsInBodyText() )
-                    {
-                        SwSbxValue aValue = aCalc.Calculate(
-                                        pGField->GetFormula());
-                        if(!aValue.IsVoidValue())
-                            pGField->SetValue(aValue.GetDouble(), pLayout);
-                    }
-                }
-                else
-                {
-                    SwSetExpField* pSField = 
const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
-                    SwSetExpFieldType* pSFieldTyp = 
static_cast<SwSetExpFieldType*>(pField->GetTyp());
-                    OUString aNew = pSFieldTyp->GetName().toString();
-
-                    SwNode* pSeqNd = nullptr;
+                SwNode* pSeqNd = nullptr;
 
-                    if( pSField->IsSequenceField() )
+                if( pSField->IsSequenceField() )
+                {
+                    const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
+                    if( MAXLEVEL > nLvl )
                     {
-                        const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
-                        if( MAXLEVEL > nLvl )
+                        // test if the Number needs to be updated
+                        pSeqNd = m_rDoc.GetNodes()[ it->GetNode() ];
+
+                        const SwTextNode* pOutlNd = pSeqNd->
+                                FindOutlineNodeOfLevel(nLvl, pLayout);
+                        auto const iter(SetExpOutlineNodeMap.find(pSFieldTyp));
+                        if (iter == SetExpOutlineNodeMap.end()
+                            || iter->second != pOutlNd)
                         {
-                            // test if the Number needs to be updated
-                            pSeqNd = m_rDoc.GetNodes()[ it->GetNode() ];
-
-                            const SwTextNode* pOutlNd = pSeqNd->
-                                    FindOutlineNodeOfLevel(nLvl, pLayout);
-                            auto const 
iter(SetExpOutlineNodeMap.find(pSFieldTyp));
-                            if (iter == SetExpOutlineNodeMap.end()
-                                || iter->second != pOutlNd)
-                            {
-                                SetExpOutlineNodeMap[pSFieldTyp] = pOutlNd;
-                                aCalc.VarChange( aNew, 0 );
-                            }
+                            SetExpOutlineNodeMap[pSFieldTyp] = pOutlNd;
+                            aCalc.VarChange( aNew, 0 );
                         }
                     }
+                }
 
-                    aNew += "=" + pSField->GetFormula();
+                aNew += "=" + pSField->GetFormula();
 
-                    SwSbxValue aValue = aCalc.Calculate( aNew );
-                    if (!aCalc.IsCalcError())
+                SwSbxValue aValue = aCalc.Calculate( aNew );
+                if (!aCalc.IsCalcError())
+                {
+                    double nErg = aValue.GetDouble();
+                    // only update one field
+                    if( !aValue.IsVoidValue() && (!pUpdateField || 
pUpdateField == pTextField) )
                     {
-                        double nErg = aValue.GetDouble();
-                        // only update one field
-                        if( !aValue.IsVoidValue() && (!pUpdateField || 
pUpdateField == pTextField) )
-                        {
-                            pSField->SetValue(nErg, pLayout);
+                        pSField->SetValue(nErg, pLayout);
 
-                            if( pSeqNd )
-                                pSFieldTyp->SetChapter(*pSField, *pSeqNd, 
pLayout);
-                        }
+                        if( pSeqNd )
+                            pSFieldTyp->SetChapter(*pSField, *pSeqNd, pLayout);
                     }
                 }
             }
@@ -1585,30 +1579,32 @@ void DocumentFieldsManager::FieldsToExpand( 
std::unordered_map<OUString, OUStrin
         switch( pField->GetTyp()->Which() )
         {
         case SwFieldIds::SetExp:
-            if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )
             {
-                // set the new value in the hash table
-                // is the formula a field?
                 SwSetExpField* pSField = 
const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
-                OUString aNew = LookString( rHashTable, pSField->GetFormula() 
);
+                if( nsSwGetSetExpType::GSE_STRING & pSField->GetSubType() )
+                {
+                    // set the new value in the hash table
+                    // is the formula a field?
+                    OUString aNew = LookString( rHashTable, 
pSField->GetFormula() );
 
-                if( aNew.isEmpty() )               // nothing found, then the 
formula is
-                    aNew = pSField->GetFormula(); // the new value
+                    if( aNew.isEmpty() )               // nothing found, then 
the formula is
+                        aNew = pSField->GetFormula(); // the new value
 
-                // #i3141# - update expression of field as in method
-                // <SwDoc::UpdateExpFields(..)> for string/text fields
-                pSField->ChgExpStr(aNew, &rLayout);
+                    // #i3141# - update expression of field as in method
+                    // <SwDoc::UpdateExpFields(..)> for string/text fields
+                    pSField->ChgExpStr(aNew, &rLayout);
 
-                // look up the field's name
-                aNew = 
static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName().toString();
-                // Entry present?
-                auto pFnd = rHashTable.find( aNew );
-                if( pFnd != rHashTable.end() )
-                    // modify entry in the hash table
-                    pFnd->second = pSField->GetExpStr(&rLayout);
-                else
-                    // insert the new entry
-                    rHashTable.insert( { aNew, pSField->GetExpStr(&rLayout) } 
);
+                    // look up the field's name
+                    aNew = 
static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName().toString();
+                    // Entry present?
+                    auto pFnd = rHashTable.find( aNew );
+                    if( pFnd != rHashTable.end() )
+                        // modify entry in the hash table
+                        pFnd->second = pSField->GetExpStr(&rLayout);
+                    else
+                        // insert the new entry
+                        rHashTable.insert( { aNew, 
pSField->GetExpStr(&rLayout) } );
+                }
             }
             break;
         case SwFieldIds::Database:
diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index 54e28f79b297..094c66bfbbda 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -923,10 +923,13 @@ void SwDocUpdateField::MakeFieldList_( SwDoc& rDoc, int 
eGetMode )
                         break;
 
                     case SwFieldIds::SetExp:
-                        if ((eGetMode != GETFLD_EXPAND) ||
-                            (nsSwGetSetExpType::GSE_STRING & 
pField->GetSubType()))
                         {
-                            sFormula = sTrue;
+                            auto pSetExpField = static_cast<const 
SwSetExpField*>(pField);
+                            if ((eGetMode != GETFLD_EXPAND) ||
+                                (nsSwGetSetExpType::GSE_STRING & 
pSetExpField->GetSubType()))
+                            {
+                                sFormula = sTrue;
+                            }
                         }
                         break;
 
diff --git a/sw/source/core/fields/dbfld.cxx b/sw/source/core/fields/dbfld.cxx
index 5bb47e2a7d89..f730628e6701 100644
--- a/sw/source/core/fields/dbfld.cxx
+++ b/sw/source/core/fields/dbfld.cxx
@@ -157,9 +157,9 @@ void SwDBFieldType::PutValue( const uno::Any& rAny, 
sal_uInt16 nWhichId )
 
 // database field
 
-SwDBField::SwDBField(SwDBFieldType* pTyp, sal_uInt32 nFormat)
+SwDBField::SwDBField(SwDBFieldType* pTyp, sal_uInt32 nFormat, sal_uInt16 
nSubType)
     :   SwValueField(pTyp, nFormat),
-        m_nSubType(0),
+        m_nSubType(nSubType),
         m_bIsInBodyText(true),
         m_bValidValue(false),
         m_bInitialized(false)
diff --git a/sw/source/core/fields/docufld.cxx 
b/sw/source/core/fields/docufld.cxx
index 8714545e8419..873702dcc60a 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -1516,9 +1516,9 @@ OUString SwHiddenTextField::GetPar2() const
     return m_aTRUEText + "|" + m_aFALSEText;
 }
 
-sal_uInt16 SwHiddenTextField::GetSubType() const
+SwFieldTypesEnum SwHiddenTextField::GetSubType() const
 {
-    return static_cast<sal_uInt16>(m_nSubType);
+    return m_nSubType;
 }
 
 bool SwHiddenTextField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index adc7328e9c64..c98f95886d18 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -46,6 +46,8 @@
 #include <unofield.hxx>
 #include <dbfld.hxx>
 #include <chpfld.hxx>
+#include <flddat.hxx>
+#include <usrfld.hxx>
 
 using namespace ::com::sun::star;
 using namespace nsSwDocInfoSubType;
@@ -266,31 +268,45 @@ SwFieldTypesEnum SwField::GetTypeId() const
     switch (m_pType->Which())
     {
     case SwFieldIds::DateTime:
-        if (GetSubType() & FIXEDFLD)
-            nRet = GetSubType() & DATEFLD ? SwFieldTypesEnum::FixedDate : 
SwFieldTypesEnum::FixedTime;
-        else
-            nRet = GetSubType() & DATEFLD ? SwFieldTypesEnum::Date : 
SwFieldTypesEnum::Time;
+        {
+            auto pDateTimeField = static_cast<const SwDateTimeField*>(this);
+            sal_uInt16 nSubType = pDateTimeField->GetSubType();
+            if (nSubType & FIXEDFLD)
+                nRet = nSubType & DATEFLD ? SwFieldTypesEnum::FixedDate : 
SwFieldTypesEnum::FixedTime;
+            else
+                nRet = nSubType & DATEFLD ? SwFieldTypesEnum::Date : 
SwFieldTypesEnum::Time;
+        }
         break;
     case SwFieldIds::GetExp:
-        nRet = nsSwGetSetExpType::GSE_FORMULA & GetSubType() ? 
SwFieldTypesEnum::Formel : SwFieldTypesEnum::Get;
+        {
+            auto pGetExpField = static_cast<const SwGetExpField*>(this);
+            nRet = nsSwGetSetExpType::GSE_FORMULA & pGetExpField->GetSubType() 
? SwFieldTypesEnum::Formel : SwFieldTypesEnum::Get;
+        }
         break;
 
     case SwFieldIds::HiddenText:
-        nRet = static_cast<SwFieldTypesEnum>(GetSubType());
+        {
+            auto pHiddenTextField = static_cast<const 
SwHiddenTextField*>(this);
+            nRet = pHiddenTextField->GetSubType();
+        }
         break;
 
     case SwFieldIds::SetExp:
-        if( nsSwGetSetExpType::GSE_SEQ & GetSubType() )
-            nRet = SwFieldTypesEnum::Sequence;
-        else if( static_cast<const SwSetExpField*>(this)->GetInputFlag() )
-            nRet = SwFieldTypesEnum::SetInput;
-        else
-            nRet = SwFieldTypesEnum::Set;
+        {
+            auto pSetExpField = static_cast<const SwSetExpField*>(this);
+            if( nsSwGetSetExpType::GSE_SEQ & pSetExpField->GetSubType() )
+                nRet = SwFieldTypesEnum::Sequence;
+            else if( pSetExpField->GetInputFlag() )
+                nRet = SwFieldTypesEnum::SetInput;
+            else
+                nRet = SwFieldTypesEnum::Set;
+        }
         break;
 
     case SwFieldIds::PageNumber:
         {
-            auto nSubType = GetSubType();
+            auto pPageNumberField = static_cast<const 
SwPageNumberField*>(this);
+            auto nSubType = pPageNumberField->GetSubType();
             if( PG_NEXT == nSubType )
                 nRet = SwFieldTypesEnum::NextPage;
             else if( PG_PREV == nSubType )
@@ -312,8 +328,9 @@ OUString SwField::GetFieldName() const
     SwFieldTypesEnum nTypeId = GetTypeId();
     if (SwFieldIds::DateTime == GetTyp()->Which())
     {
+        auto pDateTimeField = static_cast<const SwDateTimeField*>(this);
         nTypeId =
-            ((GetSubType() & DATEFLD) != 0) ? SwFieldTypesEnum::Date : 
SwFieldTypesEnum::Time;
+            ((pDateTimeField->GetSubType() & DATEFLD) != 0) ? 
SwFieldTypesEnum::Date : SwFieldTypesEnum::Time;
     }
     OUString sRet = SwFieldType::GetTypeStr( nTypeId );
     if (IsFixed())
@@ -429,13 +446,100 @@ void SwField::SetPar1(const OUString& )
 void SwField::SetPar2(const OUString& )
 {}
 
-sal_uInt16 SwField::GetSubType() const
+// for code that is still passing around untyped values
+sal_uInt16 SwField::GetUntypedSubType() const
 {
+    switch (m_pType->Which())
+    {
+    case SwFieldIds::User:
+        return static_cast<const SwUserField*>(this)->GetSubType();
+    case SwFieldIds::GetRef:
+        return static_cast<const SwGetRefField*>(this)->GetSubType();
+    case SwFieldIds::DateTime:
+        return static_cast<const SwDateTimeField*>(this)->GetSubType();
+    case SwFieldIds::Table:
+        return static_cast<const SwTableField*>(this)->GetSubType();
+    case SwFieldIds::Input:
+        return static_cast<const SwInputField*>(this)->GetSubType();
+    case SwFieldIds::GetExp:
+        return static_cast<const SwGetExpField*>(this)->GetSubType();
+    case SwFieldIds::SetExp:
+        return static_cast<const SwSetExpField*>(this)->GetSubType();
+    case SwFieldIds::ExtUser:
+        return static_cast<sal_uInt32>(static_cast<const 
SwExtUserField*>(this)->GetSubType());
+    case SwFieldIds::DocInfo:
+        return static_cast<const SwDocInfoField*>(this)->GetSubType();
+    case SwFieldIds::HiddenText:
+        return static_cast<sal_uInt16>(static_cast<const 
SwHiddenTextField*>(this)->GetSubType());
+    case SwFieldIds::DocStat:
+        return static_cast<const SwDocStatField*>(this)->GetSubType();
+    case SwFieldIds::PageNumber:
+        return static_cast<const SwPageNumberField*>(this)->GetSubType();
+    case SwFieldIds::DbNextSet:
+    case SwFieldIds::DbNumSet:
+    case SwFieldIds::DatabaseName:
+    case SwFieldIds::DbSetNumber:
+        return static_cast<const SwDBNameInfField*>(this)->GetSubType();
+    case SwFieldIds::Database:
+        return static_cast<const SwDBField*>(this)->GetSubType();
+    default: break;
+    }
     return 0;
 }
 
-void SwField::SetSubType(sal_uInt16 )
+void SwField::SetUntypedSubType(sal_uInt16 n)
 {
+    switch (m_pType->Which())
+    {
+    case SwFieldIds::User:
+        static_cast<SwUserField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::GetRef:
+        static_cast<SwGetRefField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::DateTime:
+        static_cast<SwDateTimeField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::Table:
+        static_cast<SwTableField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::Input:
+        static_cast<SwInputField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::GetExp:
+        static_cast<SwGetExpField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::SetExp:
+        static_cast<SwSetExpField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::ExtUser:
+        static_cast<SwExtUserField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::DocInfo:
+        static_cast<SwDocInfoField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::HiddenText:
+        
static_cast<SwHiddenTextField*>(this)->SetSubType(static_cast<SwFieldTypesEnum>(n));
+        break;
+    case SwFieldIds::DocStat:
+        static_cast<SwDocStatField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::PageNumber:
+        static_cast<SwPageNumberField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::DbNextSet:
+    case SwFieldIds::DbNumSet:
+    case SwFieldIds::DatabaseName:
+    case SwFieldIds::DbSetNumber:
+        static_cast<SwDBNameInfField*>(this)->SetSubType(n);
+        break;
+    case SwFieldIds::Database:
+        static_cast<SwDBField*>(this)->SetSubType(n);
+        break;
+    default:
+        assert(n == 0 && "trying to set a subtype on something I don't know 
about");
+        break;
+    }
 }
 
 bool  SwField::QueryValue( uno::Any& rVal, sal_uInt16 nWhichId ) const
@@ -539,7 +643,7 @@ bool SwField::IsFixed() const
         break;
 
     case SwFieldIds::DateTime:
-        bRet = 0 != (GetSubType() & FIXEDFLD);
+        bRet = 0 != (static_cast<const SwDateTimeField*>(this)->GetSubType() & 
FIXEDFLD);
         break;
 
     case SwFieldIds::ExtUser:
@@ -554,7 +658,7 @@ bool SwField::IsFixed() const
         break;
 
     case SwFieldIds::DocInfo:
-        bRet = 0 != (GetSubType() & DI_SUB_FIXED);
+        bRet = 0 != (static_cast<const SwDocInfoField*>(this)->GetSubType() & 
DI_SUB_FIXED);
         break;
     default: break;
     }
@@ -837,7 +941,7 @@ void SwValueField::SetLanguage( LanguageType nLng )
 
         if( (GetFormat() >= SV_COUNTRY_LANGUAGE_OFFSET ||
              LANGUAGE_SYSTEM != nFormatLng ) &&
-            !(Which() == SwFieldIds::User && 
(GetSubType()&nsSwExtendedSubType::SUB_CMD) ) )
+            !(Which() == SwFieldIds::User && (static_cast<const 
SwUserField*>(this)->GetSubType()&nsSwExtendedSubType::SUB_CMD) ) )
         {
             const SvNumberformat* pEntry = pFormatter->GetEntry(GetFormat());
 
diff --git a/sw/source/core/txtnode/atrfld.cxx 
b/sw/source/core/txtnode/atrfld.cxx
index 46cd8a6df5af..a30655086c36 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -297,7 +297,7 @@ void SwFormatField::SwClientNotify( const SwModify& 
rModify, const SfxHint& rHin
     else if (rHint.GetId() == SfxHintId::SwGatherRefFields)
     {
         const auto pGatherRefFieldsHint = static_cast<const 
sw::GatherRefFieldsHint*>( &rHint );
-        if(!GetTextField() || pGatherRefFieldsHint->m_nType != 
GetField()->GetSubType())
+        if(!GetTextField() || pGatherRefFieldsHint->m_nType != 
GetField()->GetUntypedSubType())
             return;
         SwTextNode* pNd = GetTextField()->GetpTextNode();
         if(pNd && pNd->GetNodes().IsDocNodes())
diff --git a/sw/source/core/unocore/unofield.cxx 
b/sw/source/core/unocore/unofield.cxx
index 8a26bf66db48..32eb20768768 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -203,13 +203,16 @@ static SwServiceType lcl_GetServiceForField( const 
SwField& rField )
     switch( nWhich )
     {
     case SwFieldIds::Input:
-        if( INP_USR == (rField.GetSubType() & 0x00ff) )
-            nSrvId = SwServiceType::FieldTypeInputUser;
-        break;
-
+        {
+            const auto & rInputField = static_cast<const 
SwInputField&>(rField);
+            if( INP_USR == (rInputField.GetSubType() & 0x00ff) )
+                nSrvId = SwServiceType::FieldTypeInputUser;
+            break;
+        }
     case SwFieldIds::DocInfo:
         {
-            const sal_uInt16 nSubType = rField.GetSubType();
+            auto rDocInfoField = static_cast<const SwDocInfoField&>(rField);
+            const sal_uInt16 nSubType = rDocInfoField.GetSubType();
             switch( nSubType & 0xff )
             {
             case DI_CHANGE:
@@ -239,14 +242,18 @@ static SwServiceType lcl_GetServiceForField( const 
SwField& rField )
         break;
 
     case SwFieldIds::HiddenText:
-        nSrvId = SwFieldTypesEnum::ConditionalText == 
static_cast<SwFieldTypesEnum>(rField.GetSubType())
-                        ? SwServiceType::FieldTypeConditionedText
-                        : SwServiceType::FieldTypeHiddenText;
+        {
+            auto rHiddenTextField = static_cast<const 
SwHiddenTextField&>(rField);
+            nSrvId = SwFieldTypesEnum::ConditionalText == 
rHiddenTextField.GetSubType()
+                            ? SwServiceType::FieldTypeConditionedText
+                            : SwServiceType::FieldTypeHiddenText;
+        }
         break;
 
     case SwFieldIds::DocStat:
         {
-            switch( rField.GetSubType() )
+            auto rDocStatField = static_cast<const SwDocStatField&>(rField);
+            switch( rDocStatField.GetSubType() )
             {
             case DS_PAGE_RANGE:nSrvId = 
SwServiceType::FieldTypePageCountRange; break;
             case DS_PAGE: nSrvId = SwServiceType::FieldTypePageCount; break;
@@ -1673,12 +1680,12 @@ void SAL_CALL SwXTextField::attach(
                 aData.sCommand = m_pImpl->m_pProps->sPar2;
                 aData.nCommandType = m_pImpl->m_pProps->nSHORT1;
                 xField.reset(new 
SwDBNameField(static_cast<SwDBNameFieldType*>(pFieldType), aData));
-                sal_uInt16  nSubType = xField->GetSubType();
+                sal_uInt16  nSubType = 
static_cast<SwDBNameField*>(xField.get())->GetSubType();
                 if (m_pImpl->m_pProps->bBool2)
                     nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
                 else
                     nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
-                xField->SetSubType(nSubType);
+                
static_cast<SwDBNameField*>(xField.get())->SetSubType(nSubType);
             }
             break;
             case SwServiceType::FieldTypeDatabaseNextSet:
@@ -1717,12 +1724,12 @@ void SAL_CALL SwXTextField::attach(
                         m_pImpl->m_pProps->nUSHORT1);
                 xField.reset(pDBSNField);
                 pDBSNField->SetSetNumber(m_pImpl->m_pProps->nFormat);
-                sal_uInt16 nSubType = xField->GetSubType();
+                sal_uInt16 nSubType = pDBSNField->GetSubType();
                 if (m_pImpl->m_pProps->bBool2)
                     nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
                 else
                     nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
-                xField->SetSubType(nSubType);
+                pDBSNField->SetSubType(nSubType);
             }
             break;
             case SwServiceType::FieldTypeDatabase:
@@ -1734,12 +1741,12 @@ void SAL_CALL SwXTextField::attach(
                 xField.reset(new 
SwDBField(static_cast<SwDBFieldType*>(pFieldType),
                         m_pImpl->m_pProps->nFormat));
                 
static_cast<SwDBField*>(xField.get())->InitContent(m_pImpl->m_pProps->sPar1);
-                sal_uInt16  nSubType = xField->GetSubType();
+                sal_uInt16  nSubType = 
static_cast<SwDBField*>(xField.get())->GetSubType();
                 if (m_pImpl->m_pProps->bBool2)
                     nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
                 else
                     nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
-                xField->SetSubType(nSubType);
+                static_cast<SwDBField*>(xField.get())->SetSubType(nSubType);
             }
             break;
             case SwServiceType::FieldTypeSetExp:
@@ -1761,7 +1768,7 @@ void SAL_CALL SwXTextField::attach(
                     m_pImpl->m_pProps->nUSHORT2 : m_pImpl->m_pProps->nFormat);
                 xField.reset(pSEField);
 
-                sal_uInt16  nSubType = xField->GetSubType();
+                sal_uInt16  nSubType = pSEField->GetSubType();
                 if (m_pImpl->m_pProps->bBool2)
                     nSubType &= ~nsSwExtendedSubType::SUB_INVISIBLE;
                 else
@@ -1770,7 +1777,7 @@ void SAL_CALL SwXTextField::attach(
                     nSubType |= nsSwExtendedSubType::SUB_CMD;
                 else
                     nSubType &= ~nsSwExtendedSubType::SUB_CMD;
-                xField->SetSubType(nSubType);
+                pSEField->SetSubType(nSubType);
                 pSEField->SetSeqNumber(m_pImpl->m_pProps->nUSHORT1);
                 pSEField->SetInputFlag(m_pImpl->m_pProps->bBool1);
                 pSEField->SetPromptText(m_pImpl->m_pProps->sPar3);
diff --git a/sw/source/filter/html/htmlfldw.cxx 
b/sw/source/filter/html/htmlfldw.cxx
index 048d9383acea..3e151c1ca79b 100644
--- a/sw/source/filter/html/htmlfldw.cxx
+++ b/sw/source/filter/html/htmlfldw.cxx
@@ -36,6 +36,7 @@
 #include <docufld.hxx>
 #include <flddat.hxx>
 #include <viewopt.hxx>
+#include <expfld.hxx>
 #include "htmlfld.hxx"
 #include "wrthtml.hxx"
 #include <rtl/strbuf.hxx>
@@ -87,8 +88,10 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
     switch( nField )
     {
         case SwFieldIds::ExtUser:
+        {
+            auto pExtUserField = static_cast<const SwExtUserField*>(pField);
             pTypeStr = OOO_STRING_SW_HTML_FT_sender;
-            switch( static_cast<SwExtUserSubType>(pField->GetSubType()) )
+            switch( static_cast<SwExtUserSubType>(pExtUserField->GetSubType()) 
)
             {
                 case EU_COMPANY:    pSubStr = OOO_STRING_SW_HTML_FS_company;   
     break;
                 case EU_FIRSTNAME:  pSubStr = OOO_STRING_SW_HTML_FS_firstname; 
 break;
@@ -109,9 +112,9 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
                     ;
             }
             OSL_ENSURE( pSubStr, "unknown sub type for SwExtUserField" );
-            bFixed = static_cast<const SwExtUserField*>(pField)->IsFixed();
+            bFixed = pExtUserField->IsFixed();
             break;
-
+        }
         case SwFieldIds::Author:
             pTypeStr = OOO_STRING_SW_HTML_FT_author;
             switch( static_cast<const SwAuthorField*>(pField)->GetFormat() & 
SwAuthorFormat::Mask )
@@ -139,7 +142,7 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
             {
                 auto pPageNumberField = static_cast<const SwPageNumberField 
*>(pField);
                 pTypeStr = OOO_STRING_SW_HTML_FT_page;
-                SwPageNumSubType eSubType = 
static_cast<SwPageNumSubType>(pField->GetSubType());
+                SwPageNumSubType eSubType = 
static_cast<SwPageNumSubType>(pPageNumberField->GetSubType());
                 switch( eSubType )
                 {
                     case PG_RANDOM:     pSubStr = 
OOO_STRING_SW_HTML_FS_random;     break;
@@ -171,7 +174,7 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
             {
                 auto pDocInfoField = static_cast<const 
SwDocInfoField*>(pField);
                 nNumFormat = pDocInfoField->GetFormat();
-                sal_uInt16 nSubType = pField->GetSubType();
+                sal_uInt16 nSubType = pDocInfoField->GetSubType();
                 pTypeStr = OOO_STRING_SW_HTML_FT_docinfo;
                 sal_uInt16 nExtSubType = nSubType & 0x0f00;
                 nSubType &= 0x00ff;
@@ -232,8 +235,9 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
 
         case SwFieldIds::DocStat:
             {
+                auto pDocStatField = static_cast<const 
SwDocStatField*>(pField);
                 pTypeStr = OOO_STRING_SW_HTML_FT_docstat;
-                sal_uInt16 nSubType = pField->GetSubType();
+                sal_uInt16 nSubType = pDocStatField->GetSubType();
                 switch( nSubType )
                 {
                     case DS_PAGE:       pSubStr = OOO_STRING_SW_HTML_FS_page;  
 break;
@@ -245,7 +249,7 @@ static SwHTMLWriter& OutHTML_SwField( SwHTMLWriter& rWrt, 
const SwField* pField,
                     case DS_OLE:        pSubStr = OOO_STRING_SW_HTML_FS_ole;   
 break;
                     default:            pTypeStr = nullptr;               
break;
                 }
-                pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< 
sal_uInt16 >(static_cast<const SwDocStatField*>(pField)->GetFormat()) );
+                pFormatStr = SwHTMLWriter::GetNumFormat( static_cast< 
sal_uInt16 >(pDocStatField->GetFormat()) );
             }
             break;
 
@@ -473,7 +477,7 @@ SwHTMLWriter& OutHTML_SwFormatField( SwHTMLWriter& rWrt, 
const SfxPoolItem& rHt
     const SwFieldType* pFieldTyp = pField->GetTyp();
 
     if( SwFieldIds::SetExp == pFieldTyp->Which() &&
-        (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()) )
+        (nsSwGetSetExpType::GSE_STRING & static_cast<const 
SwSetExpField*>(pField)->GetSubType()) )
     {
         const bool bOn = pFieldTyp->GetName() == "HTML_ON";
         if (!bOn && pFieldTyp->GetName() != "HTML_OFF")
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 35bcb3c2c980..39ddd1f5dca5 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -166,6 +166,7 @@
 #include <sfx2/printer.hxx>
 #include <unotxdoc.hxx>
 #include <poolfmt.hxx>
+#include <flddat.hxx>
 
 using ::editeng::SvxBorderLine;
 
@@ -2970,7 +2971,8 @@ void DocxAttributeOutput::StartField_Impl( const 
SwTextNode* pNode, sal_Int32 nP
         else
         {
             // Write the field start
-            if ( rInfos.pField && (rInfos.pField->Which() == 
SwFieldIds::DateTime) && rInfos.pField->GetSubType() & FIXEDFLD )
+            if ( rInfos.pField && (rInfos.pField->Which() == 
SwFieldIds::DateTime)
+                && (static_cast<const 
SwDateTimeField*>(rInfos.pField.get())->GetSubType() & FIXEDFLD) )
             {
                 m_pSerializer->startElementNS( XML_w, XML_fldChar,
                     FSNS( XML_w, XML_fldCharType ), "begin",
@@ -3271,9 +3273,8 @@ void DocxAttributeOutput::EndField_Impl( const 
SwTextNode* pNode, sal_Int32 nPos
         return;
     }
 
-    sal_uInt16 nSubType = rInfos.pField->GetSubType( );
     bool bIsSetField = rInfos.pField->GetTyp( )->Which( ) == 
SwFieldIds::SetExp;
-    bool bShowRef = bIsSetField && ( nSubType & 
nsSwExtendedSubType::SUB_INVISIBLE ) == 0;
+    bool bShowRef = bIsSetField && ( static_cast<const 
SwSetExpField*>(rInfos.pField.get())->GetSubType( ) & 
nsSwExtendedSubType::SUB_INVISIBLE ) == 0;
 
     if (!bShowRef)
     {
@@ -8731,13 +8732,13 @@ void DocxAttributeOutput::WriteField_Impl(const SwField 
*const pField,
         return;
 
     SwFieldIds nType = pField->GetTyp( )->Which( );
-    sal_uInt16 nSubType = pField->GetSubType();
 
     // TODO Any other field types here ?
-    if ( ( nType == SwFieldIds::SetExp ) && ( nSubType & 
nsSwGetSetExpType::GSE_STRING ) )
+    if ( nType == SwFieldIds::SetExp )
     {
         const SwSetExpField *pSet = static_cast<const SwSetExpField*>( pField 
);
-        m_sFieldBkm = pSet->GetPar1( );
+        if ( pSet->GetSubType() & nsSwGetSetExpType::GSE_STRING )
+            m_sFieldBkm = pSet->GetPar1( );
     }
     else if ( nType == SwFieldIds::Dropdown )
     {
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index ec0f70c1ec9f..a73a4e9d8ffb 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -99,6 +99,7 @@
 #include <IDocumentDeviceAccess.hxx>
 #include <sfx2/printer.hxx>
 #include <fmtftntx.hxx>
+#include <flddat.hxx>
 
 using namespace ::com::sun::star;
 using namespace sw::util;
@@ -1885,7 +1886,8 @@ void RtfAttributeOutput::WriteField_Impl(const SwField* 
const pField, ww::eField
         if (bHasInstructions)
         {
             m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_FIELD);
-            if (pField && (pField->GetSubType() & FIXEDFLD))
+            if (pField && pField->GetTyp()->Which() == SwFieldIds::DateTime
+                && (static_cast<const SwDateTimeField*>(pField)->GetSubType() 
& FIXEDFLD))
                 m_aRunText->append(OOO_STRING_SVTOOLS_RTF_FLDLOCK);
             m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE 
OOO_STRING_SVTOOLS_RTF_FLDINST
                                " ");
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 35dc8f614bf3..fbfeb01e861e 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -129,6 +129,7 @@
 #include <authfld.hxx>
 #include <dbfld.hxx>
 #include <docsh.hxx>
+#include <flddat.hxx>
 
 #include "sprmids.hxx"
 
@@ -1957,8 +1958,8 @@ void WW8Export::OutputField( const SwField* pField, 
ww::eField eFieldType,
         {
             // retrieve reference destination - the name of the bookmark
             OUString aLinkStr;
-            const sal_uInt16 nSubType = pField->GetSubType();
             const SwGetRefField& rRField = *static_cast<const 
SwGetRefField*>(pField);
+            const sal_uInt16 nSubType = rRField.GetSubType();
             if ( nSubType == REF_SETREFATTR ||
                  nSubType == REF_BOOKMARK )
             {
@@ -2028,17 +2029,18 @@ void WW8Export::OutputField( const SwField* pField, 
ww::eField eFieldType,
         if (pField->GetTyp()->Which() == SwFieldIds::Input &&
             eFieldType == ww::eFORMTEXT)
         {
-            sal_uInt16 nSubType = pField->GetSubType();
+            sal_uInt16 nSubType = static_cast<const 
SwInputField*>(pField)->GetSubType();
 
             if (nSubType == REF_SEQUENCEFLD)
                 aField15[0] |= (0x4 << 5);
         }
         // This ought to apply to any field, but just to be safe, start off 
with DATE/TIME only.
-        if (pField->GetTyp()->Which() == SwFieldIds::DateTime
-            && (pField->GetSubType() & FIXEDFLD))
+        if (pField->GetTyp()->Which() == SwFieldIds::DateTime)
         {
-            //bit 5 - Locked: do not recalculate field
-            aField15[1] |= 0x10;
+            sal_uInt16 nSubType = static_cast<const 
SwDateTimeField*>(pField)->GetSubType();
+            if (nSubType & FIXEDFLD)
+                //bit 5 - Locked: do not recalculate field
+                aField15[1] |= 0x10;
         }
     }
 
@@ -2178,7 +2180,7 @@ void 
AttributeOutputBase::GenerateBookmarksForSequenceField(const SwTextNode& rN
             const SwFormatField& rField = static_cast<const 
SwFormatField&>(pHt->GetAttr());
             const SwField* pField = rField.GetField();
             // Need to have bookmarks only for sequence fields
-            if (pField && pField->GetTyp()->Which() == SwFieldIds::SetExp && 
pField->GetSubType() == nsSwGetSetExpType::GSE_SEQ)
+            if (pField && pField->GetTyp()->Which() == SwFieldIds::SetExp && 
static_cast<const SwSetExpField*>(pField)->GetSubType() == 
nsSwGetSetExpType::GSE_SEQ)
             {
                 const sal_uInt16 nSeqFieldNumber = static_cast<const 
SwSetExpField*>(pField)->GetSeqNumber();
                 const UIName sObjectName = static_cast<const 
SwSetExpFieldType*>(pField->GetTyp())->GetName();
@@ -2952,61 +2954,65 @@ void AttributeOutputBase::TextField( const 
SwFormatField& rField )
 {
     const SwField* pField = rField.GetField();
     bool bWriteExpand = false;
-    const sal_uInt16 nSubType = pField->GetSubType();
 
     switch (pField->GetTyp()->Which())
     {
     case SwFieldIds::GetExp:
-        if (nSubType == nsSwGetSetExpType::GSE_STRING)
         {
             const SwGetExpField *pGet = static_cast<const 
SwGetExpField*>(pField);
-            RefField( *pGet, pGet->GetFormula() );
+            if (pGet->GetSubType() == nsSwGetSetExpType::GSE_STRING)
+            {
+                RefField( *pGet, pGet->GetFormula() );
+            }
+            else
+                bWriteExpand = true;
         }
-        else
-            bWriteExpand = true;
         break;
     case SwFieldIds::SetExp:
-        if (nsSwGetSetExpType::GSE_SEQ == nSubType)
-        {
-            OUString sStr;
-            if (GetExport().FieldsQuoted())
-                sStr = FieldString(ww::eSEQ) + 
pField->GetTyp()->GetName().toString() + " ";
-            else
-                sStr = FieldString(ww::eSEQ) + "\"" + 
pField->GetTyp()->GetName().toString() +"\" ";
-            GetNumberPara( sStr, *pField );
-            GetExport().OutputField(pField, ww::eSEQ, sStr);
-        }
-        else if (nSubType & nsSwGetSetExpType::GSE_STRING)
         {
-            bool bShowAsWell = false;
-            ww::eField eFieldNo;
             const SwSetExpField *pSet = static_cast<const 
SwSetExpField*>(pField);
-            const OUString sVar = pSet->GetPar2();
-            OUString sStr;
-            if (pSet->GetInputFlag())
+            sal_uInt16 nSubType = pSet->GetSubType();
+            if (nsSwGetSetExpType::GSE_SEQ == nSubType)
             {
-                sStr = FieldString(ww::eASK) + "\""
-                    + pSet->GetPar1() + "\" "
-                    + pSet->GetPromptText() + " \d "
-                    + sVar;
-                eFieldNo = ww::eASK;
+                OUString sStr;
+                if (GetExport().FieldsQuoted())
+                    sStr = FieldString(ww::eSEQ) + 
pField->GetTyp()->GetName().toString() + " ";
+                else
+                    sStr = FieldString(ww::eSEQ) + "\"" + 
pField->GetTyp()->GetName().toString() +"\" ";
+                GetNumberPara( sStr, *pField );
+                GetExport().OutputField(pField, ww::eSEQ, sStr);
             }
-            else
+            else if (nSubType & nsSwGetSetExpType::GSE_STRING)
             {
-                sStr = FieldString(ww::eSET)
-                    + pSet->GetPar1() + " \""
-                    + sVar + "\" ";
-                eFieldNo = ww::eSET;
-                bShowAsWell = (nSubType & nsSwExtendedSubType::SUB_INVISIBLE) 
== 0;
-            }
+                bool bShowAsWell = false;
+                ww::eField eFieldNo;
+                const OUString sVar = pSet->GetPar2();
+                OUString sStr;
+                if (pSet->GetInputFlag())
+                {
+                    sStr = FieldString(ww::eASK) + "\""
+                        + pSet->GetPar1() + "\" "
+                        + pSet->GetPromptText() + " \d "
+                        + sVar;
+                    eFieldNo = ww::eASK;
+                }
+                else
+                {
+                    sStr = FieldString(ww::eSET)
+                        + pSet->GetPar1() + " \""
+                        + sVar + "\" ";
+                    eFieldNo = ww::eSET;
+                    bShowAsWell = (nSubType & 
nsSwExtendedSubType::SUB_INVISIBLE) == 0;
+                }
 
-            SetField( *pField, eFieldNo, sStr );
+                SetField( *pField, eFieldNo, sStr );
 
-            if (bShowAsWell)
-                RefField( *pSet, pSet->GetPar1() );
+                if (bShowAsWell)
+                    RefField( *pSet, pSet->GetPar1() );
+            }
+            else
+                bWriteExpand = true;
         }
-        else
-            bWriteExpand = true;
         break;
     case SwFieldIds::PageNumber:
         {
@@ -3051,10 +3057,12 @@ void AttributeOutputBase::TextField( const 
SwFormatField& rField )
         GetExport().OutputField(pField, ww::eTEMPLATE, 
FieldString(ww::eTEMPLATE));
         break;
     case SwFieldIds::DocInfo:    // Last printed, last edited,...
-        if( DI_SUB_FIXED & nSubType )
-            bWriteExpand = true;
-
         {
+            auto pDocInfoField = static_cast<const SwDocInfoField*>(pField);
+            const sal_uInt16 nSubType = pDocInfoField->GetSubType();
+            if( DI_SUB_FIXED & nSubType )
+                bWriteExpand = true;
+
             OUString sStr;
             ww::eField eField(ww::eNONE);
             switch (0xff & nSubType)
@@ -3104,15 +3112,8 @@ void AttributeOutputBase::TextField( const 
SwFormatField& rField )
                     break;
                 case DI_CUSTOM:
                     eField = ww::eDOCPROPERTY;
-                    {
-                        const SwDocInfoField * pDocInfoField =
-                        dynamic_cast<const SwDocInfoField *> (pField);
-
-                        if (pDocInfoField != nullptr)
-                            sStr = "\"" + pDocInfoField->GetName() + "\"";
-
-                        bWriteExpand = false;
-                    }
+                    sStr = "\"" + pDocInfoField->GetName() + "\"";
+                    bWriteExpand = false;
                     break;
                 default:
                     break;
@@ -3128,6 +3129,8 @@ void AttributeOutputBase::TextField( const SwFormatField& 
rField )
         break;
     case SwFieldIds::DateTime:
         {
+            auto pDateTimeField = static_cast<const SwDateTimeField*>(pField);
+            const sal_uInt16 nSubType = pDateTimeField->GetSubType();
             OUString sStr;
             if (!GetExport().GetNumberFormat(*pField, sStr))
                 bWriteExpand = true;
@@ -3140,6 +3143,8 @@ void AttributeOutputBase::TextField( const SwFormatField& 
rField )
         break;
     case SwFieldIds::DocStat:
         {
+            auto pDocStatField = static_cast<const SwDocStatField*>(pField);
+            const sal_uInt16 nSubType = pDocStatField->GetSubType();
             ww::eField eField = ww::eNONE;
 
             switch (nSubType)
@@ -3167,6 +3172,8 @@ void AttributeOutputBase::TextField( const SwFormatField& 
rField )
         break;
     case SwFieldIds::ExtUser:
         {
+            auto pExtUserField = static_cast<const SwExtUserField*>(pField);
+            const sal_uInt16 nSubType = pExtUserField->GetSubType();
             ww::eField eField = ww::eNONE;
             switch (0xFF & nSubType)
             {
@@ -3234,6 +3241,7 @@ void AttributeOutputBase::TextField( const SwFormatField& 
rField )
             ww::eField eField = ww::eNONE;
             OUString sStr;
             const SwGetRefField& rRField = *static_cast<const 
SwGetRefField*>(pField);
+            const sal_uInt16 nSubType = rRField.GetSubType();
             switch (nSubType)
             {
                 case REF_SETREFATTR:
@@ -3482,7 +3490,7 @@ void AttributeOutputBase::TextField( const SwFormatField& 
rField )
             OUString sExpand(pField->GetPar2());
             if (!sExpand.isEmpty())
             {
-                auto eSubType = 
static_cast<SwFieldTypesEnum>(pField->GetSubType());
+                auto eSubType = static_cast<const 
SwHiddenTextField*>(pField)->GetSubType();
                 if (eSubType == SwFieldTypesEnum::ConditionalText)
                 {
                     OUString aCond = pField->GetPar1();
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index fd595aa3499f..80df830de865 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1586,14 +1586,18 @@ bool SwWW8FltRefStack::IsFootnoteEdnBkmField(
     sal_uInt16& rBkmNo)
 {
     const SwField* pField = rFormatField.GetField();
-    sal_uInt16 nSubType;
-    if(pField && (SwFieldIds::GetRef == pField->Which())
-        && ((REF_FOOTNOTE == (nSubType = pField->GetSubType())) || 
(REF_ENDNOTE  == nSubType))
-        && !static_cast<const 
SwGetRefField*>(pField)->GetSetRefName().isEmpty())
+    if (!pField)
+        return false;
+    if(SwFieldIds::GetRef != pField->Which())
+        return false;
+    auto pGetRefField = static_cast<const SwGetRefField*>(pField);
+    sal_uInt16 nSubType = pGetRefField->GetSubType();
+    if( ((REF_FOOTNOTE == nSubType) || (REF_ENDNOTE  == nSubType))
+        && !pGetRefField->GetSetRefName().isEmpty())
     {
         const IDocumentMarkAccess* const pMarkAccess = 
m_rDoc.getIDocumentMarkAccess();
         auto ppBkmk =
-            pMarkAccess->findMark( static_cast<const 
SwGetRefField*>(pField)->GetSetRefName() );
+            pMarkAccess->findMark( pGetRefField->GetSetRefName() );
         if(ppBkmk != pMarkAccess->getAllMarksEnd())
         {
             // find Sequence No of corresponding Foot-/Endnote
diff --git a/sw/source/ui/dbui/dbinsdlg.cxx b/sw/source/ui/dbui/dbinsdlg.cxx
index 32bce2773636..9ce7d10a4cc1 100644
--- a/sw/source/ui/dbui/dbinsdlg.cxx
+++ b/sw/source/ui/dbui/dbinsdlg.cxx
@@ -903,9 +903,7 @@ bool SwInsertDBColAutoPilot::SplitTextToColArr( const 
OUString& rText,
                                             m_aDBData );
                     pNew = new DB_Column( rFndCol, *new SwDBField(
                             static_cast<SwDBFieldType*>(rSh.InsertFieldType( 
aFieldType )),
-                                                            nFormat ) );
-                    if( nSubType )
-                        pNew->pField->SetSubType( nSubType );
+                                                            nFormat, nSubType 
) );
                 }
                 else
                     pNew = new DB_Column( rFndCol, nFormat );
diff --git a/sw/source/ui/fldui/flddb.cxx b/sw/source/ui/fldui/flddb.cxx
index fa03d1f5178b..6b6919099c26 100644
--- a/sw/source/ui/fldui/flddb.cxx
+++ b/sw/source/ui/fldui/flddb.cxx
@@ -179,7 +179,7 @@ void SwFieldDBPage::Reset(const SfxItemSet*)
         m_xValueED->save_value();
         m_sOldDBName = m_xDatabaseTLB->GetDBName(m_sOldTableName, 
m_sOldColumnName);
         m_nOldFormat = GetCurField()->GetUntypedFormat();
-        m_nOldSubType = GetCurField()->GetSubType();
+        m_nOldSubType = GetCurField()->GetUntypedSubType();
     }
 }
 
@@ -337,12 +337,12 @@ void SwFieldDBPage::TypeHdl(const weld::TreeView* pBox)
 
             if (IsFieldEdit())
             {
-                auto pValueField = static_cast<SwValueField*>(GetCurField());
-                auto nFormat = pValueField->GetFormat();
+                auto pDBField = static_cast<SwDBField*>(GetCurField());
+                auto nFormat = pDBField->GetFormat();
                 if (nFormat != 0 && nFormat != SAL_MAX_UINT32)
                     m_xNumFormatLB->SetDefFormat(nFormat);
 
-                if (GetCurField()->GetSubType() & 
nsSwExtendedSubType::SUB_OWN_FMT)
+                if (pDBField->GetSubType() & nsSwExtendedSubType::SUB_OWN_FMT)
                     m_xNewFormatRB->set_active(true);
                 else
                     m_xDBFormatRB->set_active(true);
diff --git a/sw/source/ui/fldui/flddinf.cxx b/sw/source/ui/fldui/flddinf.cxx
index 532429f2929c..00862cf23a0c 100644
--- a/sw/source/ui/fldui/flddinf.cxx
+++ b/sw/source/ui/fldui/flddinf.cxx
@@ -134,13 +134,11 @@ void SwFieldDokInfPage::Reset(const SfxItemSet* )
     if (IsFieldEdit())
     {
         const SwField* pCurField = GetCurField();
-        nSubType = pCurField->GetSubType() & 0xff;
-        if( nSubType == DI_CUSTOM )
+        if (auto const pField = dynamic_cast<SwDocInfoField const*>(pCurField))
         {
-            if (auto const pField = dynamic_cast<SwDocInfoField 
const*>(pCurField))
-            {
+            nSubType = pField->GetSubType() & 0xff;
+            if( nSubType == DI_CUSTOM )
                 m_sOldCustomFieldName = pField->GetName();
-            }
         }
         m_xFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
         SwWrtShell *pSh = GetWrtShell();
diff --git a/sw/source/ui/fldui/flddok.cxx b/sw/source/ui/fldui/flddok.cxx
index 029e7db209ea..8487e03d3362 100644
--- a/sw/source/ui/fldui/flddok.cxx
+++ b/sw/source/ui/fldui/flddok.cxx
@@ -250,9 +250,13 @@ IMPL_LINK_NOARG(SwFieldDokPage, TypeHdl, weld::TreeView&, 
void)
                             m_xSelectionLB->select_id(sId);
                         break;
                     case SwFieldTypesEnum::ExtendedUser:
+                        m_xSelectionLB->append(sId, aLst[i]);
+                        if (static_cast<const 
SwExtUserField*>(GetCurField())->GetSubType() == i)
+                            m_xSelectionLB->select_id(sId);
+                        break;
                     case SwFieldTypesEnum::DocumentStatistics:
                         m_xSelectionLB->append(sId, aLst[i]);
-                        if (GetCurField()->GetSubType() == i)
+                        if (static_cast<const 
SwDocStatField*>(GetCurField())->GetSubType() == i)
                             m_xSelectionLB->select_id(sId);
                         break;
 
diff --git a/sw/source/ui/fldui/fldedt.cxx b/sw/source/ui/fldui/fldedt.cxx
index dddb92946658..c38561e64e4c 100644
--- a/sw/source/ui/fldui/fldedt.cxx
+++ b/sw/source/ui/fldui/fldedt.cxx
@@ -116,7 +116,7 @@ SwFieldEditDlg::SwFieldEditDlg(SwView const & rVw)
 
     EnsureSelection(pCurField, aMgr);
 
-    sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), 
pCurField->GetSubType());
+    sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), 
pCurField->GetUntypedSubType());
 
     CreatePage(nGroup);
 
@@ -162,7 +162,7 @@ void SwFieldEditDlg::Init()
 
             const SwFieldTypesEnum aId(pCurField->GetTypeId());
             if ( (aId == SwFieldTypesEnum::Author) ||
-                 ((aId == SwFieldTypesEnum::DocumentInfo) && 
(pCurField->GetSubType() != (DI_CREATE|DI_SUB_AUTHOR)))) // except DocumentInfo 
> Author
+                 ((aId == SwFieldTypesEnum::DocumentInfo) && 
(static_cast<const SwDocInfoField*>(pCurField)->GetSubType() != 
(DI_CREATE|DI_SUB_AUTHOR)))) // except DocumentInfo > Author
                 m_xAddressBT->set_visible(true);
             else
                 m_xAddressBT->set_visible(false);
@@ -286,7 +286,7 @@ IMPL_LINK(SwFieldEditDlg, NextPrevHdl, weld::Button&, 
rButton, void)
     rMgr.GoNextPrev( bNext, pOldTyp );
     pCurField = rMgr.GetCurField();
 
-    sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), 
pCurField->GetSubType());
+    sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), 
pCurField->GetUntypedSubType());
 
     if (nGroup != pTabPage->GetGroup())
         pTabPage = static_cast<SwFieldPage*>(CreatePage(nGroup));
@@ -311,7 +311,8 @@ IMPL_LINK_NOARG(SwFieldEditDlg, AddressHdl, weld::Button&, 
void)
 
         EditPosition nEditPos = EditPosition::UNKNOWN;
 
-        switch(pCurField->GetSubType())
+        auto pExtUserField = static_cast<const SwExtUserField*>(pCurField);
+        switch(pExtUserField->GetSubType())
         {
             case EU_FIRSTNAME:  nEditPos = EditPosition::FIRSTNAME;  break;
             case EU_NAME:       nEditPos = EditPosition::LASTNAME;   break;
diff --git a/sw/source/ui/fldui/fldpage.cxx b/sw/source/ui/fldui/fldpage.cxx
index e4c0102f5659..762b3de89636 100644
--- a/sw/source/ui/fldui/fldpage.cxx
+++ b/sw/source/ui/fldui/fldpage.cxx
@@ -232,11 +232,11 @@ void SwFieldPage::InsertField(SwFieldTypesEnum nTypeId, 
sal_uInt16 nSubType, con
 
         case SwFieldTypesEnum::Input:
             {
+                SwSetExpField* pField = 
static_cast<SwSetExpField*>(pTmpField.get());
                 // User- or SetField ?
                 if (m_aMgr.GetFieldType(SwFieldIds::User, sPar1) == nullptr &&
-                !(pTmpField->GetSubType() & INP_TXT)) // SETEXPFLD
+                    !(pField->GetSubType() & INP_TXT)) // SETEXPFLD
                 {
-                    SwSetExpField* pField = 
static_cast<SwSetExpField*>(pTmpField.get());
                     pField->SetPromptText(sPar2);
                     sPar2 = pField->GetPar2();
                 }
@@ -256,7 +256,7 @@ void SwFieldPage::InsertField(SwFieldTypesEnum nTypeId, 
sal_uInt16 nSubType, con
 
         pSh->StartAllAction();
 
-        pTmpField->SetSubType(nSubType);
+        pTmpField->SetUntypedSubType(nSubType);
         pTmpField->SetAutomaticLanguage(bIsAutomaticLanguage);
 
         m_aMgr.UpdateCurField( nFormatId, sPar1, sPar2, std::move(pTmpField) );
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
index 11cb46cd6836..14542cdd7715 100644
--- a/sw/source/ui/fldui/fldref.cxx
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -328,20 +328,18 @@ IMPL_LINK_NOARG(SwFieldRefPage, TypeHdl, weld::TreeView&, 
void)
             OUString sName;
             sal_uInt16 nFlag = 0;
 
-            switch( GetCurField()->GetSubType() )
+            SwGetRefField* pRefField = 
dynamic_cast<SwGetRefField*>(GetCurField());
+            switch( pRefField->GetSubType() )
             {
                 case REF_BOOKMARK:
                 {
                     // #i83479#
-                    SwGetRefField* pRefField = 
dynamic_cast<SwGetRefField*>(GetCurField());
-                    if ( pRefField &&
-                         pRefField->IsRefToHeadingCrossRefBookmark() )
+                    if ( pRefField->IsRefToHeadingCrossRefBookmark() )
                     {
                         sName = m_sHeadingText;
                         nFlag = REFFLDFLAG_HEADING;
                     }
-                    else if ( pRefField &&
-                              pRefField->IsRefToNumItemCrossRefBookmark() )
+                    else if ( pRefField->IsRefToNumItemCrossRefBookmark() )
                     {
                         sName = m_sNumItemText;
                         nFlag = REFFLDFLAG_NUMITEM;
@@ -371,22 +369,14 @@ IMPL_LINK_NOARG(SwFieldRefPage, TypeHdl, weld::TreeView&, 
void)
 
                 case REF_SEQUENCEFLD:
                 {
-                    SwGetRefField const*const 
pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
-                    if (pRefField)
-                    {
-                        sName = pRefField->GetSetRefName().toString();
-                    }
+                    sName = pRefField->GetSetRefName().toString();
                     nFlag = REFFLDFLAG;
                     break;
                 }
 
                 case REF_STYLE:
                 {
-                    SwGetRefField const*const 
pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
-                    if (pRefField)
-                    {
-                        sName = pRefField->GetPar1();
-                    }
+                    sName = pRefField->GetPar1();
                     nFlag = REFFLDFLAG_STYLE;
                     break;
                 }
diff --git a/sw/source/ui/fldui/fldvar.cxx b/sw/source/ui/fldui/fldvar.cxx
index c2f0955d2c5d..d8879301e8a0 100644
--- a/sw/source/ui/fldui/fldvar.cxx
+++ b/sw/source/ui/fldui/fldvar.cxx
@@ -632,11 +632,18 @@ void SwFieldVarPage::UpdateSubType()
                         break;
 
                     case SwFieldTypesEnum::Set:
+                        if (GetCurField() && aList[i] == 
GetCurField()->GetTyp()->GetName())
+                        {
+                            bInsert = true;
+                            if 
(static_cast<SwSetExpField*>(GetCurField())->GetSubType() & 
nsSwExtendedSubType::SUB_INVISIBLE)
+                                m_xInvisibleCB->set_active(true);
+                        }
+                        break;
                     case SwFieldTypesEnum::User:
                         if (GetCurField() && aList[i] == 
GetCurField()->GetTyp()->GetName())
                         {
                             bInsert = true;
-                            if (GetCurField()->GetSubType() & 
nsSwExtendedSubType::SUB_INVISIBLE)
+                            if 
(static_cast<SwUserField*>(GetCurField())->GetSubType() & 
nsSwExtendedSubType::SUB_INVISIBLE)
                                 m_xInvisibleCB->set_active(true);
                         }
                         break;
@@ -787,7 +794,7 @@ void SwFieldVarPage::FillFormatLB(SwFieldTypesEnum nTypeId)
 
     if (IsFieldEdit() && bSpecialFormat)
     {
-        if (nTypeId == SwFieldTypesEnum::User && (GetCurField()->GetSubType() 
& nsSwExtendedSubType::SUB_CMD))
+        if (nTypeId == SwFieldTypesEnum::User && 
(static_cast<SwUserField*>(GetCurField())->GetSubType() & 
nsSwExtendedSubType::SUB_CMD))
             rWidget.select(1);
         else
             rWidget.select(0);
diff --git a/sw/source/uibase/docvw/edtwin2.cxx 
b/sw/source/uibase/docvw/edtwin2.cxx
index ef50337c53d0..a784a0d4fd33 100644
--- a/sw/source/uibase/docvw/edtwin2.cxx
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -55,6 +55,7 @@
 #include <comphelper/diagnose_ex.hxx>
 #include <comphelper/lok.hxx>
 #include <authfld.hxx>
+#include <expfld.hxx>
 
 #include <com/sun/star/text/XTextRange.hpp>
 #include <unotextrange.hxx>
@@ -553,15 +554,32 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt)
                         switch( pField->Which() )
                         {
                         case SwFieldIds::SetExp:
+                        {
+                            auto pSetExpField = 
const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
+                            sal_uInt16 nOldSubType = 
pSetExpField->GetSubType();
+                            
pSetExpField->SetSubType(nsSwExtendedSubType::SUB_CMD);
+                            sText = pSetExpField->ExpandField(true, 
rSh.GetLayout());
+                            pSetExpField->SetSubType(nOldSubType);
+                            break;
+                        }
                         case SwFieldIds::Table:
+                        {
+                            auto pTableField = 
const_cast<SwTableField*>(static_cast<const SwTableField*>(pField));
+                            sal_uInt16 nOldSubType = pTableField->GetSubType();
+                            
pTableField->SetSubType(nsSwExtendedSubType::SUB_CMD);
+                            sText = pTableField->ExpandField(true, 
rSh.GetLayout());
+                            pTableField->SetSubType(nOldSubType);
+                            break;
+                        }
                         case SwFieldIds::GetExp:
                         {
-                            sal_uInt16 nOldSubType = pField->GetSubType();
-                            
const_cast<SwField*>(pField)->SetSubType(nsSwExtendedSubType::SUB_CMD);
-                            sText = pField->ExpandField(true, rSh.GetLayout());
-                            
const_cast<SwField*>(pField)->SetSubType(nOldSubType);
+                            auto pGetExpField = 
const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
+                            sal_uInt16 nOldSubType = 
pGetExpField->GetSubType();
+                            
pGetExpField->SetSubType(nsSwExtendedSubType::SUB_CMD);
+                            sText = pGetExpField->ExpandField(true, 
rSh.GetLayout());
+                            pGetExpField->SetSubType(nOldSubType);
+                            break;
                         }
-                        break;
 
                         case SwFieldIds::Postit:
                             {
diff --git a/sw/source/uibase/fldui/fldmgr.cxx 
b/sw/source/uibase/fldui/fldmgr.cxx
index 13872c00907f..49358acbfae7 100644
--- a/sw/source/uibase/fldui/fldmgr.cxx
+++ b/sw/source/uibase/fldui/fldmgr.cxx
@@ -1243,8 +1243,7 @@ bool SwFieldMgr::InsertField(
 
             SwDBFieldType* pTyp = 
static_cast<SwDBFieldType*>(pCurShell->InsertFieldType(
                 SwDBFieldType(pCurShell->GetDoc(), sPar1, aDBData) ) );
-            pField.reset(new SwDBField(pTyp));
-            pField->SetSubType(nSubType);
+            pField.reset(new SwDBField(pTyp, nSubType));
 
             if( !(nSubType & nsSwExtendedSubType::SUB_OWN_FMT) ) // determine 
database format
             {
@@ -1362,9 +1361,7 @@ bool SwFieldMgr::InsertField(
             }
             if (pTyp->GetContent(nFormatId) != rData.m_sPar2)
                 pTyp->SetContent(rData.m_sPar2, nFormatId);
-            pField.reset(new SwUserField(pTyp, 0, nFormatId));
-            if (pField->GetSubType() != nSubType)
-                pField->SetSubType(nSubType);
+            pField.reset(new SwUserField(pTyp, nSubType, nFormatId));
             bTable = true;
             break;
         }
@@ -1448,8 +1445,7 @@ bool SwFieldMgr::InsertField(
             {
                 SwGetExpFieldType* pTyp = static_cast<SwGetExpFieldType*>( 
pCurShell->GetFieldType(
                     0, SwFieldIds::GetExp) );
-                pField.reset( new SwGetExpField(pTyp, rData.m_sPar1, 
pSetTyp->GetType(), nFormatId) );
-                pField->SetSubType(nSubType | pSetTyp->GetType());
+                pField.reset( new SwGetExpField(pTyp, rData.m_sPar1, nSubType 
| pSetTyp->GetType(), nFormatId) );
                 bExp = true;
             }
             else
@@ -1494,8 +1490,7 @@ bool SwFieldMgr::InsertField(
             {
                 SwGetExpFieldType* pTyp = static_cast<SwGetExpFieldType*>(
                     pCurShell->GetFieldType(0, SwFieldIds::GetExp) );
-                pField.reset( new SwGetExpField(pTyp, rData.m_sPar2, 
nsSwGetSetExpType::GSE_FORMULA, nFormatId) );
-                pField->SetSubType(nSubType);
+                pField.reset( new SwGetExpField(pTyp, rData.m_sPar2, nSubType, 
nFormatId) );
                 bExp = true;
             }
             break;
diff --git a/sw/source/uibase/utlui/content.cxx 
b/sw/source/uibase/utlui/content.cxx
index 8531e8bb4dbb..c473faf56fcd 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -781,8 +781,9 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                         
SwFieldMgr(m_pWrtShell).GetSubTypes(SwFieldTypesEnum::DocumentStatistics,
                                                             
aDocumentStatisticsSubTypesList);
                     OUString sSubType;
-                    if (pField->GetSubType() < 
aDocumentStatisticsSubTypesList.size())
-                        sSubType = u" - " + 
aDocumentStatisticsSubTypesList[pField->GetSubType()];
+                    sal_uInt16 nSubStype = static_cast<const 
SwDocStatField*>(pField)->GetSubType();
+                    if (nSubStype < aDocumentStatisticsSubTypesList.size())
+                        sSubType = u" - " + 
aDocumentStatisticsSubTypesList[nSubStype];
                     sText = pField->GetDescription() + u" - " + 
pField->GetFieldName() + sSubType +
                             sExpandField;
                 }
@@ -807,7 +808,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
                     else
                     {
                         OUString sFieldSubTypeOrName;
-                        auto nSubType = pField->GetSubType();
+                        auto nSubType = pRefField->GetSubType();
                         if (nSubType == REF_FOOTNOTE)
                             sFieldSubTypeOrName = SwResId(STR_FLDREF_FOOTNOTE);
                         else if (nSubType == REF_ENDNOTE)

Reply via email to