[Libreoffice-commits] core.git: Branch 'feature/refactor-god-objects' - sw/inc sw/Library_sw.mk sw/qa sw/source

Valentin Kettner vakevk+libreoffice at gmail.com
Thu Jul 24 13:45:36 PDT 2014


 sw/Library_sw.mk                             |    1 
 sw/inc/IDocumentFieldsAccess.hxx             |    2 
 sw/inc/doc.hxx                               |   58 
 sw/inc/docary.hxx                            |    2 
 sw/qa/core/uwriter.cxx                       |    3 
 sw/source/core/attr/format.cxx               |    2 
 sw/source/core/bastyp/calc.cxx               |    3 
 sw/source/core/crsr/annotationmark.cxx       |    3 
 sw/source/core/crsr/crstrvl.cxx              |    7 
 sw/source/core/doc/DocumentFieldsManager.cxx | 1660 ++++++++++++++++++++++++
 sw/source/core/doc/DocumentTimerManager.cxx  |   21 
 sw/source/core/doc/doc.cxx                   |   68 -
 sw/source/core/doc/docdesc.cxx               |    5 
 sw/source/core/doc/docfld.cxx                | 1825 ++-------------------------
 sw/source/core/doc/docfmt.cxx                |    3 
 sw/source/core/doc/docftn.cxx                |    5 
 sw/source/core/doc/docglos.cxx               |   11 
 sw/source/core/doc/doclay.cxx                |    9 
 sw/source/core/doc/docnew.cxx                |   21 
 sw/source/core/doc/docnum.cxx                |    3 
 sw/source/core/doc/docsort.cxx               |    3 
 sw/source/core/doc/doctxm.cxx                |    5 
 sw/source/core/doc/tblcpy.cxx                |    7 
 sw/source/core/doc/tblrwcl.cxx               |    7 
 sw/source/core/docnode/ndcopy.cxx            |    5 
 sw/source/core/docnode/ndnum.cxx             |    3 
 sw/source/core/docnode/ndsect.cxx            |    5 
 sw/source/core/docnode/ndtbl.cxx             |   47 
 sw/source/core/docnode/node.cxx              |    4 
 sw/source/core/docnode/nodedump.cxx          |    5 
 sw/source/core/docnode/nodes.cxx             |   11 
 sw/source/core/docnode/section.cxx           |    9 
 sw/source/core/edit/edfld.cxx                |   31 
 sw/source/core/edit/edfldexp.cxx             |    3 
 sw/source/core/edit/edglss.cxx               |    9 
 sw/source/core/edit/editsh.cxx               |    3 
 sw/source/core/edit/edtab.cxx                |    5 
 sw/source/core/fields/authfld.cxx            |    5 
 sw/source/core/fields/dbfld.cxx              |    5 
 sw/source/core/fields/ddetbl.cxx             |    3 
 sw/source/core/fields/docufld.cxx            |    3 
 sw/source/core/fields/expfld.cxx             |   11 
 sw/source/core/fields/fldlst.cxx             |    5 
 sw/source/core/fields/reffld.cxx             |   11 
 sw/source/core/fields/usrfld.cxx             |    3 
 sw/source/core/frmedt/fecopy.cxx             |   33 
 sw/source/core/inc/DocumentFieldsManager.hxx |  106 +
 sw/source/core/layout/flowfrm.cxx            |    5 
 sw/source/core/layout/frmtool.cxx            |    3 
 sw/source/core/layout/newfrm.cxx             |    1 
 sw/source/core/layout/pagechg.cxx            |    7 
 sw/source/core/layout/tabfrm.cxx             |    3 
 sw/source/core/layout/wsfrm.cxx              |    3 
 sw/source/core/table/swtable.cxx             |    3 
 sw/source/core/text/txtfrm.cxx               |    1 
 sw/source/core/txtnode/atrfld.cxx            |    2 
 sw/source/core/txtnode/thints.cxx            |   17 
 sw/source/core/undo/SwUndoField.cxx          |   15 
 sw/source/core/undo/rolbck.cxx               |    7 
 sw/source/core/undo/unsect.cxx               |    3 
 sw/source/core/undo/untbl.cxx                |   19 
 sw/source/core/unocore/unocoll.cxx           |    5 
 sw/source/core/unocore/unofield.cxx          |   95 -
 sw/source/core/unocore/unotbl.cxx            |    5 
 sw/source/core/view/printdata.cxx            |    2 
 sw/source/core/view/viewsh.cxx               |   15 
 sw/source/core/view/vnew.cxx                 |    5 
 sw/source/core/view/vprint.cxx               |    3 
 sw/source/filter/basflt/shellio.cxx          |    5 
 sw/source/filter/html/htmlbas.cxx            |    3 
 sw/source/filter/html/htmlfld.cxx            |    5 
 sw/source/filter/html/swhtml.cxx             |    5 
 sw/source/filter/ww1/fltshell.cxx            |   11 
 sw/source/filter/ww1/w1filter.cxx            |    9 
 sw/source/filter/ww8/ww8atr.cxx              |    5 
 sw/source/filter/ww8/ww8par.cxx              |    5 
 sw/source/filter/ww8/ww8par3.cxx             |    5 
 sw/source/filter/ww8/ww8par5.cxx             |   53 
 sw/source/filter/xml/xmltbli.cxx             |    7 
 sw/source/ui/fldui/fldvar.cxx                |    3 
 sw/source/uibase/app/apphdl.cxx              |    3 
 sw/source/uibase/app/docsh2.cxx              |    5 
 sw/source/uibase/app/docst.cxx               |    3 
 sw/source/uibase/dbui/dbmgr.cxx              |    3 
 sw/source/uibase/dochdl/swdtflvr.cxx         |    7 
 sw/source/uibase/docvw/PostItMgr.cxx         |    3 
 sw/source/uibase/shells/textfld.cxx          |    3 
 sw/source/uibase/uiview/view.cxx             |    5 
 sw/source/uibase/uno/unoatxt.cxx             |    9 
 sw/source/uibase/uno/unotxdoc.cxx            |    9 
 90 files changed, 2341 insertions(+), 2103 deletions(-)

New commits:
commit 25aa05583b219d88918e7a606b9aad0c1cbdce7b
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 68f5d11..8a1a0f6 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -195,6 +195,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 94f8229..a7a20b5 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 54ececf..9e039ee 100644
--- a/sw/source/core/attr/format.cxx
+++ b/sw/source/core/attr/format.cxx
@@ -765,7 +765,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 05d4d45..ff16deb 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/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx
new file mode 100644
index 0000000..ea161c7
--- /dev/null
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -0,0 +1,1660 @@
+/* -*- 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, &m_rSwdoc is also wanted there!
+        /*&& &pChk->m_rSwdoc.GetNodes() == &m_rSwdoc.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() )
+                    for( sal_uInt16 n = 0, nEnd = pTNd->GetSwpHints().Count();
+                            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 df6bc19..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!!
-            //MIB 14.03.95: From now on also the SW3-Reader relies on this, 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;
-}
-
-// All have to be re-evaluated.
-void SwDoc::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
-        GetDBManager()->CloseAll();
-#endif
-    }
-    // Only evaluate on full update
-    SetModified();
-}
-
-void SwDoc::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( *this );
-            ((SwUserFieldType*)pFldType)->GetValue( *pCalc );
-        }
-
-    if( pCalc )
-    {
-        delete pCalc;
-        SetModified();
-    }
-}
-
-/// Update reference and table fields
-void SwDoc::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 );
-}
-
-/// @note For simplicity assume that all field types have updatable contents so
-///       optimization currently only available when no fields exist.
-bool SwDoc::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;
-}
-
-void SwDoc::UpdateTblFlds( SfxPoolItem* pHt )
-{
-    OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE  == pHt->Which(),
-            "What MessageItem is this?" );
-
-    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 this 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 this 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 this 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 = GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
-    for (sal_uInt32 i = 0; i < nMaxItems; ++i)
-    {
-        if( 0 != (pItem = 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 this "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 this field is located
-                    const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
-                    if( !rTxtNd.GetNodes().IsDocNodes() )
-                        continue;
-                    const SwTableNode* pTblNd = rTxtNd.FindTableNode();
-                    if( !pTblNd )
-                        continue;
-

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list