[Libreoffice-commits] core.git: Branch 'feature/refactor-god-objects' - 529 commits - accessibility/source android/abs-lib avmedia/source basctl/source basic/source bin/find-german-comments bin/findunusedcode canvas/source chart2/AllLangResTarget_chartcontroller.mk chart2/inc chart2/Library_chartcontroller.mk chart2/opengl chart2/qa chart2/source chart2/uiconfig codemaker/source compilerplugins/clang config_host/config_vcl.h.in config_host.mk.in configmgr/qa configure.ac connectivity/registry connectivity/source cppcanvas/qa cppcanvas/source cui/source cui/uiconfig cui/UIConfig_cui.mk dbaccess/inc dbaccess/source dbaccess/uiconfig dbaccess/UIConfig_dbaccess.mk desktop/inc desktop/source desktop/test desktop/uiconfig dictionaries download.lst drawinglayer/source editeng/CppunitTest_editeng_core.mk editeng/qa editeng/source extensions/source external/beanshell external/hunspell external/hyphen external/icu external/jfreereport external/libabw external/libebook external/libetonyek external/libgltf e xternal/liblangtag external/libvisio external/libxml2 external/libxmlsec external/libxslt external/mythes external/redland extras/source filter/qa filter/source forms/source formula/source fpicker/source framework/inc framework/source helpcontent2 icon-themes/galaxy icon-themes/tango icon-themes/tango_testing include/connectivity include/editeng include/filter include/formula include/framework include/oox include/sfx2 include/svl include/svtools include/svx include/test include/tools include/vbahelper include/vcl include/xmloff jurt/com libreofficekit/Module_libreofficekit.mk libreofficekit/qa offapi/com officecfg/registry oox/inc oox/source package/source pyuno/source readlicense_oo/license reportbuilder/java reportdesign/source RepositoryExternal.mk Repository.mk ridljar/com sal/osl sal/rtl sc/CppunitTest_sc_subsequent_export_test.mk sc/CppunitTest_sc_subsequent_filters_test.mk sc/inc sc/Library_scfilt.mk sc/Library_scqahelper.mk scp2/AutoInstall.mk scp2/InstallModule_base.mk scp2 /InstallModule_impress.mk scp2/InstallModule_ooo.mk scp2/source sc/qa sc/source sc/uiconfig sd/qa sd/source sd/uiconfig sfx2/source sfx2/uiconfig slideshow/source solenv/bin solenv/gbuild sot/source starmath/source stoc/Library_javaloader.mk stoc/source svgio/inc svgio/source svl/CppunitTest_svl_notify.mk svl/Module_svl.mk svl/qa svl/source svtools/CppunitTest_svtools_graphic.mk svtools/Module_svtools.mk svtools/qa svtools/source svx/source swext/mediawiki sw/inc sw/Library_sw.mk sw/qa sw/sdi sw/source sw/uiconfig sw/UIConfig_swriter.mk test/source toolkit/source ucb/Library_cached1.mk ucb/Library_srtrs1.mk ucb/Library_ucpcmis1.mk ucb/Library_ucpftp1.mk ucb/source udkapi/com unotools/source unoxml/source unusedcode.easy uui/inc uui/source vbahelper/source vcl/generic vcl/inc vcl/qa vcl/quartz vcl/source vcl/unx vcl/win vcl/workben writerfilter/CustomTarget_source.mk writerfilter/inc writerfilter/source xmerge/source xmloff/inc xmloff/source

Valentin Kettner vakevk+libreoffice at gmail.com
Tue Jul 29 04:06:57 PDT 2014


Rebased ref, commits from common ancestor:
commit 694d25417dbbae5350240cdc888462f2f4b86c4b
Author: Valentin Kettner <vakevk+libreoffice at gmail.com>
Date:   Tue Jul 29 13:03:49 2014 +0200

    Refactored IDocumentLineNumberAccess.
    
    This interface is obsolete and was deleted.
    
    Change-Id: I56d37814f6e43f083ab3d199237ade06db287e18

diff --git a/sw/inc/IDocumentLineNumberAccess.hxx b/sw/inc/IDocumentLineNumberAccess.hxx
deleted file mode 100644
index b63d004..0000000
--- a/sw/inc/IDocumentLineNumberAccess.hxx
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SW_INC_IDOCUMENTLINENUMBERACCESS_HXX
-#define INCLUDED_SW_INC_IDOCUMENTLINENUMBERACCESS_HXX
-
-#include <sal/types.h>
-
-class SwLineNumberInfo;
-
-/** Access to the line number information
- */
-class IDocumentLineNumberAccess
-{
-public:
-
-    virtual const SwLineNumberInfo& GetLineNumberInfo() const = 0;
-    virtual void SetLineNumberInfo(const SwLineNumberInfo& rInfo) = 0;
-
-protected:
-    virtual ~IDocumentLineNumberAccess() {};
-};
-
-#endif // INCLUDED_SW_INC_IDOCUMENTLINENUMBERACCESS_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 18bb670b..6aa5ba3 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -23,7 +23,6 @@
 #include <IInterface.hxx>
 #include <IDocumentMarkAccess.hxx>
 #include <IDocumentStylePoolAccess.hxx>
-#include <IDocumentLineNumberAccess.hxx>
 #include <IDocumentStatistics.hxx>
 #include <IDocumentState.hxx>
 #include <IDocumentLayoutAccess.hxx>
@@ -251,7 +250,6 @@ void StartGrammarChecking( SwDoc &rDoc );
 class SW_DLLPUBLIC SwDoc :
     public IInterface,
     public IDocumentStylePoolAccess,
-    public IDocumentLineNumberAccess,
     public IDocumentStatistics,
     public IDocumentState,
     public IDocumentLayoutAccess,
@@ -563,9 +561,9 @@ public:
     virtual bool IsPoolFmtUsed( sal_uInt16 nId ) const SAL_OVERRIDE;
     virtual bool IsPoolPageDescUsed( sal_uInt16 nId ) const SAL_OVERRIDE;
 
-    // IDocumentLineNumberAccess
-    virtual const SwLineNumberInfo& GetLineNumberInfo() const SAL_OVERRIDE;
-    virtual void SetLineNumberInfo(const SwLineNumberInfo& rInfo) SAL_OVERRIDE;
+    // SwLineNumberInfo
+    virtual const SwLineNumberInfo& GetLineNumberInfo() const;
+    virtual void SetLineNumberInfo(const SwLineNumberInfo& rInfo);
 
     // IDocumentStatistics
     virtual void DocInfoChgd() SAL_OVERRIDE;
diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index 4de9d18..a42d2df 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -67,7 +67,6 @@ class IDocumentDeviceAccess;
 class IDocumentMarkAccess;
 class IDocumentRedlineAccess;
 class IDocumentStylePoolAccess;
-class IDocumentLineNumberAccess;
 class IDocumentLinksAdministration;
 class IDocumentFieldsAccess;
 class IDocumentContentOperations;
@@ -224,10 +223,6 @@ public:
      */
     const IDocumentStylePoolAccess* getIDocumentStylePoolAccess() const;
 
-    /** Provides access to the document line number information interface
-     */
-    const IDocumentLineNumberAccess* getIDocumentLineNumberAccess() const;
-
     /** Provides access to the document draw model interface
      */
     const IDocumentDrawModelAccess* getIDocumentDrawModelAccess() const;
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 5f65870..0cb7220 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -1925,7 +1925,6 @@ const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return
 const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return &GetDoc()->getIDocumentDeviceAccess(); }
 const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return &GetDoc()->getIDocumentRedlineAccess(); }
 const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); }
-const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); }
 const IDocumentDrawModelAccess* SwNode::getIDocumentDrawModelAccess() const { return & GetDoc()->getIDocumentDrawModelAccess(); }
 const IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() const { return GetDoc(); }
 IDocumentLayoutAccess* SwNode::getIDocumentLayoutAccess() { return GetDoc(); }
diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx
index 06f08b5..36345d1 100644
--- a/sw/source/core/text/frmpaint.cxx
+++ b/sw/source/core/text/frmpaint.cxx
@@ -49,7 +49,6 @@
 #include <EnhancedPDFExportHelper.hxx>
 
 #include <IDocumentStylePoolAccess.hxx>
-#include <IDocumentLineNumberAccess.hxx>
 
 #define REDLINE_DISTANCE 567/4
 #define REDLINE_MINDIST  567/10
@@ -288,7 +287,7 @@ void SwTxtFrm::PaintExtraData( const SwRect &rRect ) const
 
     const SwTxtNode& rTxtNode = *GetTxtNode();
     const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess();
-    const SwLineNumberInfo &rLineInf = rTxtNode.getIDocumentLineNumberAccess()->GetLineNumberInfo();
+    const SwLineNumberInfo &rLineInf = rTxtNode.GetDoc()->GetLineNumberInfo();
     const SwFmtLineNumber &rLineNum = GetAttrSet()->GetLineNumber();
     bool bLineNum = !IsInTab() && rLineInf.IsPaintLineNumbers() &&
                ( !IsInFly() || rLineInf.IsCountInFlys() ) && rLineNum.IsCount();
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 3ed835e..cdefa85 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -2375,7 +2375,7 @@ void SwTxtFrm::ChgThisLines()
 {
     // not necessary to format here (GerFormatted etc.), because we have to come from there!
     sal_uLong nNew = 0;
-    const SwLineNumberInfo &rInf = GetNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo();
+    const SwLineNumberInfo &rInf = GetNode()->GetDoc()->GetLineNumberInfo();
     if ( !GetTxt().isEmpty() && HasPara() )
     {
         SwTxtSizeInfo aInf( this );
@@ -2437,7 +2437,7 @@ void SwTxtFrm::RecalcAllLines()
         const sal_uLong nOld = GetAllLines();
         const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber();
         sal_uLong nNewNum;
-        const bool bRestart = GetTxtNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo().IsRestartEachPage();
+        const bool bRestart = GetTxtNode()->GetDoc()->GetLineNumberInfo().IsRestartEachPage();
 
         if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
             nNewNum = rLineNum.GetStartValue() - 1;
commit 794f156c1933f078ebcbd99ab3842cccb86ea24b
Author: Valentin Kettner <vakevk+libreoffice at gmail.com>
Date:   Thu Jul 24 16:46:12 2014 +0200

    Refactored IDocumentFieldsAccess out of SwDoc.
    
    Into the new class DocumentFieldsManager.
    Removed SwDoc::_MakeFldList because it is not defined anywhere.
    Also moved a few non interface methods that belong to the manager.
    
    Change-Id: Icefd7ca7adcbb05a18d6fae0529fc54150b862fd

diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 849ca27..98b9338 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -196,6 +196,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
     sw/source/core/doc/DocumentOutlineNodesManager \
     sw/source/core/doc/DocumentContentOperationsManager \
     sw/source/core/doc/DocumentRedlineManager \
+    sw/source/core/doc/DocumentFieldsManager \
     sw/source/core/doc/extinput \
     sw/source/core/doc/fmtcol \
     sw/source/core/doc/ftnidx \
diff --git a/sw/inc/IDocumentFieldsAccess.hxx b/sw/inc/IDocumentFieldsAccess.hxx
index 0b8c38b..5566047 100644
--- a/sw/inc/IDocumentFieldsAccess.hxx
+++ b/sw/inc/IDocumentFieldsAccess.hxx
@@ -37,6 +37,8 @@ class _SetGetExpFld;
 struct SwHash;
 class SwNode;
 
+namespace rtl { class OUString; }
+using rtl::OUString;
 namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }
 
  /** Document fields related interfaces
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 0a1eb82..18bb670b 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -22,7 +22,6 @@
 // SwDoc interfaces
 #include <IInterface.hxx>
 #include <IDocumentMarkAccess.hxx>
-#include <IDocumentFieldsAccess.hxx>
 #include <IDocumentStylePoolAccess.hxx>
 #include <IDocumentLineNumberAccess.hxx>
 #include <IDocumentStatistics.hxx>
@@ -213,6 +212,7 @@ namespace sw {
     class DocumentOutlineNodesManager;
     class DocumentContentOperationsManager;
     class DocumentRedlineManager;
+    class DocumentFieldsManager;
 }
 
 namespace com { namespace sun { namespace star {
@@ -250,7 +250,6 @@ void StartGrammarChecking( SwDoc &rDoc );
 // Represents the model of a Writer document.
 class SW_DLLPUBLIC SwDoc :
     public IInterface,
-    public IDocumentFieldsAccess,
     public IDocumentStylePoolAccess,
     public IDocumentLineNumberAccess,
     public IDocumentStatistics,
@@ -294,6 +293,7 @@ class SW_DLLPUBLIC SwDoc :
     const ::boost::scoped_ptr< ::sw::DocumentListsManager > m_pDocumentListsManager;
     const ::boost::scoped_ptr< ::sw::DocumentOutlineNodesManager > m_pDocumentOutlineNodesManager;
     const ::boost::scoped_ptr< ::sw::DocumentContentOperationsManager > m_pDocumentContentOperationsManager;
+    const ::boost::scoped_ptr< ::sw::DocumentFieldsManager > m_pDocumentFieldsManager;
 
     // Pointer
     SwFrmFmt        *mpDfltFrmFmt;       //< Default formats.
@@ -316,8 +316,6 @@ class SW_DLLPUBLIC SwDoc :
 
     SwViewShell       *mpCurrentView;  //< SwDoc should get a new member mpCurrentView
 
-    SwDocUpdtFld    *mpUpdtFlds;         //< Struct for updating fields
-    SwFldTypes      *mpFldTypes;
     SwDBManager         *mpDBManager;            /**< Pointer to the DBManager for
                                          evaluation of DB-fields. */
 
@@ -374,7 +372,6 @@ private:
     sal_uInt32  mnRsidRoot;          //< session ID when the document was created
 
     sal_Int32   mReferenceCount;
-    sal_Int8    mnLockExpFld;        //< If != 0 UpdateExpFlds() has no effect!
 
     bool mbGlossDoc              : 1;    //< TRUE: glossary document.
     bool mbModified              : 1;    //< TRUE: document has changed.
@@ -386,7 +383,6 @@ private:
     bool mbLoaded                : 1;    //< TRUE: Doc loaded.
     bool mbUpdateExpFld          : 1;    //< TRUE: Update expression fields.
     bool mbNewDoc                : 1;    //< TRUE: new Doc.
-    bool mbNewFldLst             : 1;    //< TRUE: Rebuild field-list.
     bool mbCopyIsMove            : 1;    //< TRUE: Copy is a hidden Move.
     bool mbInReading             : 1;    //< TRUE: Document is in the process of being read.
     bool mbInXMLImport           : 1;    //< TRUE: During xml import, attribute portion building is not necessary.
@@ -435,12 +431,7 @@ private:
     // gcc: aFtnInfo::CopyCtor is private, therefore we too have to protect ourselves.
     SwDoc( const SwDoc &);
 
-    // For fields:
-    void _InitFieldTypes();     //< Called by CTOR!!
-    void _MakeFldList( int eMode );
-
     // Database fields:
-    void UpdateDBNumFlds( SwDBNameInfField& rDBFld, SwCalc& rCalc );
     void AddUsedDBToList( std::vector<OUString>& rDBNameList,
                           const std::vector<OUString>& rUsedDBNames );
     void AddUsedDBToList( std::vector<OUString>& rDBNameList, const OUString& rDBName );
@@ -545,45 +536,11 @@ public:
     ::sw::DocumentLinksAdministrationManager & GetDocumentLinksAdministrationManager();
 
     // IDocumentFieldsAccess
-    virtual const SwFldTypes *GetFldTypes() const SAL_OVERRIDE;
-    virtual SwFieldType *InsertFldType(const SwFieldType &) SAL_OVERRIDE;
-    virtual SwFieldType *GetSysFldType( const sal_uInt16 eWhich ) const SAL_OVERRIDE;
-    virtual SwFieldType* GetFldType(sal_uInt16 nResId, const OUString& rName, bool bDbFieldMatching) const SAL_OVERRIDE;
-    virtual void RemoveFldType(sal_uInt16 nFld) SAL_OVERRIDE;
-    virtual void UpdateFlds( SfxPoolItem* pNewHt, bool bCloseDB) SAL_OVERRIDE;
-    virtual void InsDeletedFldType(SwFieldType &) SAL_OVERRIDE;
-    virtual bool PutValueToField(const SwPosition & rPos, const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich) SAL_OVERRIDE;
-    virtual bool UpdateFld(SwTxtFld * rDstFmtFld, SwField & rSrcFld, SwMsgPoolItem * pMsgHnt, bool bUpdateTblFlds) SAL_OVERRIDE;
-    virtual void UpdateRefFlds(SfxPoolItem* pHt) SAL_OVERRIDE;
-    virtual void UpdateTblFlds(SfxPoolItem* pHt) SAL_OVERRIDE;
-    virtual void UpdateExpFlds(SwTxtFld* pFld, bool bUpdateRefFlds) SAL_OVERRIDE;
-    virtual void UpdateUsrFlds() SAL_OVERRIDE;
-    virtual void UpdatePageFlds(SfxPoolItem*) SAL_OVERRIDE;
-    virtual void LockExpFlds() SAL_OVERRIDE;
-    virtual void UnlockExpFlds() SAL_OVERRIDE;
-    virtual bool IsExpFldsLocked() const SAL_OVERRIDE;
-    virtual SwDocUpdtFld& GetUpdtFlds() const SAL_OVERRIDE;
-    virtual bool SetFieldsDirty(bool b, const SwNode* pChk, sal_uLong nLen) SAL_OVERRIDE;
-    virtual void SetFixFields(bool bOnlyTimeDate, const DateTime* pNewDateTime) SAL_OVERRIDE;
-    virtual void FldsToCalc(SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt) SAL_OVERRIDE;
-    virtual void FldsToCalc(SwCalc& rCalc, const _SetGetExpFld& rToThisFld) SAL_OVERRIDE;
-    virtual void FldsToExpand(SwHash**& ppTbl, sal_uInt16& rTblSize, const _SetGetExpFld& rToThisFld) SAL_OVERRIDE;
-    virtual bool IsNewFldLst() const SAL_OVERRIDE;
-    virtual void SetNewFldLst( bool bFlag) SAL_OVERRIDE;
-    virtual void InsDelFldInFldLst(bool bIns, const SwTxtFld& rFld) SAL_OVERRIDE;
-
-    /** Returns the field at a certain position.
-       @param rPos position to search at
-       @return pointer to field at the given position or NULL in case no field is found
-    */
-    static SwField* GetFieldAtPos(const SwPosition& rPos);
+    IDocumentFieldsAccess const & getIDocumentFieldsAccess() const;
+    IDocumentFieldsAccess & getIDocumentFieldsAccess();
 
-    /** Returns the field at a certain position.
-       @param rPos position to search at
-       @return pointer to field at the given position or NULL in case no field is found
-    */
-    static SwTxtFld* GetTxtFldAtPos(const SwPosition& rPos);
-    bool containsUpdatableFields();
+    ::sw::DocumentFieldsManager const & GetDocumentFieldsMAnager() const;
+    ::sw::DocumentFieldsManager & GetDocumentFieldsManager();
 
     // IDocumentContentOperations
     IDocumentContentOperations const & getIDocumentContentOperations() const;
@@ -991,9 +948,6 @@ public:
         return &(maPatternNms[nPos]);
     }
 
-    // Delete all unreferenced field types.
-    void GCFieldTypes();    //< impl. in docfld.cxx
-
     // Query / connect current document with glossary document.
     void SetGlossaryDoc( SwDoc* pDoc ) { mpGlossaryDoc = pDoc; }
 
diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index e9e3b6f..2c7c75a 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -126,7 +126,7 @@ public:
     /// the destructor will free all objects still in the vector
     ~SwFldTypes();
     sal_uInt16 GetPos(const SwFieldType* pFieldType) const;
-    void dumpAsXml(xmlTextWriterPtr w);
+    void dumpAsXml(xmlTextWriterPtr w) const;
 };
 
 class SwTOXTypes : public std::vector<SwTOXType*> {
diff --git a/sw/qa/core/uwriter.cxx b/sw/qa/core/uwriter.cxx
index d58f5bc..b3464af 100644
--- a/sw/qa/core/uwriter.cxx
+++ b/sw/qa/core/uwriter.cxx
@@ -33,6 +33,7 @@
 #include "breakit.hxx"
 #include "doc.hxx"
 #include <IDocumentRedlineAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include "docsh.hxx"
 #include "docstat.hxx"
 #include "docufld.hxx"
@@ -597,7 +598,7 @@ void SwDocTest::testSwScanner()
 
         DateTime aDate(DateTime::SYSTEM);
         SwPostItField aPostIt(
-            (SwPostItFieldType*)m_pDoc->GetSysFldType(RES_POSTITFLD), OUString("An Author"),
+            (SwPostItFieldType*)m_pDoc->getIDocumentFieldsAccess().GetSysFldType(RES_POSTITFLD), OUString("An Author"),
             OUString("Some Text"), OUString("Initials"), OUString("Name"), aDate );
         m_pDoc->getIDocumentContentOperations().InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0);
 
diff --git a/sw/source/core/attr/format.cxx b/sw/source/core/attr/format.cxx
index ddd183e..dc090bb 100644
--- a/sw/source/core/attr/format.cxx
+++ b/sw/source/core/attr/format.cxx
@@ -766,7 +766,7 @@ IDocumentDrawModelAccess* SwFmt::getIDocumentDrawModelAccess() { return & GetDoc
 const IDocumentLayoutAccess* SwFmt::getIDocumentLayoutAccess() const { return GetDoc(); }
 IDocumentLayoutAccess* SwFmt::getIDocumentLayoutAccess() { return GetDoc(); }
 IDocumentTimerAccess* SwFmt::getIDocumentTimerAccess() { return & GetDoc()->getIDocumentTimerAccess(); }
-IDocumentFieldsAccess* SwFmt::getIDocumentFieldsAccess() { return GetDoc(); }
+IDocumentFieldsAccess* SwFmt::getIDocumentFieldsAccess() { return &GetDoc()->getIDocumentFieldsAccess(); }
 IDocumentChartDataProviderAccess* SwFmt::getIDocumentChartDataProviderAccess() { return & GetDoc()->getIDocumentChartDataProviderAccess(); }
 
 void SwFmt::GetGrabBagItem(uno::Any& rVal) const
diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx
index 5e637d0..5b95e33 100644
--- a/sw/source/core/bastyp/calc.cxx
+++ b/sw/source/core/bastyp/calc.cxx
@@ -32,6 +32,7 @@
 #include <docfld.hxx>
 #include <docstat.hxx>
 #include <doc.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <editeng/langitem.hxx>
 #include <editeng/scripttypeitem.hxx>
 #include <editeng/unolingu.hxx>
@@ -456,7 +457,7 @@ SwCalcExp* SwCalc::VarLook( const OUString& rStr, sal_uInt16 ins )
     if( !pFnd )
     {
         // then check doc
-        SwHash** ppDocTbl = rDoc.GetUpdtFlds().GetFldTypeTable();
+        SwHash** ppDocTbl = rDoc.getIDocumentFieldsAccess().GetUpdtFlds().GetFldTypeTable();
         for( SwHash* pEntry = *(ppDocTbl+ii); pEntry; pEntry = pEntry->pNext )
         {
             if( aStr == pEntry->aStr )
diff --git a/sw/source/core/crsr/annotationmark.cxx b/sw/source/core/crsr/annotationmark.cxx
index 95faaa5..faa379c 100644
--- a/sw/source/core/crsr/annotationmark.cxx
+++ b/sw/source/core/crsr/annotationmark.cxx
@@ -21,6 +21,7 @@
 
 #include <doc.hxx>
 #include <IDocumentMarkAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <fldbas.hxx>
 #include <switerator.hxx>
 #include <fmtfld.hxx>
@@ -88,7 +89,7 @@ namespace sw { namespace mark
 
         SwFmtFld* pAnnotationFmtFld = NULL;
 
-        SwFieldType* pType = pDoc->GetFldType( RES_POSTITFLD, OUString(), false );
+        SwFieldType* pType = pDoc->getIDocumentFieldsAccess().GetFldType( RES_POSTITFLD, OUString(), false );
         SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld != NULL; pFmtFld = aIter.Next() )
         {
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index e953e2c..ae728f7 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -28,6 +28,7 @@
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
 #include <IDocumentRedlineAccess.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <pagefrm.hxx>
 #include <cntfrm.hxx>
 #include <rootfrm.hxx>
@@ -628,7 +629,7 @@ bool SwCrsrShell::MoveFldType(
         if( RES_INPUTFLD == pFldType->Which() && bAddSetExpressionFldsToInputFlds )
         {
             // there are hidden input fields in the set exp. fields
-            const SwFldTypes& rFldTypes = *mpDoc->GetFldTypes();
+            const SwFldTypes& rFldTypes = *mpDoc->getIDocumentFieldsAccess().GetFldTypes();
             const size_t nSize = rFldTypes.size();
             for( size_t i=0; i < nSize; ++i )
             {
@@ -642,7 +643,7 @@ bool SwCrsrShell::MoveFldType(
     }
     else
     {
-        const SwFldTypes& rFldTypes = *mpDoc->GetFldTypes();
+        const SwFldTypes& rFldTypes = *mpDoc->getIDocumentFieldsAccess().GetFldTypes();
         const size_t nSize = rFldTypes.size();
         for( size_t i=0; i < nSize; ++i )
         {
@@ -675,7 +676,7 @@ bool SwCrsrShell::MoveFldType(
         {
             // create dummy for the search
             SwFmtFld* pFmtFld = new SwFmtFld( SwDateTimeField(
-                (SwDateTimeFieldType*)mpDoc->GetSysFldType( RES_DATETIMEFLD ) ) );
+                (SwDateTimeFieldType*)mpDoc->getIDocumentFieldsAccess().GetSysFldType( RES_DATETIMEFLD ) ) );
 
             pTxtFld = new SwTxtFld( *pFmtFld, rPos.nContent.GetIndex(),
                         mpDoc->IsClipBoard() );
diff --git a/sw/source/core/doc/CntntIdxStore.cxx b/sw/source/core/doc/CntntIdxStore.cxx
index ee22f86..ffbd356 100644
--- a/sw/source/core/doc/CntntIdxStore.cxx
+++ b/sw/source/core/doc/CntntIdxStore.cxx
@@ -23,6 +23,7 @@
 #include <boost/make_shared.hpp>
 #include <cntfrm.hxx>
 #include <doc.hxx>
+#include <IDocumentRedlineAccess.hxx>
 #include <docary.hxx>
 #include <editsh.hxx>
 #include <fmtanchr.hxx>
@@ -264,8 +265,9 @@ void CntntIdxStoreImpl::RestoreBkmks(SwDoc* pDoc, updater_t& rUpdater)
 
 void CntntIdxStoreImpl::SaveRedlines(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCntnt)
 {
+    SwRedlineTbl const & pRedlineTbl = pDoc->getIDocumentRedlineAccess().GetRedlineTbl();
     long int nIdx = 0;
-    BOOST_FOREACH(const SwRangeRedline* pRdl, pDoc->GetRedlineTbl())
+    BOOST_FOREACH(const SwRangeRedline* pRdl, std::make_pair(pRedlineTbl.begin(), pRedlineTbl.end()))
     {
         int nPointPos = lcl_RelativePosition( *pRdl->GetPoint(), nNode, nCntnt );
         int nMarkPos = pRdl->HasMark() ? lcl_RelativePosition( *pRdl->GetMark(), nNode, nCntnt ) :
@@ -291,7 +293,7 @@ void CntntIdxStoreImpl::SaveRedlines(SwDoc* pDoc, sal_uLong nNode, sal_Int32 nCn
 
 void CntntIdxStoreImpl::RestoreRedlines(SwDoc* pDoc, updater_t& rUpdater)
 {
-    const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
+    const SwRedlineTbl& rRedlTbl = pDoc->getIDocumentRedlineAccess().GetRedlineTbl();
     BOOST_FOREACH(const MarkEntry& aEntry, m_aRedlineEntries)
     {
         SwPosition* const pPos = (SwPosition*)( aEntry.m_bOther
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx
new file mode 100644
index 0000000..860765f
--- /dev/null
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -0,0 +1,1663 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with &m_rSwdoc
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with &m_rSwdoc work for additional information regarding copyright
+ *   ownership. The ASF licenses &m_rSwdoc file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use &m_rSwdoc file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <DocumentFieldsManager.hxx>
+#include <config_features.h>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <dbmgr.hxx>
+#include <chpfld.hxx>
+#include <dbfld.hxx>
+#include <reffld.hxx>
+#include <flddropdown.hxx>
+#include <poolfmt.hrc>
+#include <SwUndoField.hxx>
+#include <flddat.hxx>
+#include <cntfrm.hxx>
+#include <dbfld.hxx>
+#include <section.hxx>
+#include <docufld.hxx>
+#include <switerator.hxx>
+#include <cellatr.hxx>
+#include <swtable.hxx>
+#include <frmfmt.hxx>
+#include <fmtfld.hxx>
+#include <ndtxt.hxx>
+#include <txtfld.hxx>
+#include <docfld.hxx>
+#include <hints.hxx>
+#include <docary.hxx>
+#include <fldbas.hxx>
+#include <expfld.hxx>
+#include <ddefld.hxx>
+#include <authfld.hxx>
+#include <usrfld.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+    static OUString lcl_GetDBVarName( SwDoc& rDoc, SwDBNameInfField& rDBFld )
+    {
+        SwDBData aDBData( rDBFld.GetDBData( &rDoc ));
+        OUString sDBNumNm;
+        SwDBData aDocData = rDoc.GetDBData();
+
+        if( aDBData != aDocData )
+        {
+            sDBNumNm = aDBData.sDataSource;
+            sDBNumNm += OUString(DB_DELIM);
+            sDBNumNm += aDBData.sCommand;
+            sDBNumNm += OUString(DB_DELIM);
+        }
+        sDBNumNm += SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD);
+
+        return sDBNumNm;
+    }
+
+    static void lcl_CalcFld( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpFld& rSGEFld,
+                            SwDBManager* pMgr )
+    {
+        const SwTxtFld* pTxtFld = rSGEFld.GetTxtFld();
+        if( !pTxtFld )
+            return ;
+
+        const SwField* pFld = pTxtFld->GetFmtFld().GetField();
+        const sal_uInt16 nFldWhich = pFld->GetTyp()->Which();
+
+        if( RES_SETEXPFLD == nFldWhich )
+        {
+            SwSbxValue aValue;
+            if( nsSwGetSetExpType::GSE_EXPR & pFld->GetSubType() )
+                aValue.PutDouble( ((SwSetExpField*)pFld)->GetValue() );
+            else
+                // Extension to calculate with Strings
+                aValue.PutString( ((SwSetExpField*)pFld)->GetExpStr() );
+
+            // set the new value in Calculator
+            rCalc.VarChange( pFld->GetTyp()->GetName(), aValue );
+        }
+        else if( pMgr )
+        {
+    #if !HAVE_FEATURE_DBCONNECTIVITY
+            (void) rDoc;
+    #else
+            switch( nFldWhich )
+            {
+            case RES_DBNUMSETFLD:
+                {
+                    SwDBNumSetField* pDBFld = (SwDBNumSetField*)pFld;
+
+                    SwDBData aDBData(pDBFld->GetDBData(&rDoc));
+
+                    if( pDBFld->IsCondValid() &&
+                        pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
+                        rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBFld),
+                                        pDBFld->GetFormat() );
+                }
+                break;
+            case RES_DBNEXTSETFLD:
+                {
+                    SwDBNextSetField* pDBFld = (SwDBNextSetField*)pFld;
+                    SwDBData aDBData(pDBFld->GetDBData(&rDoc));
+                    if( !pDBFld->IsCondValid() ||
+                        !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
+                        break;
+
+                    OUString sDBNumNm(lcl_GetDBVarName( rDoc, *pDBFld));
+                    SwCalcExp* pExp = rCalc.VarLook( sDBNumNm );
+                    if( pExp )
+                        rCalc.VarChange( sDBNumNm, pExp->nValue.GetLong() + 1 );
+                }
+                break;
+
+            }
+    #endif
+        }
+    }
+}
+
+namespace sw
+{
+
+DocumentFieldsManager::DocumentFieldsManager( SwDoc& i_rSwdoc ) : m_rSwdoc( i_rSwdoc ),
+                                                                  mbNewFldLst(true),
+                                                                  mpUpdtFlds( new SwDocUpdtFld( &m_rSwdoc ) ),
+                                                                  mpFldTypes( new SwFldTypes() ),
+                                                                  mnLockExpFld( 0 )
+{
+}
+
+const SwFldTypes* DocumentFieldsManager::GetFldTypes() const
+{
+    return mpFldTypes;
+}
+
+/** Insert field types
+ *
+ * @param rFldTyp ???
+ * @return Always returns a pointer to the type, if it's new or already added.
+ */
+SwFieldType* DocumentFieldsManager::InsertFldType(const SwFieldType &rFldTyp)
+{
+    sal_uInt16 nSize = mpFldTypes->size(),
+            nFldWhich = rFldTyp.Which();
+
+    sal_uInt16 i = INIT_FLDTYPES;
+
+    switch( nFldWhich )
+    {
+    case RES_SETEXPFLD:
+            //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
+            //             Or we get doubble number circles!!
+            //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rSwdoc, when
+            //constructing string pools and when reading SetExp fields
+            if( nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType&)rFldTyp).GetType() )
+                i -= INIT_SEQ_FLDTYPES;
+        // no break;
+    case RES_DBFLD:
+    case RES_USERFLD:
+    case RES_DDEFLD:
+        {
+            const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
+            OUString sFldNm( rFldTyp.GetName() );
+            for( ; i < nSize; ++i )
+                if( nFldWhich == (*mpFldTypes)[i]->Which() &&
+                    rSCmp.isEqual( sFldNm, (*mpFldTypes)[i]->GetName() ))
+                        return (*mpFldTypes)[i];
+        }
+        break;
+
+    case RES_AUTHORITY:
+        for( ; i < nSize; ++i )
+            if( nFldWhich == (*mpFldTypes)[i]->Which() )
+                return (*mpFldTypes)[i];
+        break;
+
+    default:
+        for( i = 0; i < nSize; ++i )
+            if( nFldWhich == (*mpFldTypes)[i]->Which() )
+                return (*mpFldTypes)[i];
+    }
+
+    SwFieldType* pNew = rFldTyp.Copy();
+    switch( nFldWhich )
+    {
+    case RES_DDEFLD:
+        ((SwDDEFieldType*)pNew)->SetDoc( &m_rSwdoc );
+        break;
+
+    case RES_DBFLD:
+    case RES_TABLEFLD:
+    case RES_DATETIMEFLD:
+    case RES_GETEXPFLD:
+        ((SwValueFieldType*)pNew)->SetDoc( &m_rSwdoc );
+        break;
+
+    case RES_USERFLD:
+    case RES_SETEXPFLD:
+        ((SwValueFieldType*)pNew)->SetDoc( &m_rSwdoc );
+        // JP 29.07.96: Optionally prepare FieldList for Calculator:
+        mpUpdtFlds->InsertFldType( *pNew );
+        break;
+    case RES_AUTHORITY :
+        ((SwAuthorityFieldType*)pNew)->SetDoc( &m_rSwdoc );
+        break;
+    }
+
+    mpFldTypes->insert( mpFldTypes->begin() + nSize, pNew );
+    m_rSwdoc.SetModified();
+
+    return (*mpFldTypes)[ nSize ];
+}
+
+/// @returns the field type of the Doc
+SwFieldType *DocumentFieldsManager::GetSysFldType( const sal_uInt16 eWhich ) const
+{
+    for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
+        if( eWhich == (*mpFldTypes)[i]->Which() )
+            return (*mpFldTypes)[i];
+    return 0;
+}
+
+/// Find first type with ResId and name
+SwFieldType* DocumentFieldsManager::GetFldType(
+    sal_uInt16 nResId,
+    const OUString& rName,
+    bool bDbFieldMatching // used in some UNO calls for RES_DBFLD to use different string matching code #i51815#
+    ) const
+{
+    sal_uInt16 nSize = mpFldTypes->size(), i = 0;
+    const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
+
+    switch( nResId )
+    {
+    case RES_SETEXPFLD:
+            //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
+            //             Or we get doubble number circles!!
+            //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rSwdoc, when
+            //constructing string pools and when reading SetExp fields
+        i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES;
+        break;
+
+    case RES_DBFLD:
+    case RES_USERFLD:
+    case RES_DDEFLD:
+    case RES_AUTHORITY:
+        i = INIT_FLDTYPES;
+        break;
+    }
+
+    SwFieldType* pRet = 0;
+    for( ; i < nSize; ++i )
+    {
+        SwFieldType* pFldType = (*mpFldTypes)[i];
+
+        OUString aFldName( pFldType->GetName() );
+        if (bDbFieldMatching && nResId == RES_DBFLD)    // #i51815#
+            aFldName = aFldName.replace(DB_DELIM, '.');
+
+        if( nResId == pFldType->Which() &&
+            rSCmp.isEqual( rName, aFldName ))
+        {
+            pRet = pFldType;
+            break;
+        }
+    }
+    return pRet;
+}
+
+/// Remove field type
+void DocumentFieldsManager::RemoveFldType(sal_uInt16 nFld)
+{
+    OSL_ENSURE( INIT_FLDTYPES <= nFld,  "don't remove InitFlds" );
+    /*
+     * Dependent fields present -> ErrRaise
+     */
+    sal_uInt16 nSize = mpFldTypes->size();
+    if(nFld < nSize)
+    {
+        SwFieldType* pTmp = (*mpFldTypes)[nFld];
+
+        // JP 29.07.96: Optionally prepare FldLst for Calculator
+        sal_uInt16 nWhich = pTmp->Which();
+        switch( nWhich )
+        {
+        case RES_SETEXPFLD:
+        case RES_USERFLD:
+            mpUpdtFlds->RemoveFldType( *pTmp );
+            // no break;
+        case RES_DDEFLD:
+            if( pTmp->GetDepends() && !m_rSwdoc.IsUsed( *pTmp ) )
+            {
+                if( RES_SETEXPFLD == nWhich )
+                    ((SwSetExpFieldType*)pTmp)->SetDeleted( true );
+                else if( RES_USERFLD == nWhich )
+                    ((SwUserFieldType*)pTmp)->SetDeleted( true );
+                else
+                    ((SwDDEFieldType*)pTmp)->SetDeleted( true );
+                nWhich = 0;
+            }
+            break;
+        }
+
+        if( nWhich )
+        {
+            OSL_ENSURE( !pTmp->GetDepends(), "Dependent fields present!" );
+            // delete field type
+            delete pTmp;
+        }
+        mpFldTypes->erase( mpFldTypes->begin() + nFld );
+        m_rSwdoc.SetModified();
+    }
+}
+
+// All have to be re-evaluated.
+void DocumentFieldsManager::UpdateFlds( SfxPoolItem *pNewHt, bool bCloseDB )
+{
+    // Call Modify() for every field type,
+    // dependent SwTxtFld get notified ...
+
+    for( sal_uInt16 i=0; i < mpFldTypes->size(); ++i)
+    {
+        switch( (*mpFldTypes)[i]->Which() )
+        {
+            // Update table fields second to last
+            // Update references last
+        case RES_GETREFFLD:
+        case RES_TABLEFLD:
+        case RES_DBFLD:
+        case RES_JUMPEDITFLD:
+        case RES_REFPAGESETFLD:     // are never expanded!
+            break;
+
+        case RES_DDEFLD:
+        {
+            if( !pNewHt )
+            {
+                SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
+                (*mpFldTypes)[i]->ModifyNotification( 0, &aUpdateDDE );
+            }
+            else
+                (*mpFldTypes)[i]->ModifyNotification( 0, pNewHt );
+            break;
+        }
+        case RES_GETEXPFLD:
+        case RES_SETEXPFLD:
+        case RES_HIDDENTXTFLD:
+        case RES_HIDDENPARAFLD:
+            // Expression fields are treated separately
+            if( !pNewHt )
+                break;
+        default:
+            (*mpFldTypes)[i]->ModifyNotification ( 0, pNewHt );
+        }
+    }
+
+    if( !IsExpFldsLocked() )
+        UpdateExpFlds( 0, false );      // update expression fields
+
+    // Tables
+    UpdateTblFlds(pNewHt);
+
+    // References
+    UpdateRefFlds(pNewHt);
+    if( bCloseDB )
+    {
+#if HAVE_FEATURE_DBCONNECTIVITY
+        m_rSwdoc.GetDBManager()->CloseAll();
+#endif
+    }
+    // Only evaluate on full update
+    m_rSwdoc.SetModified();
+}
+
+void DocumentFieldsManager::InsDeletedFldType( SwFieldType& rFldTyp )
+{
+    // The FldType was marked as deleted and removed from the array.
+    // One has to look &m_rSwdoc up again, now.
+    // - If it's not present, it can be re-inserted.
+    // - If the same type is found, the deleted one has to be renamed.
+
+    sal_uInt16 nSize = mpFldTypes->size(), nFldWhich = rFldTyp.Which();
+    sal_uInt16 i = INIT_FLDTYPES;
+
+    OSL_ENSURE( RES_SETEXPFLD == nFldWhich ||
+            RES_USERFLD == nFldWhich ||
+            RES_DDEFLD == nFldWhich, "Wrong FldType" );
+
+    const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
+    const OUString& rFldNm = rFldTyp.GetName();
+    SwFieldType* pFnd;
+
+    for( ; i < nSize; ++i )
+        if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
+            rSCmp.isEqual( rFldNm, pFnd->GetName() ) )
+        {
+            // find new name
+            sal_uInt16 nNum = 1;
+            do {
+                OUString sSrch = rFldNm + OUString::number( nNum );
+                for( i = INIT_FLDTYPES; i < nSize; ++i )
+                    if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
+                        rSCmp.isEqual( sSrch, pFnd->GetName() ) )
+                        break;
+
+                if( i >= nSize )        // not found
+                {
+                    ((OUString&)rFldNm) = sSrch;
+                    break;      // exit while loop
+                }
+                ++nNum;
+            } while( true );
+            break;
+        }
+
+    // not found, so insert and delete flag
+    mpFldTypes->insert( mpFldTypes->begin() + nSize, &rFldTyp );
+    switch( nFldWhich )
+    {
+    case RES_SETEXPFLD:
+        ((SwSetExpFieldType&)rFldTyp).SetDeleted( false );
+        break;
+    case RES_USERFLD:
+        ((SwUserFieldType&)rFldTyp).SetDeleted( false );
+        break;
+    case RES_DDEFLD:
+        ((SwDDEFieldType&)rFldTyp).SetDeleted( false );
+        break;
+    }
+}
+
+bool DocumentFieldsManager::PutValueToField(const SwPosition & rPos,
+                            const Any& rVal, sal_uInt16 nWhich)
+{
+    Any aOldVal;
+    SwField * pField = GetFieldAtPos(rPos);
+
+    if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo() &&
+        pField->QueryValue(aOldVal, nWhich))
+    {
+        SwUndo *const pUndo(new SwUndoFieldFromAPI(rPos, aOldVal, rVal, nWhich));
+        m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
+    }
+
+    return pField->PutValue(rVal, nWhich);
+}
+
+bool DocumentFieldsManager::UpdateFld(SwTxtFld * pDstTxtFld, SwField & rSrcFld,
+                      SwMsgPoolItem * pMsgHnt,
+                      bool bUpdateFlds)
+{
+    OSL_ENSURE(pDstTxtFld, "no field to update!");
+
+    bool bTblSelBreak = false;
+
+    SwFmtFld * pDstFmtFld = (SwFmtFld*)&pDstTxtFld->GetFmtFld();
+    SwField * pDstFld = pDstFmtFld->GetField();
+    sal_uInt16 nFldWhich = rSrcFld.GetTyp()->Which();
+    SwNodeIndex aTblNdIdx(pDstTxtFld->GetTxtNode());
+
+    if (pDstFld->GetTyp()->Which() ==
+        rSrcFld.GetTyp()->Which())
+    {
+        if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
+        {
+            SwPosition aPosition( pDstTxtFld->GetTxtNode() );
+            aPosition.nContent = pDstTxtFld->GetStart();
+
+            SwUndo *const pUndo( new SwUndoFieldFromDoc( aPosition, *pDstFld, rSrcFld, pMsgHnt, bUpdateFlds) );
+            m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
+        }
+
+        SwField * pNewFld = rSrcFld.CopyField();
+        pDstFmtFld->SetField(pNewFld);
+
+        switch( nFldWhich )
+        {
+        case RES_SETEXPFLD:
+        case RES_GETEXPFLD:
+        case RES_HIDDENTXTFLD:
+        case RES_HIDDENPARAFLD:
+            UpdateExpFlds( pDstTxtFld, true );
+            break;
+
+        case RES_TABLEFLD:
+            {
+                const SwTableNode* pTblNd =
+                    m_rSwdoc.IsIdxInTbl(aTblNdIdx);
+                if( pTblNd )
+                {
+                    SwTableFmlUpdate aTblUpdate( &pTblNd->
+                                                 GetTable() );
+                    if (bUpdateFlds)
+                        UpdateTblFlds( &aTblUpdate );
+                    else
+                        pNewFld->GetTyp()->ModifyNotification(0, &aTblUpdate);
+
+                    if (! bUpdateFlds)
+                        bTblSelBreak = true;
+                }
+            }
+            break;
+
+        case RES_MACROFLD:
+            if( bUpdateFlds && pDstTxtFld->GetpTxtNode() )
+                (pDstTxtFld->GetpTxtNode())->
+                    ModifyNotification( 0, pDstFmtFld );
+            break;
+
+        case RES_DBNAMEFLD:
+        case RES_DBNEXTSETFLD:
+        case RES_DBNUMSETFLD:
+        case RES_DBSETNUMBERFLD:
+            m_rSwdoc.ChgDBData(((SwDBNameInfField*) pNewFld)->GetRealDBData());
+            pNewFld->GetTyp()->UpdateFlds();
+
+            break;
+
+        case RES_DBFLD:
+#if HAVE_FEATURE_DBCONNECTIVITY
+            {
+                // JP 10.02.96: call ChgValue, so that the style change sets the
+                // ContentString correctly
+                SwDBField* pDBFld = (SwDBField*)pNewFld;
+                if (pDBFld->IsInitialized())
+                    pDBFld->ChgValue( pDBFld->GetValue(), true );
+
+                pDBFld->ClearInitialized();
+                pDBFld->InitContent();
+            }
+#endif
+            // no break;
+
+        default:
+            pDstFmtFld->ModifyNotification( 0, pMsgHnt );
+        }
+
+        // The fields we can calculate here are being triggered for an update
+        // here explicitly.
+        if( nFldWhich == RES_USERFLD )
+            UpdateUsrFlds();
+    }
+
+    return bTblSelBreak;
+}
+
+/// Update reference and table fields
+void DocumentFieldsManager::UpdateRefFlds( SfxPoolItem* pHt )
+{
+    SwFieldType* pFldType;
+    for( sal_uInt16 i = 0; i < mpFldTypes->size(); ++i )
+        if( RES_GETREFFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
+            pFldType->ModifyNotification( 0, pHt );
+}
+
+void DocumentFieldsManager::UpdateTblFlds( SfxPoolItem* pHt )
+{
+    OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE  == pHt->Which(),
+            "What MessageItem is &m_rSwdoc?" );
+
+    SwFieldType* pFldType(0);
+
+    for (sal_uInt16 i = 0; i < mpFldTypes->size(); ++i)
+    {
+        if( RES_TABLEFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
+        {
+            SwTableFmlUpdate* pUpdtFld = 0;
+            if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
+                pUpdtFld = (SwTableFmlUpdate*)pHt;
+
+            SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
+            for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
+            {
+                if( pFmtFld->GetTxtFld() )
+                {
+                    SwTblField* pFld = (SwTblField*)pFmtFld->GetField();
+
+                    if( pUpdtFld )
+                    {
+                        // table where &m_rSwdoc field is located
+                        const SwTableNode* pTblNd;
+                        const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
+                        if( !rTxtNd.GetNodes().IsDocNodes() ||
+                            0 == ( pTblNd = rTxtNd.FindTableNode() ) )
+                            continue;
+
+                        switch( pUpdtFld->eFlags )
+                        {
+                        case TBL_CALC:
+                            // re-set the value flag
+                            // JP 17.06.96: internal representation of all formulas
+                            //              (reference to other table!!!)
+                            if( nsSwExtendedSubType::SUB_CMD & pFld->GetSubType() )
+                                pFld->PtrToBoxNm( pUpdtFld->pTbl );
+                            else
+                                pFld->ChgValid( false );
+                            break;
+                        case TBL_BOXNAME:
+                            // is &m_rSwdoc the wanted table?
+                            if( &pTblNd->GetTable() == pUpdtFld->pTbl )
+                                // to the external representation
+                                pFld->PtrToBoxNm( pUpdtFld->pTbl );
+                            break;
+                        case TBL_BOXPTR:
+                            // to the internal representation
+                            // JP 17.06.96: internal representation on all formulas
+                            //              (reference to other table!!!)
+                            pFld->BoxNmToPtr( pUpdtFld->pTbl );
+                            break;
+                        case TBL_RELBOXNAME:
+                            // is &m_rSwdoc the wanted table?
+                            if( &pTblNd->GetTable() == pUpdtFld->pTbl )
+                                // to the relative representation
+                                pFld->ToRelBoxNm( pUpdtFld->pTbl );
+                            break;
+                        default:
+                            break;
+                        }
+                    }
+                    else
+                        // reset the value flag for all
+                        pFld->ChgValid( false );
+                }
+            }
+
+            break;
+        }
+        pFldType = 0;
+    }
+
+    // process all table box formuals
+    const SfxPoolItem* pItem;
+    sal_uInt32 nMaxItems = m_rSwdoc.GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
+    for (sal_uInt32 i = 0; i < nMaxItems; ++i)
+    {
+        if( 0 != (pItem = m_rSwdoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
+            ((SwTblBoxFormula*)pItem)->GetDefinedIn() )
+        {
+            ((SwTblBoxFormula*)pItem)->ChangeState( pHt );
+        }
+    }
+
+    // all fields/boxes are now invalid, so we can start to calculate
+    if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
+                TBL_CALC != ((SwTableFmlUpdate*)pHt)->eFlags ))
+        return ;
+
+    SwCalc* pCalc = 0;
+
+    if( pFldType )
+    {
+        SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
+        for( SwFmtFld* pFmtFld = aIter.Last(); pFmtFld; pFmtFld = aIter.Previous() )
+        {
+                // start calculation at the end
+                // new fields are inserted at the beginning of the modify chain
+                // that gives faster calculation on import
+                // mba: do we really need &m_rSwdoc "optimization"? Is it still valid?
+                SwTblField* pFld;
+                if( !pFmtFld->GetTxtFld() || (nsSwExtendedSubType::SUB_CMD &
+                    (pFld = (SwTblField*)pFmtFld->GetField())->GetSubType() ))
+                    continue;
+
+                // needs to be recalculated
+                if( !pFld->IsValid() )
+                {
+                    // table where &m_rSwdoc field is located
+                    const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
+                    if( !rTxtNd.GetNodes().IsDocNodes() )
+                        continue;
+                    const SwTableNode* pTblNd = rTxtNd.FindTableNode();
+                    if( !pTblNd )
+                        continue;
+
+                    // if &m_rSwdoc field is not in the to-be-updated table, skip it
+                    if( pHt && &pTblNd->GetTable() !=
+                                            ((SwTableFmlUpdate*)pHt)->pTbl )
+                        continue;
+
+                    if( !pCalc )
+                        pCalc = new SwCalc( m_rSwdoc );
+
+                    // get the values of all SetExpression fields that are valid
+                    // until the table
+                    SwFrm* pFrm = 0;
+                    if( pTblNd->GetIndex() < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
+                    {
+                        // is in the special section, that's expensive!
+                        Point aPt;      // return the first frame of the layout - Tab.Headline!!
+                        pFrm = rTxtNd.getLayoutFrm( m_rSwdoc.GetCurrentLayout(), &aPt );
+                        if( pFrm )
+                        {
+                            SwPosition aPos( *pTblNd );
+                            if( GetBodyTxtNode( m_rSwdoc, aPos, *pFrm ) )
+                                FldsToCalc( *pCalc, _SetGetExpFld(
+                                    aPos.nNode, pFmtFld->GetTxtFld(),
+                                    &aPos.nContent ));
+                            else
+                                pFrm = 0;
+                        }
+                    }
+                    if( !pFrm )
+                    {
+                        // create index to determine the TextNode
+                        SwNodeIndex aIdx( rTxtNd );
+                        FldsToCalc( *pCalc,
+                            _SetGetExpFld( aIdx, pFmtFld->GetTxtFld() ));
+                    }
+
+                    SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() );
+                    pFld->CalcField( aPara );
+                    if( aPara.IsStackOverflow() )
+                    {
+                        bool const bResult = aPara.CalcWithStackOverflow();
+                        if (bResult)
+                        {
+                            pFld->CalcField( aPara );
+                        }
+                        OSL_ENSURE(bResult,
+                                "the chained formula could no be calculated");
+                    }
+                    pCalc->SetCalcError( CALC_NOERR );
+                }
+                pFmtFld->ModifyNotification( 0, pHt );
+        }
+    }
+
+    // calculate the formula at the boxes
+    for (sal_uInt32 i = 0; i < nMaxItems; ++i )
+    {
+        if( 0 != (pItem = m_rSwdoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
+            ((SwTblBoxFormula*)pItem)->GetDefinedIn() &&
+            !((SwTblBoxFormula*)pItem)->IsValid() )
+        {
+            SwTblBoxFormula* pFml = (SwTblBoxFormula*)pItem;
+            SwTableBox* pBox = pFml->GetTableBox();
+            if( pBox && pBox->GetSttNd() &&
+                pBox->GetSttNd()->GetNodes().IsDocNodes() )
+            {
+                const SwTableNode* pTblNd = pBox->GetSttNd()->FindTableNode();
+                if( !pHt || &pTblNd->GetTable() ==
+                                            ((SwTableFmlUpdate*)pHt)->pTbl )
+                {
+                    double nValue;
+                    if( !pCalc )
+                        pCalc = new SwCalc( m_rSwdoc );
+
+                    // get the values of all SetExpression fields that are valid
+                    // until the table
+                    SwFrm* pFrm = 0;
+                    if( pTblNd->GetIndex() < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
+                    {
+                        // is in the special section, that's expensive!
+                        Point aPt;      // return the first frame of the layout - Tab.Headline!!
+                        SwNodeIndex aCNdIdx( *pTblNd, +2 );
+                        SwCntntNode* pCNd = aCNdIdx.GetNode().GetCntntNode();
+                        if( !pCNd )
+                            pCNd = m_rSwdoc.GetNodes().GoNext( &aCNdIdx );
+
+                        if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( m_rSwdoc.GetCurrentLayout(), &aPt )) )
+                        {
+                            SwPosition aPos( *pCNd );
+                            if( GetBodyTxtNode( m_rSwdoc, aPos, *pFrm ) )
+                                FldsToCalc( *pCalc, _SetGetExpFld( aPos.nNode ));
+                            else
+                                pFrm = 0;
+                        }
+                    }
+                    if( !pFrm )
+                    {
+                        // create index to determine the TextNode
+                        SwNodeIndex aIdx( *pTblNd );
+                        FldsToCalc( *pCalc, _SetGetExpFld( aIdx ));
+                    }
+
+                    SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() );
+                    pFml->Calc( aPara, nValue );
+
+                    if( aPara.IsStackOverflow() )
+                    {
+                        bool const bResult = aPara.CalcWithStackOverflow();
+                        if (bResult)
+                        {
+                            pFml->Calc( aPara, nValue );
+                        }
+                        OSL_ENSURE(bResult,
+                                "the chained formula could no be calculated");
+                    }
+
+                    SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
+                    SfxItemSet aTmp( m_rSwdoc.GetAttrPool(),
+                                    RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
+
+                    if( pCalc->IsCalcError() )
+                        nValue = DBL_MAX;
+                    aTmp.Put( SwTblBoxValue( nValue ));
+                    if( SFX_ITEM_SET != pFmt->GetItemState( RES_BOXATR_FORMAT ))
+                        aTmp.Put( SwTblBoxNumFormat( 0 ));
+                    pFmt->SetFmtAttr( aTmp );
+
+                    pCalc->SetCalcError( CALC_NOERR );
+                }
+            }
+        }
+    }
+
+    delete pCalc;
+}
+
+void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds )
+{
+    if( IsExpFldsLocked() || m_rSwdoc.IsInReading() )
+        return;
+
+    bool bOldInUpdateFlds = mpUpdtFlds->IsInUpdateFlds();
+    mpUpdtFlds->SetInUpdateFlds( true );
+
+    mpUpdtFlds->MakeFldList( m_rSwdoc, true, GETFLD_ALL );
+    mbNewFldLst = false;
+
+    if( mpUpdtFlds->GetSortLst()->empty() )
+    {
+        if( bUpdRefFlds )
+            UpdateRefFlds(NULL);
+
+        mpUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds );
+        mpUpdtFlds->SetFieldsDirty( false );
+        return ;
+    }
+
+    sal_uInt16 nWhich, n;
+
+    // Hash table for all string replacements is filled on-the-fly.
+    // Try to fabricate an uneven number.
+    sal_uInt16 nStrFmtCnt = (( mpFldTypes->size() / 7 ) + 1 ) * 7;
+    SwHash** pHashStrTbl = new SwHash*[ nStrFmtCnt ];
+    memset( pHashStrTbl, 0, sizeof( _HashStr* ) * nStrFmtCnt );
+
+    {
+        const SwFieldType* pFldType;
+        // process separately:
+        for( n = mpFldTypes->size(); n; )
+            switch( ( pFldType = (*mpFldTypes)[ --n ] )->Which() )
+            {
+            case RES_USERFLD:
+                {
+                    // Entry present?
+                    sal_uInt16 nPos;
+                    const OUString& rNm = pFldType->GetName();
+                    OUString sExpand(((SwUserFieldType*)pFldType)->Expand(nsSwGetSetExpType::GSE_STRING, 0, 0));
+                    SwHash* pFnd = Find( rNm, pHashStrTbl, nStrFmtCnt, &nPos );
+                    if( pFnd )
+                        // modify entry in the hash table
+                        ((_HashStr*)pFnd)->aSetStr = sExpand;
+                    else
+                        // insert the new entry
+                        *(pHashStrTbl + nPos ) = new _HashStr( rNm, sExpand,
+                                                (_HashStr*)*(pHashStrTbl + nPos) );
+                }
+                break;
+            case RES_SETEXPFLD:
+                ((SwSetExpFieldType*)pFldType)->SetOutlineChgNd( 0 );
+                break;
+            }
+    }
+
+    // The array is filled with all fields; start calculation.
+    SwCalc aCalc( m_rSwdoc );
+
+#if HAVE_FEATURE_DBCONNECTIVITY
+    OUString sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) );
+
+    // already set the current record number
+    SwDBManager* pMgr = m_rSwdoc.GetDBManager();
+    pMgr->CloseAll(false);
+#endif
+
+    // Make sure we don't hide all sections, which would lead to a crash. First, count how many of them do we have.
+    int nShownSections = 0;
+    for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != mpUpdtFlds->GetSortLst()->end(); ++it )
+    {
+        SwSection* pSect = (SwSection*)(*it)->GetSection();
+        if ( pSect && !pSect->IsCondHidden())
+            nShownSections++;
+    }
+
+    OUString aNew;
+    for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != mpUpdtFlds->GetSortLst()->end(); ++it )
+    {
+        SwSection* pSect = (SwSection*)(*it)->GetSection();
+        if( pSect )
+        {
+
+            SwSbxValue aValue = aCalc.Calculate(
+                                        pSect->GetCondition() );
+            if(!aValue.IsVoidValue())
+            {
+                // Do we want to hide &m_rSwdoc one?
+                bool bHide = aValue.GetBool();
+                if (bHide && !pSect->IsCondHidden())
+                {
+                    // This section will be hidden, but it wasn't before
+                    if (nShownSections == 1)
+                    {
+                        // Is the last node part of a section?
+                        SwPaM aPam(m_rSwdoc.GetNodes());
+                        aPam.Move(fnMoveForward, fnGoDoc);
+                        if (aPam.Start()->nNode.GetNode().StartOfSectionNode()->IsSectionNode())
+                        {
+                            // This would be the last section, so set its condition to false, and avoid hiding it.
+                            OUString aCond("0");
+                            pSect->SetCondition(aCond);
+                            bHide = false;
+                        }
+                    }
+                    nShownSections--;
+                }
+                pSect->SetCondHidden( bHide );
+            }
+            continue;
+        }
+
+        SwTxtFld* pTxtFld = (SwTxtFld*)(*it)->GetTxtFld();
+        if( !pTxtFld )
+        {
+            OSL_ENSURE( !&m_rSwdoc, "what's wrong now'" );
+            continue;
+        }
+
+        SwFmtFld* pFmtFld = (SwFmtFld*)&pTxtFld->GetFmtFld();
+        const SwField* pFld = pFmtFld->GetField();
+
+        switch( nWhich = pFld->GetTyp()->Which() )
+        {
+        case RES_HIDDENTXTFLD:
+        {
+            SwHiddenTxtField* pHFld = (SwHiddenTxtField*)pFld;
+            SwSbxValue aValue = aCalc.Calculate( pHFld->GetPar1() );
+            bool bValue = !aValue.GetBool();
+            if(!aValue.IsVoidValue())
+            {
+                pHFld->SetValue( bValue );
+                // evaluate field
+                pHFld->Evaluate(&m_rSwdoc);
+            }
+        }
+        break;
+        case RES_HIDDENPARAFLD:
+        {
+            SwHiddenParaField* pHPFld = (SwHiddenParaField*)pFld;
+            SwSbxValue aValue = aCalc.Calculate( pHPFld->GetPar1() );
+            bool bValue = aValue.GetBool();
+            if(!aValue.IsVoidValue())
+                pHPFld->SetHidden( bValue );
+        }
+        break;
+        case RES_DBSETNUMBERFLD:
+#if HAVE_FEATURE_DBCONNECTIVITY
+        {
+            ((SwDBSetNumberField*)pFld)->Evaluate(&m_rSwdoc);
+            aCalc.VarChange( sDBNumNm, ((SwDBSetNumberField*)pFld)->GetSetNumber());
+        }
+#endif
+        break;
+        case RES_DBNEXTSETFLD:
+        case RES_DBNUMSETFLD:
+#if HAVE_FEATURE_DBCONNECTIVITY
+        {
+            UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc );
+        }
+#endif
+        break;
+        case RES_DBFLD:
+        {
+#if HAVE_FEATURE_DBCONNECTIVITY
+            // evaluate field
+            ((SwDBField*)pFld)->Evaluate();
+
+            SwDBData aTmpDBData(((SwDBField*)pFld)->GetDBData());
+
+            if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
+                aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
+
+            const OUString& rName = pFld->GetTyp()->GetName();
+
+            // Add entry to hash table
+            // Entry present?
+            sal_uInt16 nPos;
+            SwHash* pFnd = Find( rName, pHashStrTbl, nStrFmtCnt, &nPos );
+            OUString const value(pFld->ExpandField(m_rSwdoc.IsClipBoard()));
+            if( pFnd )
+            {
+                // Modify entry in the hash table
+                static_cast<_HashStr*>(pFnd)->aSetStr = value;
+            }
+            else
+            {
+                // insert new entry
+                *(pHashStrTbl + nPos ) = new _HashStr( rName,
+                    value, static_cast<_HashStr *>(*(pHashStrTbl + nPos)));
+            }
+#endif
+        }
+        break;
+        case RES_GETEXPFLD:
+        case RES_SETEXPFLD:
+        {
+            if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() )        // replace String
+            {
+                if( RES_GETEXPFLD == nWhich )
+                {
+                    SwGetExpField* pGFld = (SwGetExpField*)pFld;
+
+                    if( (!pUpdtFld || pUpdtFld == pTxtFld )
+                        && pGFld->IsInBodyTxt() )
+                    {
+                        aNew = LookString( pHashStrTbl, nStrFmtCnt,
+                                    pGFld->GetFormula() );
+                        pGFld->ChgExpStr( aNew );
+                    }
+                }
+                else
+                {
+                    SwSetExpField* pSFld = (SwSetExpField*)pFld;
+                    // is the "formula" a field?
+                    aNew = LookString( pHashStrTbl, nStrFmtCnt,
+                                pSFld->GetFormula() );
+
+                    if( aNew.isEmpty() )               // nothing found then the formula is the new value
+                        aNew = pSFld->GetFormula();
+
+                    // only update one field
+                    if( !pUpdtFld || pUpdtFld == pTxtFld )
+                        pSFld->ChgExpStr( aNew );
+
+                    // lookup the field's name
+                    aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName();
+                    // Entry present?
+                    sal_uInt16 nPos;
+                    SwHash* pFnd = Find( aNew, pHashStrTbl, nStrFmtCnt, &nPos );
+                    if( pFnd )
+                        // Modify entry in the hash table
+                        ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr();
+                    else
+                        // insert new entry
+                        *(pHashStrTbl + nPos ) = pFnd = new _HashStr( aNew,
+                                        pSFld->GetExpStr(),
+                                        (_HashStr*)*(pHashStrTbl + nPos) );
+
+                    // Extension for calculation with Strings
+                    SwSbxValue aValue;
+                    aValue.PutString( ((_HashStr*)pFnd)->aSetStr );
+                    aCalc.VarChange( aNew, aValue );
+                }
+            }
+            else            // recalculate formula
+            {
+                if( RES_GETEXPFLD == nWhich )
+                {
+                    SwGetExpField* pGFld = (SwGetExpField*)pFld;
+
+                    if( (!pUpdtFld || pUpdtFld == pTxtFld )
+                        && pGFld->IsInBodyTxt() )
+                    {
+                        SwSbxValue aValue = aCalc.Calculate(
+                                        pGFld->GetFormula());
+                        if(!aValue.IsVoidValue())
+                            pGFld->SetValue(aValue.GetDouble() );
+                    }
+                }
+                else
+                {
+                    SwSetExpField* pSFld = (SwSetExpField*)pFld;
+                    SwSetExpFieldType* pSFldTyp = (SwSetExpFieldType*)pFld->GetTyp();
+                    aNew = pSFldTyp->GetName();
+
+                    SwNode* pSeqNd = 0;
+
+                    if( pSFld->IsSequenceFld() )
+                    {
+                        const sal_uInt8 nLvl = pSFldTyp->GetOutlineLvl();
+                        if( MAXLEVEL > nLvl )
+                        {
+                            // test if the Number needs to be updated
+                            pSeqNd = m_rSwdoc.GetNodes()[ (*it)->GetNode() ];
+
+                            const SwTxtNode* pOutlNd = pSeqNd->
+                                    FindOutlineNodeOfLevel( nLvl );
+                            if( pSFldTyp->GetOutlineChgNd() != pOutlNd )
+                            {
+                                pSFldTyp->SetOutlineChgNd( pOutlNd );
+                                aCalc.VarChange( aNew, 0 );
+                            }
+                        }
+                    }
+
+                    aNew += "=";
+                    aNew += pSFld->GetFormula();
+
+                    SwSbxValue aValue = aCalc.Calculate( aNew );
+                    double nErg = aValue.GetDouble();
+                    // only update one field
+                    if( !aValue.IsVoidValue() && (!pUpdtFld || pUpdtFld == pTxtFld) )
+                    {
+                        pSFld->SetValue( nErg );
+
+                        if( pSeqNd )
+                            pSFldTyp->SetChapter( *pSFld, *pSeqNd );
+                    }
+                }
+            }
+        }
+        } // switch
+
+        pFmtFld->ModifyNotification( 0, 0 );        // trigger formatting
+
+        if( pUpdtFld == pTxtFld )       // if only &m_rSwdoc one is updated
+        {
+            if( RES_GETEXPFLD == nWhich ||      // only GetField or
+                RES_HIDDENTXTFLD == nWhich ||   // HiddenTxt?
+                RES_HIDDENPARAFLD == nWhich)    // HiddenParaFld?
+                break;                          // quit
+            pUpdtFld = 0;                       // update all from here on
+        }
+    }
+
+#if HAVE_FEATURE_DBCONNECTIVITY
+    pMgr->CloseAll(false);
+#endif
+    // delete hash table
+    ::DeleteHashTable( pHashStrTbl, nStrFmtCnt );
+
+    // update reference fields
+    if( bUpdRefFlds )
+        UpdateRefFlds(NULL);
+
+    mpUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds );
+    mpUpdtFlds->SetFieldsDirty( false );
+}
+
+/// Insert field type that was marked as deleted
+void DocumentFieldsManager::UpdateUsrFlds()
+{
+    SwCalc* pCalc = 0;
+    const SwFieldType* pFldType;
+    for( sal_uInt16 i = INIT_FLDTYPES; i < mpFldTypes->size(); ++i )
+        if( RES_USERFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
+        {
+            if( !pCalc )
+                pCalc = new SwCalc( m_rSwdoc );
+            ((SwUserFieldType*)pFldType)->GetValue( *pCalc );
+        }
+
+    if( pCalc )
+    {
+        delete pCalc;
+        m_rSwdoc.SetModified();
+    }
+}
+
+void DocumentFieldsManager::UpdatePageFlds( SfxPoolItem* pMsgHnt )
+{
+    SwFieldType* pFldType;
+    for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
+        switch( ( pFldType = (*mpFldTypes)[ i ] )->Which() )
+        {
+        case RES_PAGENUMBERFLD:
+        case RES_CHAPTERFLD:
+        case RES_GETEXPFLD:
+        case RES_REFPAGEGETFLD:
+            pFldType->ModifyNotification( 0, pMsgHnt );
+            break;
+        case RES_DOCSTATFLD:
+            pFldType->ModifyNotification( 0, 0 );
+            break;
+        }
+    SetNewFldLst(true);
+}
+
+void DocumentFieldsManager::LockExpFlds()
+{
+    ++mnLockExpFld;
+}
+
+void DocumentFieldsManager::UnlockExpFlds()
+{
+    if( mnLockExpFld )
+        --mnLockExpFld;
+}
+
+bool DocumentFieldsManager::IsExpFldsLocked() const
+{
+    return 0 != mnLockExpFld;
+}
+
+SwDocUpdtFld& DocumentFieldsManager::GetUpdtFlds() const
+{
+    return *mpUpdtFlds;
+}
+
+bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
+{
+    // See if the supplied nodes actually contain fields.
+    // If they don't, the flag doesn't need to be changed.
+    bool bFldsFnd = false;
+    if( b && pChk && !GetUpdtFlds().IsFieldsDirty() && !m_rSwdoc.IsInDtor()
+        // ?? what's up with Undo, this is also wanted there!
+        /*&& &pChk->GetNodes() == &GetNodes()*/ )
+    {
+        b = false;
+        if( !nLen )
+            ++nLen;
+        sal_uLong nStt = pChk->GetIndex();
+        const SwNodes& rNds = pChk->GetNodes();
+        while( nLen-- )
+        {
+            const SwTxtNode* pTNd = rNds[ nStt++ ]->GetTxtNode();
+            if( pTNd )
+            {
+                if( pTNd->GetAttrOutlineLevel() != 0 )
+                    // update chapter fields
+                    b = true;
+                else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
+                {
+                    const size_t nEnd = pTNd->GetSwpHints().Count();
+                    for( size_t n = 0 ; n < nEnd; ++n )
+                    {
+                        const SwTxtAttr* pAttr = pTNd->GetSwpHints()[ n ];
+                        if ( pAttr->Which() == RES_TXTATR_FIELD )
+                        {
+                            b = true;
+                            break;
+                        }
+                    }
+                }
+
+                if( b )
+                    break;
+            }
+        }
+        bFldsFnd = b;
+    }
+    GetUpdtFlds().SetFieldsDirty( b );
+    return bFldsFnd;
+}
+
+void DocumentFieldsManager::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime )
+{
+    bool bIsModified = m_rSwdoc.IsModified();
+
+    sal_Int32 nDate;
+    sal_Int64 nTime;
+    if( pNewDateTime )
+    {
+        nDate = pNewDateTime->GetDate();
+        nTime = pNewDateTime->GetTime();
+    }
+    else
+    {
+        nDate = Date( Date::SYSTEM ).GetDate();
+        nTime = Time( Time::SYSTEM ).GetTime();
+    }
+
+    sal_uInt16 aTypes[5] = {
+        /*0*/   RES_DOCINFOFLD,
+        /*1*/   RES_AUTHORFLD,
+        /*2*/   RES_EXTUSERFLD,
+        /*3*/   RES_FILENAMEFLD,
+        /*4*/   RES_DATETIMEFLD };  // MUST be at the end!
+
+    sal_uInt16 nStt = bOnlyTimeDate ? 4 : 0;
+
+    for( ; nStt < 5; ++nStt )
+    {
+        SwFieldType* pFldType = GetSysFldType( aTypes[ nStt ] );
+        SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
+        for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
+        {
+            if( pFmtFld && pFmtFld->GetTxtFld() )
+            {
+                bool bChgd = false;
+                switch( aTypes[ nStt ] )
+                {
+                case RES_DOCINFOFLD:
+                    if( ((SwDocInfoField*)pFmtFld->GetField())->IsFixed() )
+                    {
+                        bChgd = true;
+                        SwDocInfoField* pDocInfFld = (SwDocInfoField*)pFmtFld->GetField();
+                        pDocInfFld->SetExpansion( ((SwDocInfoFieldType*)
+                                    pDocInfFld->GetTyp())->Expand(
+                                        pDocInfFld->GetSubType(),
+                                        pDocInfFld->GetFormat(),
+                                        pDocInfFld->GetLanguage(),
+                                        pDocInfFld->GetName() ) );
+                    }
+                    break;
+
+                case RES_AUTHORFLD:
+                    if( ((SwAuthorField*)pFmtFld->GetField())->IsFixed() )
+                    {
+                        bChgd = true;
+                        SwAuthorField* pAuthorFld = (SwAuthorField*)pFmtFld->GetField();
+                        pAuthorFld->SetExpansion( ((SwAuthorFieldType*)
+                                    pAuthorFld->GetTyp())->Expand(
+                                                pAuthorFld->GetFormat() ) );
+                    }
+                    break;
+
+                case RES_EXTUSERFLD:
+                    if( ((SwExtUserField*)pFmtFld->GetField())->IsFixed() )
+                    {
+                        bChgd = true;
+                        SwExtUserField* pExtUserFld = (SwExtUserField*)pFmtFld->GetField();
+                        pExtUserFld->SetExpansion( ((SwExtUserFieldType*)
+                                    pExtUserFld->GetTyp())->Expand(
+                                            pExtUserFld->GetSubType(),
+                                            pExtUserFld->GetFormat()));
+                    }
+                    break;
+
+                case RES_DATETIMEFLD:
+                    if( ((SwDateTimeField*)pFmtFld->GetField())->IsFixed() )
+                    {
+                        bChgd = true;
+                        ((SwDateTimeField*)pFmtFld->GetField())->SetDateTime(
+                                                    DateTime(Date(nDate), Time(nTime)) );
+                    }
+                    break;
+
+                case RES_FILENAMEFLD:
+                    if( ((SwFileNameField*)pFmtFld->GetField())->IsFixed() )
+                    {
+                        bChgd = true;
+                        SwFileNameField* pFileNameFld =
+                            (SwFileNameField*)pFmtFld->GetField();
+                        pFileNameFld->SetExpansion( ((SwFileNameFieldType*)
+                                    pFileNameFld->GetTyp())->Expand(
+                                            pFileNameFld->GetFormat() ) );
+                    }
+                    break;
+                }
+
+                // Trigger formatting
+                if( bChgd )
+                    pFmtFld->ModifyNotification( 0, 0 );
+            }
+        }
+    }
+
+    if( !bIsModified )
+        m_rSwdoc.ResetModified();
+}
+
+
+void DocumentFieldsManager::FldsToCalc( SwCalc& rCalc, const _SetGetExpFld& rToThisFld )
+{
+    // create the sorted list of all SetFields
+    mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_CALC );
+    mbNewFldLst = false;
+
+#if !HAVE_FEATURE_DBCONNECTIVITY
+    SwDBManager* pMgr = NULL;
+#else
+    SwDBManager* pMgr = m_rSwdoc.GetDBManager();
+    pMgr->CloseAll(false);
+#endif
+
+    if( !mpUpdtFlds->GetSortLst()->empty() )
+    {
+        _SetGetExpFlds::const_iterator const itLast =
+            mpUpdtFlds->GetSortLst()->upper_bound(
+                const_cast<_SetGetExpFld*>(&rToThisFld));
+        for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != itLast; ++it )
+            ::lcl_CalcFld( m_rSwdoc, rCalc, **it, pMgr );
+    }
+#if HAVE_FEATURE_DBCONNECTIVITY
+    pMgr->CloseAll(false);
+#endif
+}
+
+void DocumentFieldsManager::FldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt )
+{
+    // create the sorted list of all SetFields
+    mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_CALC );
+    mbNewFldLst = false;
+
+#if !HAVE_FEATURE_DBCONNECTIVITY
+    SwDBManager* pMgr = NULL;
+#else
+    SwDBManager* pMgr = m_rSwdoc.GetDBManager();
+    pMgr->CloseAll(false);
+#endif
+
+    for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin();
+        it != mpUpdtFlds->GetSortLst()->end() &&
+        ( (*it)->GetNode() < nLastNd ||
+          ( (*it)->GetNode() == nLastNd && (*it)->GetCntnt() <= nLastCnt )
+        );
+        ++it )
+    {
+        ::lcl_CalcFld( m_rSwdoc, rCalc, **it, pMgr );
+    }
+
+#if HAVE_FEATURE_DBCONNECTIVITY
+    pMgr->CloseAll(false);
+#endif
+}
+
+void DocumentFieldsManager::FldsToExpand( SwHash**& ppHashTbl, sal_uInt16& rTblSize,
+                            const _SetGetExpFld& rToThisFld )
+{
+    // create the sorted list of all SetFields
+    mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_EXPAND );
+    mbNewFldLst = false;
+
+    // Hash table for all string replacements is filled on-the-fly.
+    // Try to fabricate an uneven number.
+    rTblSize = (( mpUpdtFlds->GetSortLst()->size() / 7 ) + 1 ) * 7;
+    ppHashTbl = new SwHash*[ rTblSize ];
+    memset( ppHashTbl, 0, sizeof( _HashStr* ) * rTblSize );
+
+    _SetGetExpFlds::const_iterator const itLast =
+        mpUpdtFlds->GetSortLst()->upper_bound(
+            const_cast<_SetGetExpFld*>(&rToThisFld));
+
+    for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != itLast; ++it )
+    {
+        const SwTxtFld* pTxtFld = (*it)->GetTxtFld();
+        if( !pTxtFld )
+            continue;
+
+        const SwField* pFld = pTxtFld->GetFmtFld().GetField();
+        switch( pFld->GetTyp()->Which() )
+        {
+        case RES_SETEXPFLD:
+            if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() )
+            {
+                // set the new value in the hash table
+                // is the formula a field?
+                SwSetExpField* pSFld = (SwSetExpField*)pFld;
+                OUString aNew = LookString( ppHashTbl, rTblSize, pSFld->GetFormula() );
+
+                if( aNew.isEmpty() )               // nothing found, then the formula is
+                    aNew = pSFld->GetFormula(); // the new value
+
+                // #i3141# - update expression of field as in method
+                // <DocumentFieldsManager::UpdateExpFlds(..)> for string/text fields
+                pSFld->ChgExpStr( aNew );
+
+                // look up the field's name
+                aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName();
+                // Entry present?
+                sal_uInt16 nPos;
+                SwHash* pFnd = Find( aNew, ppHashTbl, rTblSize, &nPos );
+                if( pFnd )
+                    // modify entry in the hash table
+                    ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr();
+                else
+                    // insert the new entry
+                    *(ppHashTbl + nPos ) = new _HashStr( aNew,
+                            pSFld->GetExpStr(), (_HashStr*)*(ppHashTbl + nPos) );
+            }
+            break;
+        case RES_DBFLD:
+            {
+                const OUString& rName = pFld->GetTyp()->GetName();
+
+                // Insert entry in the hash table
+                // Entry present?
+                sal_uInt16 nPos;
+                SwHash* pFnd = Find( rName, ppHashTbl, rTblSize, &nPos );
+                OUString const value(pFld->ExpandField(m_rSwdoc.IsClipBoard()));
+                if( pFnd )
+                {
+                    // modify entry in the hash table
+                    static_cast<_HashStr*>(pFnd)->aSetStr = value;
+                }
+                else
+                {
+                    // insert the new entry
+                    *(ppHashTbl + nPos ) = new _HashStr( rName,
+                        value, static_cast<_HashStr *>(*(ppHashTbl + nPos)));
+                }
+            }
+            break;
+        }
+    }
+}
+
+bool DocumentFieldsManager::IsNewFldLst() const
+{
+    return mbNewFldLst;
+}
+
+void DocumentFieldsManager::SetNewFldLst(bool bFlag)
+{
+    mbNewFldLst = bFlag;
+}
+
+void DocumentFieldsManager::InsDelFldInFldLst( bool bIns, const SwTxtFld& rFld )
+{
+    if( !mbNewFldLst || !m_rSwdoc.IsInDtor() )
+        mpUpdtFlds->InsDelFldInFldLst( bIns, rFld );
+}
+
+SwField * DocumentFieldsManager::GetFieldAtPos(const SwPosition & rPos)
+{
+    SwTxtFld * const pAttr = GetTxtFldAtPos(rPos);
+
+    return (pAttr) ? const_cast<SwField *>( pAttr->GetFmtFld().GetField() ) : 0;
+}
+
+SwTxtFld * DocumentFieldsManager::GetTxtFldAtPos(const SwPosition & rPos)
+{
+    SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode();
+
+    return (pNode != NULL)
+        ? pNode->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true )
+        : 0;
+}
+
+/// @note For simplicity assume that all field types have updatable contents so
+///       optimization currently only available when no fields exist.
+bool DocumentFieldsManager::containsUpdatableFields()
+{
+    for (sal_uInt16 i = 0; i < mpFldTypes->size(); ++i)
+    {
+        SwFieldType* pFldType = (*mpFldTypes)[i];
+        SwIterator<SwFmtFld,SwFieldType> aIter(*pFldType);
+        if (aIter.First())
+            return true;
+    }
+    return false;
+}
+
+/// Remove all unreferenced field types of a document
+void DocumentFieldsManager::GCFieldTypes()
+{
+    for( sal_uInt16 n = mpFldTypes->size(); n > INIT_FLDTYPES; )
+        if( !(*mpFldTypes)[ --n ]->GetDepends() )
+            RemoveFldType( n );
+}
+
+void DocumentFieldsManager::_InitFieldTypes()       // is being called by the CTOR
+{
+    // Field types
+    mpFldTypes->push_back( new SwDateTimeFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwChapterFieldType );
+    mpFldTypes->push_back( new SwPageNumberFieldType );
+    mpFldTypes->push_back( new SwAuthorFieldType );
+    mpFldTypes->push_back( new SwFileNameFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwDBNameFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwGetExpFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwGetRefFieldType( &m_rSwdoc ) );
+    mpFldTypes->push_back( new SwHiddenTxtFieldType );
+    mpFldTypes->push_back( new SwPostItFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwDocStatFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwDocInfoFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwInputFieldType( &m_rSwdoc ) );
+    mpFldTypes->push_back( new SwTblFieldType( &m_rSwdoc ) );
+    mpFldTypes->push_back( new SwMacroFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwHiddenParaFieldType );
+    mpFldTypes->push_back( new SwDBNextSetFieldType );
+    mpFldTypes->push_back( new SwDBNumSetFieldType );
+    mpFldTypes->push_back( new SwDBSetNumberFieldType );
+    mpFldTypes->push_back( new SwTemplNameFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwTemplNameFieldType(&m_rSwdoc) );
+    mpFldTypes->push_back( new SwExtUserFieldType );
+    mpFldTypes->push_back( new SwRefPageSetFieldType );
+    mpFldTypes->push_back( new SwRefPageGetFieldType( &m_rSwdoc ) );
+    mpFldTypes->push_back( new SwJumpEditFieldType( &m_rSwdoc ) );
+    mpFldTypes->push_back( new SwScriptFieldType( &m_rSwdoc ) );
+    mpFldTypes->push_back( new SwCombinedCharFieldType );
+    mpFldTypes->push_back( new SwDropDownFieldType );
+
+    // Types have to be at the end!
+    // We expect &m_rSwdoc in the InsertFldType!
+    // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
+    //               lcl_sw3io_InSetExpField (sw3field.cxx) now also
+    mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
+                SW_RESSTR(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
+    mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
+                SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
+    mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
+                SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
+    mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
+                SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
+
+    assert( mpFldTypes->size() == INIT_FLDTYPES );
+}
+
+void DocumentFieldsManager::ClearFieldTypes()
+{
+    for(SwFldTypes::const_iterator it = mpFldTypes->begin() + INIT_FLDTYPES;
+        it != mpFldTypes->end(); ++it)
+        delete *it;
+    mpFldTypes->erase( mpFldTypes->begin() + INIT_FLDTYPES, mpFldTypes->end() );
+}
+
+void DocumentFieldsManager::UpdateDBNumFlds( SwDBNameInfField& rDBFld, SwCalc& rCalc )
+{
+#if !HAVE_FEATURE_DBCONNECTIVITY
+    (void) rDBFld;
+    (void) rCalc;
+#else
+    SwDBManager* pMgr = m_rSwdoc.GetDBManager();
+
+    sal_uInt16 nFldType = rDBFld.Which();
+
+    bool bPar1 = rCalc.Calculate( rDBFld.GetPar1() ).GetBool();
+
+    if( RES_DBNEXTSETFLD == nFldType )
+        ((SwDBNextSetField&)rDBFld).SetCondValid( bPar1 );
+    else
+        ((SwDBNumSetField&)rDBFld).SetCondValid( bPar1 );
+
+    if( !rDBFld.GetRealDBData().sDataSource.isEmpty() )
+    {
+        // Edit a certain database
+        if( RES_DBNEXTSETFLD == nFldType )
+            ((SwDBNextSetField&)rDBFld).Evaluate(&m_rSwdoc);
+        else
+            ((SwDBNumSetField&)rDBFld).Evaluate(&m_rSwdoc);
+
+        SwDBData aTmpDBData( rDBFld.GetDBData(&m_rSwdoc) );
+
+        if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand, -1, false ))
+            rCalc.VarChange( lcl_GetDBVarName( m_rSwdoc, rDBFld),
+                        pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
+    }
+    else
+    {
+        OSL_FAIL("TODO: what should happen with unnamed DBFields?");
+    }
+#endif
+}
+
+DocumentFieldsManager::~DocumentFieldsManager()
+{
+    delete mpUpdtFlds;
+    delete mpFldTypes;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/DocumentTimerManager.cxx b/sw/source/core/doc/DocumentTimerManager.cxx
index d99f3da..3acbaf9 100644
--- a/sw/source/core/doc/DocumentTimerManager.cxx
+++ b/sw/source/core/doc/DocumentTimerManager.cxx
@@ -20,6 +20,7 @@
 
 #include <doc.hxx>
 #include <DocumentSettingManager.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <rootfrm.hxx>
 #include <viewsh.hxx>
 #include <unotools/lingucfg.hxx>
@@ -125,20 +126,20 @@ IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer *, pTimer )
         SwFldUpdateFlags nFldUpdFlag = m_rSwdoc.GetDocumentSettingManager().getFieldUpdateFlags(true);
         if( ( AUTOUPD_FIELD_ONLY == nFldUpdFlag
                     || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) &&
-                m_rSwdoc.GetUpdtFlds().IsFieldsDirty()
+                m_rSwdoc.getIDocumentFieldsAccess().GetUpdtFlds().IsFieldsDirty()
                 // If we switch the field name the Fields are not updated.
                 // So the "backgorund update" should always be carried out
                 /* && !pStartSh->GetViewOptions()->IsFldName()*/ )
         {
-            if ( m_rSwdoc.GetUpdtFlds().IsInUpdateFlds() ||
-                 m_rSwdoc.IsExpFldsLocked() )
+            if ( m_rSwdoc.getIDocumentFieldsAccess().GetUpdtFlds().IsInUpdateFlds() ||
+                 m_rSwdoc.getIDocumentFieldsAccess().IsExpFldsLocked() )
             {
                 pTimer->Start();
                 return 0;
             }
 
             //  Action brackets!
-            m_rSwdoc.GetUpdtFlds().SetInUpdateFlds( true );
+            m_rSwdoc.getIDocumentFieldsAccess().GetUpdtFlds().SetInUpdateFlds( true );
 
             pTmpRoot->StartAllAction();
 
@@ -146,17 +147,17 @@ IMPL_LINK( DocumentTimerManager, DoIdleJobs, Timer *, pTimer )
             const bool bOldLockView = pStartSh->IsViewLocked();
             pStartSh->LockView( true );
 
-            m_rSwdoc.GetSysFldType( RES_CHAPTERFLD )->ModifyNotification( 0, 0 );    // ChapterField
-            m_rSwdoc.UpdateExpFlds( 0, false );      // Updates ExpressionFields
-            m_rSwdoc.UpdateTblFlds(NULL);                // Tables
-            m_rSwdoc.UpdateRefFlds(NULL);                // References
+            m_rSwdoc.getIDocumentFieldsAccess().GetSysFldType( RES_CHAPTERFLD )->ModifyNotification( 0, 0 );    // ChapterField
+            m_rSwdoc.getIDocumentFieldsAccess().UpdateExpFlds( 0, false );      // Updates ExpressionFields
+            m_rSwdoc.getIDocumentFieldsAccess().UpdateTblFlds(NULL);                // Tables
+            m_rSwdoc.getIDocumentFieldsAccess().UpdateRefFlds(NULL);                // References
 
             pTmpRoot->EndAllAction();
 
             pStartSh->LockView( bOldLockView );
 
-            m_rSwdoc.GetUpdtFlds().SetInUpdateFlds( false );
-            m_rSwdoc.GetUpdtFlds().SetFieldsDirty( false );
+            m_rSwdoc.getIDocumentFieldsAccess().GetUpdtFlds().SetInUpdateFlds( false );
+            m_rSwdoc.getIDocumentFieldsAccess().GetUpdtFlds().SetFieldsDirty( false );
         }
     }
 #ifdef TIMELOG
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index a7034e4..3e5a320 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -29,6 +29,7 @@
 #include <DocumentOutlineNodesManager.hxx>
 #include <DocumentContentOperationsManager.hxx>
 #include <DocumentRedlineManager.hxx>
+#include <DocumentFieldsManager.hxx>
 #include <UndoManager.hxx>
 #include <hintids.hxx>
 #include <tools/shl.hxx>
@@ -383,6 +384,28 @@ IDocumentRedlineAccess& SwDoc::getIDocumentRedlineAccess()
     return *m_pDocumentRedlineManager;
 }
 
+//IDocumentFieldsAccess
+
+IDocumentFieldsAccess const & SwDoc::getIDocumentFieldsAccess() const
+{
+    return *m_pDocumentFieldsManager;
+}
+
+IDocumentFieldsAccess & SwDoc::getIDocumentFieldsAccess()
+{
+    return *m_pDocumentFieldsManager;
+}
+
+::sw::DocumentFieldsManager const & SwDoc::GetDocumentFieldsMAnager() const
+{
+    return *m_pDocumentFieldsManager;
+}
+
+::sw::DocumentFieldsManager & SwDoc::GetDocumentFieldsManager()
+{
+    return *m_pDocumentFieldsManager;
+}
+
 /* Implementations the next Interface here */
 
 /*
@@ -396,20 +419,11 @@ void SwDoc::ChgDBData(const SwDBData& rNewData)
         maDBData = rNewData;
         SetModified();
     }
-    GetSysFldType(RES_DBNAMEFLD)->UpdateFlds();
+    getIDocumentFieldsAccess().GetSysFldType(RES_DBNAMEFLD)->UpdateFlds();
 }
 
 
 
-/// @returns the field type of the Doc
-SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const
-{
-    for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
-        if( eWhich == (*mpFldTypes)[i]->Which() )
-            return (*mpFldTypes)[i];
-    return 0;
-}
-
 void SwDoc::SetDocStat( const SwDocStat& rStat )
 {
     *mpDocStat = rStat;
@@ -1006,7 +1020,7 @@ bool SwDoc::IncrementalDocStatCalculate(long nChars, bool bFields)
 
     // #i93174#: notes contain paragraphs that are not nodes
     {
-        SwFieldType * const pPostits( GetSysFldType(RES_POSTITFLD) );
+        SwFieldType * const pPostits( getIDocumentFieldsAccess().GetSysFldType(RES_POSTITFLD) );
         SwIterator<SwFmtFld,SwFieldType> aIter( *pPostits );
         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld;  pFmtFld = aIter.Next() )
         {
@@ -1068,7 +1082,7 @@ bool SwDoc::IncrementalDocStatCalculate(long nChars, bool bFields)
     // optionally update stat. fields
     if (bFields)
     {
-        SwFieldType *pType = GetSysFldType(RES_DOCSTATFLD);
+        SwFieldType *pType = getIDocumentFieldsAccess().GetSysFldType(RES_DOCSTATFLD);
         pType->UpdateFlds();
     }
 
@@ -1104,8 +1118,8 @@ void SwDoc::UpdateDocStat( bool bCompleteAsync, bool bFields )
 
 void SwDoc::DocInfoChgd( )
 {
-    GetSysFldType( RES_DOCINFOFLD )->UpdateFlds();
-    GetSysFldType( RES_TEMPLNAMEFLD )->UpdateFlds();
+    getIDocumentFieldsAccess().GetSysFldType( RES_DOCINFOFLD )->UpdateFlds();
+    getIDocumentFieldsAccess().GetSysFldType( RES_TEMPLNAMEFLD )->UpdateFlds();
     SetModified();
 }
 
@@ -1456,7 +1470,7 @@ bool SwDoc::RemoveInvisibleContent()
 
     {
         SwTxtNode* pTxtNd;
-        SwIterator<SwFmtFld,SwFieldType> aIter( *GetSysFldType( RES_HIDDENPARAFLD )  );
+        SwIterator<SwFmtFld,SwFieldType> aIter( *getIDocumentFieldsAccess().GetSysFldType( RES_HIDDENPARAFLD )  );
         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld;  pFmtFld = aIter.Next() )
         {
             if( pFmtFld->GetTxtFld() &&
@@ -1620,7 +1634,7 @@ bool SwDoc::HasInvisibleContent() const
 {
     bool bRet = false;
 
-    SwClientIter aIter( *GetSysFldType( RES_HIDDENPARAFLD ) );
+    SwClientIter aIter( *getIDocumentFieldsAccess().GetSysFldType( RES_HIDDENPARAFLD ) );
     if( aIter.First( TYPE( SwFmtFld ) ) )
         bRet = true;
 
@@ -1676,10 +1690,10 @@ bool SwDoc::RestoreInvisibleContent()
 bool SwDoc::ConvertFieldsToText()
 {
     bool bRet = false;
-    LockExpFlds();
+    getIDocumentFieldsAccess().LockExpFlds();
     GetIDocumentUndoRedo().StartUndo( UNDO_UI_REPLACE, NULL );
 
-    const SwFldTypes* pMyFldTypes = GetFldTypes();
+    const SwFldTypes* pMyFldTypes = getIDocumentFieldsAccess().GetFldTypes();
     sal_uInt16 nCount = pMyFldTypes->size();
     //go backward, field types are removed
     for(sal_uInt16 nType = nCount;  nType > 0;  --nType)
@@ -1747,7 +1761,7 @@ bool SwDoc::ConvertFieldsToText()
     if( bRet )
         SetModified();
     GetIDocumentUndoRedo().EndUndo( UNDO_UI_REPLACE, NULL );
-    UnlockExpFlds();
+    getIDocumentFieldsAccess().UnlockExpFlds();
     return bRet;
 
 }
@@ -1834,22 +1848,6 @@ OUString SwDoc::GetPaMDescr(const SwPaM & rPam) const
     return OUString("??");
 }
 
-SwField * SwDoc::GetFieldAtPos(const SwPosition & rPos)
-{
-    SwTxtFld * const pAttr = GetTxtFldAtPos(rPos);
-
-    return (pAttr) ? const_cast<SwField *>( pAttr->GetFmtFld().GetField() ) : 0;
-}
-
-SwTxtFld * SwDoc::GetTxtFldAtPos(const SwPosition & rPos)
-{
-    SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode();
-
-    return (pNode != NULL)
-        ? pNode->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true )
-        : 0;
-}
-
 bool SwDoc::ContainsHiddenChars() const
 {
     for( sal_uLong n = GetNodes().Count(); n; )
diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index 9630543..e10e9aa 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -34,6 +34,7 @@
 #include <mdiexp.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <DocumentContentOperationsManager.hxx>
 #include <docary.hxx>
 #include <rootfrm.hxx>
@@ -395,8 +396,8 @@ void SwDoc::ChgPageDesc( sal_uInt16 i, const SwPageDesc &rChged )
     {
         pDesc->SetNumType( rChged.GetNumType() );
         // Notify page number fields that NumFormat has changed
-        GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds();
-        GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds();
+        getIDocumentFieldsAccess().GetSysFldType( RES_PAGENUMBERFLD )->UpdateFlds();
+        getIDocumentFieldsAccess().GetSysFldType( RES_REFPAGEGETFLD )->UpdateFlds();
 
         // If the numbering scheme has changed we could have QuoVadis/ErgoSum texts
         // that refer to a changed page, so we invalidate foot notes.
diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index 3288259..00562e0 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -30,6 +30,7 @@
 #include <unotools/transliterationwrapper.hxx>
 #include <doc.hxx>
 #include <IDocumentUndoRedo.hxx>
+#include <IDocumentFieldsAccess.hxx>
 #include <cntfrm.hxx>
 #include <pam.hxx>
 #include <ndtxt.hxx>
@@ -63,653 +64,6 @@
 
 using namespace ::com::sun::star::uno;
 
-/** Insert field types
- *
- * @param rFldTyp ???
- * @return Always returns a pointer to the type, if it's new or already added.
- */
-SwFieldType* SwDoc::InsertFldType(const SwFieldType &rFldTyp)
-{
-    sal_uInt16 nSize = mpFldTypes->size(),
-            nFldWhich = rFldTyp.Which();
-
-    sal_uInt16 i = INIT_FLDTYPES;
-
-    switch( nFldWhich )
-    {
-    case RES_SETEXPFLD:
-            //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
-            //             Or we get doubble number circles!!
-            //MIB 14.03.95: From now on also the SW3-Reader relies on this, when
-            //constructing string pools and when reading SetExp fields
-            if( nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType&)rFldTyp).GetType() )
-                i -= INIT_SEQ_FLDTYPES;
-        // no break;
-    case RES_DBFLD:
-    case RES_USERFLD:
-    case RES_DDEFLD:
-        {
-            const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
-            OUString sFldNm( rFldTyp.GetName() );
-            for( ; i < nSize; ++i )
-                if( nFldWhich == (*mpFldTypes)[i]->Which() &&
-                    rSCmp.isEqual( sFldNm, (*mpFldTypes)[i]->GetName() ))
-                        return (*mpFldTypes)[i];
-        }
-        break;
-
-    case RES_AUTHORITY:
-        for( ; i < nSize; ++i )
-            if( nFldWhich == (*mpFldTypes)[i]->Which() )
-                return (*mpFldTypes)[i];
-        break;
-
-    default:
-        for( i = 0; i < nSize; ++i )
-            if( nFldWhich == (*mpFldTypes)[i]->Which() )
-                return (*mpFldTypes)[i];
-    }
-
-    SwFieldType* pNew = rFldTyp.Copy();
-    switch( nFldWhich )
-    {
-    case RES_DDEFLD:
-        ((SwDDEFieldType*)pNew)->SetDoc( this );
-        break;
-
-    case RES_DBFLD:
-    case RES_TABLEFLD:
-    case RES_DATETIMEFLD:
-    case RES_GETEXPFLD:
-        ((SwValueFieldType*)pNew)->SetDoc( this );
-        break;
-
-    case RES_USERFLD:
-    case RES_SETEXPFLD:
-        ((SwValueFieldType*)pNew)->SetDoc( this );
-        // JP 29.07.96: Optionally prepare FieldList for Calculator:
-        mpUpdtFlds->InsertFldType( *pNew );
-        break;
-    case RES_AUTHORITY :
-        ((SwAuthorityFieldType*)pNew)->SetDoc( this );
-        break;
-    }
-
-    mpFldTypes->insert( mpFldTypes->begin() + nSize, pNew );
-    SetModified();
-
-    return (*mpFldTypes)[ nSize ];
-}
-
-/// Insert field type that was marked as deleted
-void SwDoc::InsDeletedFldType( SwFieldType& rFldTyp )
-{
-    // The FldType was marked as deleted and removed from the array.
-    // One has to look this up again, now.
-    // - If it's not present, it can be re-inserted.
-    // - If the same type is found, the deleted one has to be renamed.
-
-    sal_uInt16 nSize = mpFldTypes->size(), nFldWhich = rFldTyp.Which();
-    sal_uInt16 i = INIT_FLDTYPES;
-
-    OSL_ENSURE( RES_SETEXPFLD == nFldWhich ||
-            RES_USERFLD == nFldWhich ||
-            RES_DDEFLD == nFldWhich, "Wrong FldType" );
-
-    const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
-    const OUString& rFldNm = rFldTyp.GetName();
-    SwFieldType* pFnd;
-
-    for( ; i < nSize; ++i )
-        if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
-            rSCmp.isEqual( rFldNm, pFnd->GetName() ) )
-        {
-            // find new name
-            sal_uInt16 nNum = 1;
-            do {
-                OUString sSrch = rFldNm + OUString::number( nNum );
-                for( i = INIT_FLDTYPES; i < nSize; ++i )
-                    if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
-                        rSCmp.isEqual( sSrch, pFnd->GetName() ) )
-                        break;
-
-                if( i >= nSize )        // not found
-                {
-                    ((OUString&)rFldNm) = sSrch;
-                    break;      // exit while loop
-                }
-                ++nNum;
-            } while( true );
-            break;
-        }
-
-    // not found, so insert and delete flag
-    mpFldTypes->insert( mpFldTypes->begin() + nSize, &rFldTyp );
-    switch( nFldWhich )
-    {
-    case RES_SETEXPFLD:
-        ((SwSetExpFieldType&)rFldTyp).SetDeleted( false );
-        break;
-    case RES_USERFLD:
-        ((SwUserFieldType&)rFldTyp).SetDeleted( false );
-        break;
-    case RES_DDEFLD:
-        ((SwDDEFieldType&)rFldTyp).SetDeleted( false );
-        break;
-    }
-}
-
-/// Remove field type
-void SwDoc::RemoveFldType(sal_uInt16 nFld)
-{
-    OSL_ENSURE( INIT_FLDTYPES <= nFld,  "don't remove InitFlds" );
-    /*
-     * Dependent fields present -> ErrRaise
-     */
-    sal_uInt16 nSize = mpFldTypes->size();
-    if(nFld < nSize)
-    {
-        SwFieldType* pTmp = (*mpFldTypes)[nFld];
-
-        // JP 29.07.96: Optionally prepare FldLst for Calculator
-        sal_uInt16 nWhich = pTmp->Which();
-        switch( nWhich )
-        {
-        case RES_SETEXPFLD:
-        case RES_USERFLD:
-            mpUpdtFlds->RemoveFldType( *pTmp );
-            // no break;
-        case RES_DDEFLD:
-            if( pTmp->GetDepends() && !IsUsed( *pTmp ) )
-            {
-                if( RES_SETEXPFLD == nWhich )
-                    ((SwSetExpFieldType*)pTmp)->SetDeleted( true );
-                else if( RES_USERFLD == nWhich )
-                    ((SwUserFieldType*)pTmp)->SetDeleted( true );
-                else
-                    ((SwDDEFieldType*)pTmp)->SetDeleted( true );
-                nWhich = 0;
-            }
-            break;
-        }
-
-        if( nWhich )
-        {
-            OSL_ENSURE( !pTmp->GetDepends(), "Dependent fields present!" );
-            // delete field type
-            delete pTmp;
-        }
-        mpFldTypes->erase( mpFldTypes->begin() + nFld );
-        SetModified();
-    }
-}
-
-const SwFldTypes* SwDoc::GetFldTypes() const
-{
-    return mpFldTypes;
-}
-
-/// Find first type with ResId and name
-SwFieldType* SwDoc::GetFldType(
-    sal_uInt16 nResId,
-    const OUString& rName,
-    bool bDbFieldMatching // used in some UNO calls for RES_DBFLD to use different string matching code #i51815#
-    ) const
-{
-    sal_uInt16 nSize = mpFldTypes->size(), i = 0;
-    const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
-
-    switch( nResId )
-    {
-    case RES_SETEXPFLD:
-            //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
-            //             Or we get doubble number circles!!

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list