LCOV - code coverage report
Current view: top level - sw/source/core/doc - DocumentFieldsManager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 403 781 51.6 %
Date: 2015-06-13 12:38:46 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_rDoc 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 <calbck.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& rDBField )
      61             :     {
      62           0 :         SwDBData aDBData( rDBField.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           1 :     static void lcl_CalcField( SwDoc& rDoc, SwCalc& rCalc, const _SetGetExpField& rSGEField,
      81             :                             SwDBManager* pMgr )
      82             :     {
      83           1 :         const SwTextField* pTextField = rSGEField.GetTextField();
      84           1 :         if( !pTextField )
      85           1 :             return ;
      86             : 
      87           1 :         const SwField* pField = pTextField->GetFormatField().GetField();
      88           1 :         const sal_uInt16 nFieldWhich = pField->GetTyp()->Which();
      89             : 
      90           1 :         if( RES_SETEXPFLD == nFieldWhich )
      91             :         {
      92           1 :             SwSbxValue aValue;
      93           1 :             if( nsSwGetSetExpType::GSE_EXPR & pField->GetSubType() )
      94           1 :                 aValue.PutDouble( static_cast<const SwSetExpField*>(pField)->GetValue() );
      95             :             else
      96             :                 // Extension to calculate with Strings
      97           0 :                 aValue.PutString( static_cast<const SwSetExpField*>(pField)->GetExpStr() );
      98             : 
      99             :             // set the new value in Calculator
     100           1 :             rCalc.VarChange( pField->GetTyp()->GetName(), aValue );
     101             :         }
     102           0 :         else if( pMgr )
     103             :         {
     104             :     #if !HAVE_FEATURE_DBCONNECTIVITY
     105             :             (void) rDoc;
     106             :     #else
     107           0 :             switch( nFieldWhich )
     108             :             {
     109             :             case RES_DBNUMSETFLD:
     110             :                 {
     111           0 :                     SwDBNumSetField* pDBField = const_cast<SwDBNumSetField*>(static_cast<const SwDBNumSetField*>(pField));
     112             : 
     113           0 :                     SwDBData aDBData(pDBField->GetDBData(&rDoc));
     114             : 
     115           0 :                     if( pDBField->IsCondValid() &&
     116           0 :                         pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
     117             :                         rCalc.VarChange( lcl_GetDBVarName( rDoc, *pDBField),
     118           0 :                                         pDBField->GetFormat() );
     119             :                 }
     120           0 :                 break;
     121             :             case RES_DBNEXTSETFLD:
     122             :                 {
     123           0 :                     SwDBNextSetField* pDBField = const_cast<SwDBNextSetField*>(static_cast<const SwDBNextSetField*>(pField));
     124           0 :                     SwDBData aDBData(pDBField->GetDBData(&rDoc));
     125           0 :                     if( !pDBField->IsCondValid() ||
     126           0 :                         !pMgr->OpenDataSource( aDBData.sDataSource, aDBData.sCommand ))
     127           0 :                         break;
     128             : 
     129           0 :                     OUString sDBNumNm(lcl_GetDBVarName( rDoc, *pDBField));
     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        2958 : DocumentFieldsManager::DocumentFieldsManager( SwDoc& i_rSwdoc ) : m_rDoc( i_rSwdoc ),
     146             :                                                                   mbNewFieldLst(true),
     147        2958 :                                                                   mpUpdateFields( new SwDocUpdateField( &m_rDoc ) ),
     148           0 :                                                                   mpFieldTypes( new SwFieldTypes() ),
     149        5916 :                                                                   mnLockExpField( 0 )
     150             : {
     151        2958 : }
     152             : 
     153       30016 : const SwFieldTypes* DocumentFieldsManager::GetFieldTypes() const
     154             : {
     155       30016 :     return mpFieldTypes;
     156             : }
     157             : 
     158             : /** Insert field types
     159             :  *
     160             :  * @param rFieldTyp ???
     161             :  * @return Always returns a pointer to the type, if it's new or already added.
     162             :  */
     163         251 : SwFieldType* DocumentFieldsManager::InsertFieldType(const SwFieldType &rFieldTyp)
     164             : {
     165         251 :     const SwFieldTypes::size_type nSize = mpFieldTypes->size();
     166         251 :     const sal_uInt16 nFieldWhich = rFieldTyp.Which();
     167             : 
     168         251 :     SwFieldTypes::size_type i = INIT_FLDTYPES;
     169             : 
     170         251 :     switch( nFieldWhich )
     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_rDoc, when
     176             :             //constructing string pools and when reading SetExp fields
     177          84 :             if( nsSwGetSetExpType::GSE_SEQ & static_cast<const SwSetExpFieldType&>(rFieldTyp).GetType() )
     178          54 :                 i -= INIT_SEQ_FLDTYPES;
     179             :         // no break;
     180             :     case RES_DBFLD:
     181             :     case RES_USERFLD:
     182             :     case RES_DDEFLD:
     183             :         {
     184         225 :             const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
     185         225 :             OUString sFieldNm( rFieldTyp.GetName() );
     186         634 :             for( ; i < nSize; ++i )
     187        1846 :                 if( nFieldWhich == (*mpFieldTypes)[i]->Which() &&
     188        1802 :                     rSCmp.isEqual( sFieldNm, (*mpFieldTypes)[i]->GetName() ))
     189         225 :                         return (*mpFieldTypes)[i];
     190             :         }
     191         167 :         break;
     192             : 
     193             :     case RES_AUTHORITY:
     194          26 :         for( ; i < nSize; ++i )
     195           3 :             if( nFieldWhich == (*mpFieldTypes)[i]->Which() )
     196           3 :                 return (*mpFieldTypes)[i];
     197          23 :         break;
     198             : 
     199             :     default:
     200           0 :         for( i = 0; i < nSize; ++i )
     201           0 :             if( nFieldWhich == (*mpFieldTypes)[i]->Which() )
     202           0 :                 return (*mpFieldTypes)[i];
     203             :     }
     204             : 
     205         190 :     SwFieldType* pNew = rFieldTyp.Copy();
     206         190 :     switch( nFieldWhich )
     207             :     {
     208             :     case RES_DDEFLD:
     209           0 :         static_cast<SwDDEFieldType*>(pNew)->SetDoc( &m_rDoc );
     210           0 :         break;
     211             : 
     212             :     case RES_DBFLD:
     213             :     case RES_TABLEFLD:
     214             :     case RES_DATETIMEFLD:
     215             :     case RES_GETEXPFLD:
     216         109 :         static_cast<SwValueFieldType*>(pNew)->SetDoc( &m_rDoc );
     217         109 :         break;
     218             : 
     219             :     case RES_USERFLD:
     220             :     case RES_SETEXPFLD:
     221          58 :         static_cast<SwValueFieldType*>(pNew)->SetDoc( &m_rDoc );
     222             :         // JP 29.07.96: Optionally prepare FieldList for Calculator:
     223          58 :         mpUpdateFields->InsertFieldType( *pNew );
     224          58 :         break;
     225             :     case RES_AUTHORITY :
     226          23 :         static_cast<SwAuthorityFieldType*>(pNew)->SetDoc( &m_rDoc );
     227          23 :         break;
     228             :     }
     229             : 
     230         190 :     mpFieldTypes->insert( mpFieldTypes->begin() + nSize, pNew );
     231         190 :     m_rDoc.getIDocumentState().SetModified();
     232             : 
     233         190 :     return (*mpFieldTypes)[ nSize ];
     234             : }
     235             : 
     236             : /// @returns the field type of the Doc
     237       26727 : SwFieldType *DocumentFieldsManager::GetSysFieldType( const sal_uInt16 eWhich ) const
     238             : {
     239      241916 :     for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
     240      241916 :         if( eWhich == (*mpFieldTypes)[i]->Which() )
     241       26727 :             return (*mpFieldTypes)[i];
     242           0 :     return 0;
     243             : }
     244             : 
     245             : /// Find first type with ResId and name
     246        6321 : SwFieldType* DocumentFieldsManager::GetFieldType(
     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        6321 :     const SwFieldTypes::size_type nSize = mpFieldTypes->size();
     253        6321 :     SwFieldTypes::size_type i {0};
     254        6321 :     const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
     255             : 
     256        6321 :     switch( nResId )
     257             :     {
     258             :     case RES_SETEXPFLD:
     259             :             //JP 29.01.96: SequenceFields start at INIT_FLDTYPES - 3!!
     260             :             //             Or we get doubble number circles!!
     261             :             //MIB 14.03.95: From now on also the SW3-Reader relies on &m_rDoc, when
     262             :             //constructing string pools and when reading SetExp fields
     263        3153 :         i = INIT_FLDTYPES - INIT_SEQ_FLDTYPES;
     264        3153 :         break;
     265             : 
     266             :     case RES_DBFLD:
     267             :     case RES_USERFLD:
     268             :     case RES_DDEFLD:
     269             :     case RES_AUTHORITY:
     270         252 :         i = INIT_FLDTYPES;
     271         252 :         break;
     272             :     }
     273             : 
     274        6321 :     SwFieldType* pRet = 0;
     275       38447 :     for( ; i < nSize; ++i )
     276             :     {
     277       38176 :         SwFieldType* pFieldType = (*mpFieldTypes)[i];
     278             : 
     279       38176 :         OUString aFieldName( pFieldType->GetName() );
     280       38176 :         if (bDbFieldMatching && nResId == RES_DBFLD)    // #i51815#
     281           2 :             aFieldName = aFieldName.replace(DB_DELIM, '.');
     282             : 
     283       49802 :         if( nResId == pFieldType->Which() &&
     284       11626 :             rSCmp.isEqual( rName, aFieldName ))
     285             :         {
     286        6050 :             pRet = pFieldType;
     287        6050 :             break;
     288             :         }
     289       32126 :     }
     290        6321 :     return pRet;
     291             : }
     292             : 
     293             : /// Remove field type
     294         108 : void DocumentFieldsManager::RemoveFieldType(size_t nField)
     295             : {
     296             :     OSL_ENSURE( INIT_FLDTYPES <= nField,  "don't remove InitFields" );
     297             :     /*
     298             :      * Dependent fields present -> ErrRaise
     299             :      */
     300         108 :     if(nField < mpFieldTypes->size())
     301             :     {
     302         108 :         SwFieldType* pTmp = (*mpFieldTypes)[nField];
     303             : 
     304             :         // JP 29.07.96: Optionally prepare FieldLst for Calculator
     305         108 :         sal_uInt16 nWhich = pTmp->Which();
     306         108 :         switch( nWhich )
     307             :         {
     308             :         case RES_SETEXPFLD:
     309             :         case RES_USERFLD:
     310           0 :             mpUpdateFields->RemoveFieldType( *pTmp );
     311             :             // no break;
     312             :         case RES_DDEFLD:
     313           0 :             if( pTmp->HasWriterListeners() && !m_rDoc.IsUsed( *pTmp ) )
     314             :             {
     315           0 :                 if( RES_SETEXPFLD == nWhich )
     316           0 :                     static_cast<SwSetExpFieldType*>(pTmp)->SetDeleted( true );
     317           0 :                 else if( RES_USERFLD == nWhich )
     318           0 :                     static_cast<SwUserFieldType*>(pTmp)->SetDeleted( true );
     319             :                 else
     320           0 :                     static_cast<SwDDEFieldType*>(pTmp)->SetDeleted( true );
     321           0 :                 nWhich = 0;
     322             :             }
     323           0 :             break;
     324             :         }
     325             : 
     326         108 :         if( nWhich )
     327             :         {
     328             :             OSL_ENSURE( !pTmp->HasWriterListeners(), "Dependent fields present!" );
     329             :             // delete field type
     330           0 :             delete pTmp;
     331             :         }
     332         108 :         mpFieldTypes->erase( mpFieldTypes->begin() + nField );
     333         108 :         m_rDoc.getIDocumentState().SetModified();
     334             :     }
     335         108 : }
     336             : 
     337             : // All have to be re-evaluated.
     338         220 : void DocumentFieldsManager::UpdateFields( SfxPoolItem *pNewHt, bool bCloseDB )
     339             : {
     340             :     // Call Modify() for every field type,
     341             :     // dependent SwTextField get notified ...
     342             : 
     343        7371 :     for( auto pFieldType : *mpFieldTypes )
     344             :     {
     345        7151 :         switch( pFieldType->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         987 :             break;
     355             : 
     356             :         case RES_DDEFLD:
     357             :         {
     358           0 :             if( !pNewHt )
     359             :             {
     360           0 :                 SwMsgPoolItem aUpdateDDE( RES_UPDATEDDETBL );
     361           0 :                 pFieldType->ModifyNotification( 0, &aUpdateDDE );
     362             :             }
     363             :             else
     364           0 :                 pFieldType->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        1543 :             if( !pNewHt )
     373        1543 :                 break;
     374             :         default:
     375        4621 :             pFieldType->ModifyNotification ( 0, pNewHt );
     376             :         }
     377             :     }
     378             : 
     379         220 :     if( !IsExpFieldsLocked() )
     380         220 :         UpdateExpFields( 0, false );      // update expression fields
     381             : 
     382             :     // Tables
     383         220 :     UpdateTableFields(pNewHt);
     384             : 
     385             :     // References
     386         220 :     UpdateRefFields(pNewHt);
     387         220 :     if( bCloseDB )
     388             :     {
     389             : #if HAVE_FEATURE_DBCONNECTIVITY
     390           1 :         m_rDoc.GetDBManager()->CloseAll();
     391             : #endif
     392             :     }
     393             :     // Only evaluate on full update
     394         220 :     m_rDoc.getIDocumentState().SetModified();
     395         220 : }
     396             : 
     397           0 : void DocumentFieldsManager::InsDeletedFieldType( SwFieldType& rFieldTyp )
     398             : {
     399             :     // The FieldType was marked as deleted and removed from the array.
     400             :     // One has to look &m_rDoc 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 :     const SwFieldTypes::size_type nSize = mpFieldTypes->size();
     405           0 :     const sal_uInt16 nFieldWhich = rFieldTyp.Which();
     406             : 
     407             :     OSL_ENSURE( RES_SETEXPFLD == nFieldWhich ||
     408             :             RES_USERFLD == nFieldWhich ||
     409             :             RES_DDEFLD == nFieldWhich, "Wrong FieldType" );
     410             : 
     411           0 :     const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
     412           0 :     const OUString& rFieldNm = rFieldTyp.GetName();
     413             :     SwFieldType* pFnd;
     414             : 
     415           0 :     for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < nSize; ++i )
     416           0 :         if( nFieldWhich == (pFnd = (*mpFieldTypes)[i])->Which() &&
     417           0 :             rSCmp.isEqual( rFieldNm, pFnd->GetName() ) )
     418             :         {
     419             :             // find new name
     420           0 :             SwFieldTypes::size_type nNum = 1;
     421             :             do {
     422           0 :                 OUString sSrch = rFieldNm + OUString::number( nNum );
     423           0 :                 for( i = INIT_FLDTYPES; i < nSize; ++i )
     424           0 :                     if( nFieldWhich == (pFnd = (*mpFieldTypes)[i])->Which() &&
     425           0 :                         rSCmp.isEqual( sSrch, pFnd->GetName() ) )
     426           0 :                         break;
     427             : 
     428           0 :                 if( i >= nSize )        // not found
     429             :                 {
     430           0 :                     const_cast<OUString&>(rFieldNm) = 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 :     mpFieldTypes->insert( mpFieldTypes->begin() + nSize, &rFieldTyp );
     440           0 :     switch( nFieldWhich )
     441             :     {
     442             :     case RES_SETEXPFLD:
     443           0 :         static_cast<SwSetExpFieldType&>(rFieldTyp).SetDeleted( false );
     444           0 :         break;
     445             :     case RES_USERFLD:
     446           0 :         static_cast<SwUserFieldType&>(rFieldTyp).SetDeleted( false );
     447           0 :         break;
     448             :     case RES_DDEFLD:
     449           0 :         static_cast<SwDDEFieldType&>(rFieldTyp).SetDeleted( false );
     450           0 :         break;
     451           0 :     }
     452           0 : }
     453             : 
     454         246 : bool DocumentFieldsManager::PutValueToField(const SwPosition & rPos,
     455             :                             const Any& rVal, sal_uInt16 nWhich)
     456             : {
     457         246 :     Any aOldVal;
     458         246 :     SwField * pField = GetFieldAtPos(rPos);
     459             : 
     460         286 :     if (m_rDoc.GetIDocumentUndoRedo().DoesUndo() &&
     461          40 :         pField->QueryValue(aOldVal, nWhich))
     462             :     {
     463          40 :         SwUndo *const pUndo(new SwUndoFieldFromAPI(rPos, aOldVal, rVal, nWhich));
     464          40 :         m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
     465             :     }
     466             : 
     467         246 :     return pField->PutValue(rVal, nWhich);
     468             : }
     469             : 
     470           0 : bool DocumentFieldsManager::UpdateField(SwTextField * pDstTextField, SwField & rSrcField,
     471             :                       SwMsgPoolItem * pMsgHint,
     472             :                       bool bUpdateFields)
     473             : {
     474             :     OSL_ENSURE(pDstTextField, "no field to update!");
     475             : 
     476           0 :     bool bTableSelBreak = false;
     477             : 
     478           0 :     SwFormatField * pDstFormatField = const_cast<SwFormatField*>(&pDstTextField->GetFormatField());
     479           0 :     SwField * pDstField = pDstFormatField->GetField();
     480           0 :     sal_uInt16 nFieldWhich = rSrcField.GetTyp()->Which();
     481           0 :     SwNodeIndex aTableNdIdx(pDstTextField->GetTextNode());
     482             : 
     483           0 :     if (pDstField->GetTyp()->Which() ==
     484           0 :         rSrcField.GetTyp()->Which())
     485             :     {
     486           0 :         if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
     487             :         {
     488           0 :             SwPosition aPosition( pDstTextField->GetTextNode() );
     489           0 :             aPosition.nContent = pDstTextField->GetStart();
     490             : 
     491           0 :             SwUndo *const pUndo( new SwUndoFieldFromDoc( aPosition, *pDstField, rSrcField, pMsgHint, bUpdateFields) );
     492           0 :             m_rDoc.GetIDocumentUndoRedo().AppendUndo(pUndo);
     493             :         }
     494             : 
     495           0 :         SwField * pNewField = rSrcField.CopyField();
     496           0 :         pDstFormatField->SetField(pNewField);
     497             : 
     498           0 :         switch( nFieldWhich )
     499             :         {
     500             :         case RES_SETEXPFLD:
     501             :         case RES_GETEXPFLD:
     502             :         case RES_HIDDENTXTFLD:
     503             :         case RES_HIDDENPARAFLD:
     504           0 :             UpdateExpFields( pDstTextField, true );
     505           0 :             break;
     506             : 
     507             :         case RES_TABLEFLD:
     508             :             {
     509             :                 const SwTableNode* pTableNd =
     510           0 :                     m_rDoc.IsIdxInTable(aTableNdIdx);
     511           0 :                 if( pTableNd )
     512             :                 {
     513             :                     SwTableFormulaUpdate aTableUpdate( &pTableNd->
     514           0 :                                                  GetTable() );
     515           0 :                     if (bUpdateFields)
     516           0 :                         UpdateTableFields( &aTableUpdate );
     517             :                     else
     518           0 :                         pNewField->GetTyp()->ModifyNotification(0, &aTableUpdate);
     519             : 
     520           0 :                     if (! bUpdateFields)
     521           0 :                         bTableSelBreak = true;
     522             :                 }
     523             :             }
     524           0 :             break;
     525             : 
     526             :         case RES_MACROFLD:
     527           0 :             if( bUpdateFields && pDstTextField->GetpTextNode() )
     528           0 :                 (pDstTextField->GetpTextNode())->
     529           0 :                     ModifyNotification( 0, pDstFormatField );
     530           0 :             break;
     531             : 
     532             :         case RES_DBNAMEFLD:
     533             :         case RES_DBNEXTSETFLD:
     534             :         case RES_DBNUMSETFLD:
     535             :         case RES_DBSETNUMBERFLD:
     536           0 :             m_rDoc.ChgDBData(static_cast<SwDBNameInfField*>( pNewField)->GetRealDBData());
     537           0 :             pNewField->GetTyp()->UpdateFields();
     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* pDBField = static_cast<SwDBField*>(pNewField);
     547           0 :                 if (pDBField->IsInitialized())
     548           0 :                     pDBField->ChgValue( pDBField->GetValue(), true );
     549             : 
     550           0 :                 pDBField->ClearInitialized();
     551           0 :                 pDBField->InitContent();
     552             :             }
     553             : #endif
     554             :             // no break;
     555             : 
     556             :         default:
     557           0 :             pDstFormatField->ModifyNotification( 0, pMsgHint );
     558             :         }
     559             : 
     560             :         // The fields we can calculate here are being triggered for an update
     561             :         // here explicitly.
     562           0 :         if( nFieldWhich == RES_USERFLD )
     563           0 :             UpdateUsrFields();
     564             :     }
     565             : 
     566           0 :     return bTableSelBreak;
     567             : }
     568             : 
     569             : /// Update reference and table fields
     570         425 : void DocumentFieldsManager::UpdateRefFields( SfxPoolItem* pHt )
     571             : {
     572       14157 :     for( auto pFieldType : *mpFieldTypes )
     573       13732 :         if( RES_GETREFFLD == pFieldType->Which() )
     574         425 :             pFieldType->ModifyNotification( 0, pHt );
     575         425 : }
     576             : 
     577        1320 : void DocumentFieldsManager::UpdateTableFields( SfxPoolItem* pHt )
     578             : {
     579             :     OSL_ENSURE( !pHt || RES_TABLEFML_UPDATE  == pHt->Which(),
     580             :             "What MessageItem is &m_rDoc?" );
     581             : 
     582        1320 :     SwFieldType* pFieldType(0);
     583             : 
     584       18480 :     for (auto pFieldTypeTmp : *mpFieldTypes)
     585             :     {
     586       18480 :         if( RES_TABLEFLD == pFieldTypeTmp->Which() )
     587             :         {
     588        1320 :             SwTableFormulaUpdate* pUpdateField = 0;
     589        1320 :             if( pHt && RES_TABLEFML_UPDATE == pHt->Which() )
     590        1013 :                 pUpdateField = static_cast<SwTableFormulaUpdate*>(pHt);
     591             : 
     592        1320 :             SwIterator<SwFormatField,SwFieldType> aIter( *pFieldTypeTmp );
     593        1320 :             for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
     594             :             {
     595           0 :                 if( pFormatField->GetTextField() )
     596             :                 {
     597           0 :                     SwTableField* pField = static_cast<SwTableField*>(pFormatField->GetField());
     598             : 
     599           0 :                     if( pUpdateField )
     600             :                     {
     601             :                         // table where &m_rDoc field is located
     602             :                         const SwTableNode* pTableNd;
     603           0 :                         const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
     604           0 :                         if( !rTextNd.GetNodes().IsDocNodes() ||
     605           0 :                             0 == ( pTableNd = rTextNd.FindTableNode() ) )
     606           0 :                             continue;
     607             : 
     608           0 :                         switch( pUpdateField->eFlags )
     609             :                         {
     610             :                         case TBL_CALC:
     611             :                             // re-set the value flag
     612             :                             // JP 17.06.96: internal representation of all formulas
     613             :                             //              (reference to other table!!!)
     614           0 :                             if( nsSwExtendedSubType::SUB_CMD & pField->GetSubType() )
     615           0 :                                 pField->PtrToBoxNm( pUpdateField->pTable );
     616             :                             else
     617           0 :                                 pField->ChgValid( false );
     618           0 :                             break;
     619             :                         case TBL_BOXNAME:
     620             :                             // is &m_rDoc the wanted table?
     621           0 :                             if( &pTableNd->GetTable() == pUpdateField->pTable )
     622             :                                 // to the external representation
     623           0 :                                 pField->PtrToBoxNm( pUpdateField->pTable );
     624           0 :                             break;
     625             :                         case TBL_BOXPTR:
     626             :                             // to the internal representation
     627             :                             // JP 17.06.96: internal representation on all formulas
     628             :                             //              (reference to other table!!!)
     629           0 :                             pField->BoxNmToPtr( pUpdateField->pTable );
     630           0 :                             break;
     631             :                         case TBL_RELBOXNAME:
     632             :                             // is &m_rDoc the wanted table?
     633           0 :                             if( &pTableNd->GetTable() == pUpdateField->pTable )
     634             :                                 // to the relative representation
     635           0 :                                 pField->ToRelBoxNm( pUpdateField->pTable );
     636           0 :                             break;
     637             :                         default:
     638           0 :                             break;
     639             :                         }
     640             :                     }
     641             :                     else
     642             :                         // reset the value flag for all
     643           0 :                         pField->ChgValid( false );
     644             :                 }
     645             :             }
     646        1320 :             pFieldType = pFieldTypeTmp;
     647        1320 :             break;
     648             :         }
     649             :     }
     650             : 
     651             :     // process all table box formulas
     652             :     const SfxPoolItem* pItem;
     653        1320 :     sal_uInt32 nMaxItems = m_rDoc.GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
     654        1320 :     for (sal_uInt32 i = 0; i < nMaxItems; ++i)
     655             :     {
     656           0 :         if( 0 != (pItem = m_rDoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
     657           0 :             static_cast<const SwTableBoxFormula*>(pItem)->GetDefinedIn() )
     658             :         {
     659           0 :             const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem))->ChangeState( pHt );
     660             :         }
     661             :     }
     662             : 
     663             :     // all fields/boxes are now invalid, so we can start to calculate
     664        2333 :     if( pHt && ( RES_TABLEFML_UPDATE != pHt->Which() ||
     665        1013 :                 TBL_CALC != static_cast<SwTableFormulaUpdate*>(pHt)->eFlags ))
     666        2028 :         return ;
     667             : 
     668         612 :     SwCalc* pCalc = 0;
     669             : 
     670         612 :     if( pFieldType )
     671             :     {
     672         612 :         SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
     673         612 :         for( SwFormatField* pFormatField = aIter.Last(); pFormatField; pFormatField = aIter.Previous() )
     674             :         {
     675             :                 // start calculation at the end
     676             :                 // new fields are inserted at the beginning of the modify chain
     677             :                 // that gives faster calculation on import
     678             :                 // mba: do we really need &m_rDoc "optimization"? Is it still valid?
     679             :                 SwTableField* pField;
     680           0 :                 if( !pFormatField->GetTextField() || (nsSwExtendedSubType::SUB_CMD &
     681           0 :                     (pField = static_cast<SwTableField*>(pFormatField->GetField()))->GetSubType() ))
     682           0 :                     continue;
     683             : 
     684             :                 // needs to be recalculated
     685           0 :                 if( !pField->IsValid() )
     686             :                 {
     687             :                     // table where &m_rDoc field is located
     688           0 :                     const SwTextNode& rTextNd = pFormatField->GetTextField()->GetTextNode();
     689           0 :                     if( !rTextNd.GetNodes().IsDocNodes() )
     690           0 :                         continue;
     691           0 :                     const SwTableNode* pTableNd = rTextNd.FindTableNode();
     692           0 :                     if( !pTableNd )
     693           0 :                         continue;
     694             : 
     695             :                     // if &m_rDoc field is not in the to-be-updated table, skip it
     696           0 :                     if( pHt && &pTableNd->GetTable() !=
     697             :                                             static_cast<SwTableFormulaUpdate*>(pHt)->pTable )
     698           0 :                         continue;
     699             : 
     700           0 :                     if( !pCalc )
     701           0 :                         pCalc = new SwCalc( m_rDoc );
     702             : 
     703             :                     // get the values of all SetExpression fields that are valid
     704             :                     // until the table
     705           0 :                     SwFrm* pFrm = 0;
     706           0 :                     if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
     707             :                     {
     708             :                         // is in the special section, that's expensive!
     709           0 :                         Point aPt;      // return the first frame of the layout - Tab.Headline!!
     710           0 :                         pFrm = rTextNd.getLayoutFrm( m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt );
     711           0 :                         if( pFrm )
     712             :                         {
     713           0 :                             SwPosition aPos( *pTableNd );
     714           0 :                             if( GetBodyTextNode( m_rDoc, aPos, *pFrm ) )
     715             :                                 FieldsToCalc( *pCalc, _SetGetExpField(
     716           0 :                                     aPos.nNode, pFormatField->GetTextField(),
     717           0 :                                     &aPos.nContent ));
     718             :                             else
     719           0 :                                 pFrm = 0;
     720             :                         }
     721             :                     }
     722           0 :                     if( !pFrm )
     723             :                     {
     724             :                         // create index to determine the TextNode
     725           0 :                         SwNodeIndex aIdx( rTextNd );
     726             :                         FieldsToCalc( *pCalc,
     727           0 :                             _SetGetExpField( aIdx, pFormatField->GetTextField() ));
     728             :                     }
     729             : 
     730           0 :                     SwTableCalcPara aPara( *pCalc, pTableNd->GetTable() );
     731           0 :                     pField->CalcField( aPara );
     732           0 :                     if( aPara.IsStackOverflow() )
     733             :                     {
     734           0 :                         bool const bResult = aPara.CalcWithStackOverflow();
     735           0 :                         if (bResult)
     736             :                         {
     737           0 :                             pField->CalcField( aPara );
     738             :                         }
     739             :                         OSL_ENSURE(bResult,
     740             :                                 "the chained formula could no be calculated");
     741             :                     }
     742           0 :                     pCalc->SetCalcError( CALC_NOERR );
     743             :                 }
     744           0 :                 pFormatField->ModifyNotification( 0, pHt );
     745         612 :         }
     746             :     }
     747             : 
     748             :     // calculate the formula at the boxes
     749         612 :     for (sal_uInt32 i = 0; i < nMaxItems; ++i )
     750             :     {
     751           0 :         if( 0 != (pItem = m_rDoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
     752           0 :             static_cast<const SwTableBoxFormula*>(pItem)->GetDefinedIn() &&
     753           0 :             !static_cast<const SwTableBoxFormula*>(pItem)->IsValid() )
     754             :         {
     755           0 :             SwTableBoxFormula* pFormula = const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem));
     756           0 :             SwTableBox* pBox = pFormula->GetTableBox();
     757           0 :             if( pBox && pBox->GetSttNd() &&
     758           0 :                 pBox->GetSttNd()->GetNodes().IsDocNodes() )
     759             :             {
     760           0 :                 const SwTableNode* pTableNd = pBox->GetSttNd()->FindTableNode();
     761           0 :                 if( !pHt || &pTableNd->GetTable() ==
     762             :                                             static_cast<SwTableFormulaUpdate*>(pHt)->pTable )
     763             :                 {
     764             :                     double nValue;
     765           0 :                     if( !pCalc )
     766           0 :                         pCalc = new SwCalc( m_rDoc );
     767             : 
     768             :                     // get the values of all SetExpression fields that are valid
     769             :                     // until the table
     770           0 :                     SwFrm* pFrm = 0;
     771           0 :                     if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
     772             :                     {
     773             :                         // is in the special section, that's expensive!
     774           0 :                         Point aPt;      // return the first frame of the layout - Tab.Headline!!
     775           0 :                         SwNodeIndex aCNdIdx( *pTableNd, +2 );
     776           0 :                         SwContentNode* pCNd = aCNdIdx.GetNode().GetContentNode();
     777           0 :                         if( !pCNd )
     778           0 :                             pCNd = m_rDoc.GetNodes().GoNext( &aCNdIdx );
     779             : 
     780           0 :                         if( pCNd && 0 != (pFrm = pCNd->getLayoutFrm( m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout(), &aPt )) )
     781             :                         {
     782           0 :                             SwPosition aPos( *pCNd );
     783           0 :                             if( GetBodyTextNode( m_rDoc, aPos, *pFrm ) )
     784           0 :                                 FieldsToCalc( *pCalc, _SetGetExpField( aPos.nNode ));
     785             :                             else
     786           0 :                                 pFrm = 0;
     787           0 :                         }
     788             :                     }
     789           0 :                     if( !pFrm )
     790             :                     {
     791             :                         // create index to determine the TextNode
     792           0 :                         SwNodeIndex aIdx( *pTableNd );
     793           0 :                         FieldsToCalc( *pCalc, _SetGetExpField( aIdx ));
     794             :                     }
     795             : 
     796           0 :                     SwTableCalcPara aPara( *pCalc, pTableNd->GetTable() );
     797           0 :                     pFormula->Calc( aPara, nValue );
     798             : 
     799           0 :                     if( aPara.IsStackOverflow() )
     800             :                     {
     801           0 :                         bool const bResult = aPara.CalcWithStackOverflow();
     802           0 :                         if (bResult)
     803             :                         {
     804           0 :                             pFormula->Calc( aPara, nValue );
     805             :                         }
     806             :                         OSL_ENSURE(bResult,
     807             :                                 "the chained formula could no be calculated");
     808             :                     }
     809             : 
     810           0 :                     SwFrameFormat* pFormat = pBox->ClaimFrameFormat();
     811           0 :                     SfxItemSet aTmp( m_rDoc.GetAttrPool(),
     812           0 :                                     RES_BOXATR_BEGIN,RES_BOXATR_END-1 );
     813             : 
     814           0 :                     if( pCalc->IsCalcError() )
     815           0 :                         nValue = DBL_MAX;
     816           0 :                     aTmp.Put( SwTableBoxValue( nValue ));
     817           0 :                     if( SfxItemState::SET != pFormat->GetItemState( RES_BOXATR_FORMAT ))
     818           0 :                         aTmp.Put( SwTableBoxNumFormat( 0 ));
     819           0 :                     pFormat->SetFormatAttr( aTmp );
     820             : 
     821           0 :                     pCalc->SetCalcError( CALC_NOERR );
     822             :                 }
     823             :             }
     824             :         }
     825             :     }
     826             : 
     827         612 :     delete pCalc;
     828             : }
     829             : 
     830        7198 : void DocumentFieldsManager::UpdateExpFields( SwTextField* pUpdateField, bool bUpdRefFields )
     831             : {
     832        7198 :     if( IsExpFieldsLocked() || m_rDoc.IsInReading() )
     833       13918 :         return;
     834             : 
     835         405 :     bool bOldInUpdateFields = mpUpdateFields->IsInUpdateFields();
     836         405 :     mpUpdateFields->SetInUpdateFields( true );
     837             : 
     838         405 :     mpUpdateFields->MakeFieldList( m_rDoc, true, GETFLD_ALL );
     839         405 :     mbNewFieldLst = false;
     840             : 
     841         405 :     if( mpUpdateFields->GetSortLst()->empty() )
     842             :     {
     843         332 :         if( bUpdRefFields )
     844          94 :             UpdateRefFields(NULL);
     845             : 
     846         332 :         mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
     847         332 :         mpUpdateFields->SetFieldsDirty( false );
     848         332 :         return ;
     849             :     }
     850             : 
     851             :     sal_uInt16 nWhich;
     852             : 
     853             :     // Hash table for all string replacements is filled on-the-fly.
     854             :     // Try to fabricate an uneven number.
     855          73 :     const SwFieldTypes::size_type nHashSize {(( mpFieldTypes->size() / 7 ) + 1 ) * 7};
     856          73 :     const sal_uInt16 nStrFormatCnt = static_cast<sal_uInt16>(nHashSize);
     857             :     OSL_ENSURE( nStrFormatCnt == nHashSize, "Downcasting to sal_uInt16 lost information!" );
     858          73 :     SwHash** pHashStrTable = new SwHash*[ nStrFormatCnt ];
     859          73 :     memset( pHashStrTable, 0, sizeof( _HashStr* ) * nStrFormatCnt );
     860             : 
     861             :     {
     862             :         const SwFieldType* pFieldType;
     863             :         // process separately:
     864        2612 :         for( auto n = mpFieldTypes->size(); n; )
     865        2466 :             switch( ( pFieldType = (*mpFieldTypes)[ --n ] )->Which() )
     866             :             {
     867             :             case RES_USERFLD:
     868             :                 {
     869             :                     // Entry present?
     870             :                     sal_uInt16 nPos;
     871           3 :                     const OUString& rNm = pFieldType->GetName();
     872           6 :                     OUString sExpand(const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->Expand(nsSwGetSetExpType::GSE_STRING, 0, 0));
     873           3 :                     SwHash* pFnd = Find( rNm, pHashStrTable, nStrFormatCnt, &nPos );
     874           3 :                     if( pFnd )
     875             :                         // modify entry in the hash table
     876           0 :                         static_cast<_HashStr*>(pFnd)->aSetStr = sExpand;
     877             :                     else
     878             :                         // insert the new entry
     879           3 :                         *(pHashStrTable + nPos ) = new _HashStr( rNm, sExpand,
     880           9 :                                                 static_cast<_HashStr*>(*(pHashStrTable + nPos)) );
     881             :                 }
     882           3 :                 break;
     883             :             case RES_SETEXPFLD:
     884         298 :                 const_cast<SwSetExpFieldType*>(static_cast<const SwSetExpFieldType*>(pFieldType))->SetOutlineChgNd( 0 );
     885         298 :                 break;
     886             :             }
     887             :     }
     888             : 
     889             :     // The array is filled with all fields; start calculation.
     890          73 :     SwCalc aCalc( m_rDoc );
     891             : 
     892             : #if HAVE_FEATURE_DBCONNECTIVITY
     893         146 :     OUString sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD ) );
     894             : 
     895             :     // already set the current record number
     896          73 :     SwDBManager* pMgr = m_rDoc.GetDBManager();
     897          73 :     pMgr->CloseAll( false );
     898             : 
     899         146 :     SvtSysLocale aSysLocale;
     900          73 :     const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
     901          73 :     const long nLang = pLclData->getLanguageTag().getLanguageType();
     902          73 :     bool bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.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          73 :     int nShownSections = 0;
     907         209 :     for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != mpUpdateFields->GetSortLst()->end(); ++it )
     908             :     {
     909         136 :         SwSection* pSect = const_cast<SwSection*>((*it)->GetSection());
     910         136 :         if ( pSect && !pSect->IsCondHidden())
     911           5 :             nShownSections++;
     912             :     }
     913             : 
     914         146 :     OUString aNew;
     915         209 :     for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != mpUpdateFields->GetSortLst()->end(); ++it )
     916             :     {
     917         136 :         SwSection* pSect = const_cast<SwSection*>((*it)->GetSection());
     918         136 :         if( pSect )
     919             :         {
     920             : 
     921             :             SwSbxValue aValue = aCalc.Calculate(
     922           5 :                                         pSect->GetCondition() );
     923           5 :             if(!aValue.IsVoidValue())
     924             :             {
     925             :                 // Do we want to hide this one?
     926           5 :                 bool bHide = aValue.GetBool();
     927           5 :                 if (bHide && !pSect->IsCondHidden())
     928             :                 {
     929             :                     // This section will be hidden, but it wasn't before
     930           4 :                     if (nShownSections == 1)
     931             :                     {
     932             :                         // Is the last node part of a section?
     933           4 :                         SwPaM aPam(m_rDoc.GetNodes());
     934           4 :                         aPam.Move(fnMoveForward, fnGoDoc);
     935           4 :                         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           2 :                             OUString aCond("0");
     939           2 :                             pSect->SetCondition(aCond);
     940           2 :                             bHide = false;
     941           4 :                         }
     942             :                     }
     943           4 :                     nShownSections--;
     944             :                 }
     945           5 :                 pSect->SetCondHidden( bHide );
     946             :             }
     947           5 :             continue;
     948             :         }
     949             : 
     950         131 :         SwTextField* pTextField = const_cast<SwTextField*>((*it)->GetTextField());
     951         131 :         if( !pTextField )
     952             :         {
     953             :             OSL_ENSURE( false, "what's wrong now'" );
     954           0 :             continue;
     955             :         }
     956             : 
     957         131 :         SwFormatField* pFormatField = const_cast<SwFormatField*>(&pTextField->GetFormatField());
     958         131 :         const SwField* pField = pFormatField->GetField();
     959             : 
     960         131 :         switch( nWhich = pField->GetTyp()->Which() )
     961             :         {
     962             :         case RES_HIDDENTXTFLD:
     963             :         {
     964           0 :             SwHiddenTextField* pHField = const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField));
     965           0 :             SwSbxValue aValue = aCalc.Calculate( pHField->GetPar1() );
     966           0 :             bool bValue = !aValue.GetBool();
     967           0 :             if(!aValue.IsVoidValue())
     968             :             {
     969           0 :                 pHField->SetValue( bValue );
     970             :                 // evaluate field
     971           0 :                 pHField->Evaluate(&m_rDoc);
     972           0 :             }
     973             :         }
     974           0 :         break;
     975             :         case RES_HIDDENPARAFLD:
     976             :         {
     977           0 :             SwHiddenParaField* pHPField = const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField));
     978           0 :             SwSbxValue aValue = aCalc.Calculate( pHPField->GetPar1() );
     979           0 :             bool bValue = aValue.GetBool();
     980           0 :             if(!aValue.IsVoidValue())
     981           0 :                 pHPField->SetHidden( bValue );
     982             :         }
     983           0 :         break;
     984             :         case RES_DBSETNUMBERFLD:
     985             : #if HAVE_FEATURE_DBCONNECTIVITY
     986             :         {
     987           0 :             const_cast<SwDBSetNumberField*>(static_cast<const SwDBSetNumberField*>(pField))->Evaluate(&m_rDoc);
     988           0 :             aCalc.VarChange( sDBNumNm, static_cast<const SwDBSetNumberField*>(pField)->GetSetNumber());
     989             :         }
     990             : #endif
     991           0 :         break;
     992             :         case RES_DBNEXTSETFLD:
     993             :         case RES_DBNUMSETFLD:
     994             : #if HAVE_FEATURE_DBCONNECTIVITY
     995             :         {
     996           0 :             UpdateDBNumFields( *const_cast<SwDBNameInfField*>(static_cast<const SwDBNameInfField*>(pField)), aCalc );
     997           0 :             if( bCanFill )
     998           0 :                 bCanFill = pMgr->FillCalcWithMergeData( m_rDoc.GetNumberFormatter(), nLang, true, aCalc );
     999             :         }
    1000             : #endif
    1001           0 :         break;
    1002             :         case RES_DBFLD:
    1003             :         {
    1004             : #if HAVE_FEATURE_DBCONNECTIVITY
    1005             :             // evaluate field
    1006         118 :             const_cast<SwDBField*>(static_cast<const SwDBField*>(pField))->Evaluate();
    1007             : 
    1008         118 :             SwDBData aTmpDBData(static_cast<const SwDBField*>(pField)->GetDBData());
    1009             : 
    1010         118 :             if( pMgr->IsDataSourceOpen(aTmpDBData.sDataSource, aTmpDBData.sCommand, false))
    1011          60 :                 aCalc.VarChange( sDBNumNm, pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType));
    1012             : 
    1013         236 :             const OUString& rName = pField->GetTyp()->GetName();
    1014             : 
    1015             :             // Add entry to hash table
    1016             :             // Entry present?
    1017             :             sal_uInt16 nPos;
    1018         118 :             SwHash* pFnd = Find( rName, pHashStrTable, nStrFormatCnt, &nPos );
    1019         236 :             OUString const value(pField->ExpandField(m_rDoc.IsClipBoard()));
    1020         118 :             if( pFnd )
    1021             :             {
    1022             :                 // Modify entry in the hash table
    1023           3 :                 static_cast<_HashStr*>(pFnd)->aSetStr = value;
    1024             :             }
    1025             :             else
    1026             :             {
    1027             :                 // insert new entry
    1028         115 :                 *(pHashStrTable + nPos ) = new _HashStr( rName,
    1029         230 :                     value, static_cast<_HashStr *>(*(pHashStrTable + nPos)));
    1030         118 :             }
    1031             : #endif
    1032             :         }
    1033         118 :         break;
    1034             :         case RES_GETEXPFLD:
    1035             :         case RES_SETEXPFLD:
    1036             :         {
    1037          13 :             if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )        // replace String
    1038             :             {
    1039           1 :                 if( RES_GETEXPFLD == nWhich )
    1040             :                 {
    1041           0 :                     SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
    1042             : 
    1043           0 :                     if( (!pUpdateField || pUpdateField == pTextField )
    1044           0 :                         && pGField->IsInBodyText() )
    1045             :                     {
    1046           0 :                         aNew = LookString( pHashStrTable, nStrFormatCnt,
    1047           0 :                                     pGField->GetFormula() );
    1048           0 :                         pGField->ChgExpStr( aNew );
    1049             :                     }
    1050             :                 }
    1051             :                 else
    1052             :                 {
    1053           1 :                     SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
    1054             :                     // is the "formula" a field?
    1055           3 :                     aNew = LookString( pHashStrTable, nStrFormatCnt,
    1056           2 :                                 pSField->GetFormula() );
    1057             : 
    1058           1 :                     if( aNew.isEmpty() )               // nothing found then the formula is the new value
    1059           1 :                         aNew = pSField->GetFormula();
    1060             : 
    1061             :                     // only update one field
    1062           1 :                     if( !pUpdateField || pUpdateField == pTextField )
    1063           1 :                         pSField->ChgExpStr( aNew );
    1064             : 
    1065             :                     // lookup the field's name
    1066           1 :                     aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
    1067             :                     // Entry present?
    1068             :                     sal_uInt16 nPos;
    1069           1 :                     SwHash* pFnd = Find( aNew, pHashStrTable, nStrFormatCnt, &nPos );
    1070           1 :                     if( pFnd )
    1071             :                         // Modify entry in the hash table
    1072           0 :                         static_cast<_HashStr*>(pFnd)->aSetStr = pSField->GetExpStr();
    1073             :                     else
    1074             :                         // insert new entry
    1075           1 :                         *(pHashStrTable + nPos ) = pFnd = new _HashStr( aNew,
    1076             :                                         pSField->GetExpStr(),
    1077           1 :                                         static_cast<_HashStr*>(*(pHashStrTable + nPos) ));
    1078             : 
    1079             :                     // Extension for calculation with Strings
    1080           1 :                     SwSbxValue aValue;
    1081           1 :                     aValue.PutString( static_cast<_HashStr*>(pFnd)->aSetStr );
    1082           1 :                     aCalc.VarChange( aNew, aValue );
    1083             :                 }
    1084             :             }
    1085             :             else            // recalculate formula
    1086             :             {
    1087          12 :                 if( RES_GETEXPFLD == nWhich )
    1088             :                 {
    1089           0 :                     SwGetExpField* pGField = const_cast<SwGetExpField*>(static_cast<const SwGetExpField*>(pField));
    1090             : 
    1091           0 :                     if( (!pUpdateField || pUpdateField == pTextField )
    1092           0 :                         && pGField->IsInBodyText() )
    1093             :                     {
    1094             :                         SwSbxValue aValue = aCalc.Calculate(
    1095           0 :                                         pGField->GetFormula());
    1096           0 :                         if(!aValue.IsVoidValue())
    1097           0 :                             pGField->SetValue(aValue.GetDouble() );
    1098             :                     }
    1099             :                 }
    1100             :                 else
    1101             :                 {
    1102          12 :                     SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
    1103          12 :                     SwSetExpFieldType* pSFieldTyp = static_cast<SwSetExpFieldType*>(pField->GetTyp());
    1104          12 :                     aNew = pSFieldTyp->GetName();
    1105             : 
    1106          12 :                     SwNode* pSeqNd = 0;
    1107             : 
    1108          12 :                     if( pSField->IsSequenceField() )
    1109             :                     {
    1110           9 :                         const sal_uInt8 nLvl = pSFieldTyp->GetOutlineLvl();
    1111           9 :                         if( MAXLEVEL > nLvl )
    1112             :                         {
    1113             :                             // test if the Number needs to be updated
    1114           3 :                             pSeqNd = m_rDoc.GetNodes()[ (*it)->GetNode() ];
    1115             : 
    1116             :                             const SwTextNode* pOutlNd = pSeqNd->
    1117           3 :                                     FindOutlineNodeOfLevel( nLvl );
    1118           3 :                             if( pSFieldTyp->GetOutlineChgNd() != pOutlNd )
    1119             :                             {
    1120           1 :                                 pSFieldTyp->SetOutlineChgNd( pOutlNd );
    1121           1 :                                 aCalc.VarChange( aNew, 0 );
    1122             :                             }
    1123             :                         }
    1124             :                     }
    1125             : 
    1126          12 :                     aNew += "=";
    1127          12 :                     aNew += pSField->GetFormula();
    1128             : 
    1129          12 :                     SwSbxValue aValue = aCalc.Calculate( aNew );
    1130          12 :                     double nErg = aValue.GetDouble();
    1131             :                     // only update one field
    1132          12 :                     if( !aValue.IsVoidValue() && (!pUpdateField || pUpdateField == pTextField) )
    1133             :                     {
    1134          12 :                         pSField->SetValue( nErg );
    1135             : 
    1136          12 :                         if( pSeqNd )
    1137           3 :                             pSFieldTyp->SetChapter( *pSField, *pSeqNd );
    1138          12 :                     }
    1139             :                 }
    1140             :             }
    1141             :         }
    1142             :         } // switch
    1143             : 
    1144         131 :         pFormatField->ModifyNotification( 0, 0 );        // trigger formatting
    1145             : 
    1146         131 :         if( pUpdateField == pTextField )       // if only &m_rDoc one is updated
    1147             :         {
    1148           0 :             if( RES_GETEXPFLD == nWhich ||      // only GetField or
    1149           0 :                 RES_HIDDENTXTFLD == nWhich ||   // HiddenText?
    1150             :                 RES_HIDDENPARAFLD == nWhich)    // HiddenParaField?
    1151             :                 break;                          // quit
    1152           0 :             pUpdateField = 0;                       // update all from here on
    1153             :         }
    1154             :     }
    1155             : 
    1156             : #if HAVE_FEATURE_DBCONNECTIVITY
    1157          73 :     pMgr->CloseAll(false);
    1158             : #endif
    1159             :     // delete hash table
    1160          73 :     ::DeleteHashTable( pHashStrTable, nStrFormatCnt );
    1161             : 
    1162             :     // update reference fields
    1163          73 :     if( bUpdRefFields )
    1164           4 :         UpdateRefFields(NULL);
    1165             : 
    1166          73 :     mpUpdateFields->SetInUpdateFields( bOldInUpdateFields );
    1167         146 :     mpUpdateFields->SetFieldsDirty( false );
    1168             : }
    1169             : 
    1170             : /// Insert field type that was marked as deleted
    1171           0 : void DocumentFieldsManager::UpdateUsrFields()
    1172             : {
    1173           0 :     SwCalc* pCalc = 0;
    1174             :     const SwFieldType* pFieldType;
    1175           0 :     for( SwFieldTypes::size_type i = INIT_FLDTYPES; i < mpFieldTypes->size(); ++i )
    1176           0 :         if( RES_USERFLD == ( pFieldType = (*mpFieldTypes)[i] )->Which() )
    1177             :         {
    1178           0 :             if( !pCalc )
    1179           0 :                 pCalc = new SwCalc( m_rDoc );
    1180           0 :             const_cast<SwUserFieldType*>(static_cast<const SwUserFieldType*>(pFieldType))->GetValue( *pCalc );
    1181             :         }
    1182             : 
    1183           0 :     if( pCalc )
    1184             :     {
    1185           0 :         delete pCalc;
    1186           0 :         m_rDoc.getIDocumentState().SetModified();
    1187             :     }
    1188           0 : }
    1189             : 
    1190        4010 : void DocumentFieldsManager::UpdatePageFields( SfxPoolItem* pMsgHint )
    1191             : {
    1192      132330 :     for( SwFieldTypes::size_type i = 0; i < INIT_FLDTYPES; ++i )
    1193             :     {
    1194      128320 :         SwFieldType* pFieldType = (*mpFieldTypes)[ i ];
    1195      128320 :         switch( pFieldType->Which() )
    1196             :         {
    1197             :         case RES_PAGENUMBERFLD:
    1198             :         case RES_CHAPTERFLD:
    1199             :         case RES_GETEXPFLD:
    1200             :         case RES_REFPAGEGETFLD:
    1201       16040 :             pFieldType->ModifyNotification( 0, pMsgHint );
    1202       16040 :             break;
    1203             :         case RES_DOCSTATFLD:
    1204        4010 :             pFieldType->ModifyNotification( 0, 0 );
    1205        4010 :             break;
    1206             :         }
    1207             :     }
    1208        4010 :     SetNewFieldLst(true);
    1209        4010 : }
    1210             : 
    1211        3014 : void DocumentFieldsManager::LockExpFields()
    1212             : {
    1213        3014 :     ++mnLockExpField;
    1214        3014 : }
    1215             : 
    1216        3013 : void DocumentFieldsManager::UnlockExpFields()
    1217             : {
    1218             :     assert(mnLockExpField != 0);
    1219        3013 :     if( mnLockExpField )
    1220        3013 :         --mnLockExpField;
    1221        3013 : }
    1222             : 
    1223        7515 : bool DocumentFieldsManager::IsExpFieldsLocked() const
    1224             : {
    1225        7515 :     return 0 != mnLockExpField;
    1226             : }
    1227             : 
    1228       31013 : SwDocUpdateField& DocumentFieldsManager::GetUpdateFields() const
    1229             : {
    1230       31013 :     return *mpUpdateFields;
    1231             : }
    1232             : 
    1233       13354 : bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLong nLen )
    1234             : {
    1235             :     // See if the supplied nodes actually contain fields.
    1236             :     // If they don't, the flag doesn't need to be changed.
    1237       13354 :     bool bFieldsFnd = false;
    1238       13354 :     if( b && pChk && !GetUpdateFields().IsFieldsDirty() && !m_rDoc.IsInDtor()
    1239             :         // ?? what's up with Undo, this is also wanted there!
    1240             :         /*&& &pChk->GetNodes() == &GetNodes()*/ )
    1241             :     {
    1242        9137 :         b = false;
    1243        9137 :         if( !nLen )
    1244           0 :             ++nLen;
    1245        9137 :         sal_uLong nStt = pChk->GetIndex();
    1246        9137 :         const SwNodes& rNds = pChk->GetNodes();
    1247       27244 :         while( nLen-- )
    1248             :         {
    1249        9146 :             const SwTextNode* pTNd = rNds[ nStt++ ]->GetTextNode();
    1250        9146 :             if( pTNd )
    1251             :             {
    1252        9145 :                 if( pTNd->GetAttrOutlineLevel() != 0 )
    1253             :                     // update chapter fields
    1254           0 :                     b = true;
    1255        9145 :                 else if( pTNd->GetpSwpHints() && pTNd->GetSwpHints().Count() )
    1256             :                 {
    1257         661 :                     const size_t nEnd = pTNd->GetSwpHints().Count();
    1258        1467 :                     for( size_t n = 0 ; n < nEnd; ++n )
    1259             :                     {
    1260         982 :                         const SwTextAttr* pAttr = pTNd->GetSwpHints()[ n ];
    1261         982 :                         if ( pAttr->Which() == RES_TXTATR_FIELD )
    1262             :                         {
    1263         176 :                             b = true;
    1264         176 :                             break;
    1265             :                         }
    1266             :                     }
    1267             :                 }
    1268             : 
    1269        9145 :                 if( b )
    1270         176 :                     break;
    1271             :             }
    1272             :         }
    1273        9137 :         bFieldsFnd = b;
    1274             :     }
    1275       13354 :     GetUpdateFields().SetFieldsDirty( b );
    1276       13354 :     return bFieldsFnd;
    1277             : }
    1278             : 
    1279          58 : void DocumentFieldsManager::SetFixFields( bool bOnlyTimeDate, const DateTime* pNewDateTime )
    1280             : {
    1281          58 :     bool bIsModified = m_rDoc.getIDocumentState().IsModified();
    1282             : 
    1283             :     sal_Int32 nDate;
    1284             :     sal_Int64 nTime;
    1285          58 :     if( pNewDateTime )
    1286             :     {
    1287           0 :         nDate = pNewDateTime->GetDate();
    1288           0 :         nTime = pNewDateTime->GetTime();
    1289             :     }
    1290             :     else
    1291             :     {
    1292          58 :         nDate = Date( Date::SYSTEM ).GetDate();
    1293          58 :         nTime = tools::Time( tools::Time::SYSTEM ).GetTime();
    1294             :     }
    1295             : 
    1296             :     sal_uInt16 aTypes[5] = {
    1297             :         /*0*/   RES_DOCINFOFLD,
    1298             :         /*1*/   RES_AUTHORFLD,
    1299             :         /*2*/   RES_EXTUSERFLD,
    1300             :         /*3*/   RES_FILENAMEFLD,
    1301          58 :         /*4*/   RES_DATETIMEFLD };  // MUST be at the end!
    1302             : 
    1303          58 :     sal_uInt16 nStt = bOnlyTimeDate ? 4 : 0;
    1304             : 
    1305         348 :     for( ; nStt < 5; ++nStt )
    1306             :     {
    1307         290 :         SwFieldType* pFieldType = GetSysFieldType( aTypes[ nStt ] );
    1308         290 :         SwIterator<SwFormatField,SwFieldType> aIter( *pFieldType );
    1309         294 :         for( SwFormatField* pFormatField = aIter.First(); pFormatField; pFormatField = aIter.Next() )
    1310             :         {
    1311           4 :             if( pFormatField && pFormatField->GetTextField() )
    1312             :             {
    1313           4 :                 bool bChgd = false;
    1314           4 :                 switch( aTypes[ nStt ] )
    1315             :                 {
    1316             :                 case RES_DOCINFOFLD:
    1317           0 :                     if( static_cast<SwDocInfoField*>(pFormatField->GetField())->IsFixed() )
    1318             :                     {
    1319           0 :                         bChgd = true;
    1320           0 :                         SwDocInfoField* pDocInfField = static_cast<SwDocInfoField*>(pFormatField->GetField());
    1321             :                         pDocInfField->SetExpansion( static_cast<SwDocInfoFieldType*>(
    1322           0 :                                     pDocInfField->GetTyp())->Expand(
    1323           0 :                                         pDocInfField->GetSubType(),
    1324             :                                         pDocInfField->GetFormat(),
    1325           0 :                                         pDocInfField->GetLanguage(),
    1326           0 :                                         pDocInfField->GetName() ) );
    1327             :                     }
    1328           0 :                     break;
    1329             : 
    1330             :                 case RES_AUTHORFLD:
    1331           0 :                     if( static_cast<SwAuthorField*>(pFormatField->GetField())->IsFixed() )
    1332             :                     {
    1333           0 :                         bChgd = true;
    1334           0 :                         SwAuthorField* pAuthorField = static_cast<SwAuthorField*>(pFormatField->GetField());
    1335           0 :                         pAuthorField->SetExpansion( SwAuthorFieldType::Expand( pAuthorField->GetFormat() ) );
    1336             :                     }
    1337           0 :                     break;
    1338             : 
    1339             :                 case RES_EXTUSERFLD:
    1340           0 :                     if( static_cast<SwExtUserField*>(pFormatField->GetField())->IsFixed() )
    1341             :                     {
    1342           0 :                         bChgd = true;
    1343           0 :                         SwExtUserField* pExtUserField = static_cast<SwExtUserField*>(pFormatField->GetField());
    1344             :                         pExtUserField->SetExpansion( SwExtUserFieldType::Expand(
    1345           0 :                                             pExtUserField->GetSubType(),
    1346           0 :                                             pExtUserField->GetFormat()));
    1347             :                     }
    1348           0 :                     break;
    1349             : 
    1350             :                 case RES_DATETIMEFLD:
    1351           4 :                     if( static_cast<SwDateTimeField*>(pFormatField->GetField())->IsFixed() )
    1352             :                     {
    1353           0 :                         bChgd = true;
    1354           0 :                         static_cast<SwDateTimeField*>(pFormatField->GetField())->SetDateTime(
    1355           0 :                                                     DateTime(Date(nDate), tools::Time(nTime)) );
    1356             :                     }
    1357           4 :                     break;
    1358             : 
    1359             :                 case RES_FILENAMEFLD:
    1360           0 :                     if( static_cast<SwFileNameField*>(pFormatField->GetField())->IsFixed() )
    1361             :                     {
    1362           0 :                         bChgd = true;
    1363             :                         SwFileNameField* pFileNameField =
    1364           0 :                             static_cast<SwFileNameField*>(pFormatField->GetField());
    1365             :                         pFileNameField->SetExpansion( static_cast<SwFileNameFieldType*>(
    1366           0 :                                     pFileNameField->GetTyp())->Expand(
    1367           0 :                                             pFileNameField->GetFormat() ) );
    1368             :                     }
    1369           0 :                     break;
    1370             :                 }
    1371             : 
    1372             :                 // Trigger formatting
    1373           4 :                 if( bChgd )
    1374           0 :                     pFormatField->ModifyNotification( 0, 0 );
    1375             :             }
    1376             :         }
    1377         290 :     }
    1378             : 
    1379          58 :     if( !bIsModified )
    1380          37 :         m_rDoc.getIDocumentState().ResetModified();
    1381          58 : }
    1382             : 
    1383           0 : void DocumentFieldsManager::FieldsToCalc( SwCalc& rCalc, const _SetGetExpField& rToThisField )
    1384             : {
    1385             :     // create the sorted list of all SetFields
    1386           0 :     mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
    1387           0 :     mbNewFieldLst = false;
    1388             : 
    1389             : #if !HAVE_FEATURE_DBCONNECTIVITY
    1390             :     SwDBManager* pMgr = NULL;
    1391             : #else
    1392           0 :     SwDBManager* pMgr = m_rDoc.GetDBManager();
    1393           0 :     pMgr->CloseAll(false);
    1394             : #endif
    1395             : 
    1396           0 :     if( !mpUpdateFields->GetSortLst()->empty() )
    1397             :     {
    1398             :         _SetGetExpFields::const_iterator const itLast =
    1399           0 :             mpUpdateFields->GetSortLst()->upper_bound(
    1400           0 :                 const_cast<_SetGetExpField*>(&rToThisField));
    1401           0 :         for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != itLast; ++it )
    1402           0 :             lcl_CalcField( m_rDoc, rCalc, **it, pMgr );
    1403             :     }
    1404             : #if HAVE_FEATURE_DBCONNECTIVITY
    1405           0 :     pMgr->CloseAll(false);
    1406             : #endif
    1407           0 : }
    1408             : 
    1409           1 : void DocumentFieldsManager::FieldsToCalc( SwCalc& rCalc, sal_uLong nLastNd, sal_uInt16 nLastCnt )
    1410             : {
    1411             :     // create the sorted list of all SetFields
    1412           1 :     mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_CALC );
    1413           1 :     mbNewFieldLst = false;
    1414             : 
    1415             : #if !HAVE_FEATURE_DBCONNECTIVITY
    1416             :     SwDBManager* pMgr = NULL;
    1417             : #else
    1418           1 :     SwDBManager* pMgr = m_rDoc.GetDBManager();
    1419           1 :     pMgr->CloseAll(false);
    1420             : #endif
    1421             : 
    1422           6 :     for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin();
    1423           8 :         it != mpUpdateFields->GetSortLst()->end() &&
    1424           1 :         ( (*it)->GetNode() < nLastNd ||
    1425           0 :           ( (*it)->GetNode() == nLastNd && (*it)->GetContent() <= nLastCnt )
    1426             :         );
    1427             :         ++it )
    1428             :     {
    1429           1 :         lcl_CalcField( m_rDoc, rCalc, **it, pMgr );
    1430             :     }
    1431             : 
    1432             : #if HAVE_FEATURE_DBCONNECTIVITY
    1433           1 :     pMgr->CloseAll(false);
    1434             : #endif
    1435           1 : }
    1436             : 
    1437           0 : void DocumentFieldsManager::FieldsToExpand( SwHash**& ppHashTable, sal_uInt16& rTableSize,
    1438             :                             const _SetGetExpField& rToThisField )
    1439             : {
    1440             :     // create the sorted list of all SetFields
    1441           0 :     mpUpdateFields->MakeFieldList( m_rDoc, mbNewFieldLst, GETFLD_EXPAND );
    1442           0 :     mbNewFieldLst = false;
    1443             : 
    1444             :     // Hash table for all string replacements is filled on-the-fly.
    1445             :     // Try to fabricate an uneven number.
    1446           0 :     rTableSize = (( mpUpdateFields->GetSortLst()->size() / 7 ) + 1 ) * 7;
    1447           0 :     ppHashTable = new SwHash*[ rTableSize ];
    1448           0 :     memset( ppHashTable, 0, sizeof( _HashStr* ) * rTableSize );
    1449             : 
    1450             :     _SetGetExpFields::const_iterator const itLast =
    1451           0 :         mpUpdateFields->GetSortLst()->upper_bound(
    1452           0 :             const_cast<_SetGetExpField*>(&rToThisField));
    1453             : 
    1454           0 :     for( _SetGetExpFields::const_iterator it = mpUpdateFields->GetSortLst()->begin(); it != itLast; ++it )
    1455             :     {
    1456           0 :         const SwTextField* pTextField = (*it)->GetTextField();
    1457           0 :         if( !pTextField )
    1458           0 :             continue;
    1459             : 
    1460           0 :         const SwField* pField = pTextField->GetFormatField().GetField();
    1461           0 :         switch( pField->GetTyp()->Which() )
    1462             :         {
    1463             :         case RES_SETEXPFLD:
    1464           0 :             if( nsSwGetSetExpType::GSE_STRING & pField->GetSubType() )
    1465             :             {
    1466             :                 // set the new value in the hash table
    1467             :                 // is the formula a field?
    1468           0 :                 SwSetExpField* pSField = const_cast<SwSetExpField*>(static_cast<const SwSetExpField*>(pField));
    1469           0 :                 OUString aNew = LookString( ppHashTable, rTableSize, pSField->GetFormula() );
    1470             : 
    1471           0 :                 if( aNew.isEmpty() )               // nothing found, then the formula is
    1472           0 :                     aNew = pSField->GetFormula(); // the new value
    1473             : 
    1474             :                 // #i3141# - update expression of field as in method
    1475             :                 // <SwDoc::UpdateExpFields(..)> for string/text fields
    1476           0 :                 pSField->ChgExpStr( aNew );
    1477             : 
    1478             :                 // look up the field's name
    1479           0 :                 aNew = static_cast<SwSetExpFieldType*>(pSField->GetTyp())->GetSetRefName();
    1480             :                 // Entry present?
    1481             :                 sal_uInt16 nPos;
    1482           0 :                 SwHash* pFnd = Find( aNew, ppHashTable, rTableSize, &nPos );
    1483           0 :                 if( pFnd )
    1484             :                     // modify entry in the hash table
    1485           0 :                     static_cast<_HashStr*>(pFnd)->aSetStr = pSField->GetExpStr();
    1486             :                 else
    1487             :                     // insert the new entry
    1488           0 :                     *(ppHashTable + nPos ) = new _HashStr( aNew,
    1489           0 :                             pSField->GetExpStr(), static_cast<_HashStr*>(*(ppHashTable + nPos)) );
    1490             :             }
    1491           0 :             break;
    1492             :         case RES_DBFLD:
    1493             :             {
    1494           0 :                 const OUString& rName = pField->GetTyp()->GetName();
    1495             : 
    1496             :                 // Insert entry in the hash table
    1497             :                 // Entry present?
    1498             :                 sal_uInt16 nPos;
    1499           0 :                 SwHash* pFnd = Find( rName, ppHashTable, rTableSize, &nPos );
    1500           0 :                 OUString const value(pField->ExpandField(m_rDoc.IsClipBoard()));
    1501           0 :                 if( pFnd )
    1502             :                 {
    1503             :                     // modify entry in the hash table
    1504           0 :                     static_cast<_HashStr*>(pFnd)->aSetStr = value;
    1505             :                 }
    1506             :                 else
    1507             :                 {
    1508             :                     // insert the new entry
    1509           0 :                     *(ppHashTable + nPos ) = new _HashStr( rName,
    1510           0 :                         value, static_cast<_HashStr *>(*(ppHashTable + nPos)));
    1511           0 :                 }
    1512             :             }
    1513           0 :             break;
    1514             :         }
    1515             :     }
    1516           0 : }
    1517             : 
    1518             : 
    1519        2073 : bool DocumentFieldsManager::IsNewFieldLst() const
    1520             : {
    1521        2073 :     return mbNewFieldLst;
    1522             : }
    1523             : 
    1524        5704 : void DocumentFieldsManager::SetNewFieldLst(bool bFlag)
    1525             : {
    1526        5704 :     mbNewFieldLst = bFlag;
    1527        5704 : }
    1528             : 
    1529          30 : void DocumentFieldsManager::InsDelFieldInFieldLst( bool bIns, const SwTextField& rField )
    1530             : {
    1531          30 :     if( !mbNewFieldLst || !m_rDoc.IsInDtor() )
    1532          30 :         mpUpdateFields->InsDelFieldInFieldLst( bIns, rField );
    1533          30 : }
    1534             : 
    1535         246 : SwField * DocumentFieldsManager::GetFieldAtPos(const SwPosition & rPos)
    1536             : {
    1537         246 :     SwTextField * const pAttr = GetTextFieldAtPos(rPos);
    1538             : 
    1539         246 :     return (pAttr) ? const_cast<SwField *>( pAttr->GetFormatField().GetField() ) : 0;
    1540             : }
    1541             : 
    1542         276 : SwTextField * DocumentFieldsManager::GetTextFieldAtPos(const SwPosition & rPos)
    1543             : {
    1544         276 :     SwTextNode * const pNode = rPos.nNode.GetNode().GetTextNode();
    1545             : 
    1546             :     return (pNode != NULL)
    1547         276 :         ? pNode->GetFieldTextAttrAt( rPos.nContent.GetIndex(), true )
    1548         552 :         : 0;
    1549             : }
    1550             : 
    1551             : /// @note For simplicity assume that all field types have updatable contents so
    1552             : ///       optimization currently only available when no fields exist.
    1553          98 : bool DocumentFieldsManager::containsUpdatableFields()
    1554             : {
    1555        2903 :     for (auto pFieldType : *mpFieldTypes)
    1556             :     {
    1557        2819 :         SwIterator<SwFormatField,SwFieldType> aIter(*pFieldType);
    1558        2819 :         if (aIter.First())
    1559          14 :             return true;
    1560        2805 :     }
    1561          84 :     return false;
    1562             : }
    1563             : 
    1564             : /// Remove all unreferenced field types of a document
    1565           3 : void DocumentFieldsManager::GCFieldTypes()
    1566             : {
    1567           6 :     for( auto n = mpFieldTypes->size(); n > INIT_FLDTYPES; )
    1568           0 :         if( !(*mpFieldTypes)[ --n ]->HasWriterListeners() )
    1569           0 :             RemoveFieldType( n );
    1570           3 : }
    1571             : 
    1572        2958 : void DocumentFieldsManager::_InitFieldTypes()       // is being called by the CTOR
    1573             : {
    1574             :     // Field types
    1575        2958 :     mpFieldTypes->push_back( new SwDateTimeFieldType(&m_rDoc) );
    1576        2958 :     mpFieldTypes->push_back( new SwChapterFieldType );
    1577        2958 :     mpFieldTypes->push_back( new SwPageNumberFieldType );
    1578        2958 :     mpFieldTypes->push_back( new SwAuthorFieldType );
    1579        2958 :     mpFieldTypes->push_back( new SwFileNameFieldType(&m_rDoc) );
    1580        2958 :     mpFieldTypes->push_back( new SwDBNameFieldType(&m_rDoc) );
    1581        2958 :     mpFieldTypes->push_back( new SwGetExpFieldType(&m_rDoc) );
    1582        2958 :     mpFieldTypes->push_back( new SwGetRefFieldType( &m_rDoc ) );
    1583        2958 :     mpFieldTypes->push_back( new SwHiddenTextFieldType );
    1584        2958 :     mpFieldTypes->push_back( new SwPostItFieldType(&m_rDoc) );
    1585        2958 :     mpFieldTypes->push_back( new SwDocStatFieldType(&m_rDoc) );
    1586        2958 :     mpFieldTypes->push_back( new SwDocInfoFieldType(&m_rDoc) );
    1587        2958 :     mpFieldTypes->push_back( new SwInputFieldType( &m_rDoc ) );
    1588        2958 :     mpFieldTypes->push_back( new SwTableFieldType( &m_rDoc ) );
    1589        2958 :     mpFieldTypes->push_back( new SwMacroFieldType(&m_rDoc) );
    1590        2958 :     mpFieldTypes->push_back( new SwHiddenParaFieldType );
    1591        2958 :     mpFieldTypes->push_back( new SwDBNextSetFieldType );
    1592        2958 :     mpFieldTypes->push_back( new SwDBNumSetFieldType );
    1593        2958 :     mpFieldTypes->push_back( new SwDBSetNumberFieldType );
    1594        2958 :     mpFieldTypes->push_back( new SwTemplNameFieldType(&m_rDoc) );
    1595        2958 :     mpFieldTypes->push_back( new SwTemplNameFieldType(&m_rDoc) );
    1596        2958 :     mpFieldTypes->push_back( new SwExtUserFieldType );
    1597        2958 :     mpFieldTypes->push_back( new SwRefPageSetFieldType );
    1598        2958 :     mpFieldTypes->push_back( new SwRefPageGetFieldType( &m_rDoc ) );
    1599        2958 :     mpFieldTypes->push_back( new SwJumpEditFieldType( &m_rDoc ) );
    1600        2958 :     mpFieldTypes->push_back( new SwScriptFieldType( &m_rDoc ) );
    1601        2958 :     mpFieldTypes->push_back( new SwCombinedCharFieldType );
    1602        2958 :     mpFieldTypes->push_back( new SwDropDownFieldType );
    1603             : 
    1604             :     // Types have to be at the end!
    1605             :     // We expect &m_rDoc in the InsertFieldType!
    1606             :     // MIB 14.04.95: In Sw3StringPool::Setup (sw3imp.cxx) and
    1607             :     //               lcl_sw3io_InSetExpField (sw3field.cxx) now also
    1608             :     mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
    1609        2958 :                 SW_RESSTR(STR_POOLCOLL_LABEL_ABB), nsSwGetSetExpType::GSE_SEQ) );
    1610             :     mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
    1611        2958 :                 SW_RESSTR(STR_POOLCOLL_LABEL_TABLE), nsSwGetSetExpType::GSE_SEQ) );
    1612             :     mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
    1613        2958 :                 SW_RESSTR(STR_POOLCOLL_LABEL_FRAME), nsSwGetSetExpType::GSE_SEQ) );
    1614             :     mpFieldTypes->push_back( new SwSetExpFieldType(&m_rDoc,
    1615        2958 :                 SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING), nsSwGetSetExpType::GSE_SEQ) );
    1616             : 
    1617             :     assert( mpFieldTypes->size() == INIT_FLDTYPES );
    1618        2958 : }
    1619             : 
    1620          21 : void DocumentFieldsManager::ClearFieldTypes()
    1621             : {
    1622          63 :     for(SwFieldTypes::const_iterator it = mpFieldTypes->begin() + INIT_FLDTYPES;
    1623          42 :         it != mpFieldTypes->end(); ++it)
    1624           0 :         delete *it;
    1625          21 :     mpFieldTypes->erase( mpFieldTypes->begin() + INIT_FLDTYPES, mpFieldTypes->end() );
    1626          21 : }
    1627             : 
    1628           0 : void DocumentFieldsManager::UpdateDBNumFields( SwDBNameInfField& rDBField, SwCalc& rCalc )
    1629             : {
    1630             : #if !HAVE_FEATURE_DBCONNECTIVITY
    1631             :     (void) rDBField;
    1632             :     (void) rCalc;
    1633             : #else
    1634           0 :     SwDBManager* pMgr = m_rDoc.GetDBManager();
    1635             : 
    1636           0 :     sal_uInt16 nFieldType = rDBField.Which();
    1637             : 
    1638           0 :     bool bPar1 = rCalc.Calculate( rDBField.GetPar1() ).GetBool();
    1639             : 
    1640           0 :     if( RES_DBNEXTSETFLD == nFieldType )
    1641           0 :         static_cast<SwDBNextSetField&>(rDBField).SetCondValid( bPar1 );
    1642             :     else
    1643           0 :         static_cast<SwDBNumSetField&>(rDBField).SetCondValid( bPar1 );
    1644             : 
    1645           0 :     if( !rDBField.GetRealDBData().sDataSource.isEmpty() )
    1646             :     {
    1647             :         // Edit a certain database
    1648           0 :         if( RES_DBNEXTSETFLD == nFieldType )
    1649           0 :             static_cast<SwDBNextSetField&>(rDBField).Evaluate(&m_rDoc);
    1650             :         else
    1651           0 :             static_cast<SwDBNumSetField&>(rDBField).Evaluate(&m_rDoc);
    1652             : 
    1653           0 :         SwDBData aTmpDBData( rDBField.GetDBData(&m_rDoc) );
    1654             : 
    1655           0 :         if( pMgr->OpenDataSource( aTmpDBData.sDataSource, aTmpDBData.sCommand, -1, false ))
    1656             :             rCalc.VarChange( lcl_GetDBVarName( m_rDoc, rDBField),
    1657           0 :                         pMgr->GetSelectedRecordId(aTmpDBData.sDataSource, aTmpDBData.sCommand, aTmpDBData.nCommandType) );
    1658             :     }
    1659             :     else
    1660             :     {
    1661             :         OSL_FAIL("TODO: what should happen with unnamed DBFields?");
    1662             :     }
    1663             : #endif
    1664           0 : }
    1665             : 
    1666        8847 : DocumentFieldsManager::~DocumentFieldsManager()
    1667             : {
    1668        2949 :     delete mpUpdateFields;
    1669        2949 :     delete mpFieldTypes;
    1670        5898 : }
    1671             : 
    1672         177 : }
    1673             : 
    1674             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11