LCOV - code coverage report
Current view: top level - sw/source/core/doc - DocumentFieldsManager.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 393 781 50.3 %
Date: 2014-11-03 Functions: 33 40 82.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with &m_rSwdoc work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #include <DocumentFieldsManager.hxx>
      20             : #include <config_features.h>
      21             : #include <doc.hxx>
      22             : #include <IDocumentUndoRedo.hxx>
      23             : #include <IDocumentState.hxx>
      24             : #include <IDocumentLayoutAccess.hxx>
      25             : #include <dbmgr.hxx>
      26             : #include <chpfld.hxx>
      27             : #include <dbfld.hxx>
      28             : #include <reffld.hxx>
      29             : #include <flddropdown.hxx>
      30             : #include <poolfmt.hrc>
      31             : #include <SwUndoField.hxx>
      32             : #include <flddat.hxx>
      33             : #include <cntfrm.hxx>
      34             : #include <section.hxx>
      35             : #include <docufld.hxx>
      36             : #include <switerator.hxx>
      37             : #include <cellatr.hxx>
      38             : #include <swtable.hxx>
      39             : #include <frmfmt.hxx>
      40             : #include <fmtfld.hxx>
      41             : #include <ndtxt.hxx>
      42             : #include <txtfld.hxx>
      43             : #include <docfld.hxx>
      44             : #include <hints.hxx>
      45             : #include <docary.hxx>
      46             : #include <fldbas.hxx>
      47             : #include <expfld.hxx>
      48             : #include <ddefld.hxx>
      49             : #include <authfld.hxx>
      50             : #include <usrfld.hxx>
      51             : #include <unotools/transliterationwrapper.hxx>
      52             : #include <com/sun/star/uno/Any.hxx>
      53             : 
      54             : using namespace ::com::sun::star::uno;
      55             : 
      56             : namespace
      57             : {
      58             :     #if HAVE_FEATURE_DBCONNECTIVITY
      59             : 
      60           0 :     static OUString lcl_GetDBVarName( SwDoc& rDoc, SwDBNameInfField& rDBFld )
      61             :     {
      62           0 :         SwDBData aDBData( rDBFld.GetDBData( &rDoc ));
      63           0 :         OUString sDBNumNm;
      64           0 :         SwDBData aDocData = rDoc.GetDBData();
      65             : 
      66           0 :         if( aDBData != aDocData )
      67             :         {
      68           0 :             sDBNumNm = aDBData.sDataSource;
      69           0 :             sDBNumNm += OUString(DB_DELIM);
      70           0 :             sDBNumNm += aDBData.sCommand;
      71           0 :             sDBNumNm += OUString(DB_DELIM);
      72             :         }
      73           0 :         sDBNumNm += SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD);
      74             : 
      75           0 :         return sDBNumNm;
      76             :     }
      77             : 
      78             :     #endif
      79             : 
      80          12 :     static void lcl_CalcFld( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpFld& rSGEFld,
      81             :                             SwDBManager* pMgr )
      82             :     {
      83          12 :         const SwTxtFld* pTxtFld = rSGEFld.GetTxtFld();
      84          12 :         if( !pTxtFld )
      85          22 :             return ;
      86             : 
      87           2 :         const SwField* pFld = pTxtFld->GetFmtFld().GetField();
      88           2 :         const sal_uInt16 nFldWhich = pFld->GetTyp()->Which();
      89             : 
      90           2 :         if( RES_SETEXPFLD == nFldWhich )
      91             :         {
      92           2 :             SwSbxValue aValue;
      93           2 :             if( nsSwGetSetExpType::GSE_EXPR & pFld->GetSubType() )
      94           2 :                 aValue.PutDouble( ((SwSetExpField*)pFld)->GetValue() );
      95             :             else
      96             :                 // Extension to calculate with Strings
      97           0 :                 aValue.PutString( ((SwSetExpField*)pFld)->GetExpStr() );
      98             : 
      99             :             // set the new value in Calculator
     100           2 :             rCalc.VarChange( pFld->GetTyp()->GetName(), aValue );
     101             :         }
     102           0 :         else if( pMgr )
     103             :         {
     104             :     #if !HAVE_FEATURE_DBCONNECTIVITY
     105             :             (void) rDoc;
     106             :     #else
     107           0 :             switch( nFldWhich )
     108             :             {
     109             :             case RES_DBNUMSETFLD:
     110             :                 {
     111           0 :                     SwDBNumSetField* pDBFld = (SwDBNumSetField*)pFld;
     112             : 
     113           0 :                     SwDBData aDBData(pDBFld->GetDBData(&rDoc));
     114             : 
     115           0 :                     if( pDBFld->IsCondValid() &&
     116           0 :                         pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
     117             :                         rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBFld),
     118           0 :                                         pDBFld->GetFormat() );
     119             :                 }
     120           0 :                 break;
     121             :             case RES_DBNEXTSETFLD:
     122             :                 {
     123           0 :                     SwDBNextSetField* pDBFld = (SwDBNextSetField*)pFld;
     124           0 :                     SwDBData aDBData(pDBFld->GetDBData(&rDoc));
     125           0 :                     if( !pDBFld->IsCondValid() ||
     126           0 :                         !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
     127           0 :                         break;
     128             : 
     129           0 :                     OUString sDBNumNm(lcl_GetDBVarName( rDoc, *pDBFld));
     130           0 :                     SwCalcExp* pExp = rCalc.VarLook( sDBNumNm );
     131           0 :                     if( pExp )
     132           0 :                         rCalc.VarChange( sDBNumNm, pExp->nValue.GetLong() + 1 );
     133             :                 }
     134           0 :                 break;
     135             : 
     136             :             }
     137             :     #endif
     138             :         }
     139             :     }
     140             : }
     141             : 
     142             : namespace sw
     143             : {
     144             : 
     145        5052 : DocumentFieldsManager::DocumentFieldsManager( SwDoc& i_rSwdoc ) : m_rSwdoc( i_rSwdoc ),
     146             :                                                                   mbNewFldLst(true),
     147        5052 :                                                                   mpUpdtFlds( new SwDocUpdtFld( &m_rSwdoc ) ),
     148             :                                                                   mpFldTypes( new SwFldTypes() ),
     149       10104 :                                                                   mnLockExpFld( 0 )
     150             : {
     151        5052 : }
     152             : 
     153       37452 : const SwFldTypes* DocumentFieldsManager::GetFldTypes() const
     154             : {
     155       37452 :     return mpFldTypes;
     156             : }
     157             : 
     158             : /** Insert field types
     159             :  *
     160             :  * @param rFldTyp ???
     161             :  * @return Always returns a pointer to the type, if it's new or already added.
     162             :  */
     163         280 : SwFieldType* DocumentFieldsManager::InsertFldType(const SwFieldType &rFldTyp)
     164             : {
     165         280 :     sal_uInt16 nSize = mpFldTypes->size(),
     166         280 :             nFldWhich = rFldTyp.Which();
     167             : 
     168         280 :     sal_uInt16 i = INIT_FLDTYPES;
     169             : 
     170         280 :     switch( nFldWhich )
     171             :     {
     172             :     case RES_SETEXPFLD:
     173             :             //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
     174             :             //             Or we get doubble number circles!!
     175             :             //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rSwdoc, when
     176             :             //constructing string pools and when reading SetExp fields
     177         126 :             if( nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType&)rFldTyp).GetType() )
     178          88 :                 i -= INIT_SEQ_FLDTYPES;
     179             :         // no break;
     180             :     case RES_DBFLD:
     181             :     case RES_USERFLD:
     182             :     case RES_DDEFLD:
     183             :         {
     184         234 :             const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
     185         234 :             OUString sFldNm( rFldTyp.GetName() );
     186         858 :             for( ; i < nSize; ++i )
     187        2840 :                 if( nFldWhich == (*mpFldTypes)[i]->Which() &&
     188        2776 :                     rSCmp.isEqual( sFldNm, (*mpFldTypes)[i]->GetName() ))
     189         234 :                         return (*mpFldTypes)[i];
     190             :         }
     191         140 :         break;
     192             : 
     193             :     case RES_AUTHORITY:
     194          46 :         for( ; i < nSize; ++i )
     195           6 :             if( nFldWhich == (*mpFldTypes)[i]->Which() )
     196           6 :                 return (*mpFldTypes)[i];
     197          40 :         break;
     198             : 
     199             :     default:
     200           0 :         for( i = 0; i < nSize; ++i )
     201           0 :             if( nFldWhich == (*mpFldTypes)[i]->Which() )
     202           0 :                 return (*mpFldTypes)[i];
     203             :     }
     204             : 
     205         180 :     SwFieldType* pNew = rFldTyp.Copy();
     206         180 :     switch( nFldWhich )
     207             :     {
     208             :     case RES_DDEFLD:
     209           0 :         ((SwDDEFieldType*)pNew)->SetDoc( &m_rSwdoc );
     210           0 :         break;
     211             : 
     212             :     case RES_DBFLD:
     213             :     case RES_TABLEFLD:
     214             :     case RES_DATETIMEFLD:
     215             :     case RES_GETEXPFLD:
     216          52 :         ((SwValueFieldType*)pNew)->SetDoc( &m_rSwdoc );
     217          52 :         break;
     218             : 
     219             :     case RES_USERFLD:
     220             :     case RES_SETEXPFLD:
     221          88 :         ((SwValueFieldType*)pNew)->SetDoc( &m_rSwdoc );
     222             :         // JP 29.07.96: Optionally prepare FieldList for Calculator:
     223          88 :         mpUpdtFlds->InsertFldType( *pNew );
     224          88 :         break;
     225             :     case RES_AUTHORITY :
     226          40 :         ((SwAuthorityFieldType*)pNew)->SetDoc( &m_rSwdoc );
     227          40 :         break;
     228             :     }
     229             : 
     230         180 :     mpFldTypes->insert( mpFldTypes->begin() + nSize, pNew );
     231         180 :     m_rSwdoc.getIDocumentState().SetModified();
     232             : 
     233         180 :     return (*mpFldTypes)[ nSize ];
     234             : }
     235             : 
     236             : /// @returns the field type of the Doc
     237       42514 : SwFieldType *DocumentFieldsManager::GetSysFldType( const sal_uInt16 eWhich ) const
     238             : {
     239      368007 :     for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
     240      368007 :         if( eWhich == (*mpFldTypes)[i]->Which() )
     241       42514 :             return (*mpFldTypes)[i];
     242           0 :     return 0;
     243             : }
     244             : 
     245             : /// Find first type with ResId and name
     246        8418 : SwFieldType* DocumentFieldsManager::GetFldType(
     247             :     sal_uInt16 nResId,
     248             :     const OUString& rName,
     249             :     bool bDbFieldMatching // used in some UNO calls for RES_DBFLD to use different string matching code #i51815#
     250             :     ) const
     251             : {
     252        8418 :     sal_uInt16 nSize = mpFldTypes->size(), i = 0;
     253        8418 :     const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
     254             : 
     255        8418 :     switch( nResId )
     256             :     {
     257             :     case RES_SETEXPFLD:
     258             :             //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
     259             :             //             Or we get doubble number circles!!
     260             :             //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rSwdoc, when
     261             :             //constructing string pools and when reading SetExp fields
     262        3346 :         i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES;
     263        3346 :         break;
     264             : 
     265             :     case RES_DBFLD:
     266             :     case RES_USERFLD:
     267             :     case RES_DDEFLD:
     268             :     case RES_AUTHORITY:
     269         276 :         i = INIT_FLDTYPES;
     270         276 :         break;
     271             :     }
     272             : 
     273        8418 :     SwFieldType* pRet = 0;
     274       58256 :     for( ; i < nSize; ++i )
     275             :     {
     276       57904 :         SwFieldType* pFldType = (*mpFldTypes)[i];
     277             : 
     278       57904 :         OUString aFldName( pFldType->GetName() );
     279       57904 :         if (bDbFieldMatching && nResId == RES_DBFLD)    // #i51815#
     280           4 :             aFldName = aFldName.replace(DB_DELIM, '.');
     281             : 
     282       72258 :         if( nResId == pFldType->Which() &&
     283       14354 :             rSCmp.isEqual( rName, aFldName ))
     284             :         {
     285        8066 :             pRet = pFldType;
     286        8066 :             break;
     287             :         }
     288       49838 :     }
     289        8418 :     return pRet;
     290             : }
     291             : 
     292             : /// Remove field type
     293          50 : void DocumentFieldsManager::RemoveFldType(sal_uInt16 nFld)
     294             : {
     295             :     OSL_ENSURE( INIT_FLDTYPES <= nFld,  "don't remove InitFlds" );
     296             :     /*
     297             :      * Dependent fields present -> ErrRaise
     298             :      */
     299          50 :     sal_uInt16 nSize = mpFldTypes->size();
     300          50 :     if(nFld < nSize)
     301             :     {
     302          50 :         SwFieldType* pTmp = (*mpFldTypes)[nFld];
     303             : 
     304             :         // JP 29.07.96: Optionally prepare FldLst for Calculator
     305          50 :         sal_uInt16 nWhich = pTmp->Which();
     306          50 :         switch( nWhich )
     307             :         {
     308             :         case RES_SETEXPFLD:
     309             :         case RES_USERFLD:
     310           0 :             mpUpdtFlds->RemoveFldType( *pTmp );
     311             :             // no break;
     312             :         case RES_DDEFLD:
     313           0 :             if( pTmp->GetDepends() && !m_rSwdoc.IsUsed( *pTmp ) )
     314             :             {
     315           0 :                 if( RES_SETEXPFLD == nWhich )
     316           0 :                     ((SwSetExpFieldType*)pTmp)->SetDeleted( true );
     317           0 :                 else if( RES_USERFLD == nWhich )
     318           0 :                     ((SwUserFieldType*)pTmp)->SetDeleted( true );
     319             :                 else
     320           0 :                     ((SwDDEFieldType*)pTmp)->SetDeleted( true );
     321           0 :                 nWhich = 0;
     322             :             }
     323           0 :             break;
     324             :         }
     325             : 
     326          50 :         if( nWhich )
     327             :         {
     328             :             OSL_ENSURE( !pTmp->GetDepends(), "Dependent fields present!" );
     329             :             // delete field type
     330           0 :             delete pTmp;
     331             :         }
     332          50 :         mpFldTypes->erase( mpFldTypes->begin() + nFld );
     333          50 :         m_rSwdoc.getIDocumentState().SetModified();
     334             :     }
     335          50 : }
     336             : 
     337             : // All have to be re-evaluated.
     338         154 : void DocumentFieldsManager::UpdateFlds( SfxPoolItem *pNewHt, bool bCloseDB )
     339             : {
     340             :     // Call Modify() for every field type,
     341             :     // dependent SwTxtFld get notified ...
     342             : 
     343        5134 :     for( sal_uInt16 i=0; i < mpFldTypes->size(); ++i)
     344             :     {
     345        4980 :         switch( (*mpFldTypes)[i]->Which() )
     346             :         {
     347             :             // Update table fields second to last
     348             :             // Update references last
     349             :         case RES_GETREFFLD:
     350             :         case RES_TABLEFLD:
     351             :         case RES_DBFLD:
     352             :         case RES_JUMPEDITFLD:
     353             :         case RES_REFPAGESETFLD:     // are never expanded!
     354         658 :             break;
     355             : 
     356             :         case RES_DDEFLD:
     357             :         {
     358           0 :             if( !pNewHt )
     359             :             {
     360           0 :                 SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
     361           0 :                 (*mpFldTypes)[i]->ModifyNotification( 0, &aUpdateDDE );
     362             :             }
     363             :             else
     364           0 :                 (*mpFldTypes)[i]->ModifyNotification( 0, pNewHt );
     365           0 :             break;
     366             :         }
     367             :         case RES_GETEXPFLD:
     368             :         case RES_SETEXPFLD:
     369             :         case RES_HIDDENTXTFLD:
     370             :         case RES_HIDDENPARAFLD:
     371             :             // Expression fields are treated separately
     372        1084 :             if( !pNewHt )
     373        1084 :                 break;
     374             :         default:
     375        3238 :             (*mpFldTypes)[i]->ModifyNotification ( 0, pNewHt );
     376             :         }
     377             :     }
     378             : 
     379         154 :     if( !IsExpFldsLocked() )
     380         154 :         UpdateExpFlds( 0, false );      // update expression fields
     381             : 
     382             :     // Tables
     383         154 :     UpdateTblFlds(pNewHt);
     384             : 
     385             :     // References
     386         154 :     UpdateRefFlds(pNewHt);
     387         154 :     if( bCloseDB )
     388             :     {
     389             : #if HAVE_FEATURE_DBCONNECTIVITY
     390           0 :         m_rSwdoc.GetDBManager()->CloseAll();
     391             : #endif
     392             :     }
     393             :     // Only evaluate on full update
     394         154 :     m_rSwdoc.getIDocumentState().SetModified();
     395         154 : }
     396             : 
     397           0 : void DocumentFieldsManager::InsDeletedFldType( SwFieldType& rFldTyp )
     398             : {
     399             :     // The FldType was marked as deleted and removed from the array.
     400             :     // One has to look &m_rSwdoc up again, now.
     401             :     // - If it's not present, it can be re-inserted.
     402             :     // - If the same type is found, the deleted one has to be renamed.
     403             : 
     404           0 :     sal_uInt16 nSize = mpFldTypes->size(), nFldWhich = rFldTyp.Which();
     405           0 :     sal_uInt16 i = INIT_FLDTYPES;
     406             : 
     407             :     OSL_ENSURE( RES_SETEXPFLD == nFldWhich ||
     408             :             RES_USERFLD == nFldWhich ||
     409             :             RES_DDEFLD == nFldWhich, "Wrong FldType" );
     410             : 
     411           0 :     const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
     412           0 :     const OUString& rFldNm = rFldTyp.GetName();
     413             :     SwFieldType* pFnd;
     414             : 
     415           0 :     for( ; i < nSize; ++i )
     416           0 :         if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
     417           0 :             rSCmp.isEqual( rFldNm, pFnd->GetName() ) )
     418             :         {
     419             :             // find new name
     420           0 :             sal_uInt16 nNum = 1;
     421             :             do {
     422           0 :                 OUString sSrch = rFldNm + OUString::number( nNum );
     423           0 :                 for( i = INIT_FLDTYPES; i < nSize; ++i )
     424           0 :                     if( nFldWhich == (pFnd = (*mpFldTypes)[i])->Which() &&
     425           0 :                         rSCmp.isEqual( sSrch, pFnd->GetName() ) )
     426           0 :                         break;
     427             : 
     428           0 :                 if( i >= nSize )        // not found
     429             :                 {
     430           0 :                     ((OUString&)rFldNm) = sSrch;
     431           0 :                     break;      // exit while loop
     432             :                 }
     433           0 :                 ++nNum;
     434             :             } while( true );
     435           0 :             break;
     436             :         }
     437             : 
     438             :     // not found, so insert and delete flag
     439           0 :     mpFldTypes->insert( mpFldTypes->begin() + nSize, &rFldTyp );
     440           0 :     switch( nFldWhich )
     441             :     {
     442             :     case RES_SETEXPFLD:
     443           0 :         ((SwSetExpFieldType&)rFldTyp).SetDeleted( false );
     444           0 :         break;
     445             :     case RES_USERFLD:
     446           0 :         ((SwUserFieldType&)rFldTyp).SetDeleted( false );
     447           0 :         break;
     448             :     case RES_DDEFLD:
     449           0 :         ((SwDDEFieldType&)rFldTyp).SetDeleted( false );
     450           0 :         break;
     451           0 :     }
     452           0 : }
     453             : 
     454         236 : bool DocumentFieldsManager::PutValueToField(const SwPosition & rPos,
     455             :                             const Any& rVal, sal_uInt16 nWhich)
     456             : {
     457         236 :     Any aOldVal;
     458         236 :     SwField * pField = GetFieldAtPos(rPos);
     459             : 
     460         340 :     if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo() &&
     461         104 :         pField->QueryValue(aOldVal, nWhich))
     462             :     {
     463         104 :         SwUndo *const pUndo(new SwUndoFieldFromAPI(rPos, aOldVal, rVal, nWhich));
     464         104 :         m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
     465             :     }
     466             : 
     467         236 :     return pField->PutValue(rVal, nWhich);
     468             : }
     469             : 
     470           0 : bool DocumentFieldsManager::UpdateFld(SwTxtFld * pDstTxtFld, SwField & rSrcFld,
     471             :                       SwMsgPoolItem * pMsgHnt,
     472             :                       bool bUpdateFlds)
     473             : {
     474             :     OSL_ENSURE(pDstTxtFld, "no field to update!");
     475             : 
     476           0 :     bool bTblSelBreak = false;
     477             : 
     478           0 :     SwFmtFld * pDstFmtFld = (SwFmtFld*)&pDstTxtFld->GetFmtFld();
     479           0 :     SwField * pDstFld = pDstFmtFld->GetField();
     480           0 :     sal_uInt16 nFldWhich = rSrcFld.GetTyp()->Which();
     481           0 :     SwNodeIndex aTblNdIdx(pDstTxtFld->GetTxtNode());
     482             : 
     483           0 :     if (pDstFld->GetTyp()->Which() ==
     484           0 :         rSrcFld.GetTyp()->Which())
     485             :     {
     486           0 :         if (m_rSwdoc.GetIDocumentUndoRedo().DoesUndo())
     487             :         {
     488           0 :             SwPosition aPosition( pDstTxtFld->GetTxtNode() );
     489           0 :             aPosition.nContent = pDstTxtFld->GetStart();
     490             : 
     491           0 :             SwUndo *const pUndo( new SwUndoFieldFromDoc( aPosition, *pDstFld, rSrcFld, pMsgHnt, bUpdateFlds) );
     492           0 :             m_rSwdoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
     493             :         }
     494             : 
     495           0 :         SwField * pNewFld = rSrcFld.CopyField();
     496           0 :         pDstFmtFld->SetField(pNewFld);
     497             : 
     498           0 :         switch( nFldWhich )
     499             :         {
     500             :         case RES_SETEXPFLD:
     501             :         case RES_GETEXPFLD:
     502             :         case RES_HIDDENTXTFLD:
     503             :         case RES_HIDDENPARAFLD:
     504           0 :             UpdateExpFlds( pDstTxtFld, true );
     505           0 :             break;
     506             : 
     507             :         case RES_TABLEFLD:
     508             :             {
     509             :                 const SwTableNode* pTblNd =
     510           0 :                     m_rSwdoc.IsIdxInTbl(aTblNdIdx);
     511           0 :                 if( pTblNd )
     512             :                 {
     513             :                     SwTableFmlUpdate aTblUpdate( &pTblNd->
     514           0 :                                                  GetTable() );
     515           0 :                     if (bUpdateFlds)
     516           0 :                         UpdateTblFlds( &aTblUpdate );
     517             :                     else
     518           0 :                         pNewFld->GetTyp()->ModifyNotification(0, &aTblUpdate);
     519             : 
     520           0 :                     if (! bUpdateFlds)
     521           0 :                         bTblSelBreak = true;
     522             :                 }
     523             :             }
     524           0 :             break;
     525             : 
     526             :         case RES_MACROFLD:
     527           0 :             if( bUpdateFlds && pDstTxtFld->GetpTxtNode() )
     528           0 :                 (pDstTxtFld->GetpTxtNode())->
     529           0 :                     ModifyNotification( 0, pDstFmtFld );
     530           0 :             break;
     531             : 
     532             :         case RES_DBNAMEFLD:
     533             :         case RES_DBNEXTSETFLD:
     534             :         case RES_DBNUMSETFLD:
     535             :         case RES_DBSETNUMBERFLD:
     536           0 :             m_rSwdoc.ChgDBData(((SwDBNameInfField*) pNewFld)->GetRealDBData());
     537           0 :             pNewFld->GetTyp()->UpdateFlds();
     538             : 
     539           0 :             break;
     540             : 
     541             :         case RES_DBFLD:
     542             : #if HAVE_FEATURE_DBCONNECTIVITY
     543             :             {
     544             :                 // JP 10.02.96: call ChgValue, so that the style change sets the
     545             :                 // ContentString correctly
     546           0 :                 SwDBField* pDBFld = (SwDBField*)pNewFld;
     547           0 :                 if (pDBFld->IsInitialized())
     548           0 :                     pDBFld->ChgValue( pDBFld->GetValue(), true );
     549             : 
     550           0 :                 pDBFld->ClearInitialized();
     551           0 :                 pDBFld->InitContent();
     552             :             }
     553             : #endif
     554             :             // no break;
     555             : 
     556             :         default:
     557           0 :             pDstFmtFld->ModifyNotification( 0, pMsgHnt );
     558             :         }
     559             : 
     560             :         // The fields we can calculate here are being triggered for an update
     561             :         // here explicitly.
     562           0 :         if( nFldWhich == RES_USERFLD )
     563           0 :             UpdateUsrFlds();
     564             :     }
     565             : 
     566           0 :     return bTblSelBreak;
     567             : }
     568             : 
     569             : /// Update reference and table fields
     570         402 : void DocumentFieldsManager::UpdateRefFlds( SfxPoolItem* pHt )
     571             : {
     572             :     SwFieldType* pFldType;
     573       13336 :     for( sal_uInt16 i = 0; i < mpFldTypes->size(); ++i )
     574       12934 :         if( RES_GETREFFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
     575         402 :             pFldType->ModifyNotification( 0, pHt );
     576         402 : }
     577             : 
     578        1892 : void DocumentFieldsManager::UpdateTblFlds( SfxPoolItem* pHt )
     579             : {
     580             :     OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE  == pHt->Which(),
     581             :             "What MessageItem is &m_rSwdoc?" );
     582             : 
     583        1892 :     SwFieldType* pFldType(0);
     584             : 
     585       26488 :     for (sal_uInt16 i = 0; i < mpFldTypes->size(); ++i)
     586             :     {
     587       26488 :         if( RES_TABLEFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
     588             :         {
     589        1892 :             SwTableFmlUpdate* pUpdtFld = 0;
     590        1892 :             if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
     591        1738 :                 pUpdtFld = (SwTableFmlUpdate*)pHt;
     592             : 
     593        1892 :             SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
     594        1892 :             for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
     595             :             {
     596           0 :                 if( pFmtFld->GetTxtFld() )
     597             :                 {
     598           0 :                     SwTblField* pFld = (SwTblField*)pFmtFld->GetField();
     599             : 
     600           0 :                     if( pUpdtFld )
     601             :                     {
     602             :                         // table where &m_rSwdoc field is located
     603             :                         const SwTableNode* pTblNd;
     604           0 :                         const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
     605           0 :                         if( !rTxtNd.GetNodes().IsDocNodes() ||
     606           0 :                             0 == ( pTblNd = rTxtNd.FindTableNode() ) )
     607           0 :                             continue;
     608             : 
     609           0 :                         switch( pUpdtFld->eFlags )
     610             :                         {
     611             :                         case TBL_CALC:
     612             :                             // re-set the value flag
     613             :                             // JP 17.06.96: internal representation of all formulas
     614             :                             //              (reference to other table!!!)
     615           0 :                             if( nsSwExtendedSubType::SUB_CMD & pFld->GetSubType() )
     616           0 :                                 pFld->PtrToBoxNm( pUpdtFld->pTbl );
     617             :                             else
     618           0 :                                 pFld->ChgValid( false );
     619           0 :                             break;
     620             :                         case TBL_BOXNAME:
     621             :                             // is &m_rSwdoc the wanted table?
     622           0 :                             if( &pTblNd->GetTable() == pUpdtFld->pTbl )
     623             :                                 // to the external representation
     624           0 :                                 pFld->PtrToBoxNm( pUpdtFld->pTbl );
     625           0 :                             break;
     626             :                         case TBL_BOXPTR:
     627             :                             // to the internal representation
     628             :                             // JP 17.06.96: internal representation on all formulas
     629             :                             //              (reference to other table!!!)
     630           0 :                             pFld->BoxNmToPtr( pUpdtFld->pTbl );
     631           0 :                             break;
     632             :                         case TBL_RELBOXNAME:
     633             :                             // is &m_rSwdoc the wanted table?
     634           0 :                             if( &pTblNd->GetTable() == pUpdtFld->pTbl )
     635             :                                 // to the relative representation
     636           0 :                                 pFld->ToRelBoxNm( pUpdtFld->pTbl );
     637           0 :                             break;
     638             :                         default:
     639           0 :                             break;
     640             :                         }
     641             :                     }
     642             :                     else
     643             :                         // reset the value flag for all
     644           0 :                         pFld->ChgValid( false );
     645             :                 }
     646             :             }
     647             : 
     648        1892 :             break;
     649             :         }
     650       24596 :         pFldType = 0;
     651             :     }
     652             : 
     653             :     // process all table box formulas
     654             :     const SfxPoolItem* pItem;
     655        1892 :     sal_uInt32 nMaxItems = m_rSwdoc.GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
     656        1892 :     for (sal_uInt32 i = 0; i < nMaxItems; ++i)
     657             :     {
     658           0 :         if( 0 != (pItem = m_rSwdoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
     659           0 :             ((SwTblBoxFormula*)pItem)->GetDefinedIn() )
     660             :         {
     661           0 :             ((SwTblBoxFormula*)pItem)->ChangeState( pHt );
     662             :         }
     663             :     }
     664             : 
     665             :     // all fields/boxes are now invalid, so we can start to calculate
     666        3630 :     if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
     667        1738 :                 TBL_CALC != ((SwTableFmlUpdate*)pHt)->eFlags ))
     668        3088 :         return ;
     669             : 
     670         696 :     SwCalc* pCalc = 0;
     671             : 
     672         696 :     if( pFldType )
     673             :     {
     674         696 :         SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
     675         696 :         for( SwFmtFld* pFmtFld = aIter.Last(); pFmtFld; pFmtFld = aIter.Previous() )
     676             :         {
     677             :                 // start calculation at the end
     678             :                 // new fields are inserted at the beginning of the modify chain
     679             :                 // that gives faster calculation on import
     680             :                 // mba: do we really need &m_rSwdoc "optimization"? Is it still valid?
     681             :                 SwTblField* pFld;
     682           0 :                 if( !pFmtFld->GetTxtFld() || (nsSwExtendedSubType::SUB_CMD &
     683           0 :                     (pFld = (SwTblField*)pFmtFld->GetField())->GetSubType() ))
     684           0 :                     continue;
     685             : 
     686             :                 // needs to be recalculated
     687           0 :                 if( !pFld->IsValid() )
     688             :                 {
     689             :                     // table where &m_rSwdoc field is located
     690           0 :                     const SwTxtNode& rTxtNd = pFmtFld->GetTxtFld()->GetTxtNode();
     691           0 :                     if( !rTxtNd.GetNodes().IsDocNodes() )
     692           0 :                         continue;
     693           0 :                     const SwTableNode* pTblNd = rTxtNd.FindTableNode();
     694           0 :                     if( !pTblNd )
     695           0 :                         continue;
     696             : 
     697             :                     // if &m_rSwdoc field is not in the to-be-updated table, skip it
     698           0 :                     if( pHt && &pTblNd->GetTable() !=
     699             :                                             ((SwTableFmlUpdate*)pHt)->pTbl )
     700           0 :                         continue;
     701             : 
     702           0 :                     if( !pCalc )
     703           0 :                         pCalc = new SwCalc( m_rSwdoc );
     704             : 
     705             :                     // get the values of all SetExpression fields that are valid
     706             :                     // until the table
     707           0 :                     SwFrm* pFrm = 0;
     708           0 :                     if( pTblNd->GetIndex() < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
     709             :                     {
     710             :                         // is in the special section, that's expensive!
     711           0 :                         Point aPt;      // return the first frame of the layout - Tab.Headline!!
     712           0 :                         pFrm = rTxtNd.getLayoutFrm( m_rSwdoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt );
     713           0 :                         if( pFrm )
     714             :                         {
     715           0 :                             SwPosition aPos( *pTblNd );
     716           0 :                             if( GetBodyTxtNode( m_rSwdoc, aPos, *pFrm ) )
     717             :                                 FldsToCalc( *pCalc, _SetGetExpFld(
     718           0 :                                     aPos.nNode, pFmtFld->GetTxtFld(),
     719           0 :                                     &aPos.nContent ));
     720             :                             else
     721           0 :                                 pFrm = 0;
     722             :                         }
     723             :                     }
     724           0 :                     if( !pFrm )
     725             :                     {
     726             :                         // create index to determine the TextNode
     727           0 :                         SwNodeIndex aIdx( rTxtNd );
     728             :                         FldsToCalc( *pCalc,
     729           0 :                             _SetGetExpFld( aIdx, pFmtFld->GetTxtFld() ));
     730             :                     }
     731             : 
     732           0 :                     SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() );
     733           0 :                     pFld->CalcField( aPara );
     734           0 :                     if( aPara.IsStackOverflow() )
     735             :                     {
     736           0 :                         bool const bResult = aPara.CalcWithStackOverflow();
     737           0 :                         if (bResult)
     738             :                         {
     739           0 :                             pFld->CalcField( aPara );
     740             :                         }
     741             :                         OSL_ENSURE(bResult,
     742             :                                 "the chained formula could no be calculated");
     743             :                     }
     744           0 :                     pCalc->SetCalcError( CALC_NOERR );
     745             :                 }
     746           0 :                 pFmtFld->ModifyNotification( 0, pHt );
     747         696 :         }
     748             :     }
     749             : 
     750             :     // calculate the formula at the boxes
     751         696 :     for (sal_uInt32 i = 0; i < nMaxItems; ++i )
     752             :     {
     753           0 :         if( 0 != (pItem = m_rSwdoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
     754           0 :             ((SwTblBoxFormula*)pItem)->GetDefinedIn() &&
     755           0 :             !((SwTblBoxFormula*)pItem)->IsValid() )
     756             :         {
     757           0 :             SwTblBoxFormula* pFml = (SwTblBoxFormula*)pItem;
     758           0 :             SwTableBox* pBox = pFml->GetTableBox();
     759           0 :             if( pBox && pBox->GetSttNd() &&
     760           0 :                 pBox->GetSttNd()->GetNodes().IsDocNodes() )
     761             :             {
     762           0 :                 const SwTableNode* pTblNd = pBox->GetSttNd()->FindTableNode();
     763           0 :                 if( !pHt || &pTblNd->GetTable() ==
     764             :                                             ((SwTableFmlUpdate*)pHt)->pTbl )
     765             :                 {
     766             :                     double nValue;
     767           0 :                     if( !pCalc )
     768           0 :                         pCalc = new SwCalc( m_rSwdoc );
     769             : 
     770             :                     // get the values of all SetExpression fields that are valid
     771             :                     // until the table
     772           0 :                     SwFrm* pFrm = 0;
     773           0 :                     if( pTblNd->GetIndex() < m_rSwdoc.GetNodes().GetEndOfExtras().GetIndex() )
     774             :                     {
     775             :                         // is in the special section, that's expensive!
     776           0 :                         Point aPt;      // return the first frame of the layout - Tab.Headline!!
     777           0 :                         SwNodeIndex aCNdIdx( *pTblNd, +2 );
     778           0 :                         SwCntntNode* pCNd = aCNdIdx.GetNode().GetCntntNode();
     779           0 :                         if( !pCNd )
     780           0 :                             pCNd = m_rSwdoc.GetNodes().GoNext( &aCNdIdx );
     781             : 
     782           0 :                         if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( m_rSwdoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt )) )
     783             :                         {
     784           0 :                             SwPosition aPos( *pCNd );
     785           0 :                             if( GetBodyTxtNode( m_rSwdoc, aPos, *pFrm ) )
     786           0 :                                 FldsToCalc( *pCalc, _SetGetExpFld( aPos.nNode ));
     787             :                             else
     788           0 :                                 pFrm = 0;
     789           0 :                         }
     790             :                     }
     791           0 :                     if( !pFrm )
     792             :                     {
     793             :                         // create index to determine the TextNode
     794           0 :                         SwNodeIndex aIdx( *pTblNd );
     795           0 :                         FldsToCalc( *pCalc, _SetGetExpFld( aIdx ));
     796             :                     }
     797             : 
     798           0 :                     SwTblCalcPara aPara( *pCalc, pTblNd->GetTable() );
     799           0 :                     pFml->Calc( aPara, nValue );
     800             : 
     801           0 :                     if( aPara.IsStackOverflow() )
     802             :                     {
     803           0 :                         bool const bResult = aPara.CalcWithStackOverflow();
     804           0 :                         if (bResult)
     805             :                         {
     806           0 :                             pFml->Calc( aPara, nValue );
     807             :                         }
     808             :                         OSL_ENSURE(bResult,
     809             :                                 "the chained formula could no be calculated");
     810             :                     }
     811             : 
     812           0 :                     SwFrmFmt* pFmt = pBox->ClaimFrmFmt();
     813           0 :                     SfxItemSet aTmp( m_rSwdoc.GetAttrPool(),
     814           0 :                                     RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
     815             : 
     816           0 :                     if( pCalc->IsCalcError() )
     817           0 :                         nValue = DBL_MAX;
     818           0 :                     aTmp.Put( SwTblBoxValue( nValue ));
     819           0 :                     if( SfxItemState::SET != pFmt->GetItemState( RES_BOXATR_FORMAT ))
     820           0 :                         aTmp.Put( SwTblBoxNumFormat( 0 ));
     821           0 :                     pFmt->SetFmtAttr( aTmp );
     822             : 
     823           0 :                     pCalc->SetCalcError( CALC_NOERR );
     824             :                 }
     825             :             }
     826             :         }
     827             :     }
     828             : 
     829         696 :     delete pCalc;
     830             : }
     831             : 
     832        8164 : void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds )
     833             : {
     834        8164 :     if( IsExpFldsLocked() || m_rSwdoc.IsInReading() )
     835       15944 :         return;
     836             : 
     837         362 :     bool bOldInUpdateFlds = mpUpdtFlds->IsInUpdateFlds();
     838         362 :     mpUpdtFlds->SetInUpdateFlds( true );
     839             : 
     840         362 :     mpUpdtFlds->MakeFldList( m_rSwdoc, true, GETFLD_ALL );
     841         362 :     mbNewFldLst = false;
     842             : 
     843         362 :     if( mpUpdtFlds->GetSortLst()->empty() )
     844             :     {
     845         340 :         if( bUpdRefFlds )
     846         200 :             UpdateRefFlds(NULL);
     847             : 
     848         340 :         mpUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds );
     849         340 :         mpUpdtFlds->SetFieldsDirty( false );
     850         340 :         return ;
     851             :     }
     852             : 
     853             :     sal_uInt16 nWhich, n;
     854             : 
     855             :     // Hash table for all string replacements is filled on-the-fly.
     856             :     // Try to fabricate an uneven number.
     857          22 :     sal_uInt16 nStrFmtCnt = (( mpFldTypes->size() / 7 ) + 1 ) * 7;
     858          22 :     SwHash** pHashStrTbl = new SwHash*[ nStrFmtCnt ];
     859          22 :     memset( pHashStrTbl, 0, sizeof( _HashStr* ) * nStrFmtCnt );
     860             : 
     861             :     {
     862             :         const SwFieldType* pFldType;
     863             :         // process separately:
     864         816 :         for( n = mpFldTypes->size(); n; )
     865         772 :             switch( ( pFldType = (*mpFldTypes)[ --n ] )->Which() )
     866             :             {
     867             :             case RES_USERFLD:
     868             :                 {
     869             :                     // Entry present?
     870             :                     sal_uInt16 nPos;
     871           6 :                     const OUString& rNm = pFldType->GetName();
     872          12 :                     OUString sExpand(((SwUserFieldType*)pFldType)->Expand(nsSwGetSetExpType::GSE_STRING, 0, 0));
     873           6 :                     SwHash* pFnd = Find( rNm, pHashStrTbl, nStrFmtCnt, &nPos );
     874           6 :                     if( pFnd )
     875             :                         // modify entry in the hash table
     876           0 :                         ((_HashStr*)pFnd)->aSetStr = sExpand;
     877             :                     else
     878             :                         // insert the new entry
     879           6 :                         *(pHashStrTbl + nPos ) = new _HashStr( rNm, sExpand,
     880          18 :                                                 (_HashStr*)*(pHashStrTbl + nPos) );
     881             :                 }
     882           6 :                 break;
     883             :             case RES_SETEXPFLD:
     884          94 :                 ((SwSetExpFieldType*)pFldType)->SetOutlineChgNd( 0 );
     885          94 :                 break;
     886             :             }
     887             :     }
     888             : 
     889             :     // The array is filled with all fields; start calculation.
     890          22 :     SwCalc aCalc( m_rSwdoc );
     891             : 
     892             : #if HAVE_FEATURE_DBCONNECTIVITY
     893          44 :     OUString sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) );
     894             : 
     895             :     // already set the current record number
     896          22 :     SwDBManager* pMgr = m_rSwdoc.GetDBManager();
     897          22 :     pMgr->CloseAll( false );
     898             : 
     899          44 :     SvtSysLocale aSysLocale;
     900          22 :     const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
     901          22 :     const long nLang = pLclData->getLanguageTag().getLanguageType();
     902          22 :     bool bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc );
     903             : #endif
     904             : 
     905             :     // Make sure we don't hide all sections, which would lead to a crash. First, count how many of them do we have.
     906          22 :     int nShownSections = 0;
     907          92 :     for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != mpUpdtFlds->GetSortLst()->end(); ++it )
     908             :     {
     909          70 :         SwSection* pSect = (SwSection*)(*it)->GetSection();
     910          70 :         if ( pSect && !pSect->IsCondHidden())
     911          14 :             nShownSections++;
     912             :     }
     913             : 
     914          44 :     OUString aNew;
     915          92 :     for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != mpUpdtFlds->GetSortLst()->end(); ++it )
     916             :     {
     917          70 :         SwSection* pSect = (SwSection*)(*it)->GetSection();
     918          70 :         if( pSect )
     919             :         {
     920             : 
     921             :             SwSbxValue aValue = aCalc.Calculate(
     922          14 :                                         pSect->GetCondition() );
     923          14 :             if(!aValue.IsVoidValue())
     924             :             {
     925             :                 // Do we want to hide this one?
     926           8 :                 bool bHide = aValue.GetBool();
     927           8 :                 if (bHide && !pSect->IsCondHidden())
     928             :                 {
     929             :                     // This section will be hidden, but it wasn't before
     930           6 :                     if (nShownSections == 1)
     931             :                     {
     932             :                         // Is the last node part of a section?
     933           6 :                         SwPaM aPam(m_rSwdoc.GetNodes());
     934           6 :                         aPam.Move(fnMoveForward, fnGoDoc);
     935           6 :                         if (aPam.Start()->nNode.GetNode().StartOfSectionNode()->IsSectionNode())
     936             :                         {
     937             :                             // This would be the last section, so set its condition to false, and avoid hiding it.
     938           4 :                             OUString aCond("0");
     939           4 :                             pSect->SetCondition(aCond);
     940           4 :                             bHide = false;
     941           6 :                         }
     942             :                     }
     943           6 :                     nShownSections--;
     944             :                 }
     945           8 :                 pSect->SetCondHidden( bHide );
     946             :             }
     947          14 :             continue;
     948             :         }
     949             : 
     950          56 :         SwTxtFld* pTxtFld = (SwTxtFld*)(*it)->GetTxtFld();
     951          56 :         if( !pTxtFld )
     952             :         {
     953             :             OSL_ENSURE( false, "what's wrong now'" );
     954           0 :             continue;
     955             :         }
     956             : 
     957          56 :         SwFmtFld* pFmtFld = (SwFmtFld*)&pTxtFld->GetFmtFld();
     958          56 :         const SwField* pFld = pFmtFld->GetField();
     959             : 
     960          56 :         switch( nWhich = pFld->GetTyp()->Which() )
     961             :         {
     962             :         case RES_HIDDENTXTFLD:
     963             :         {
     964           0 :             SwHiddenTxtField* pHFld = (SwHiddenTxtField*)pFld;
     965           0 :             SwSbxValue aValue = aCalc.Calculate( pHFld->GetPar1() );
     966           0 :             bool bValue = !aValue.GetBool();
     967           0 :             if(!aValue.IsVoidValue())
     968             :             {
     969           0 :                 pHFld->SetValue( bValue );
     970             :                 // evaluate field
     971           0 :                 pHFld->Evaluate(&m_rSwdoc);
     972           0 :             }
     973             :         }
     974           0 :         break;
     975             :         case RES_HIDDENPARAFLD:
     976             :         {
     977           0 :             SwHiddenParaField* pHPFld = (SwHiddenParaField*)pFld;
     978           0 :             SwSbxValue aValue = aCalc.Calculate( pHPFld->GetPar1() );
     979           0 :             bool bValue = aValue.GetBool();
     980           0 :             if(!aValue.IsVoidValue())
     981           0 :                 pHPFld->SetHidden( bValue );
     982             :         }
     983           0 :         break;
     984             :         case RES_DBSETNUMBERFLD:
     985             : #if HAVE_FEATURE_DBCONNECTIVITY
     986             :         {
     987           0 :             ((SwDBSetNumberField*)pFld)->Evaluate(&m_rSwdoc);
     988           0 :             aCalc.VarChange( sDBNumNm, ((SwDBSetNumberField*)pFld)->GetSetNumber());
     989             :         }
     990             : #endif
     991           0 :         break;
     992             :         case RES_DBNEXTSETFLD:
     993             :         case RES_DBNUMSETFLD:
     994             : #if HAVE_FEATURE_DBCONNECTIVITY
     995             :         {
     996           0 :             UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc );
     997           0 :             if( bCanFill )
     998           0 :                 bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc );
     999             :         }
    1000             : #endif
    1001           0 :         break;
    1002             :         case RES_DBFLD:
    1003             :         {
    1004             : #if HAVE_FEATURE_DBCONNECTIVITY
    1005             :             // evaluate field
    1006          50 :             ((SwDBField*)pFld)->Evaluate();
    1007             : 
    1008          50 :             SwDBData aTmpDBData(((SwDBField*)pFld)->GetDBData());
    1009             : 
    1010          50 :             if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
    1011           0 :                 aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
    1012             : 
    1013         100 :             const OUString& rName = pFld->GetTyp()->GetName();
    1014             : 
    1015             :             // Add entry to hash table
    1016             :             // Entry present?
    1017             :             sal_uInt16 nPos;
    1018          50 :             SwHash* pFnd = Find( rName, pHashStrTbl, nStrFmtCnt, &nPos );
    1019         100 :             OUString const value(pFld->ExpandField(m_rSwdoc.IsClipBoard()));
    1020          50 :             if( pFnd )
    1021             :             {
    1022             :                 // Modify entry in the hash table
    1023           6 :                 static_cast<_HashStr*>(pFnd)->aSetStr = value;
    1024             :             }
    1025             :             else
    1026             :             {
    1027             :                 // insert new entry
    1028          44 :                 *(pHashStrTbl + nPos ) = new _HashStr( rName,
    1029          88 :                     value, static_cast<_HashStr *>(*(pHashStrTbl + nPos)));
    1030          50 :             }
    1031             : #endif
    1032             :         }
    1033          50 :         break;
    1034             :         case RES_GETEXPFLD:
    1035             :         case RES_SETEXPFLD:
    1036             :         {
    1037           6 :             if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() )        // replace String
    1038             :             {
    1039           2 :                 if( RES_GETEXPFLD == nWhich )
    1040             :                 {
    1041           0 :                     SwGetExpField* pGFld = (SwGetExpField*)pFld;
    1042             : 
    1043           0 :                     if( (!pUpdtFld || pUpdtFld == pTxtFld )
    1044           0 :                         && pGFld->IsInBodyTxt() )
    1045             :                     {
    1046           0 :                         aNew = LookString( pHashStrTbl, nStrFmtCnt,
    1047           0 :                                     pGFld->GetFormula() );
    1048           0 :                         pGFld->ChgExpStr( aNew );
    1049             :                     }
    1050             :                 }
    1051             :                 else
    1052             :                 {
    1053           2 :                     SwSetExpField* pSFld = (SwSetExpField*)pFld;
    1054             :                     // is the "formula" a field?
    1055           6 :                     aNew = LookString( pHashStrTbl, nStrFmtCnt,
    1056           4 :                                 pSFld->GetFormula() );
    1057             : 
    1058           2 :                     if( aNew.isEmpty() )               // nothing found then the formula is the new value
    1059           2 :                         aNew = pSFld->GetFormula();
    1060             : 
    1061             :                     // only update one field
    1062           2 :                     if( !pUpdtFld || pUpdtFld == pTxtFld )
    1063           2 :                         pSFld->ChgExpStr( aNew );
    1064             : 
    1065             :                     // lookup the field's name
    1066           2 :                     aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName();
    1067             :                     // Entry present?
    1068             :                     sal_uInt16 nPos;
    1069           2 :                     SwHash* pFnd = Find( aNew, pHashStrTbl, nStrFmtCnt, &nPos );
    1070           2 :                     if( pFnd )
    1071             :                         // Modify entry in the hash table
    1072           0 :                         ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr();
    1073             :                     else
    1074             :                         // insert new entry
    1075           2 :                         *(pHashStrTbl + nPos ) = pFnd = new _HashStr( aNew,
    1076             :                                         pSFld->GetExpStr(),
    1077           2 :                                         (_HashStr*)*(pHashStrTbl + nPos) );
    1078             : 
    1079             :                     // Extension for calculation with Strings
    1080           2 :                     SwSbxValue aValue;
    1081           2 :                     aValue.PutString( ((_HashStr*)pFnd)->aSetStr );
    1082           2 :                     aCalc.VarChange( aNew, aValue );
    1083             :                 }
    1084             :             }
    1085             :             else            // recalculate formula
    1086             :             {
    1087           4 :                 if( RES_GETEXPFLD == nWhich )
    1088             :                 {
    1089           0 :                     SwGetExpField* pGFld = (SwGetExpField*)pFld;
    1090             : 
    1091           0 :                     if( (!pUpdtFld || pUpdtFld == pTxtFld )
    1092           0 :                         && pGFld->IsInBodyTxt() )
    1093             :                     {
    1094             :                         SwSbxValue aValue = aCalc.Calculate(
    1095           0 :                                         pGFld->GetFormula());
    1096           0 :                         if(!aValue.IsVoidValue())
    1097           0 :                             pGFld->SetValue(aValue.GetDouble() );
    1098             :                     }
    1099             :                 }
    1100             :                 else
    1101             :                 {
    1102           4 :                     SwSetExpField* pSFld = (SwSetExpField*)pFld;
    1103           4 :                     SwSetExpFieldType* pSFldTyp = (SwSetExpFieldType*)pFld->GetTyp();
    1104           4 :                     aNew = pSFldTyp->GetName();
    1105             : 
    1106           4 :                     SwNode* pSeqNd = 0;
    1107             : 
    1108           4 :                     if( pSFld->IsSequenceFld() )
    1109             :                     {
    1110           0 :                         const sal_uInt8 nLvl = pSFldTyp->GetOutlineLvl();
    1111           0 :                         if( MAXLEVEL > nLvl )
    1112             :                         {
    1113             :                             // test if the Number needs to be updated
    1114           0 :                             pSeqNd = m_rSwdoc.GetNodes()[ (*it)->GetNode() ];
    1115             : 
    1116             :                             const SwTxtNode* pOutlNd = pSeqNd->
    1117           0 :                                     FindOutlineNodeOfLevel( nLvl );
    1118           0 :                             if( pSFldTyp->GetOutlineChgNd() != pOutlNd )
    1119             :                             {
    1120           0 :                                 pSFldTyp->SetOutlineChgNd( pOutlNd );
    1121           0 :                                 aCalc.VarChange( aNew, 0 );
    1122             :                             }
    1123             :                         }
    1124             :                     }
    1125             : 
    1126           4 :                     aNew += "=";
    1127           4 :                     aNew += pSFld->GetFormula();
    1128             : 
    1129           4 :                     SwSbxValue aValue = aCalc.Calculate( aNew );
    1130           4 :                     double nErg = aValue.GetDouble();
    1131             :                     // only update one field
    1132           4 :                     if( !aValue.IsVoidValue() && (!pUpdtFld || pUpdtFld == pTxtFld) )
    1133             :                     {
    1134           4 :                         pSFld->SetValue( nErg );
    1135             : 
    1136           4 :                         if( pSeqNd )
    1137           0 :                             pSFldTyp->SetChapter( *pSFld, *pSeqNd );
    1138           4 :                     }
    1139             :                 }
    1140             :             }
    1141             :         }
    1142             :         } // switch
    1143             : 
    1144          56 :         pFmtFld->ModifyNotification( 0, 0 );        // trigger formatting
    1145             : 
    1146          56 :         if( pUpdtFld == pTxtFld )       // if only &m_rSwdoc one is updated
    1147             :         {
    1148           0 :             if( RES_GETEXPFLD == nWhich ||      // only GetField or
    1149           0 :                 RES_HIDDENTXTFLD == nWhich ||   // HiddenTxt?
    1150             :                 RES_HIDDENPARAFLD == nWhich)    // HiddenParaFld?
    1151             :                 break;                          // quit
    1152           0 :             pUpdtFld = 0;                       // update all from here on
    1153             :         }
    1154             :     }
    1155             : 
    1156             : #if HAVE_FEATURE_DBCONNECTIVITY
    1157          22 :     pMgr->CloseAll(false);
    1158             : #endif
    1159             :     // delete hash table
    1160          22 :     ::DeleteHashTable( pHashStrTbl, nStrFmtCnt );
    1161             : 
    1162             :     // update reference fields
    1163          22 :     if( bUpdRefFlds )
    1164           8 :         UpdateRefFlds(NULL);
    1165             : 
    1166          22 :     mpUpdtFlds->SetInUpdateFlds( bOldInUpdateFlds );
    1167          44 :     mpUpdtFlds->SetFieldsDirty( false );
    1168             : }
    1169             : 
    1170             : /// Insert field type that was marked as deleted
    1171           0 : void DocumentFieldsManager::UpdateUsrFlds()
    1172             : {
    1173           0 :     SwCalc* pCalc = 0;
    1174             :     const SwFieldType* pFldType;
    1175           0 :     for( sal_uInt16 i = INIT_FLDTYPES; i < mpFldTypes->size(); ++i )
    1176           0 :         if( RES_USERFLD == ( pFldType = (*mpFldTypes)[i] )->Which() )
    1177             :         {
    1178           0 :             if( !pCalc )
    1179           0 :                 pCalc = new SwCalc( m_rSwdoc );
    1180           0 :             ((SwUserFieldType*)pFldType)->GetValue( *pCalc );
    1181             :         }
    1182             : 
    1183           0 :     if( pCalc )
    1184             :     {
    1185           0 :         delete pCalc;
    1186           0 :         m_rSwdoc.getIDocumentState().SetModified();
    1187             :     }
    1188           0 : }
    1189             : 
    1190        6956 : void DocumentFieldsManager::UpdatePageFlds( SfxPoolItem* pMsgHnt )
    1191             : {
    1192             :     SwFieldType* pFldType;
    1193      229548 :     for( sal_uInt16 i = 0; i < INIT_FLDTYPES; ++i )
    1194      222592 :         switch( ( pFldType = (*mpFldTypes)[ i ] )->Which() )
    1195             :         {
    1196             :         case RES_PAGENUMBERFLD:
    1197             :         case RES_CHAPTERFLD:
    1198             :         case RES_GETEXPFLD:
    1199             :         case RES_REFPAGEGETFLD:
    1200       27824 :             pFldType->ModifyNotification( 0, pMsgHnt );
    1201       27824 :             break;
    1202             :         case RES_DOCSTATFLD:
    1203        6956 :             pFldType->ModifyNotification( 0, 0 );
    1204        6956 :             break;
    1205             :         }
    1206        6956 :     SetNewFldLst(true);
    1207        6956 : }
    1208             : 
    1209        4810 : void DocumentFieldsManager::LockExpFlds()
    1210             : {
    1211        4810 :     ++mnLockExpFld;
    1212        4810 : }
    1213             : 
    1214        4808 : void DocumentFieldsManager::UnlockExpFlds()
    1215             : {
    1216             :     assert(mnLockExpFld != 0);
    1217        4808 :     if( mnLockExpFld )
    1218        4808 :         --mnLockExpFld;
    1219        4808 : }
    1220             : 
    1221        8354 : bool DocumentFieldsManager::IsExpFldsLocked() const
    1222             : {
    1223        8354 :     return 0 != mnLockExpFld;
    1224             : }
    1225             : 
    1226       48828 : SwDocUpdtFld& DocumentFieldsManager::GetUpdtFlds() const
    1227             : {
    1228       48828 :     return *mpUpdtFlds;
    1229             : }
    1230             : 
    1231       25502 : bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
    1232             : {
    1233             :     // See if the supplied nodes actually contain fields.
    1234             :     // If they don't, the flag doesn't need to be changed.
    1235       25502 :     bool bFldsFnd = false;
    1236       25502 :     if( b && pChk && !GetUpdtFlds().IsFieldsDirty() && !m_rSwdoc.IsInDtor()
    1237             :         // ?? what's up with Undo, this is also wanted there!
    1238             :         /*&& &pChk->GetNodes() == &GetNodes()*/ )
    1239             :     {
    1240       18304 :         b = false;
    1241       18304 :         if( !nLen )
    1242           0 :             ++nLen;
    1243       18304 :         sal_uLong nStt = pChk->GetIndex();
    1244       18304 :         const SwNodes& rNds = pChk->GetNodes();
    1245       54806 :         while( nLen-- )
    1246             :         {
    1247       18324 :             const SwTxtNode* pTNd = rNds[ nStt++ ]->GetTxtNode();
    1248       18324 :             if( pTNd )
    1249             :             {
    1250       18318 :                 if( pTNd->GetAttrOutlineLevel() != 0 )
    1251             :                     // update chapter fields
    1252           0 :                     b = true;
    1253       18318 :                 else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
    1254             :                 {
    1255        1014 :                     const size_t nEnd = pTNd->GetSwpHints().Count();
    1256        2368 :                     for( size_t n = 0 ; n < nEnd; ++n )
    1257             :                     {
    1258        1480 :                         const SwTxtAttr* pAttr = pTNd->GetSwpHints()[ n ];
    1259        1480 :                         if ( pAttr->Which() == RES_TXTATR_FIELD )
    1260             :                         {
    1261         126 :                             b = true;
    1262         126 :                             break;
    1263             :                         }
    1264             :                     }
    1265             :                 }
    1266             : 
    1267       18318 :                 if( b )
    1268         126 :                     break;
    1269             :             }
    1270             :         }
    1271       18304 :         bFldsFnd = b;
    1272             :     }
    1273       25502 :     GetUpdtFlds().SetFieldsDirty( b );
    1274       25502 :     return bFldsFnd;
    1275             : }
    1276             : 
    1277          76 : void DocumentFieldsManager::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime )
    1278             : {
    1279          76 :     bool bIsModified = m_rSwdoc.getIDocumentState().IsModified();
    1280             : 
    1281             :     sal_Int32 nDate;
    1282             :     sal_Int64 nTime;
    1283          76 :     if( pNewDateTime )
    1284             :     {
    1285           0 :         nDate = pNewDateTime->GetDate();
    1286           0 :         nTime = pNewDateTime->GetTime();
    1287             :     }
    1288             :     else
    1289             :     {
    1290          76 :         nDate = Date( Date::SYSTEM ).GetDate();
    1291          76 :         nTime = tools::Time( tools::Time::SYSTEM ).GetTime();
    1292             :     }
    1293             : 
    1294             :     sal_uInt16 aTypes[5] = {
    1295             :         /*0*/   RES_DOCINFOFLD,
    1296             :         /*1*/   RES_AUTHORFLD,
    1297             :         /*2*/   RES_EXTUSERFLD,
    1298             :         /*3*/   RES_FILENAMEFLD,
    1299          76 :         /*4*/   RES_DATETIMEFLD };  // MUST be at the end!
    1300             : 
    1301          76 :     sal_uInt16 nStt = bOnlyTimeDate ? 4 : 0;
    1302             : 
    1303         456 :     for( ; nStt < 5; ++nStt )
    1304             :     {
    1305         380 :         SwFieldType* pFldType = GetSysFldType( aTypes[ nStt ] );
    1306         380 :         SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
    1307         388 :         for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() )
    1308             :         {
    1309           8 :             if( pFmtFld && pFmtFld->GetTxtFld() )
    1310             :             {
    1311           8 :                 bool bChgd = false;
    1312           8 :                 switch( aTypes[ nStt ] )
    1313             :                 {
    1314             :                 case RES_DOCINFOFLD:
    1315           0 :                     if( ((SwDocInfoField*)pFmtFld->GetField())->IsFixed() )
    1316             :                     {
    1317           0 :                         bChgd = true;
    1318           0 :                         SwDocInfoField* pDocInfFld = (SwDocInfoField*)pFmtFld->GetField();
    1319             :                         pDocInfFld->SetExpansion( ((SwDocInfoFieldType*)
    1320           0 :                                     pDocInfFld->GetTyp())->Expand(
    1321           0 :                                         pDocInfFld->GetSubType(),
    1322             :                                         pDocInfFld->GetFormat(),
    1323           0 :                                         pDocInfFld->GetLanguage(),
    1324           0 :                                         pDocInfFld->GetName() ) );
    1325             :                     }
    1326           0 :                     break;
    1327             : 
    1328             :                 case RES_AUTHORFLD:
    1329           0 :                     if( ((SwAuthorField*)pFmtFld->GetField())->IsFixed() )
    1330             :                     {
    1331           0 :                         bChgd = true;
    1332           0 :                         SwAuthorField* pAuthorFld = (SwAuthorField*)pFmtFld->GetField();
    1333             :                         pAuthorFld->SetExpansion( ((SwAuthorFieldType*)
    1334           0 :                                     pAuthorFld->GetTyp())->Expand(
    1335           0 :                                                 pAuthorFld->GetFormat() ) );
    1336             :                     }
    1337           0 :                     break;
    1338             : 
    1339             :                 case RES_EXTUSERFLD:
    1340           0 :                     if( ((SwExtUserField*)pFmtFld->GetField())->IsFixed() )
    1341             :                     {
    1342           0 :                         bChgd = true;
    1343           0 :                         SwExtUserField* pExtUserFld = (SwExtUserField*)pFmtFld->GetField();
    1344             :                         pExtUserFld->SetExpansion( ((SwExtUserFieldType*)
    1345           0 :                                     pExtUserFld->GetTyp())->Expand(
    1346           0 :                                             pExtUserFld->GetSubType(),
    1347           0 :                                             pExtUserFld->GetFormat()));
    1348             :                     }
    1349           0 :                     break;
    1350             : 
    1351             :                 case RES_DATETIMEFLD:
    1352           8 :                     if( ((SwDateTimeField*)pFmtFld->GetField())->IsFixed() )
    1353             :                     {
    1354           0 :                         bChgd = true;
    1355           0 :                         ((SwDateTimeField*)pFmtFld->GetField())->SetDateTime(
    1356           0 :                                                     DateTime(Date(nDate), tools::Time(nTime)) );
    1357             :                     }
    1358           8 :                     break;
    1359             : 
    1360             :                 case RES_FILENAMEFLD:
    1361           0 :                     if( ((SwFileNameField*)pFmtFld->GetField())->IsFixed() )
    1362             :                     {
    1363           0 :                         bChgd = true;
    1364             :                         SwFileNameField* pFileNameFld =
    1365           0 :                             (SwFileNameField*)pFmtFld->GetField();
    1366             :                         pFileNameFld->SetExpansion( ((SwFileNameFieldType*)
    1367           0 :                                     pFileNameFld->GetTyp())->Expand(
    1368           0 :                                             pFileNameFld->GetFormat() ) );
    1369             :                     }
    1370           0 :                     break;
    1371             :                 }
    1372             : 
    1373             :                 // Trigger formatting
    1374           8 :                 if( bChgd )
    1375           0 :                     pFmtFld->ModifyNotification( 0, 0 );
    1376             :             }
    1377             :         }
    1378         380 :     }
    1379             : 
    1380          76 :     if( !bIsModified )
    1381          44 :         m_rSwdoc.getIDocumentState().ResetModified();
    1382          76 : }
    1383             : 
    1384           0 : void DocumentFieldsManager::FldsToCalc( SwCalc& rCalc, const _SetGetExpFld& rToThisFld )
    1385             : {
    1386             :     // create the sorted list of all SetFields
    1387           0 :     mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_CALC );
    1388           0 :     mbNewFldLst = false;
    1389             : 
    1390             : #if !HAVE_FEATURE_DBCONNECTIVITY
    1391             :     SwDBManager* pMgr = NULL;
    1392             : #else
    1393           0 :     SwDBManager* pMgr = m_rSwdoc.GetDBManager();
    1394           0 :     pMgr->CloseAll(false);
    1395             : #endif
    1396             : 
    1397           0 :     if( !mpUpdtFlds->GetSortLst()->empty() )
    1398             :     {
    1399             :         _SetGetExpFlds::const_iterator const itLast =
    1400           0 :             mpUpdtFlds->GetSortLst()->upper_bound(
    1401           0 :                 const_cast<_SetGetExpFld*>(&rToThisFld));
    1402           0 :         for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != itLast; ++it )
    1403           0 :             lcl_CalcFld( m_rSwdoc, rCalc, **it, pMgr );
    1404             :     }
    1405             : #if HAVE_FEATURE_DBCONNECTIVITY
    1406           0 :     pMgr->CloseAll(false);
    1407             : #endif
    1408           0 : }
    1409             : 
    1410          16 : void DocumentFieldsManager::FldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt )
    1411             : {
    1412             :     // create the sorted list of all SetFields
    1413          16 :     mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_CALC );
    1414          16 :     mbNewFldLst = false;
    1415             : 
    1416             : #if !HAVE_FEATURE_DBCONNECTIVITY
    1417             :     SwDBManager* pMgr = NULL;
    1418             : #else
    1419          16 :     SwDBManager* pMgr = m_rSwdoc.GetDBManager();
    1420          16 :     pMgr->CloseAll(false);
    1421             : #endif
    1422             : 
    1423          84 :     for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin();
    1424         108 :         it != mpUpdtFlds->GetSortLst()->end() &&
    1425          22 :         ( (*it)->GetNode() < nLastNd ||
    1426          20 :           ( (*it)->GetNode() == nLastNd && (*it)->GetCntnt() <= nLastCnt )
    1427             :         );
    1428             :         ++it )
    1429             :     {
    1430          12 :         lcl_CalcFld( m_rSwdoc, rCalc, **it, pMgr );
    1431             :     }
    1432             : 
    1433             : #if HAVE_FEATURE_DBCONNECTIVITY
    1434          16 :     pMgr->CloseAll(false);
    1435             : #endif
    1436          16 : }
    1437             : 
    1438           0 : void DocumentFieldsManager::FldsToExpand( SwHash**& ppHashTbl, sal_uInt16& rTblSize,
    1439             :                             const _SetGetExpFld& rToThisFld )
    1440             : {
    1441             :     // create the sorted list of all SetFields
    1442           0 :     mpUpdtFlds->MakeFldList( m_rSwdoc, mbNewFldLst, GETFLD_EXPAND );
    1443           0 :     mbNewFldLst = false;
    1444             : 
    1445             :     // Hash table for all string replacements is filled on-the-fly.
    1446             :     // Try to fabricate an uneven number.
    1447           0 :     rTblSize = (( mpUpdtFlds->GetSortLst()->size() / 7 ) + 1 ) * 7;
    1448           0 :     ppHashTbl = new SwHash*[ rTblSize ];
    1449           0 :     memset( ppHashTbl, 0, sizeof( _HashStr* ) * rTblSize );
    1450             : 
    1451             :     _SetGetExpFlds::const_iterator const itLast =
    1452           0 :         mpUpdtFlds->GetSortLst()->upper_bound(
    1453           0 :             const_cast<_SetGetExpFld*>(&rToThisFld));
    1454             : 
    1455           0 :     for( _SetGetExpFlds::const_iterator it = mpUpdtFlds->GetSortLst()->begin(); it != itLast; ++it )
    1456             :     {
    1457           0 :         const SwTxtFld* pTxtFld = (*it)->GetTxtFld();
    1458           0 :         if( !pTxtFld )
    1459           0 :             continue;
    1460             : 
    1461           0 :         const SwField* pFld = pTxtFld->GetFmtFld().GetField();
    1462           0 :         switch( pFld->GetTyp()->Which() )
    1463             :         {
    1464             :         case RES_SETEXPFLD:
    1465           0 :             if( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType() )
    1466             :             {
    1467             :                 // set the new value in the hash table
    1468             :                 // is the formula a field?
    1469           0 :                 SwSetExpField* pSFld = (SwSetExpField*)pFld;
    1470           0 :                 OUString aNew = LookString( ppHashTbl, rTblSize, pSFld->GetFormula() );
    1471             : 
    1472           0 :                 if( aNew.isEmpty() )               // nothing found, then the formula is
    1473           0 :                     aNew = pSFld->GetFormula(); // the new value
    1474             : 
    1475             :                 // #i3141# - update expression of field as in method
    1476             :                 // <SwDoc::UpdateExpFlds(..)> for string/text fields
    1477           0 :                 pSFld->ChgExpStr( aNew );
    1478             : 
    1479             :                 // look up the field's name
    1480           0 :                 aNew = ((SwSetExpFieldType*)pSFld->GetTyp())->GetSetRefName();
    1481             :                 // Entry present?
    1482             :                 sal_uInt16 nPos;
    1483           0 :                 SwHash* pFnd = Find( aNew, ppHashTbl, rTblSize, &nPos );
    1484           0 :                 if( pFnd )
    1485             :                     // modify entry in the hash table
    1486           0 :                     ((_HashStr*)pFnd)->aSetStr = pSFld->GetExpStr();
    1487             :                 else
    1488             :                     // insert the new entry
    1489           0 :                     *(ppHashTbl + nPos ) = new _HashStr( aNew,
    1490           0 :                             pSFld->GetExpStr(), (_HashStr*)*(ppHashTbl + nPos) );
    1491             :             }
    1492           0 :             break;
    1493             :         case RES_DBFLD:
    1494             :             {
    1495           0 :                 const OUString& rName = pFld->GetTyp()->GetName();
    1496             : 
    1497             :                 // Insert entry in the hash table
    1498             :                 // Entry present?
    1499             :                 sal_uInt16 nPos;
    1500           0 :                 SwHash* pFnd = Find( rName, ppHashTbl, rTblSize, &nPos );
    1501           0 :                 OUString const value(pFld->ExpandField(m_rSwdoc.IsClipBoard()));
    1502           0 :                 if( pFnd )
    1503             :                 {
    1504             :                     // modify entry in the hash table
    1505           0 :                     static_cast<_HashStr*>(pFnd)->aSetStr = value;
    1506             :                 }
    1507             :                 else
    1508             :                 {
    1509             :                     // insert the new entry
    1510           0 :                     *(ppHashTbl + nPos ) = new _HashStr( rName,
    1511           0 :                         value, static_cast<_HashStr *>(*(ppHashTbl + nPos)));
    1512           0 :                 }
    1513             :             }
    1514           0 :             break;
    1515             :         }
    1516             :     }
    1517           0 : }
    1518             : 
    1519             : 
    1520        2980 : bool DocumentFieldsManager::IsNewFldLst() const
    1521             : {
    1522        2980 :     return mbNewFldLst;
    1523             : }
    1524             : 
    1525        9924 : void DocumentFieldsManager::SetNewFldLst(bool bFlag)
    1526             : {
    1527        9924 :     mbNewFldLst = bFlag;
    1528        9924 : }
    1529             : 
    1530          16 : void DocumentFieldsManager::InsDelFldInFldLst( bool bIns, const SwTxtFld& rFld )
    1531             : {
    1532          16 :     if( !mbNewFldLst || !m_rSwdoc.IsInDtor() )
    1533          16 :         mpUpdtFlds->InsDelFldInFldLst( bIns, rFld );
    1534          16 : }
    1535             : 
    1536         236 : SwField * DocumentFieldsManager::GetFieldAtPos(const SwPosition & rPos)
    1537             : {
    1538         236 :     SwTxtFld * const pAttr = GetTxtFldAtPos(rPos);
    1539             : 
    1540         236 :     return (pAttr) ? const_cast<SwField *>( pAttr->GetFmtFld().GetField() ) : 0;
    1541             : }
    1542             : 
    1543         264 : SwTxtFld * DocumentFieldsManager::GetTxtFldAtPos(const SwPosition & rPos)
    1544             : {
    1545         264 :     SwTxtNode * const pNode = rPos.nNode.GetNode().GetTxtNode();
    1546             : 
    1547             :     return (pNode != NULL)
    1548         264 :         ? pNode->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true )
    1549         528 :         : 0;
    1550             : }
    1551             : 
    1552             : /// @note For simplicity assume that all field types have updatable contents so
    1553             : ///       optimization currently only available when no fields exist.
    1554         132 : bool DocumentFieldsManager::containsUpdatableFields()
    1555             : {
    1556        3928 :     for (sal_uInt16 i = 0; i < mpFldTypes->size(); ++i)
    1557             :     {
    1558        3814 :         SwFieldType* pFldType = (*mpFldTypes)[i];
    1559        3814 :         SwIterator<SwFmtFld,SwFieldType> aIter(*pFldType);
    1560        3814 :         if (aIter.First())
    1561          18 :             return true;
    1562        3796 :     }
    1563         114 :     return false;
    1564             : }
    1565             : 
    1566             : /// Remove all unreferenced field types of a document
    1567           6 : void DocumentFieldsManager::GCFieldTypes()
    1568             : {
    1569          12 :     for( sal_uInt16 n = mpFldTypes->size(); n > INIT_FLDTYPES; )
    1570           0 :         if( !(*mpFldTypes)[ --n ]->GetDepends() )
    1571           0 :             RemoveFldType( n );
    1572           6 : }
    1573             : 
    1574        5052 : void DocumentFieldsManager::_InitFieldTypes()       // is being called by the CTOR
    1575             : {
    1576             :     // Field types
    1577        5052 :     mpFldTypes->push_back( new SwDateTimeFieldType(&m_rSwdoc) );
    1578        5052 :     mpFldTypes->push_back( new SwChapterFieldType );
    1579        5052 :     mpFldTypes->push_back( new SwPageNumberFieldType );
    1580        5052 :     mpFldTypes->push_back( new SwAuthorFieldType );
    1581        5052 :     mpFldTypes->push_back( new SwFileNameFieldType(&m_rSwdoc) );
    1582        5052 :     mpFldTypes->push_back( new SwDBNameFieldType(&m_rSwdoc) );
    1583        5052 :     mpFldTypes->push_back( new SwGetExpFieldType(&m_rSwdoc) );
    1584        5052 :     mpFldTypes->push_back( new SwGetRefFieldType( &m_rSwdoc ) );
    1585        5052 :     mpFldTypes->push_back( new SwHiddenTxtFieldType );
    1586        5052 :     mpFldTypes->push_back( new SwPostItFieldType(&m_rSwdoc) );
    1587        5052 :     mpFldTypes->push_back( new SwDocStatFieldType(&m_rSwdoc) );
    1588        5052 :     mpFldTypes->push_back( new SwDocInfoFieldType(&m_rSwdoc) );
    1589        5052 :     mpFldTypes->push_back( new SwInputFieldType( &m_rSwdoc ) );
    1590        5052 :     mpFldTypes->push_back( new SwTblFieldType( &m_rSwdoc ) );
    1591        5052 :     mpFldTypes->push_back( new SwMacroFieldType(&m_rSwdoc) );
    1592        5052 :     mpFldTypes->push_back( new SwHiddenParaFieldType );
    1593        5052 :     mpFldTypes->push_back( new SwDBNextSetFieldType );
    1594        5052 :     mpFldTypes->push_back( new SwDBNumSetFieldType );
    1595        5052 :     mpFldTypes->push_back( new SwDBSetNumberFieldType );
    1596        5052 :     mpFldTypes->push_back( new SwTemplNameFieldType(&m_rSwdoc) );
    1597        5052 :     mpFldTypes->push_back( new SwTemplNameFieldType(&m_rSwdoc) );
    1598        5052 :     mpFldTypes->push_back( new SwExtUserFieldType );
    1599        5052 :     mpFldTypes->push_back( new SwRefPageSetFieldType );
    1600        5052 :     mpFldTypes->push_back( new SwRefPageGetFieldType( &m_rSwdoc ) );
    1601        5052 :     mpFldTypes->push_back( new SwJumpEditFieldType( &m_rSwdoc ) );
    1602        5052 :     mpFldTypes->push_back( new SwScriptFieldType( &m_rSwdoc ) );
    1603        5052 :     mpFldTypes->push_back( new SwCombinedCharFieldType );
    1604        5052 :     mpFldTypes->push_back( new SwDropDownFieldType );
    1605             : 
    1606             :     // Types have to be at the end!
    1607             :     // We expect &m_rSwdoc in the InsertFldType!
    1608             :     // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
    1609             :     //               lcl_sw3io_InSetExpField (sw3field.cxx) now also
    1610             :     mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
    1611        5052 :                 SW_RESSTR(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
    1612             :     mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
    1613        5052 :                 SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
    1614             :     mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
    1615        5052 :                 SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
    1616             :     mpFldTypes->push_back( new SwSetExpFieldType(&m_rSwdoc,
    1617        5052 :                 SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
    1618             : 
    1619             :     assert( mpFldTypes->size() == INIT_FLDTYPES );
    1620        5052 : }
    1621             : 
    1622          38 : void DocumentFieldsManager::ClearFieldTypes()
    1623             : {
    1624         114 :     for(SwFldTypes::const_iterator it = mpFldTypes->begin() + INIT_FLDTYPES;
    1625          76 :         it != mpFldTypes->end(); ++it)
    1626           0 :         delete *it;
    1627          38 :     mpFldTypes->erase( mpFldTypes->begin() + INIT_FLDTYPES, mpFldTypes->end() );
    1628          38 : }
    1629             : 
    1630           0 : void DocumentFieldsManager::UpdateDBNumFlds( SwDBNameInfField& rDBFld, SwCalc& rCalc )
    1631             : {
    1632             : #if !HAVE_FEATURE_DBCONNECTIVITY
    1633             :     (void) rDBFld;
    1634             :     (void) rCalc;
    1635             : #else
    1636           0 :     SwDBManager* pMgr = m_rSwdoc.GetDBManager();
    1637             : 
    1638           0 :     sal_uInt16 nFldType = rDBFld.Which();
    1639             : 
    1640           0 :     bool bPar1 = rCalc.Calculate( rDBFld.GetPar1() ).GetBool();
    1641             : 
    1642           0 :     if( RES_DBNEXTSETFLD == nFldType )
    1643           0 :         ((SwDBNextSetField&)rDBFld).SetCondValid( bPar1 );
    1644             :     else
    1645           0 :         ((SwDBNumSetField&)rDBFld).SetCondValid( bPar1 );
    1646             : 
    1647           0 :     if( !rDBFld.GetRealDBData().sDataSource.isEmpty() )
    1648             :     {
    1649             :         // Edit a certain database
    1650           0 :         if( RES_DBNEXTSETFLD == nFldType )
    1651           0 :             ((SwDBNextSetField&)rDBFld).Evaluate(&m_rSwdoc);
    1652             :         else
    1653           0 :             ((SwDBNumSetField&)rDBFld).Evaluate(&m_rSwdoc);
    1654             : 
    1655           0 :         SwDBData aTmpDBData( rDBFld.GetDBData(&m_rSwdoc) );
    1656             : 
    1657           0 :         if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand, -1, false ))
    1658             :             rCalc.VarChange( lcl_GetDBVarName( m_rSwdoc, rDBFld),
    1659           0 :                         pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
    1660             :     }
    1661             :     else
    1662             :     {
    1663             :         OSL_FAIL("TODO: what should happen with unnamed DBFields?");
    1664             :     }
    1665             : #endif
    1666           0 : }
    1667             : 
    1668       15135 : DocumentFieldsManager::~DocumentFieldsManager()
    1669             : {
    1670        5045 :     delete mpUpdtFlds;
    1671        5045 :     delete mpFldTypes;
    1672       10090 : }
    1673             : 
    1674         270 : }
    1675             : 
    1676             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10