1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docfld.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
39 #include <tools/datetime.hxx>
41 #define _SVSTDARR_ULONGS
42 #include <svtools/svarray.hxx>
44 #ifndef _APP_HXX //autogen
45 #include <vcl/svapp.hxx>
47 #ifndef _APP_HXX //autogen
48 #include <vcl/svapp.hxx>
50 #include <unotools/charclass.hxx>
51 #include <unotools/transliterationwrapper.hxx>
56 #include <swtable.hxx>
61 #include <txttxmrk.hxx>
62 #include <docfld.hxx> // fuer Expression-Felder
63 #include <docufld.hxx>
71 #include <flddropdown.hxx>
75 #include <section.hxx>
76 #include <cellatr.hxx>
78 #include <authfld.hxx>
79 #include <txtinet.hxx>
81 #include <poolfmt.hrc> // fuer InitFldTypes
84 #include <SwUndoField.hxx>
86 using namespace ::com::sun::star::uno
;
88 extern BOOL
IsFrameBehind( const SwTxtNode
& rMyNd
, USHORT nMySttPos
,
89 const SwTxtNode
& rBehindNd
, USHORT nSttPos
);
91 SV_IMPL_OP_PTRARR_SORT( _SetGetExpFlds
, _SetGetExpFldPtr
)
94 /*--------------------------------------------------------------------
95 Beschreibung: Feldtypen einfuegen
96 --------------------------------------------------------------------*/
98 * Implementierung der Feldfunktionen am Doc
99 * Return immer einen gueltigen Pointer auf den Typ. Wenn er also neu
100 * zugefuegt oder schon vorhanden ist.
103 SwFieldType
* SwDoc::InsertFldType(const SwFieldType
&rFldTyp
)
105 USHORT nSize
= pFldTypes
->Count(),
106 nFldWhich
= rFldTyp
.Which();
108 USHORT i
= INIT_FLDTYPES
;
113 //JP 29.01.96: SequenceFelder beginnen aber bei INIT_FLDTYPES - 3!!
114 // Sonst gibt es doppelte Nummernkreise!!
115 //MIB 14.03.95: Ab sofort verlaesst sich auch der SW3-Reader
116 //beim Aufbau der String-Pools und beim Einlesen von SetExp-Feldern
118 if( nsSwGetSetExpType::GSE_SEQ
& ((SwSetExpFieldType
&)rFldTyp
).GetType() )
119 i
-= INIT_SEQ_FLDTYPES
;
125 const ::utl::TransliterationWrapper
& rSCmp
= GetAppCmpStrIgnore();
126 String
sFldNm( rFldTyp
.GetName() );
127 for( ; i
< nSize
; ++i
)
128 if( nFldWhich
== (*pFldTypes
)[i
]->Which() &&
129 rSCmp
.isEqual( sFldNm
, (*pFldTypes
)[i
]->GetName() ))
130 return (*pFldTypes
)[i
];
135 for( ; i
< nSize
; ++i
)
136 if( nFldWhich
== (*pFldTypes
)[i
]->Which() )
137 return (*pFldTypes
)[i
];
141 for( i
= 0; i
< nSize
; ++i
)
142 if( nFldWhich
== (*pFldTypes
)[i
]->Which() )
143 return (*pFldTypes
)[i
];
146 SwFieldType
* pNew
= rFldTyp
.Copy();
150 ((SwDDEFieldType
*)pNew
)->SetDoc( this );
155 case RES_DATETIMEFLD
:
157 ((SwValueFieldType
*)pNew
)->SetDoc( this );
162 ((SwValueFieldType
*)pNew
)->SetDoc( this );
163 // JP 29.07.96: opt. FeldListe fuer den Calculator vorbereiten:
164 pUpdtFlds
->InsertFldType( *pNew
);
167 ((SwAuthorityFieldType
*)pNew
)->SetDoc( this );
171 pFldTypes
->Insert( pNew
, nSize
);
174 return (*pFldTypes
)[ nSize
];
177 void SwDoc::InsDeletedFldType( SwFieldType
& rFldTyp
)
179 // der FeldTyp wurde als geloescht gekennzeichnet und aus dem
180 // Array entfernt. Nun muss man nach diesem wieder suchen.
181 // - Ist der nicht vorhanden, dann kann er eingefuegt werden.
182 // - Wird genau der gleiche Typ gefunden, dann muss der geloeschte
183 // einen anderen Namen erhalten.
185 USHORT nSize
= pFldTypes
->Count(), nFldWhich
= rFldTyp
.Which();
186 USHORT i
= INIT_FLDTYPES
;
188 ASSERT( RES_SETEXPFLD
== nFldWhich
||
189 RES_USERFLD
== nFldWhich
||
190 RES_DDEFLD
== nFldWhich
, "Falscher FeldTyp" );
192 const ::utl::TransliterationWrapper
& rSCmp
= GetAppCmpStrIgnore();
193 const String
& rFldNm
= rFldTyp
.GetName();
196 for( ; i
< nSize
; ++i
)
197 if( nFldWhich
== (pFnd
= (*pFldTypes
)[i
])->Which() &&
198 rSCmp
.isEqual( rFldNm
, pFnd
->GetName() ) )
200 // neuen Namen suchen
203 String
sSrch( rFldNm
);
204 sSrch
.Append( String::CreateFromInt32( nNum
));
205 for( i
= INIT_FLDTYPES
; i
< nSize
; ++i
)
206 if( nFldWhich
== (pFnd
= (*pFldTypes
)[i
])->Which() &&
207 rSCmp
.isEqual( sSrch
, pFnd
->GetName() ) )
210 if( i
>= nSize
) // nicht gefunden
212 ((String
&)rFldNm
) = sSrch
;
213 break; // raus aus der While-Schleife
220 // nicht gefunden, also eintragen und Flag loeschen
221 pFldTypes
->Insert( &rFldTyp
, nSize
);
225 ((SwSetExpFieldType
&)rFldTyp
).SetDeleted( FALSE
);
228 ((SwUserFieldType
&)rFldTyp
).SetDeleted( FALSE
);
231 ((SwDDEFieldType
&)rFldTyp
).SetDeleted( FALSE
);
236 /*--------------------------------------------------------------------
237 Beschreibung: Feldtypen loeschen
238 --------------------------------------------------------------------*/
240 void SwDoc::RemoveFldType(USHORT nFld
)
242 ASSERT( INIT_FLDTYPES
<= nFld
, "keine InitFields loeschen" );
244 * Abheangige Felder vorhanden -> ErrRaise
246 USHORT nSize
= pFldTypes
->Count();
249 SwFieldType
* pTmp
= (*pFldTypes
)[nFld
];
251 // JP 29.07.96: opt. FeldListe fuer den Calculator vorbereiten:
252 USHORT nWhich
= pTmp
->Which();
257 pUpdtFlds
->RemoveFldType( *pTmp
);
260 if( pTmp
->GetDepends() && !IsUsed( *pTmp
) )
262 if( RES_SETEXPFLD
== nWhich
)
263 ((SwSetExpFieldType
*)pTmp
)->SetDeleted( TRUE
);
264 else if( RES_USERFLD
== nWhich
)
265 ((SwUserFieldType
*)pTmp
)->SetDeleted( TRUE
);
267 ((SwDDEFieldType
*)pTmp
)->SetDeleted( TRUE
);
275 ASSERT( !pTmp
->GetDepends(), "Abhaengige vorh.!" );
279 pFldTypes
->Remove( nFld
);
284 const SwFldTypes
* SwDoc::GetFldTypes() const
289 /*--------------------------------------------------------------------
290 Beschreibung: Den ersten Typen mit ResId und Namen finden
291 --------------------------------------------------------------------*/
293 SwFieldType
* SwDoc::GetFldType( USHORT nResId
, const String
& rName
,
294 bool bDbFieldMatching
// used in some UNO calls for RES_DBFLD
295 // to use different string matching code
299 USHORT nSize
= pFldTypes
->Count(), i
= 0;
300 const ::utl::TransliterationWrapper
& rSCmp
= GetAppCmpStrIgnore();
305 //JP 29.01.96: SequenceFelder beginnen aber bei INIT_FLDTYPES - 3!!
306 // Sonst gibt es doppelte Nummernkreise!!
307 //MIB 14.03.95: Ab sofort verlaesst sich auch der SW3-Reader
308 //beim Aufbau der String-Pools und beim Einlesen von SetExp-Feldern
310 i
= INIT_FLDTYPES
- INIT_SEQ_FLDTYPES
;
321 SwFieldType
* pRet
= 0;
322 for( ; i
< nSize
; ++i
)
324 SwFieldType
* pFldType
= (*pFldTypes
)[i
];
326 String
aFldName( pFldType
->GetName() );
327 if (bDbFieldMatching
&& nResId
== RES_DBFLD
) // #i51815#
328 aFldName
.SearchAndReplaceAll(DB_DELIM
, '.');
330 if( nResId
== pFldType
->Which() &&
331 rSCmp
.isEqual( rName
, aFldName
))
341 /*************************************************************************
342 |* SwDoc::UpdateFlds()
343 |* Beschreibung Felder updaten
344 *************************************************************************/
346 * Alle sollen neu evaluiert werden.
349 void SwDoc::UpdateFlds( SfxPoolItem
*pNewHt
, bool bCloseDB
)
351 // Modify() fuer jeden Feldtypen rufen,
352 // abhaengige SwTxtFld werden benachrichtigt ...
354 for( USHORT i
=0; i
< pFldTypes
->Count(); ++i
)
356 switch( (*pFldTypes
)[i
]->Which() )
358 // Tabellen-Felder als vorletztes Updaten
359 // Referenzen als letztes Updaten
363 case RES_JUMPEDITFLD
:
364 case RES_REFPAGESETFLD
: // werden nie expandiert!
371 SwMsgPoolItem
aUpdateDDE( RES_UPDATEDDETBL
);
372 (*pFldTypes
)[i
]->Modify( 0, &aUpdateDDE
);
375 (*pFldTypes
)[i
]->Modify( 0, pNewHt
);
380 case RES_HIDDENTXTFLD
:
381 case RES_HIDDENPARAFLD
:
382 // Expression-Felder werden gesondert behandelt
386 (*pFldTypes
)[i
]->Modify( 0, pNewHt
);
390 if( !IsExpFldsLocked() )
391 UpdateExpFlds( 0, FALSE
); // Expression-Felder Updaten
394 UpdateTblFlds(pNewHt
);
397 UpdateRefFlds(pNewHt
);
400 GetNewDBMgr()->CloseAll();
402 // Nur bei KomplettUpdate evaluieren
406 /******************************************************************************
407 * void SwDoc::UpdateUsrFlds()
408 ******************************************************************************/
410 void SwDoc::UpdateUsrFlds()
413 const SwFieldType
* pFldType
;
414 for( USHORT i
= INIT_FLDTYPES
; i
< pFldTypes
->Count(); ++i
)
415 if( RES_USERFLD
== ( pFldType
= (*pFldTypes
)[i
] )->Which() )
418 pCalc
= new SwCalc( *this );
419 ((SwUserFieldType
*)pFldType
)->GetValue( *pCalc
);
429 /*--------------------------------------------------------------------
430 Beschreibung: Referenzfelder und TableFelder erneuern
431 --------------------------------------------------------------------*/
433 void SwDoc::UpdateRefFlds( SfxPoolItem
* pHt
)
435 SwFieldType
* pFldType
;
436 for( USHORT i
= 0; i
< pFldTypes
->Count(); ++i
)
437 if( RES_GETREFFLD
== ( pFldType
= (*pFldTypes
)[i
] )->Which() )
438 pFldType
->Modify( 0, pHt
);
441 void SwDoc::UpdateTblFlds( SfxPoolItem
* pHt
)
443 ASSERT( !pHt
|| RES_TABLEFML_UPDATE
== pHt
->Which(),
444 "Was ist das fuer ein MessageItem?" );
446 SwFieldType
* pFldType(0);
449 for( i
= 0; i
< pFldTypes
->Count(); ++i
)
451 if( RES_TABLEFLD
== ( pFldType
= (*pFldTypes
)[i
] )->Which() )
453 SwTableFmlUpdate
* pUpdtFld
= 0;
454 if( pHt
&& RES_TABLEFML_UPDATE
== pHt
->Which() )
455 pUpdtFld
= (SwTableFmlUpdate
*)pHt
;
457 SwClientIter
aIter( *pFldType
);
458 for( SwFmtFld
* pFmtFld
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
));
459 pFmtFld
; pFmtFld
= (SwFmtFld
*)aIter
.Next() )
460 if( pFmtFld
->GetTxtFld() )
462 SwTblField
* pFld
= (SwTblField
*)pFmtFld
->GetFld();
466 // bestimme Tabelle, in der das Feld steht
467 const SwTableNode
* pTblNd
;
468 const SwTxtNode
& rTxtNd
= pFmtFld
->GetTxtFld()->GetTxtNode();
469 if( !rTxtNd
.GetNodes().IsDocNodes() ||
470 0 == ( pTblNd
= rTxtNd
.FindTableNode() ) )
473 switch( pUpdtFld
->eFlags
)
476 // setze das Value-Flag zurueck
477 // JP 17.06.96: interne Darstellung auf alle Formeln
478 // (Referenzen auf andere Tabellen!!!)
479 if( nsSwExtendedSubType::SUB_CMD
& pFld
->GetSubType() )
480 pFld
->PtrToBoxNm( pUpdtFld
->pTbl
);
482 pFld
->ChgValid( FALSE
);
485 // ist es die gesuchte Tabelle ??
486 if( &pTblNd
->GetTable() == pUpdtFld
->pTbl
)
487 // zur externen Darstellung
488 pFld
->PtrToBoxNm( pUpdtFld
->pTbl
);
491 // zur internen Darstellung
492 // JP 17.06.96: interne Darstellung auf alle Formeln
493 // (Referenzen auf andere Tabellen!!!)
494 pFld
->BoxNmToPtr( pUpdtFld
->pTbl
);
497 // ist es die gesuchte Tabelle ??
498 if( &pTblNd
->GetTable() == pUpdtFld
->pTbl
)
499 // zur relativen Darstellung
500 pFld
->ToRelBoxNm( pUpdtFld
->pTbl
);
507 // setze bei allen das Value-Flag zurueck
508 pFld
->ChgValid( FALSE
);
516 // und dann noch alle Tabellen Box Formeln abklappern
517 const SfxPoolItem
* pItem
;
518 USHORT nMaxItems
= GetAttrPool().GetItemCount( RES_BOXATR_FORMULA
);
519 for( i
= 0; i
< nMaxItems
; ++i
)
520 if( 0 != (pItem
= GetAttrPool().GetItem( RES_BOXATR_FORMULA
, i
) ) &&
521 ((SwTblBoxFormula
*)pItem
)->GetDefinedIn() )
523 ((SwTblBoxFormula
*)pItem
)->ChangeState( pHt
);
527 // alle Felder/Boxen sind jetzt invalide, also kann das Rechnen anfangen
528 if( pHt
&& ( RES_TABLEFML_UPDATE
!= pHt
->Which() ||
529 TBL_CALC
!= ((SwTableFmlUpdate
*)pHt
)->eFlags
))
537 SwClientIter
aIter( *pFldType
);
538 // dann rechne mal schoen
539 // JP 27.03.97: Beim Berechnen am Ende anfangen - weil neue
540 // Felder immer am Anfang der Modifykette eingefuegt
541 // werden. Beim Import haben wir damit eine bessere/
542 // schnellere Berechnung bei "Kettenformeln"
543 if( 0 != ( pLast
= aIter
.GoEnd() ))
545 SwFmtFld
* pFmtFld
= (SwFmtFld
*)pLast
;
547 if( !pFmtFld
->GetTxtFld() || (nsSwExtendedSubType::SUB_CMD
&
548 (pFld
= (SwTblField
*)pFmtFld
->GetFld())->GetSubType() ))
551 // muss neu berechnet werden (und ist keine textuelle Anzeige)
552 if( !pFld
->IsValid() )
554 // bestimme Tabelle, in der das Feld steht
555 const SwTxtNode
& rTxtNd
= pFmtFld
->GetTxtFld()->GetTxtNode();
556 if( !rTxtNd
.GetNodes().IsDocNodes() )
558 const SwTableNode
* pTblNd
= rTxtNd
.FindTableNode();
562 // falls dieses Feld nicht in der zu updatenden
563 // Tabelle steht, ueberspringen !!
564 if( pHt
&& &pTblNd
->GetTable() !=
565 ((SwTableFmlUpdate
*)pHt
)->pTbl
)
569 pCalc
= new SwCalc( *this );
571 // bestimme die Werte aller SetExpresion Felder, die
572 // bis zur Tabelle gueltig sind
574 if( pTblNd
->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() )
576 // steht im Sonderbereich, wird teuer !!
577 Point aPt
; // den im Layout 1. Frame returnen - Tab.Kopfzeile !!
578 pFrm
= rTxtNd
.GetFrm( &aPt
);
581 SwPosition
aPos( *pTblNd
);
582 if( GetBodyTxtNode( *this, aPos
, *pFrm
) )
583 FldsToCalc( *pCalc
, _SetGetExpFld(
584 aPos
.nNode
, pFmtFld
->GetTxtFld(),
592 // einen Index fuers bestimmen vom TextNode anlegen
593 SwNodeIndex
aIdx( rTxtNd
);
595 _SetGetExpFld( aIdx
, pFmtFld
->GetTxtFld() ));
598 SwTblCalcPara
aPara( *pCalc
, pTblNd
->GetTable() );
599 pFld
->CalcField( aPara
);
600 if( aPara
.IsStackOverFlow() )
602 if( aPara
.CalcWithStackOverflow() )
603 pFld
->CalcField( aPara
);
608 ASSERT( !this, "die Kettenformel konnte nicht errechnet werden" );
612 pCalc
->SetCalcError( CALC_NOERR
);
614 pFmtFld
->Modify( 0, pHt
);
615 } while( 0 != ( pLast
= aIter
-- ));
618 // dann berechene noch die Formeln an den Boxen
619 for( i
= 0; i
< nMaxItems
; ++i
)
620 if( 0 != (pItem
= GetAttrPool().GetItem( RES_BOXATR_FORMULA
, i
) ) &&
621 ((SwTblBoxFormula
*)pItem
)->GetDefinedIn() &&
622 !((SwTblBoxFormula
*)pItem
)->IsValid() )
624 SwTblBoxFormula
* pFml
= (SwTblBoxFormula
*)pItem
;
625 SwTableBox
* pBox
= pFml
->GetTableBox();
626 if( pBox
&& pBox
->GetSttNd() &&
627 pBox
->GetSttNd()->GetNodes().IsDocNodes() )
629 const SwTableNode
* pTblNd
= pBox
->GetSttNd()->FindTableNode();
630 if( !pHt
|| &pTblNd
->GetTable() ==
631 ((SwTableFmlUpdate
*)pHt
)->pTbl
)
635 pCalc
= new SwCalc( *this );
637 // bestimme die Werte aller SetExpresion Felder, die
638 // bis zur Tabelle gueltig sind
640 if( pTblNd
->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() )
642 // steht im Sonderbereich, wird teuer !!
643 Point aPt
; // den im Layout 1. Frame returnen - Tab.Kopfzeile !!
644 SwNodeIndex
aCNdIdx( *pTblNd
, +2 );
645 SwCntntNode
* pCNd
= aCNdIdx
.GetNode().GetCntntNode();
647 pCNd
= GetNodes().GoNext( &aCNdIdx
);
649 if( pCNd
&& 0 != (pFrm
= pCNd
->GetFrm( &aPt
)) )
651 SwPosition
aPos( *pCNd
);
652 if( GetBodyTxtNode( *this, aPos
, *pFrm
) )
653 FldsToCalc( *pCalc
, _SetGetExpFld( aPos
.nNode
));
660 // einen Index fuers bestimmen vom TextNode anlegen
661 SwNodeIndex
aIdx( *pTblNd
);
662 FldsToCalc( *pCalc
, _SetGetExpFld( aIdx
));
665 SwTblCalcPara
aPara( *pCalc
, pTblNd
->GetTable() );
666 pFml
->Calc( aPara
, nValue
);
668 if( aPara
.IsStackOverFlow() )
670 if( aPara
.CalcWithStackOverflow() )
671 pFml
->Calc( aPara
, nValue
);
676 ASSERT( !this, "die Kettenformel konnte nicht errechnet werden" );
681 SwFrmFmt
* pFmt
= pBox
->ClaimFrmFmt();
682 SfxItemSet
aTmp( GetAttrPool(),
683 RES_BOXATR_BEGIN
,RES_BOXATR_END
-1 );
685 if( pCalc
->IsCalcError() )
687 aTmp
.Put( SwTblBoxValue( nValue
));
688 if( SFX_ITEM_SET
!= pFmt
->GetItemState( RES_BOXATR_FORMAT
))
689 aTmp
.Put( SwTblBoxNumFormat( 0 ));
690 pFmt
->SetFmtAttr( aTmp
);
692 pCalc
->SetCalcError( CALC_NOERR
);
701 void SwDoc::UpdatePageFlds( SfxPoolItem
* pMsgHnt
)
703 SwFieldType
* pFldType
;
704 for( USHORT i
= 0; i
< INIT_FLDTYPES
; ++i
)
705 switch( ( pFldType
= (*pFldTypes
)[ i
] )->Which() )
707 case RES_PAGENUMBERFLD
:
710 case RES_REFPAGEGETFLD
:
711 pFldType
->Modify( 0, pMsgHnt
);
714 pFldType
->Modify( 0, 0 );
720 /*--------------------------------------------------------------------
722 --------------------------------------------------------------------*/
724 // ---- Loesche alle nicht referenzierten FeldTypen eines Dokumentes --
725 void SwDoc::GCFieldTypes()
727 for( USHORT n
= pFldTypes
->Count(); n
> INIT_FLDTYPES
; )
728 if( !(*pFldTypes
)[ --n
]->GetDepends() )
732 void SwDoc::LockExpFlds()
737 void SwDoc::UnlockExpFlds()
743 bool SwDoc::IsExpFldsLocked() const
745 return 0 != nLockExpFld
;
748 SwDocUpdtFld
& SwDoc::GetUpdtFlds() const
753 bool SwDoc::IsNewFldLst() const
758 void SwDoc::SetNewFldLst(bool bFlag
)
764 //----------------------------------------------------------------------
766 // der StartIndex kann optional mit angegeben werden (z.B. wenn dieser
767 // zuvor schon mal erfragt wurde - ist sonst eine virtuelle Methode !!)
769 _SetGetExpFld::_SetGetExpFld( const SwNodeIndex
& rNdIdx
, const SwTxtFld
* pFld
,
770 const SwIndex
* pIdx
)
772 eSetGetExpFldType
= TEXTFIELD
;
773 CNTNT
.pTxtFld
= pFld
;
774 nNode
= rNdIdx
.GetIndex();
776 nCntnt
= pIdx
->GetIndex();
778 nCntnt
= *pFld
->GetStart();
783 _SetGetExpFld::_SetGetExpFld( const SwNodeIndex
& rNdIdx
,
784 const SwTxtINetFmt
& rINet
, const SwIndex
* pIdx
)
786 eSetGetExpFldType
= TEXTINET
;
787 CNTNT
.pTxtINet
= &rINet
;
788 nNode
= rNdIdx
.GetIndex();
790 nCntnt
= pIdx
->GetIndex();
792 nCntnt
= *rINet
.GetStart();
795 //Erweiterung fuer Sections:
796 // diese haben immer als Content-Position 0xffff !!
797 // Auf dieser steht nie ein Feld, maximal bis STRING_MAXLEN moeglich
798 _SetGetExpFld::_SetGetExpFld( const SwSectionNode
& rSectNd
,
799 const SwPosition
* pPos
)
801 eSetGetExpFldType
= SECTIONNODE
;
802 CNTNT
.pSection
= &rSectNd
.GetSection();
806 nNode
= pPos
->nNode
.GetIndex();
807 nCntnt
= pPos
->nContent
.GetIndex();
811 nNode
= rSectNd
.GetIndex();
816 _SetGetExpFld::_SetGetExpFld( const SwTableBox
& rTBox
, const SwPosition
* pPos
)
818 eSetGetExpFldType
= TABLEBOX
;
819 CNTNT
.pTBox
= &rTBox
;
823 nNode
= pPos
->nNode
.GetIndex();
824 nCntnt
= pPos
->nContent
.GetIndex();
830 if( rTBox
.GetSttNd() )
832 SwNodeIndex
aIdx( *rTBox
.GetSttNd() );
833 const SwCntntNode
* pNd
= aIdx
.GetNode().GetNodes().GoNext( &aIdx
);
835 nNode
= pNd
->GetIndex();
840 _SetGetExpFld::_SetGetExpFld( const SwNodeIndex
& rNdIdx
,
841 const SwTxtTOXMark
& rTOX
,
842 const SwIndex
* pIdx
)
844 eSetGetExpFldType
= TEXTTOXMARK
;
845 CNTNT
.pTxtTOX
= &rTOX
;
846 nNode
= rNdIdx
.GetIndex();
848 nCntnt
= pIdx
->GetIndex();
850 nCntnt
= *rTOX
.GetStart();
853 _SetGetExpFld::_SetGetExpFld( const SwPosition
& rPos
)
855 eSetGetExpFldType
= CRSRPOS
;
857 nNode
= rPos
.nNode
.GetIndex();
858 nCntnt
= rPos
.nContent
.GetIndex();
861 _SetGetExpFld::_SetGetExpFld( const SwFlyFrmFmt
& rFlyFmt
,
862 const SwPosition
* pPos
)
864 eSetGetExpFldType
= FLYFRAME
;
865 CNTNT
.pFlyFmt
= &rFlyFmt
;
868 nNode
= pPos
->nNode
.GetIndex();
869 nCntnt
= pPos
->nContent
.GetIndex();
873 const SwFmtCntnt
& rCntnt
= rFlyFmt
.GetCntnt();
874 nNode
= rCntnt
.GetCntntIdx()->GetIndex() + 1;
879 void _SetGetExpFld::GetPos( SwPosition
& rPos
) const
882 rPos
.nContent
.Assign( rPos
.nNode
.GetNode().GetCntntNode(), nCntnt
);
885 void _SetGetExpFld::GetPosOfContent( SwPosition
& rPos
) const
887 const SwNode
* pNd
= GetNodeFromCntnt();
889 pNd
= pNd
->GetCntntNode();
894 rPos
.nContent
.Assign( (SwCntntNode
*)pNd
,GetCntPosFromCntnt() );
899 rPos
.nContent
.Assign( rPos
.nNode
.GetNode().GetCntntNode(), nCntnt
);
903 void _SetGetExpFld::SetBodyPos( const SwCntntFrm
& rFrm
)
905 if( !rFrm
.IsInDocBody() )
907 SwNodeIndex
aIdx( *rFrm
.GetNode() );
908 SwDoc
& rDoc
= *aIdx
.GetNodes().GetDoc();
909 SwPosition
aPos( aIdx
);
911 ASSERT( ::GetBodyTxtNode( rDoc
, aPos
, rFrm
), "wo steht das Feld" );
913 ::GetBodyTxtNode( rDoc
, aPos
, rFrm
);
915 nNode
= aPos
.nNode
.GetIndex();
916 nCntnt
= aPos
.nContent
.GetIndex();
920 BOOL
_SetGetExpFld::operator<( const _SetGetExpFld
& rFld
) const
922 if( nNode
< rFld
.nNode
|| ( nNode
== rFld
.nNode
&& nCntnt
< rFld
.nCntnt
))
924 else if( nNode
!= rFld
.nNode
|| nCntnt
!= rFld
.nCntnt
)
927 const SwNode
*pFirst
= GetNodeFromCntnt(),
928 *pNext
= rFld
.GetNodeFromCntnt();
930 // Position gleich: nur weiter wenn beide FeldPointer besetzt sind !!
931 if( !pFirst
|| !pNext
)
934 // gleiche Section ??
935 if( pFirst
->StartOfSectionNode() != pNext
->StartOfSectionNode() )
937 // sollte einer in der Tabelle stehen ?
938 const SwNode
*pFirstStt
, *pNextStt
;
939 const SwTableNode
* pTblNd
= pFirst
->FindTableNode();
941 pFirstStt
= pTblNd
->StartOfSectionNode();
943 pFirstStt
= pFirst
->StartOfSectionNode();
945 if( 0 != ( pTblNd
= pNext
->FindTableNode() ) )
946 pNextStt
= pTblNd
->StartOfSectionNode();
948 pNextStt
= pNext
->StartOfSectionNode();
950 if( pFirstStt
!= pNextStt
)
952 if( pFirst
->IsTxtNode() && pNext
->IsTxtNode() &&
953 ( pFirst
->FindFlyStartNode() || pNext
->FindFlyStartNode() ))
955 return ::IsFrameBehind( *(SwTxtNode
*)pNext
, nCntnt
,
956 *(SwTxtNode
*)pFirst
, nCntnt
);
958 return pFirstStt
->GetIndex() < pNextStt
->GetIndex();
962 // ist gleiche Section, dann Feld im gleichen Node ?
963 if( pFirst
!= pNext
)
964 return pFirst
->GetIndex() < pNext
->GetIndex();
966 // gleicher Node in der Section, dann Position im Node
967 return GetCntPosFromCntnt() < rFld
.GetCntPosFromCntnt();
970 const SwNode
* _SetGetExpFld::GetNodeFromCntnt() const
972 const SwNode
* pRet
= 0;
974 switch( eSetGetExpFldType
)
977 pRet
= &CNTNT
.pTxtFld
->GetTxtNode();
981 pRet
= &CNTNT
.pTxtINet
->GetTxtNode();
985 pRet
= CNTNT
.pSection
->GetFmt()->GetSectionNode();
989 pRet
= &CNTNT
.pPos
->nNode
.GetNode();
993 pRet
= &CNTNT
.pTxtTOX
->GetTxtNode();
997 if( CNTNT
.pTBox
->GetSttNd() )
999 SwNodeIndex
aIdx( *CNTNT
.pTBox
->GetSttNd() );
1000 pRet
= aIdx
.GetNode().GetNodes().GoNext( &aIdx
);
1006 SwNodeIndex
aIdx( *CNTNT
.pFlyFmt
->GetCntnt().GetCntntIdx() );
1007 pRet
= aIdx
.GetNode().GetNodes().GoNext( &aIdx
);
1014 xub_StrLen
_SetGetExpFld::GetCntPosFromCntnt() const
1018 switch( eSetGetExpFldType
)
1023 nRet
= *CNTNT
.pTxtFld
->GetStart();
1026 nRet
= CNTNT
.pPos
->nContent
.GetIndex();
1034 _HashStr::_HashStr( const String
& rName
, const String
& rText
,
1036 : SwHash( rName
), aSetStr( rText
)
1041 // suche nach dem Namen, ist er vorhanden, returne seinen String, sonst
1043 void LookString( SwHash
** ppTbl
, USHORT nSize
, const String
& rName
,
1044 String
& rRet
, USHORT
* pPos
)
1047 rRet
.EraseLeadingChars().EraseTrailingChars();
1048 SwHash
* pFnd
= Find( rRet
, ppTbl
, nSize
, pPos
);
1050 rRet
= ((_HashStr
*)pFnd
)->aSetStr
;
1055 /*--------------------------------------------------------------------
1057 --------------------------------------------------------------------*/
1059 String
lcl_GetDBVarName( SwDoc
& rDoc
, SwDBNameInfField
& rDBFld
)
1061 SwDBData
aDBData( rDBFld
.GetDBData( &rDoc
));
1063 SwDBData aDocData
= rDoc
.GetDBData();
1065 if( aDBData
!= aDocData
)
1067 sDBNumNm
= aDBData
.sDataSource
;
1068 sDBNumNm
+= DB_DELIM
;
1069 sDBNumNm
+= String(aDBData
.sCommand
);
1070 sDBNumNm
+= DB_DELIM
;
1072 sDBNumNm
+= SwFieldType::GetTypeStr(TYP_DBSETNUMBERFLD
);
1077 /*--------------------------------------------------------------------
1079 --------------------------------------------------------------------*/
1081 void lcl_CalcFld( SwDoc
& rDoc
, SwCalc
& rCalc
, const _SetGetExpFld
& rSGEFld
,
1084 const SwTxtFld
* pTxtFld
= rSGEFld
.GetFld();
1088 const SwField
* pFld
= pTxtFld
->GetFld().GetFld();
1089 const USHORT nFldWhich
= pFld
->GetTyp()->Which();
1091 if( RES_SETEXPFLD
== nFldWhich
)
1094 if( nsSwGetSetExpType::GSE_EXPR
& pFld
->GetSubType() )
1095 aValue
.PutDouble( ((SwSetExpField
*)pFld
)->GetValue() );
1097 // Erweiterung fuers Rechnen mit Strings
1098 aValue
.PutString( ((SwSetExpField
*)pFld
)->GetExpStr() );
1100 // setze im Calculator den neuen Wert
1101 rCalc
.VarChange( pFld
->GetTyp()->GetName(), aValue
);
1107 case RES_DBNUMSETFLD
:
1109 SwDBNumSetField
* pDBFld
= (SwDBNumSetField
*)pFld
;
1111 SwDBData
aDBData(pDBFld
->GetDBData(&rDoc
));
1113 if( pDBFld
->IsCondValid() &&
1114 pMgr
->OpenDataSource( aDBData
.sDataSource
, aDBData
.sCommand
))
1115 rCalc
.VarChange( lcl_GetDBVarName( rDoc
, *pDBFld
),
1116 pDBFld
->GetFormat() );
1119 case RES_DBNEXTSETFLD
:
1121 SwDBNextSetField
* pDBFld
= (SwDBNextSetField
*)pFld
;
1122 SwDBData
aDBData(pDBFld
->GetDBData(&rDoc
));
1123 if( !pDBFld
->IsCondValid() ||
1124 !pMgr
->OpenDataSource( aDBData
.sDataSource
, aDBData
.sCommand
))
1127 String
sDBNumNm(lcl_GetDBVarName( rDoc
, *pDBFld
));
1128 SwCalcExp
* pExp
= rCalc
.VarLook( sDBNumNm
);
1130 rCalc
.VarChange( sDBNumNm
, pExp
->nValue
.GetLong() + 1 );
1138 void SwDoc::FldsToCalc( SwCalc
& rCalc
, const _SetGetExpFld
& rToThisFld
)
1140 // erzeuge die Sortierteliste aller SetFelder
1141 pUpdtFlds
->MakeFldList( *this, mbNewFldLst
, GETFLD_CALC
);
1142 mbNewFldLst
= FALSE
;
1144 SwNewDBMgr
* pMgr
= GetNewDBMgr();
1145 pMgr
->CloseAll(FALSE
);
1147 if( pUpdtFlds
->GetSortLst()->Count() )
1150 _SetGetExpFld
* pFld
= (_SetGetExpFld
*)&rToThisFld
;
1151 if( pUpdtFlds
->GetSortLst()->Seek_Entry( pFld
, &nLast
) )
1154 const _SetGetExpFldPtr
* ppSortLst
= pUpdtFlds
->GetSortLst()->GetData();
1155 for( USHORT n
= 0; n
< nLast
; ++n
, ++ppSortLst
)
1156 lcl_CalcFld( *this, rCalc
, **ppSortLst
, pMgr
);
1159 pMgr
->CloseAll(FALSE
);
1162 void SwDoc::FldsToCalc( SwCalc
& rCalc
, ULONG nLastNd
, sal_uInt16 nLastCnt
)
1164 // erzeuge die Sortierteliste aller SetFelder
1165 pUpdtFlds
->MakeFldList( *this, mbNewFldLst
, GETFLD_CALC
);
1166 mbNewFldLst
= FALSE
;
1168 SwNewDBMgr
* pMgr
= GetNewDBMgr();
1169 pMgr
->CloseAll(FALSE
);
1171 const _SetGetExpFldPtr
* ppSortLst
= pUpdtFlds
->GetSortLst()->GetData();
1173 for( USHORT n
= pUpdtFlds
->GetSortLst()->Count();
1175 ( (*ppSortLst
)->GetNode() < nLastNd
||
1176 ( (*ppSortLst
)->GetNode() == nLastNd
&& (*ppSortLst
)->GetCntnt() <= nLastCnt
)
1179 lcl_CalcFld( *this, rCalc
, **ppSortLst
, pMgr
);
1181 pMgr
->CloseAll(FALSE
);
1184 void SwDoc::FldsToExpand( SwHash
**& ppHashTbl
, USHORT
& rTblSize
,
1185 const _SetGetExpFld
& rToThisFld
)
1187 // erzeuge die Sortierteliste aller SetFelder
1188 pUpdtFlds
->MakeFldList( *this, mbNewFldLst
, GETFLD_EXPAND
);
1189 mbNewFldLst
= FALSE
;
1191 // HashTabelle fuer alle String Ersetzungen, wird "one the fly" gefuellt
1192 // (versuche eine "ungerade"-Zahl zu erzeugen)
1193 rTblSize
= (( pUpdtFlds
->GetSortLst()->Count() / 7 ) + 1 ) * 7;
1194 ppHashTbl
= new SwHash
*[ rTblSize
];
1195 memset( ppHashTbl
, 0, sizeof( _HashStr
* ) * rTblSize
);
1199 _SetGetExpFld
* pTmp
= (_SetGetExpFld
*)&rToThisFld
;
1200 if( pUpdtFlds
->GetSortLst()->Seek_Entry( pTmp
, &nLast
) )
1207 const _SetGetExpFldPtr
* ppSortLst
= pUpdtFlds
->GetSortLst()->GetData();
1208 for( ; nLast
; --nLast
, ++ppSortLst
)
1210 const SwTxtFld
* pTxtFld
= (*ppSortLst
)->GetFld();
1214 const SwField
* pFld
= pTxtFld
->GetFld().GetFld();
1215 switch( pFld
->GetTyp()->Which() )
1218 if( nsSwGetSetExpType::GSE_STRING
& pFld
->GetSubType() )
1220 // setze in der HashTabelle den neuen Wert
1221 // ist die "Formel" ein Feld ??
1222 SwSetExpField
* pSFld
= (SwSetExpField
*)pFld
;
1223 LookString( ppHashTbl
, rTblSize
, pSFld
->GetFormula(), aNew
);
1225 if( !aNew
.Len() ) // nichts gefunden, dann ist
1226 aNew
= pSFld
->GetFormula(); // die Formel der neue Wert
1228 // OD 11.02.2003 #i3141# - update expression of field as in
1229 // method <SwDoc::UpdateExpFlds(..)> for string/text fields
1230 pSFld
->ChgExpStr( aNew
);
1232 // suche den Namen vom Feld
1233 aNew
= ((SwSetExpFieldType
*)pSFld
->GetTyp())->GetSetRefName();
1234 // Eintrag vorhanden ?
1235 pFnd
= Find( aNew
, ppHashTbl
, rTblSize
, &nPos
);
1237 // Eintrag in der HashTabelle aendern
1238 ((_HashStr
*)pFnd
)->aSetStr
= pSFld
->GetExpStr();
1240 // neuen Eintrag einfuegen
1241 *(ppHashTbl
+ nPos
) = new _HashStr( aNew
,
1242 pSFld
->GetExpStr(), (_HashStr
*)*(ppHashTbl
+ nPos
) );
1247 const String
& rName
= pFld
->GetTyp()->GetName();
1249 // Eintrag in den HashTable eintragen
1250 // Eintrag vorhanden ?
1251 pFnd
= Find( rName
, ppHashTbl
, rTblSize
, &nPos
);
1253 // Eintrag in der HashTabelle aendern
1254 ((_HashStr
*)pFnd
)->aSetStr
= pFld
->Expand();
1256 // neuen Eintrag einfuegen
1257 *(ppHashTbl
+ nPos
) = new _HashStr( rName
,
1258 pFld
->Expand(), (_HashStr
*)*(ppHashTbl
+ nPos
));
1266 void SwDoc::UpdateExpFlds( SwTxtFld
* pUpdtFld
, bool bUpdRefFlds
)
1268 if( IsExpFldsLocked() || IsInReading() )
1271 BOOL bOldInUpdateFlds
= pUpdtFlds
->IsInUpdateFlds();
1272 pUpdtFlds
->SetInUpdateFlds( TRUE
);
1274 pUpdtFlds
->MakeFldList( *this, TRUE
, GETFLD_ALL
);
1275 mbNewFldLst
= FALSE
;
1277 if( !pUpdtFlds
->GetSortLst()->Count() )
1280 UpdateRefFlds(NULL
);
1282 pUpdtFlds
->SetInUpdateFlds( bOldInUpdateFlds
);
1283 pUpdtFlds
->SetFieldsDirty( FALSE
);
1289 // HashTabelle fuer alle String Ersetzungen, wird "one the fly" gefuellt
1290 // (versuche eine "ungerade"-Zahl zu erzeugen)
1291 USHORT nStrFmtCnt
= (( pFldTypes
->Count() / 7 ) + 1 ) * 7;
1292 SwHash
** pHashStrTbl
= new SwHash
*[ nStrFmtCnt
];
1293 memset( pHashStrTbl
, 0, sizeof( _HashStr
* ) * nStrFmtCnt
);
1296 const SwFieldType
* pFldType
;
1297 // gesondert behandeln:
1298 for( n
= pFldTypes
->Count(); n
; )
1299 switch( ( pFldType
= (*pFldTypes
)[ --n
] )->Which() )
1303 // Eintrag vorhanden ?
1305 const String
& rNm
= pFldType
->GetName();
1306 String
sExpand(((SwUserFieldType
*)pFldType
)->Expand(nsSwGetSetExpType::GSE_STRING
, 0, 0));
1307 SwHash
* pFnd
= Find( rNm
, pHashStrTbl
, nStrFmtCnt
, &nPos
);
1309 // Eintrag in der HashTabelle aendern ??
1310 ((_HashStr
*)pFnd
)->aSetStr
= sExpand
;
1312 // neuen Eintrag einfuegen
1313 *(pHashStrTbl
+ nPos
) = new _HashStr( rNm
, sExpand
,
1314 (_HashStr
*)*(pHashStrTbl
+ nPos
) );
1318 ((SwSetExpFieldType
*)pFldType
)->SetOutlineChgNd( 0 );
1323 // Ok, das Array ist soweit mit allen Feldern gefuellt, dann rechne mal
1324 SwCalc
aCalc( *this );
1326 String
sDBNumNm( SwFieldType::GetTypeStr( TYP_DBSETNUMBERFLD
) );
1328 // aktuelle Datensatznummer schon vorher einstellen
1329 SwNewDBMgr
* pMgr
= GetNewDBMgr();
1330 pMgr
->CloseAll(FALSE
);
1332 if(pMgr && pMgr->OpenDB(DBMGR_STD, GetDBDesc(), FALSE))
1334 if(!pMgr->IsInMerge() )
1335 pMgr->ToFirstSelectedRecord(DBMGR_STD);
1337 aCalc.VarChange( sDBNumNm, pMgr->GetCurSelectedRecordId(DBMGR_STD));
1342 const _SetGetExpFldPtr
* ppSortLst
= pUpdtFlds
->GetSortLst()->GetData();
1343 for( n
= pUpdtFlds
->GetSortLst()->Count(); n
; --n
, ++ppSortLst
)
1345 SwSection
* pSect
= (SwSection
*)(*ppSortLst
)->GetSection();
1350 // if( pGFld->IsInBodyTxt() )
1351 SwSbxValue aValue
= aCalc
.Calculate(
1352 pSect
->GetCondition() );
1353 if(!aValue
.IsVoidValue())
1354 pSect
->SetCondHidden( aValue
.GetBool() );
1358 SwTxtFld
* pTxtFld
= (SwTxtFld
*)(*ppSortLst
)->GetFld();
1361 ASSERT( !this, "was ist es denn nun" );
1365 SwFmtFld
* pFmtFld
= (SwFmtFld
*)&pTxtFld
->GetFld();
1366 SwField
* pFld
= pFmtFld
->GetFld();
1368 switch( nWhich
= pFld
->GetTyp()->Which() )
1370 case RES_HIDDENTXTFLD
:
1372 SwHiddenTxtField
* pHFld
= (SwHiddenTxtField
*)pFld
;
1373 SwSbxValue aValue
= aCalc
.Calculate( pHFld
->GetPar1() );
1374 sal_Bool bValue
= !aValue
.GetBool();
1375 if(!aValue
.IsVoidValue())
1377 pHFld
->SetValue( bValue
);
1379 pHFld
->Evaluate(this);
1383 case RES_HIDDENPARAFLD
:
1385 SwHiddenParaField
* pHPFld
= (SwHiddenParaField
*)pFld
;
1386 SwSbxValue aValue
= aCalc
.Calculate( pHPFld
->GetPar1() );
1387 sal_Bool bValue
= aValue
.GetBool();
1388 if(!aValue
.IsVoidValue())
1389 pHPFld
->SetHidden( bValue
);
1392 case RES_DBSETNUMBERFLD
:
1394 ((SwDBSetNumberField
*)pFld
)->Evaluate(this);
1395 aCalc
.VarChange( sDBNumNm
, ((SwDBSetNumberField
*)pFld
)->GetSetNumber());
1398 case RES_DBNEXTSETFLD
:
1399 case RES_DBNUMSETFLD
:
1400 UpdateDBNumFlds( *(SwDBNameInfField
*)pFld
, aCalc
);
1405 ((SwDBField
*)pFld
)->Evaluate();
1407 SwDBData
aTmpDBData(((SwDBField
*)pFld
)->GetDBData());
1409 if( pMgr
->IsDataSourceOpen(aTmpDBData
.sDataSource
, aTmpDBData
.sCommand
, sal_False
))
1410 aCalc
.VarChange( sDBNumNm
, pMgr
->GetSelectedRecordId(aTmpDBData
.sDataSource
, aTmpDBData
.sCommand
, aTmpDBData
.nCommandType
));
1412 const String
& rName
= pFld
->GetTyp()->GetName();
1414 // Wert fuer den Calculator setzen
1415 //JP 10.02.96: GetValue macht hier doch keinen Sinn
1416 // ((SwDBField*)pFld)->GetValue();
1418 //!OK aCalc.VarChange(aName, ((SwDBField*)pFld)->GetValue(aCalc));
1420 // Eintrag in den HashTable eintragen
1421 // Eintrag vorhanden ?
1423 SwHash
* pFnd
= Find( rName
, pHashStrTbl
, nStrFmtCnt
, &nPos
);
1425 // Eintrag in der HashTabelle aendern
1426 ((_HashStr
*)pFnd
)->aSetStr
= pFld
->Expand();
1428 // neuen Eintrag einfuegen
1429 *(pHashStrTbl
+ nPos
) = new _HashStr( rName
,
1430 pFld
->Expand(), (_HashStr
*)*(pHashStrTbl
+ nPos
));
1436 if( nsSwGetSetExpType::GSE_STRING
& pFld
->GetSubType() ) // String Ersetzung
1438 if( RES_GETEXPFLD
== nWhich
)
1440 SwGetExpField
* pGFld
= (SwGetExpField
*)pFld
;
1442 if( (!pUpdtFld
|| pUpdtFld
== pTxtFld
)
1443 && pGFld
->IsInBodyTxt() )
1445 LookString( pHashStrTbl
, nStrFmtCnt
,
1446 pGFld
->GetFormula(), aNew
);
1447 pGFld
->ChgExpStr( aNew
);
1452 SwSetExpField
* pSFld
= (SwSetExpField
*)pFld
;
1453 // ist die "Formel" ein Feld ??
1454 LookString( pHashStrTbl
, nStrFmtCnt
,
1455 pSFld
->GetFormula(), aNew
);
1457 if( !aNew
.Len() ) // nichts gefunden, dann ist die
1458 aNew
= pSFld
->GetFormula(); // Formel der neue Wert
1460 // nur ein spezielles FeldUpdaten ?
1461 if( !pUpdtFld
|| pUpdtFld
== pTxtFld
)
1462 pSFld
->ChgExpStr( aNew
);
1464 // suche den Namen vom Feld
1465 aNew
= ((SwSetExpFieldType
*)pSFld
->GetTyp())->GetSetRefName();
1466 // Eintrag vorhanden ?
1468 SwHash
* pFnd
= Find( aNew
, pHashStrTbl
, nStrFmtCnt
, &nPos
);
1470 // Eintrag in der HashTabelle aendern
1471 ((_HashStr
*)pFnd
)->aSetStr
= pSFld
->GetExpStr();
1473 // neuen Eintrag einfuegen
1474 *(pHashStrTbl
+ nPos
) = pFnd
= new _HashStr( aNew
,
1476 (_HashStr
*)*(pHashStrTbl
+ nPos
) );
1478 // Erweiterung fuers Rechnen mit Strings
1480 aValue
.PutString( ((_HashStr
*)pFnd
)->aSetStr
);
1481 aCalc
.VarChange( aNew
, aValue
);
1484 else // Formel neu berechnen
1486 if( RES_GETEXPFLD
== nWhich
)
1488 SwGetExpField
* pGFld
= (SwGetExpField
*)pFld
;
1490 if( (!pUpdtFld
|| pUpdtFld
== pTxtFld
)
1491 && pGFld
->IsInBodyTxt() )
1493 SwSbxValue aValue
= aCalc
.Calculate(
1494 pGFld
->GetFormula());
1495 if(!aValue
.IsVoidValue())
1496 pGFld
->SetValue(aValue
.GetDouble() );
1501 SwSetExpField
* pSFld
= (SwSetExpField
*)pFld
;
1502 SwSetExpFieldType
* pSFldTyp
= (SwSetExpFieldType
*)pFld
->GetTyp();
1503 aNew
= pSFldTyp
->GetName();
1507 if( pSFld
->IsSequenceFld() )
1509 const BYTE nLvl
= pSFldTyp
->GetOutlineLvl();
1510 if( MAXLEVEL
> nLvl
)
1512 // dann teste, ob die Nummer neu aufsetzen muss
1513 pSeqNd
= GetNodes()[ (*ppSortLst
)->GetNode() ];
1515 const SwTxtNode
* pOutlNd
= pSeqNd
->
1516 FindOutlineNodeOfLevel( nLvl
);
1517 if( pSFldTyp
->GetOutlineChgNd() != pOutlNd
)
1519 pSFldTyp
->SetOutlineChgNd( pOutlNd
);
1520 aCalc
.VarChange( aNew
, 0 );
1526 aNew
+= pSFld
->GetFormula();
1528 SwSbxValue aValue
= aCalc
.Calculate( aNew
);
1529 double nErg
= aValue
.GetDouble();
1530 // nur ein spezielles Feld updaten ?
1531 if( !aValue
.IsVoidValue() && (!pUpdtFld
|| pUpdtFld
== pTxtFld
) )
1533 pSFld
->SetValue( nErg
);
1536 pSFldTyp
->SetChapter( *pSFld
, *pSeqNd
);
1543 pFmtFld
->Modify( 0, 0 ); // Formatierung anstossen
1545 if( pUpdtFld
== pTxtFld
) // sollte nur dieses geupdatet werden
1547 if( RES_GETEXPFLD
== nWhich
|| // nur GetFeld oder
1548 RES_HIDDENTXTFLD
== nWhich
|| // HiddenTxt?
1549 RES_HIDDENPARAFLD
== nWhich
) // HiddenParaFld?
1551 pUpdtFld
= 0; // ab jetzt alle Updaten
1555 pMgr
->CloseAll(FALSE
);
1556 // HashTabelle wieder loeschen
1557 ::DeleteHashTable( pHashStrTbl
, nStrFmtCnt
);
1559 // Referenzfelder updaten
1561 UpdateRefFlds(NULL
);
1563 pUpdtFlds
->SetInUpdateFlds( bOldInUpdateFlds
);
1564 pUpdtFlds
->SetFieldsDirty( FALSE
);
1567 /*--------------------------------------------------------------------
1569 --------------------------------------------------------------------*/
1571 void SwDoc::UpdateDBNumFlds( SwDBNameInfField
& rDBFld
, SwCalc
& rCalc
)
1573 SwNewDBMgr
* pMgr
= GetNewDBMgr();
1575 USHORT nFldType
= rDBFld
.Which();
1577 BOOL bPar1
= rCalc
.Calculate( rDBFld
.GetPar1() ).GetBool();
1579 if( RES_DBNEXTSETFLD
== nFldType
)
1580 ((SwDBNextSetField
&)rDBFld
).SetCondValid( bPar1
);
1582 ((SwDBNumSetField
&)rDBFld
).SetCondValid( bPar1
);
1584 if( rDBFld
.GetRealDBData().sDataSource
.getLength() )
1586 // Eine bestimmte Datenbank bearbeiten
1587 if( RES_DBNEXTSETFLD
== nFldType
)
1588 ((SwDBNextSetField
&)rDBFld
).Evaluate(this);
1590 ((SwDBNumSetField
&)rDBFld
).Evaluate(this);
1592 SwDBData
aTmpDBData( rDBFld
.GetDBData(this) );
1594 if( pMgr
->OpenDataSource( aTmpDBData
.sDataSource
, aTmpDBData
.sCommand
, -1, false ))
1595 rCalc
.VarChange( lcl_GetDBVarName( *this, rDBFld
),
1596 pMgr
->GetSelectedRecordId(aTmpDBData
.sDataSource
, aTmpDBData
.sCommand
, aTmpDBData
.nCommandType
) );
1600 DBG_ERROR("TODO: what should happen with unnamed DBFields?");
1604 /*--------------------------------------------------------------------
1606 --------------------------------------------------------------------*/
1608 void SwDoc::_InitFieldTypes() // wird vom CTOR gerufen!!
1611 USHORT nFldType
= 0;
1612 pFldTypes
->Insert( new SwDateTimeFieldType(this), nFldType
++ );
1613 pFldTypes
->Insert( new SwChapterFieldType
, nFldType
++ );
1614 pFldTypes
->Insert( new SwPageNumberFieldType
, nFldType
++ );
1615 pFldTypes
->Insert( new SwAuthorFieldType
, nFldType
++ );
1616 pFldTypes
->Insert( new SwFileNameFieldType(this), nFldType
++ );
1617 pFldTypes
->Insert( new SwDBNameFieldType(this), nFldType
++);
1618 pFldTypes
->Insert( new SwGetExpFieldType(this), nFldType
++ );
1619 pFldTypes
->Insert( new SwGetRefFieldType( this ), nFldType
++ );
1620 pFldTypes
->Insert( new SwHiddenTxtFieldType
, nFldType
++ );
1621 pFldTypes
->Insert( new SwPostItFieldType(this), nFldType
++ );
1622 pFldTypes
->Insert( new SwDocStatFieldType(this), nFldType
++);
1623 pFldTypes
->Insert( new SwDocInfoFieldType(this), nFldType
++);
1624 pFldTypes
->Insert( new SwInputFieldType( this ), nFldType
++ );
1625 pFldTypes
->Insert( new SwTblFieldType( this ), nFldType
++);
1626 pFldTypes
->Insert( new SwMacroFieldType(this), nFldType
++ );
1627 pFldTypes
->Insert( new SwHiddenParaFieldType
, nFldType
++ );
1628 pFldTypes
->Insert( new SwDBNextSetFieldType
, nFldType
++ );
1629 pFldTypes
->Insert( new SwDBNumSetFieldType
, nFldType
++ );
1630 pFldTypes
->Insert( new SwDBSetNumberFieldType
, nFldType
++ );
1631 pFldTypes
->Insert( new SwTemplNameFieldType(this), nFldType
++);
1632 pFldTypes
->Insert( new SwTemplNameFieldType(this),nFldType
++);
1633 pFldTypes
->Insert( new SwExtUserFieldType
, nFldType
++ );
1634 pFldTypes
->Insert( new SwRefPageSetFieldType
, nFldType
++ );
1635 pFldTypes
->Insert( new SwRefPageGetFieldType( this ), nFldType
++ );
1636 pFldTypes
->Insert( new SwJumpEditFieldType( this ), nFldType
++ );
1637 pFldTypes
->Insert( new SwScriptFieldType( this ), nFldType
++ );
1638 pFldTypes
->Insert( new SwCombinedCharFieldType
, nFldType
++ );
1639 pFldTypes
->Insert( new SwDropDownFieldType
, nFldType
++ );
1641 // Types muessen am Ende stehen !!
1642 // Im InsertFldType wird davon ausgegangen !!!!
1643 // MIB 14.04.95: Im Sw3StringPool::Setup (sw3imp.cxx) und
1644 // lcl_sw3io_InSetExpField (sw3field.cxx) jetzt auch
1645 pFldTypes
->Insert( new SwSetExpFieldType(this,
1646 SW_RESSTR(STR_POOLCOLL_LABEL_ABB
), nsSwGetSetExpType::GSE_SEQ
), nFldType
++);
1647 pFldTypes
->Insert( new SwSetExpFieldType(this,
1648 SW_RESSTR(STR_POOLCOLL_LABEL_TABLE
), nsSwGetSetExpType::GSE_SEQ
),nFldType
++);
1649 pFldTypes
->Insert( new SwSetExpFieldType(this,
1650 SW_RESSTR(STR_POOLCOLL_LABEL_FRAME
), nsSwGetSetExpType::GSE_SEQ
),nFldType
++);
1651 pFldTypes
->Insert( new SwSetExpFieldType(this,
1652 SW_RESSTR(STR_POOLCOLL_LABEL_DRAWING
), nsSwGetSetExpType::GSE_SEQ
),nFldType
++);
1654 ASSERT( nFldType
== INIT_FLDTYPES
, "Bad initsize: SwFldTypes" );
1657 void SwDoc::InsDelFldInFldLst( bool bIns
, const SwTxtFld
& rFld
)
1659 if( !mbNewFldLst
|| !IsInDtor() )
1660 pUpdtFlds
->InsDelFldInFldLst( bIns
, rFld
);
1663 SwDBData
SwDoc::GetDBData()
1668 const SwDBData
& SwDoc::GetDBDesc()
1670 if(!aDBData
.sDataSource
.getLength())
1672 const USHORT nSize
= pFldTypes
->Count();
1673 for(USHORT i
= 0; i
< nSize
&& !aDBData
.sDataSource
.getLength(); ++i
)
1675 SwFieldType
& rFldType
= *((*pFldTypes
)[i
]);
1676 USHORT nWhich
= rFldType
.Which();
1677 if(IsUsed(rFldType
))
1682 case RES_DBNEXTSETFLD
:
1683 case RES_DBNUMSETFLD
:
1684 case RES_DBSETNUMBERFLD
:
1686 SwClientIter
aIter( rFldType
);
1687 SwFmtFld
* pFld
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
));
1690 if(pFld
->IsFldInDoc())
1692 if(RES_DBFLD
== nWhich
)
1694 (static_cast < SwDBFieldType
* > (pFld
->GetFld()->GetTyp()))
1697 aDBData
= (static_cast < SwDBNameInfField
* > (pFld
->GetFld()))->GetRealDBData();
1700 pFld
= (SwFmtFld
*)aIter
.Next();
1708 if(!aDBData
.sDataSource
.getLength())
1709 aDBData
= GetNewDBMgr()->GetAddressDBName();
1713 void SwDoc::SetInitDBFields( BOOL b
)
1715 GetNewDBMgr()->SetInitDBFields( b
);
1718 /*--------------------------------------------------------------------
1719 Beschreibung: Alle von Feldern verwendete Datenbanken herausfinden
1720 --------------------------------------------------------------------*/
1721 String
lcl_DBDataToString(const SwDBData
& rData
)
1723 String sRet
= rData
.sDataSource
;
1725 sRet
+= (String
)rData
.sCommand
;
1727 sRet
+= String::CreateFromInt32(rData
.nCommandType
);
1730 void SwDoc::GetAllUsedDB( SvStringsDtor
& rDBNameList
,
1731 const SvStringsDtor
* pAllDBNames
)
1734 SvStringsDtor aUsedDBNames
;
1735 SvStringsDtor aAllDBNames
;
1739 GetAllDBNames( aAllDBNames
);
1740 pAllDBNames
= &aAllDBNames
;
1743 SwSectionFmts
& rArr
= GetSections();
1744 for( n
= rArr
.Count(); n
; )
1746 SwSection
* pSect
= rArr
[ --n
]->GetSection();
1750 String
aCond( pSect
->GetCondition() );
1751 AddUsedDBToList( rDBNameList
, FindUsedDBs( *pAllDBNames
,
1752 aCond
, aUsedDBNames
) );
1753 aUsedDBNames
.DeleteAndDestroy( 0, aUsedDBNames
.Count() );
1757 const SfxPoolItem
* pItem
;
1758 USHORT nMaxItems
= GetAttrPool().GetItemCount( RES_TXTATR_FIELD
);
1759 for( n
= 0; n
< nMaxItems
; ++n
)
1761 if( 0 == (pItem
= GetAttrPool().GetItem( RES_TXTATR_FIELD
, n
) ))
1764 const SwFmtFld
* pFmtFld
= (SwFmtFld
*)pItem
;
1765 const SwTxtFld
* pTxtFld
= pFmtFld
->GetTxtFld();
1766 if( !pTxtFld
|| !pTxtFld
->GetTxtNode().GetNodes().IsDocNodes() )
1769 const SwField
* pFld
= pFmtFld
->GetFld();
1770 switch( pFld
->GetTyp()->Which() )
1773 AddUsedDBToList( rDBNameList
,
1774 lcl_DBDataToString(((SwDBField
*)pFld
)->GetDBData() ));
1777 case RES_DBSETNUMBERFLD
:
1779 AddUsedDBToList( rDBNameList
,
1780 lcl_DBDataToString(((SwDBNameInfField
*)pFld
)->GetRealDBData() ));
1783 case RES_DBNUMSETFLD
:
1784 case RES_DBNEXTSETFLD
:
1785 AddUsedDBToList( rDBNameList
,
1786 lcl_DBDataToString(((SwDBNameInfField
*)pFld
)->GetRealDBData() ));
1787 // kein break // JP: ist das so richtig ??
1789 case RES_HIDDENTXTFLD
:
1790 case RES_HIDDENPARAFLD
:
1791 AddUsedDBToList(rDBNameList
, FindUsedDBs( *pAllDBNames
,
1792 pFld
->GetPar1(), aUsedDBNames
));
1793 aUsedDBNames
.DeleteAndDestroy( 0, aUsedDBNames
.Count() );
1799 AddUsedDBToList(rDBNameList
, FindUsedDBs( *pAllDBNames
,
1800 pFld
->GetFormula(), aUsedDBNames
));
1801 aUsedDBNames
.DeleteAndDestroy( 0, aUsedDBNames
.Count() );
1807 /*--------------------------------------------------------------------
1809 --------------------------------------------------------------------*/
1811 void SwDoc::GetAllDBNames( SvStringsDtor
& rAllDBNames
)
1813 SwNewDBMgr
* pMgr
= GetNewDBMgr();
1815 const SwDSParamArr
& rArr
= pMgr
->GetDSParamArray();
1816 for(USHORT i
= 0; i
< rArr
.Count(); i
++)
1818 SwDSParam
* pParam
= rArr
[i
];
1819 String
* pStr
= new String( pParam
->sDataSource
);
1820 (*pStr
) += DB_DELIM
;
1821 (*pStr
) += (String
)pParam
->sCommand
;
1822 rAllDBNames
.Insert( pStr
, rAllDBNames
.Count() );
1826 /*--------------------------------------------------------------------
1828 --------------------------------------------------------------------*/
1830 SvStringsDtor
& SwDoc::FindUsedDBs( const SvStringsDtor
& rAllDBNames
,
1831 const String
& rFormel
,
1832 SvStringsDtor
& rUsedDBNames
)
1834 const CharClass
& rCC
= GetAppCharClass();
1835 String
sFormel( rFormel
);
1837 rCC
.toUpper( sFormel
);
1841 for (USHORT i
= 0; i
< rAllDBNames
.Count(); ++i
)
1843 const String
* pStr
= rAllDBNames
.GetObject(i
);
1845 if( STRING_NOTFOUND
!= (nPos
= sFormel
.Search( *pStr
)) &&
1846 sFormel
.GetChar( nPos
+ pStr
->Len() ) == '.' &&
1847 (!nPos
|| !rCC
.isLetterNumeric( sFormel
, nPos
- 1 )))
1849 // Tabellenname suchen
1851 nPos
+= pStr
->Len() + 1;
1852 if( STRING_NOTFOUND
!= (nEndPos
= sFormel
.Search('.', nPos
)) )
1854 String
* pDBNm
= new String( *pStr
);
1855 pDBNm
->Append( DB_DELIM
);
1856 pDBNm
->Append( sFormel
.Copy( nPos
, nEndPos
- nPos
));
1857 rUsedDBNames
.Insert( pDBNm
, rUsedDBNames
.Count() );
1861 return rUsedDBNames
;
1864 /*--------------------------------------------------------------------
1866 --------------------------------------------------------------------*/
1868 void SwDoc::AddUsedDBToList( SvStringsDtor
& rDBNameList
,
1869 const SvStringsDtor
& rUsedDBNames
)
1871 for (USHORT i
= 0; i
< rUsedDBNames
.Count(); i
++)
1872 AddUsedDBToList( rDBNameList
, *rUsedDBNames
.GetObject(i
) );
1875 /*--------------------------------------------------------------------
1877 --------------------------------------------------------------------*/
1879 void SwDoc::AddUsedDBToList( SvStringsDtor
& rDBNameList
, const String
& rDBName
)
1881 if( !rDBName
.Len() )
1885 for( USHORT i
= 0; i
< rDBNameList
.Count(); ++i
)
1886 if( rDBName
== rDBNameList
.GetObject(i
)->GetToken(0) )
1889 const ::utl::TransliterationWrapper
& rSCmp
= GetAppCmpStrIgnore();
1890 for( USHORT i
= 0; i
< rDBNameList
.Count(); ++i
)
1891 if( rSCmp
.isEqual( rDBName
, rDBNameList
.GetObject(i
)->GetToken(0) ) )
1896 aData
.sDataSource
= rDBName
.GetToken(0, DB_DELIM
);
1897 aData
.sCommand
= rDBName
.GetToken(1, DB_DELIM
);
1898 aData
.nCommandType
= -1;
1899 GetNewDBMgr()->CreateDSData(aData
);
1900 String
* pNew
= new String( rDBName
);
1901 rDBNameList
.Insert( pNew
, rDBNameList
.Count() );
1904 /*--------------------------------------------------------------------
1906 --------------------------------------------------------------------*/
1908 void SwDoc::ChangeDBFields( const SvStringsDtor
& rOldNames
,
1909 const String
& rNewName
)
1911 SwDBData aNewDBData
;
1912 aNewDBData
.sDataSource
= rNewName
.GetToken(0, DB_DELIM
);
1913 aNewDBData
.sCommand
= rNewName
.GetToken(1, DB_DELIM
);
1914 aNewDBData
.nCommandType
= (short)rNewName
.GetToken(2, DB_DELIM
).ToInt32();
1919 SwSectionFmts
& rArr
= GetSections();
1920 for( n
= rArr
.Count(); n
; )
1922 SwSection
* pSect
= rArr
[ --n
]->GetSection();
1926 sFormel
= pSect
->GetCondition();
1927 ReplaceUsedDBs( rOldNames
, rNewName
, sFormel
);
1928 pSect
->SetCondition(sFormel
);
1932 const SfxPoolItem
* pItem
;
1933 USHORT nMaxItems
= GetAttrPool().GetItemCount( RES_TXTATR_FIELD
);
1935 for( n
= 0; n
< nMaxItems
; ++n
)
1937 if( 0 == (pItem
= GetAttrPool().GetItem( RES_TXTATR_FIELD
, n
) ))
1940 SwFmtFld
* pFmtFld
= (SwFmtFld
*)pItem
;
1941 SwTxtFld
* pTxtFld
= pFmtFld
->GetTxtFld();
1942 if( !pTxtFld
|| !pTxtFld
->GetTxtNode().GetNodes().IsDocNodes() )
1945 SwField
* pFld
= pFmtFld
->GetFld();
1946 BOOL bExpand
= FALSE
;
1948 switch( pFld
->GetTyp()->Which() )
1951 if( IsNameInArray( rOldNames
, lcl_DBDataToString(((SwDBField
*)pFld
)->GetDBData())))
1953 SwDBFieldType
* pOldTyp
= (SwDBFieldType
*)pFld
->GetTyp();
1955 SwDBFieldType
* pTyp
= (SwDBFieldType
*)InsertFldType(
1956 SwDBFieldType(this, pOldTyp
->GetColumnName(), aNewDBData
));
1958 pTyp
->Add(pFmtFld
); // Feld auf neuen Typ umhaengen
1961 ((SwDBField
*)pFld
)->ClearInitialized();
1962 ((SwDBField
*)pFld
)->InitContent();
1968 case RES_DBSETNUMBERFLD
:
1970 if( IsNameInArray( rOldNames
,
1971 lcl_DBDataToString(((SwDBNameInfField
*)pFld
)->GetRealDBData())))
1973 ((SwDBNameInfField
*)pFld
)->SetDBData(aNewDBData
);
1978 case RES_DBNUMSETFLD
:
1979 case RES_DBNEXTSETFLD
:
1980 if( IsNameInArray( rOldNames
,
1981 lcl_DBDataToString(((SwDBNameInfField
*)pFld
)->GetRealDBData())))
1983 ((SwDBNameInfField
*)pFld
)->SetDBData(aNewDBData
);
1987 case RES_HIDDENTXTFLD
:
1988 case RES_HIDDENPARAFLD
:
1989 sFormel
= pFld
->GetPar1();
1990 ReplaceUsedDBs( rOldNames
, rNewName
, sFormel
);
1991 pFld
->SetPar1( sFormel
);
1998 sFormel
= pFld
->GetFormula();
1999 ReplaceUsedDBs( rOldNames
, rNewName
, sFormel
);
2000 pFld
->SetPar2( sFormel
);
2006 pTxtFld
->ExpandAlways();
2011 /*--------------------------------------------------------------------
2013 --------------------------------------------------------------------*/
2015 void SwDoc::ReplaceUsedDBs( const SvStringsDtor
& rUsedDBNames
,
2016 const String
& rNewName
, String
& rFormel
)
2018 const CharClass
& rCC
= GetAppCharClass();
2019 String
sFormel(rFormel
);
2020 String
sNewName( rNewName
);
2021 sNewName
.SearchAndReplace( DB_DELIM
, '.');
2022 //the command type is not part of the condition
2023 sNewName
= sNewName
.GetToken(0, DB_DELIM
);
2024 String
sUpperNewNm( sNewName
);
2027 for( USHORT i
= 0; i
< rUsedDBNames
.Count(); ++i
)
2029 String
sDBName( *rUsedDBNames
.GetObject( i
) );
2031 sDBName
.SearchAndReplace( DB_DELIM
, '.');
2032 //cut off command type
2033 sDBName
= sDBName
.GetToken(0, DB_DELIM
);
2034 if( !sDBName
.Equals( sUpperNewNm
))
2036 xub_StrLen nPos
= 0;
2038 while ((nPos
= sFormel
.Search(sDBName
, nPos
)) != STRING_NOTFOUND
)
2040 if( sFormel
.GetChar( nPos
+ sDBName
.Len() ) == '.' &&
2041 (!nPos
|| !rCC
.isLetterNumeric( sFormel
, nPos
- 1 )))
2043 rFormel
.Erase( nPos
, sDBName
.Len() );
2044 rFormel
.Insert( sNewName
, nPos
);
2045 //prevent re-searching - this is useless and provokes
2046 //endless loops when names containing each other and numbers are exchanged
2047 //e.g.: old ?12345.12345 new: i12345.12345
2048 nPos
= nPos
+ sNewName
.Len();
2056 /*--------------------------------------------------------------------
2058 --------------------------------------------------------------------*/
2060 BOOL
SwDoc::IsNameInArray( const SvStringsDtor
& rArr
, const String
& rName
)
2063 for( USHORT i
= 0; i
< rArr
.Count(); ++i
)
2064 if( rName
== *rArr
[ i
] )
2067 const ::utl::TransliterationWrapper
& rSCmp
= GetAppCmpStrIgnore();
2068 for( USHORT i
= 0; i
< rArr
.Count(); ++i
)
2069 if( rSCmp
.isEqual( rName
, *rArr
[ i
] ))
2075 void SwDoc::SetFixFields( bool bOnlyTimeDate
, const DateTime
* pNewDateTime
)
2077 BOOL bIsModified
= IsModified();
2082 nDate
= pNewDateTime
->GetDate();
2083 nTime
= pNewDateTime
->GetTime();
2087 nDate
= Date().GetDate();
2088 nTime
= Time().GetTime();
2091 USHORT aTypes
[5] = {
2092 /*0*/ RES_DOCINFOFLD
,
2093 /*1*/ RES_AUTHORFLD
,
2094 /*2*/ RES_EXTUSERFLD
,
2095 /*3*/ RES_FILENAMEFLD
,
2096 /*4*/ RES_DATETIMEFLD
}; // MUSS am Ende stehen!!
2098 USHORT nStt
= bOnlyTimeDate
? 4 : 0;
2100 for( ; nStt
< 5; ++nStt
)
2102 SwFieldType
* pFldType
= GetSysFldType( aTypes
[ nStt
] );
2103 SwClientIter
aDocInfIter( *pFldType
);
2105 for( SwFmtFld
* pFld
= (SwFmtFld
*)aDocInfIter
.First( TYPE( SwFmtFld
));
2106 pFld
; pFld
= (SwFmtFld
*)aDocInfIter
.Next() )
2108 if( pFld
&& pFld
->GetTxtFld() )
2111 switch( aTypes
[ nStt
] )
2113 case RES_DOCINFOFLD
:
2114 if( ((SwDocInfoField
*)pFld
->GetFld())->IsFixed() )
2117 SwDocInfoField
* pDocInfFld
= (SwDocInfoField
*)pFld
->GetFld();
2118 pDocInfFld
->SetExpansion( ((SwDocInfoFieldType
*)
2119 pDocInfFld
->GetTyp())->Expand(
2120 pDocInfFld
->GetSubType(),
2121 pDocInfFld
->GetFormat(),
2122 pDocInfFld
->GetLanguage(),
2123 pDocInfFld
->GetName() ) );
2128 if( ((SwAuthorField
*)pFld
->GetFld())->IsFixed() )
2131 SwAuthorField
* pAuthorFld
= (SwAuthorField
*)pFld
->GetFld();
2132 pAuthorFld
->SetExpansion( ((SwAuthorFieldType
*)
2133 pAuthorFld
->GetTyp())->Expand(
2134 pAuthorFld
->GetFormat() ) );
2138 case RES_EXTUSERFLD
:
2139 if( ((SwExtUserField
*)pFld
->GetFld())->IsFixed() )
2142 SwExtUserField
* pExtUserFld
= (SwExtUserField
*)pFld
->GetFld();
2143 pExtUserFld
->SetExpansion( ((SwExtUserFieldType
*)
2144 pExtUserFld
->GetTyp())->Expand(
2145 pExtUserFld
->GetSubType(),
2146 pExtUserFld
->GetFormat()));
2150 case RES_DATETIMEFLD
:
2151 if( ((SwDateTimeField
*)pFld
->GetFld())->IsFixed() )
2154 ((SwDateTimeField
*)pFld
->GetFld())->SetDateTime(
2155 DateTime(Date(nDate
), Time(nTime
)) );
2159 case RES_FILENAMEFLD
:
2160 if( ((SwFileNameField
*)pFld
->GetFld())->IsFixed() )
2163 SwFileNameField
* pFileNameFld
=
2164 (SwFileNameField
*)pFld
->GetFld();
2165 pFileNameFld
->SetExpansion( ((SwFileNameFieldType
*)
2166 pFileNameFld
->GetTyp())->Expand(
2167 pFileNameFld
->GetFormat() ) );
2172 // Formatierung anstossen
2174 pFld
->Modify( 0, 0 );
2183 bool SwDoc::SetFieldsDirty( bool b
, const SwNode
* pChk
, ULONG nLen
)
2185 // teste ggfs. mal, ob die angegbenen Nodes ueberhaupt Felder beinhalten.
2186 // wenn nicht, braucht das Flag nicht veraendert werden.
2187 BOOL bFldsFnd
= FALSE
;
2188 if( b
&& pChk
&& !GetUpdtFlds().IsFieldsDirty() && !IsInDtor()
2189 // ?? was ist mit Undo, da will man es doch auch haben !!
2190 /*&& &pChk->GetNodes() == &GetNodes()*/ )
2195 ULONG nStt
= pChk
->GetIndex();
2196 const SwNodes
& rNds
= pChk
->GetNodes();
2199 const SwTxtNode
* pTNd
= rNds
[ nStt
++ ]->GetTxtNode();
2202 if( //pTNd->GetFmtColl() && //#outline level,zhaojianwei
2203 // MAXLEVEL > pTNd->GetTxtColl()->GetOutlineLevel() )
2204 pTNd
->GetAttrOutlineLevel() != 0 )//<-end,zhaojianwei
2205 // Kapitelfelder aktualisieren
2207 else if( pTNd
->GetpSwpHints() && pTNd
->GetSwpHints().Count() )
2208 for( USHORT n
= 0, nEnd
= pTNd
->GetSwpHints().Count();
2211 const SwTxtAttr
* pAttr
= pTNd
->GetSwpHints()[ n
];
2212 if( RES_TXTATR_FIELD
== pAttr
->Which() )
2225 GetUpdtFlds().SetFieldsDirty( b
);
2228 /* -----------------------------21.12.99 12:55--------------------------------
2230 ---------------------------------------------------------------------------*/
2231 void SwDoc::ChangeAuthorityData( const SwAuthEntry
* pNewData
)
2233 const USHORT nSize
= pFldTypes
->Count();
2235 for( USHORT i
= INIT_FLDTYPES
; i
< nSize
; ++i
)
2237 SwFieldType
* pFldType
= (*pFldTypes
)[i
];
2238 if( RES_AUTHORITY
== pFldType
->Which() )
2240 SwAuthorityFieldType
* pAuthType
= (SwAuthorityFieldType
*)pFldType
;
2241 pAuthType
->ChangeEntryContent(pNewData
);
2247 /*--------------------------------------------------------------------
2249 --------------------------------------------------------------------*/
2251 void SwDocUpdtFld::InsDelFldInFldLst( BOOL bIns
, const SwTxtFld
& rFld
)
2253 USHORT nWhich
= rFld
.GetFld().GetFld()->GetTyp()->Which();
2258 case RES_HIDDENPARAFLD
:
2259 case RES_HIDDENTXTFLD
:
2260 case RES_DBNUMSETFLD
:
2261 case RES_DBNEXTSETFLD
:
2262 case RES_DBSETNUMBERFLD
:
2264 break; // diese muessen ein-/ausgetragen werden!
2270 SetFieldsDirty( TRUE
);
2273 if( !bIns
) // keine Liste vorhanden und loeschen
2274 return; // dann nichts tun
2275 pFldSortLst
= new _SetGetExpFlds( 64, 16 );
2278 if( bIns
) // neu einfuegen:
2279 GetBodyNode( rFld
, nWhich
);
2282 // ueber den pTxtFld Pointer suchen. Ist zwar eine Sortierte
2283 // Liste, aber nach Node-Positionen sortiert. Bis dieser
2284 // bestimmt ist, ist das Suchen nach dem Pointer schon fertig
2285 for( USHORT n
= 0; n
< pFldSortLst
->Count(); ++n
)
2286 if( &rFld
== (*pFldSortLst
)[ n
]->GetPointer() )
2287 pFldSortLst
->DeleteAndDestroy( n
--, 1 );
2288 // ein Feld kann mehrfach vorhanden sein!
2292 void SwDocUpdtFld::MakeFldList( SwDoc
& rDoc
, int bAll
, int eGetMode
)
2294 if( !pFldSortLst
|| bAll
|| !( eGetMode
& nFldLstGetMode
) ||
2295 rDoc
.GetNodes().Count() != nNodes
)
2296 _MakeFldList( rDoc
, eGetMode
);
2299 void SwDocUpdtFld::_MakeFldList( SwDoc
& rDoc
, int eGetMode
)
2301 // neue Version: gehe ueber alle Felder vom Attribut-Pool
2304 pFldSortLst
= new _SetGetExpFlds( 64, 16 );
2306 /// OD 09.08.2002 [#101207#,#101216#,#101778#] - consider and unhide sections
2307 /// with hide condition, only in mode GETFLD_ALL (<eGetMode == GETFLD_ALL>)
2309 /// eGetMode == GETFLD_CALC in call from methods SwDoc::FldsToCalc
2310 /// eGetMode == GETFLD_EXPAND in call from method SwDoc::FldsToExpand
2311 /// eGetMode == GETFLD_ALL in call from method SwDoc::UpdateExpFlds
2312 /// I figured out that hidden section only have to be shown,
2313 /// if fields have updated (call by SwDoc::UpdateExpFlds) and thus
2314 /// the hide conditions of section have to be updated.
2315 /// For correct updating the hide condition of a section, its position
2316 /// have to be known in order to insert the hide condition as a new
2317 /// expression field into the sorted field list (<pFldSortLst>).
2318 if ( eGetMode
== GETFLD_ALL
)
2319 // zuerst die Bereiche einsammeln. Alle die ueber Bedingung
2320 // gehiddet sind, wieder mit Frames versorgen, damit die darin
2321 // enthaltenen Felder richtig einsortiert werden!!!
2323 // damit die Frames richtig angelegt werden, muessen sie in der
2324 // Reihenfolgen von oben nach unten expandiert werden
2326 SwSectionFmts
& rArr
= rDoc
.GetSections();
2327 SwSectionNode
* pSectNd
;
2329 ULONG nSttCntnt
= rDoc
.GetNodes().GetEndOfExtras().GetIndex();
2332 for( n
= rArr
.Count(); n
; )
2334 SwSection
* pSect
= rArr
[ --n
]->GetSection();
2335 if( pSect
&& pSect
->IsHidden() && pSect
->GetCondition().Len() &&
2336 0 != ( pSectNd
= pSect
->GetFmt()->GetSectionNode() ))
2338 ULONG nIdx
= pSectNd
->GetIndex();
2341 for( i
= 0; i
< aTmpArr
.Count() && aTmpArr
[ i
] < nIdx
; ++i
)
2343 aTmpArr
.Insert( nIdx
, i
);
2344 if( nIdx
< nSttCntnt
)
2349 // erst alle anzeigen, damit die Frames vorhanden sind. Mit deren
2350 // Position wird das BodyAnchor ermittelt.
2351 // Dafuer erst den ContentBereich, dann die Sonderbereiche!!!
2352 for( n
= nArrStt
; n
< aTmpArr
.Count(); ++n
)
2354 pSectNd
= rDoc
.GetNodes()[ aTmpArr
[ n
] ]->GetSectionNode();
2355 ASSERT( pSectNd
, "Wo ist mein SectionNode" );
2356 pSectNd
->GetSection().SetCondHidden( FALSE
);
2358 for( n
= 0; n
< nArrStt
; ++n
)
2360 pSectNd
= rDoc
.GetNodes()[ aTmpArr
[ n
] ]->GetSectionNode();
2361 ASSERT( pSectNd
, "Wo ist mein SectionNode" );
2362 pSectNd
->GetSection().SetCondHidden( FALSE
);
2365 // so, erst jetzt alle sortiert in die Liste eintragen
2366 for( n
= 0; n
< aTmpArr
.Count(); ++n
)
2367 GetBodyNode( *rDoc
.GetNodes()[ aTmpArr
[ n
] ]->GetSectionNode() );
2370 String
sTrue( String::CreateFromAscii(
2371 RTL_CONSTASCII_STRINGPARAM( "TRUE" ))),
2372 sFalse( String::CreateFromAscii(
2373 RTL_CONSTASCII_STRINGPARAM( "FALSE" )));
2375 BOOL bIsDBMgr
= 0 != rDoc
.GetNewDBMgr();
2377 const String
* pFormel
= 0;
2378 const SfxPoolItem
* pItem
;
2379 USHORT nMaxItems
= rDoc
.GetAttrPool().GetItemCount( RES_TXTATR_FIELD
);
2380 for( n
= 0; n
< nMaxItems
; ++n
)
2382 if( 0 == (pItem
= rDoc
.GetAttrPool().GetItem( RES_TXTATR_FIELD
, n
)) )
2385 const SwFmtFld
* pFmtFld
= (SwFmtFld
*)pItem
;
2386 const SwTxtFld
* pTxtFld
= pFmtFld
->GetTxtFld();
2387 if( !pTxtFld
|| !pTxtFld
->GetTxtNode().GetNodes().IsDocNodes() )
2390 const SwField
* pFld
= pFmtFld
->GetFld();
2391 switch( nWhich
= pFld
->GetTyp()->Which() )
2393 case RES_DBSETNUMBERFLD
:
2395 if( GETFLD_ALL
== eGetMode
)
2400 if( GETFLD_EXPAND
& eGetMode
)
2405 /// OD 04.10.2002 #102894#
2406 /// fields of subtype <string> have also been add
2407 /// for calculation (eGetMode == GETFLD_CALC).
2408 /// Thus, add fields of subtype <string> in all modes
2409 /// (eGetMode == GETFLD_EXPAND||GETFLD_CALC||GETFLD_ALL)
2410 /// and fields of other subtypes only in the modes
2411 /// (eGetMode == GETFLD_CALC||GETFLD_ALL)
2412 /* "old" if construct - not deleted for history and code review
2413 if( ( nsSwGetSetExpType::GSE_STRING & pFld->GetSubType()
2414 ? GETFLD_EXPAND : GETFLD_CALC )
2417 if ( !(eGetMode
== GETFLD_EXPAND
) ||
2418 (nsSwGetSetExpType::GSE_STRING
& pFld
->GetSubType()) )
2424 case RES_HIDDENPARAFLD
:
2425 if( GETFLD_ALL
== eGetMode
)
2427 pFormel
= &pFld
->GetPar1();
2428 if( !pFormel
->Len() || pFormel
->Equals( sFalse
))
2429 ((SwHiddenParaField
*)pFld
)->SetHidden( FALSE
);
2430 else if( pFormel
->Equals( sTrue
))
2431 ((SwHiddenParaField
*)pFld
)->SetHidden( TRUE
);
2436 // Formatierung anstossen
2437 ((SwFmtFld
*)pFmtFld
)->Modify( 0, 0 );
2441 case RES_HIDDENTXTFLD
:
2442 if( GETFLD_ALL
== eGetMode
)
2444 pFormel
= &pFld
->GetPar1();
2445 if( !pFormel
->Len() || pFormel
->Equals( sFalse
))
2446 ((SwHiddenTxtField
*)pFld
)->SetValue( TRUE
);
2447 else if( pFormel
->Equals( sTrue
))
2448 ((SwHiddenTxtField
*)pFld
)->SetValue( FALSE
);
2455 ((SwHiddenTxtField
*)pFld
)->Evaluate(&rDoc
);
2456 // Formatierung anstossen
2457 ((SwFmtFld
*)pFmtFld
)->Modify( 0, 0 );
2461 case RES_DBNUMSETFLD
:
2463 SwDBData
aDBData(((SwDBNumSetField
*)pFld
)->GetDBData(&rDoc
));
2466 rDoc
.GetNewDBMgr()->OpenDataSource( aDBData
.sDataSource
, aDBData
.sCommand
)&&
2467 GETFLD_ALL
== eGetMode
||
2468 ( GETFLD_CALC
& eGetMode
&&
2469 ((SwDBNumSetField
*)pFld
)->IsCondValid()))
2470 pFormel
= &pFld
->GetPar1();
2473 case RES_DBNEXTSETFLD
:
2475 SwDBData
aDBData(((SwDBNextSetField
*)pFld
)->GetDBData(&rDoc
));
2478 rDoc
.GetNewDBMgr()->OpenDataSource( aDBData
.sDataSource
, aDBData
.sCommand
)&&
2479 GETFLD_ALL
== eGetMode
||
2480 ( GETFLD_CALC
& eGetMode
&&
2481 ((SwDBNextSetField
*)pFld
)->IsCondValid() ))
2482 pFormel
= &pFld
->GetPar1();
2487 if( pFormel
&& pFormel
->Len() )
2489 GetBodyNode( *pTxtFld
, nWhich
);
2493 nFldLstGetMode
= static_cast<BYTE
>( eGetMode
);
2494 nNodes
= rDoc
.GetNodes().Count();
2498 SvFileStream
sOut( "f:\\x.x", STREAM_STD_WRITE
);
2499 sOut
.Seek( STREAM_SEEK_TO_END
);
2500 sOut
<< "------------------" << endl
;
2501 const _SetGetExpFldPtr
* pSortLst
= pFldSortLst
->GetData();
2502 for( USHORT n
= pFldSortLst
->Count(); n
; --n
, ++pSortLst
)
2504 String
sStr( (*pSortLst
)->GetNode() );
2506 sStr
+= (*pSortLst
)->GetCntnt();
2508 sStr
+= (*pSortLst
)->GetFld()->GetTxtNode().StartOfSectionIndex();
2510 sStr
+= *(*pSortLst
)->GetFld()->GetStart();
2512 sStr
+= (*pSortLst
)->GetFld()->GetFld().GetFld()->GetTyp()->Which();
2514 sOut
<< sStr
.GetStr() << endl
;
2521 /*--------------------------------------------------------------------
2523 --------------------------------------------------------------------*/
2525 void SwDocUpdtFld::GetBodyNode( const SwTxtFld
& rTFld
, USHORT nFldWhich
)
2527 const SwTxtNode
& rTxtNd
= rTFld
.GetTxtNode();
2528 const SwDoc
& rDoc
= *rTxtNd
.GetDoc();
2530 // immer den ersten !! (in Tab-Headline, Kopf-/Fuss )
2532 const SwCntntFrm
* pFrm
= rTxtNd
.GetFrm( &aPt
, 0, FALSE
);
2534 _SetGetExpFld
* pNew
= NULL
;
2535 BOOL bIsInBody
= FALSE
;
2537 if( !pFrm
|| pFrm
->IsInDocBody() )
2539 // einen Index fuers bestimmen vom TextNode anlegen
2540 SwNodeIndex
aIdx( rTxtNd
);
2541 bIsInBody
= rDoc
.GetNodes().GetEndOfExtras().GetIndex() < aIdx
.GetIndex();
2543 // #104291# dvo: We don't want to update fields in redlines, or those
2544 // in frames whose anchor is in redline. However, we do want to update
2545 // fields in hidden sections. So: In order to be updated, a field 1)
2546 // must have a frame, or 2) it must be in the document body.
2547 if( (pFrm
!= NULL
) || bIsInBody
)
2548 pNew
= new _SetGetExpFld( aIdx
, &rTFld
);
2552 // einen Index fuers bestimmen vom TextNode anlegen
2553 SwPosition
aPos( rDoc
.GetNodes().GetEndOfPostIts() );
2555 ASSERT( GetBodyTxtNode( rDoc
, aPos
, *pFrm
), "wo steht das Feld" );
2557 GetBodyTxtNode( rDoc
, aPos
, *pFrm
);
2559 pNew
= new _SetGetExpFld( aPos
.nNode
, &rTFld
, &aPos
.nContent
);
2562 // bei GetExp.-/DB.-Felder immer das BodyTxtFlag setzen
2563 if( RES_GETEXPFLD
== nFldWhich
)
2565 SwGetExpField
* pGetFld
= (SwGetExpField
*)rTFld
.GetFld().GetFld();
2566 pGetFld
->ChgBodyTxtFlag( bIsInBody
);
2568 else if( RES_DBFLD
== nFldWhich
)
2570 SwDBField
* pDBFld
= (SwDBField
*)rTFld
.GetFld().GetFld();
2571 pDBFld
->ChgBodyTxtFlag( bIsInBody
);
2575 if( !pFldSortLst
->Insert( pNew
))
2579 void SwDocUpdtFld::GetBodyNode( const SwSectionNode
& rSectNd
)
2581 const SwDoc
& rDoc
= *rSectNd
.GetDoc();
2582 _SetGetExpFld
* pNew
= 0;
2584 if( rSectNd
.GetIndex() < rDoc
.GetNodes().GetEndOfExtras().GetIndex() )
2586 do { // middle check loop
2588 // dann muessen wir uns mal den Anker besorgen!
2589 // einen Index fuers bestimmen vom TextNode anlegen
2590 SwPosition
aPos( rSectNd
);
2591 SwCntntNode
* pCNd
= rDoc
.GetNodes().GoNext( &aPos
.nNode
); // zum naechsten ContentNode
2593 if( !pCNd
|| !pCNd
->IsTxtNode() )
2596 // immer den ersten !! (in Tab-Headline, Kopf-/Fuss )
2598 const SwCntntFrm
* pFrm
= pCNd
->GetFrm( &aPt
, 0, FALSE
);
2603 ASSERT( GetBodyTxtNode( rDoc
, aPos
, *pFrm
), "wo steht das Feld" );
2605 GetBodyTxtNode( rDoc
, aPos
, *pFrm
);
2607 pNew
= new _SetGetExpFld( rSectNd
, &aPos
);
2613 pNew
= new _SetGetExpFld( rSectNd
);
2615 if( !pFldSortLst
->Insert( pNew
))
2619 void SwDocUpdtFld::InsertFldType( const SwFieldType
& rType
)
2622 switch( rType
.Which() )
2625 sFldName
= ((SwUserFieldType
&)rType
).GetName();
2628 sFldName
= ((SwSetExpFieldType
&)rType
).GetName();
2631 ASSERT( !this, "kein gueltiger FeldTyp" );
2634 if( sFldName
.Len() )
2636 SetFieldsDirty( TRUE
);
2637 // suchen und aus der HashTabelle entfernen
2638 GetAppCharClass().toLower( sFldName
);
2641 SwHash
* pFnd
= Find( sFldName
, GetFldTypeTable(), TBLSZ
, &n
);
2645 SwCalcFldType
* pNew
= new SwCalcFldType( sFldName
, &rType
);
2646 pNew
->pNext
= aFldTypeTable
[ n
];
2647 aFldTypeTable
[ n
] = pNew
;
2652 void SwDocUpdtFld::RemoveFldType( const SwFieldType
& rType
)
2655 switch( rType
.Which() )
2658 sFldName
= ((SwUserFieldType
&)rType
).GetName();
2661 sFldName
= ((SwSetExpFieldType
&)rType
).GetName();
2665 if( sFldName
.Len() )
2667 SetFieldsDirty( TRUE
);
2668 // suchen und aus der HashTabelle entfernen
2669 GetAppCharClass().toLower( sFldName
);
2672 SwHash
* pFnd
= Find( sFldName
, GetFldTypeTable(), TBLSZ
, &n
);
2675 if( aFldTypeTable
[ n
] == pFnd
)
2676 aFldTypeTable
[ n
] = (SwCalcFldType
*)pFnd
->pNext
;
2679 SwHash
* pPrev
= aFldTypeTable
[ n
];
2680 while( pPrev
->pNext
!= pFnd
)
2681 pPrev
= pPrev
->pNext
;
2682 pPrev
->pNext
= pFnd
->pNext
;
2690 SwDocUpdtFld::SwDocUpdtFld()
2691 : pFldSortLst(0), nFldUpdtPos(LONG_MAX
), nFldLstGetMode(0)
2693 bInUpdateFlds
= bFldsDirty
= FALSE
;
2694 memset( aFldTypeTable
, 0, sizeof( aFldTypeTable
) );
2697 SwDocUpdtFld::~SwDocUpdtFld()
2701 for( USHORT n
= 0; n
< TBLSZ
; ++n
)
2702 delete aFldTypeTable
[n
];
2706 bool SwDoc::UpdateFld(SwTxtFld
* pDstTxtFld
, SwField
& rSrcFld
,
2707 SwMsgPoolItem
* pMsgHnt
,
2710 ASSERT(pDstTxtFld
, "no field to update!");
2712 BOOL bTblSelBreak
= FALSE
;
2714 SwFmtFld
* pDstFmtFld
= (SwFmtFld
*)&pDstTxtFld
->GetFld();
2715 SwField
* pDstFld
= pDstFmtFld
->GetFld();
2716 USHORT nFldWhich
= rSrcFld
.GetTyp()->Which();
2717 SwNodeIndex
aTblNdIdx(pDstTxtFld
->GetTxtNode());
2719 if (pDstFld
->GetTyp()->Which() ==
2720 rSrcFld
.GetTyp()->Which())
2724 SwPosition
aPosition( pDstTxtFld
->GetTxtNode() );
2725 aPosition
.nContent
= *pDstTxtFld
->GetStart();
2727 AppendUndo(new SwUndoFieldFromDoc(aPosition
, *pDstFld
, rSrcFld
,
2728 pMsgHnt
, bUpdateFlds
));
2731 // Das gefundene Feld wird angepasst ...
2732 //pDstFld->ChangeFormat( rSrcFld.GetFormat() );
2733 //pDstFld->SetLanguage( rSrcFld.GetLanguage() );
2735 SwField
* pNewFld
= rSrcFld
.Copy();
2736 pDstFmtFld
->SetFld(pNewFld
);
2742 case RES_HIDDENTXTFLD
:
2743 case RES_HIDDENPARAFLD
:
2744 UpdateExpFlds( pDstTxtFld
, true );
2749 const SwTableNode
* pTblNd
=
2750 IsIdxInTbl(aTblNdIdx
);
2753 SwTableFmlUpdate
aTblUpdate( &pTblNd
->
2756 UpdateTblFlds( &aTblUpdate
);
2758 pNewFld
->GetTyp()->Modify(0, &aTblUpdate
);
2761 bTblSelBreak
= TRUE
;
2767 if( bUpdateFlds
&& pDstTxtFld
->GetpTxtNode() )
2768 (pDstTxtFld
->GetpTxtNode())->
2769 Modify( 0, pDstFmtFld
);
2773 case RES_DBNEXTSETFLD
:
2774 case RES_DBNUMSETFLD
:
2775 case RES_DBSETNUMBERFLD
:
2776 ChgDBData(((SwDBNameInfField
*) pNewFld
)->GetRealDBData());
2777 pNewFld
->GetTyp()->UpdateFlds();
2783 // JP 10.02.96: ChgValue aufrufen, damit
2784 //die Format- aenderung den ContentString
2786 SwDBField
* pDBFld
= (SwDBField
*)pNewFld
;
2787 if (pDBFld
->IsInitialized())
2788 pDBFld
->ChgValue( pDBFld
->GetValue(), TRUE
);
2790 pDBFld
->ClearInitialized();
2791 pDBFld
->InitContent();
2796 pDstFmtFld
->Modify( 0, pMsgHnt
);
2799 // Die Felder die wir berechnen koennen werden hier expli.
2800 // zum Update angestossen.
2801 if( nFldWhich
== RES_USERFLD
)
2805 return bTblSelBreak
;
2808 bool SwDoc::PutValueToField(const SwPosition
& rPos
,
2809 const Any
& rVal
, USHORT nWhich
)
2812 SwField
* pField
= GetField(rPos
);
2815 if (DoesUndo() && pField
->QueryValue(aOldVal
, nWhich
))
2816 AppendUndo(new SwUndoFieldFromAPI(rPos
, aOldVal
, rVal
, nWhich
));
2818 return pField
->PutValue(rVal
, nWhich
);