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: atrfld.cxx,v $
10 * $Revision: 1.16.190.1 $
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"
34 #include "fldbas.hxx" // fuer FieldType
37 #include <docufld.hxx>
43 #include "swfont.hxx" // fuer GetFldsColor
44 #include "ndtxt.hxx" // SwTxtNode
45 #include "calc.hxx" // Update fuer UserFields
47 #include <IDocumentFieldsAccess.hxx>
49 #include <svtools/smplhint.hxx>
51 TYPEINIT3( SwFmtFld
, SfxPoolItem
, SwClient
,SfxBroadcaster
)
52 TYPEINIT1(SwFmtFldHint
, SfxHint
);
54 /****************************************************************************
58 ****************************************************************************/
60 // Konstruktor fuers Default vom Attribut-Pool
62 : SfxPoolItem( RES_TXTATR_FIELD
),
69 SwFmtFld::SwFmtFld( const SwField
&rFld
)
70 : SfxPoolItem( RES_TXTATR_FIELD
),
71 SwClient( rFld
.GetTyp() ),
78 // Since Items are used in ItemPool and in default constructed ItemSets with
79 // full pool range, all items need to be clonable. Thus, this one needed to be
81 SwFmtFld::SwFmtFld( const SwFmtFld
& rAttr
)
82 : SfxPoolItem( RES_TXTATR_FIELD
), SwClient(), SfxBroadcaster(),
88 rAttr
.GetFld()->GetTyp()->Add(this);
89 pField
= rAttr
.GetFld()->Copy();
95 SwFieldType
* pType
= pField
? pField
->GetTyp() : 0;
97 if (pType
&& pType
->Which() == RES_DBFLD
)
98 pType
= 0; // DB-Feldtypen zerstoeren sich selbst
100 Broadcast( SwFmtFldHint( this, SWFMTFLD_REMOVED
) );
103 // bei einige FeldTypen muessen wir den FeldTypen noch loeschen
104 if( pType
&& pType
->IsLastDepend() )
107 switch( pType
->Which() )
110 bDel
= ((SwUserFieldType
*)pType
)->IsDeleted();
114 bDel
= ((SwSetExpFieldType
*)pType
)->IsDeleted();
118 bDel
= ((SwDDEFieldType
*)pType
)->IsDeleted();
124 // vorm loeschen erstmal austragen
125 pType
->Remove( this );
132 void SwFmtFld::SetFld(SwField
* _pField
)
138 Broadcast( SwFmtFldHint( this, SWFMTFLD_CHANGED
) );
141 int SwFmtFld::operator==( const SfxPoolItem
& rAttr
) const
143 ASSERT( SfxPoolItem::operator==( rAttr
), "keine gleichen Attribute" );
144 // OD 2004-05-14 #i29146# - correction: check, if <pField> and
145 // <((SwFmtFld&)rAttr).GetFld()> are set.
146 // OD 2004-05-14 #i29146# - items are equal, if both fields aren't set.
147 return ( pField
&& ((SwFmtFld
&)rAttr
).GetFld() &&
148 pField
->GetTyp() == ((SwFmtFld
&)rAttr
).GetFld()->GetTyp() &&
149 pField
->GetFormat() == ((SwFmtFld
&)rAttr
).GetFld()->GetFormat() ) ||
150 ( !pField
&& !((SwFmtFld
&)rAttr
).GetFld() );
153 SfxPoolItem
* SwFmtFld::Clone( SfxItemPool
* ) const
155 return new SwFmtFld( *this );
158 void SwFmtFld::Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
)
163 SwTxtNode
* pTxtNd
= (SwTxtNode
*)&pTxtAttr
->GetTxtNode();
164 ASSERT( pTxtNd
, "wo ist denn mein Node?" );
167 switch( pNew
->Which() )
169 case RES_OBJECTDYING
:
170 return; // don't do anything, especially not expand!
171 case RES_TXTATR_FLDCHG
:
172 // "Farbe hat sich geaendert !"
173 // this, this fuer "nur Painten"
174 pTxtNd
->Modify( this, this );
176 case RES_REFMARKFLD_UPDATE
:
177 // GetReferenz-Felder aktualisieren
178 if( RES_GETREFFLD
== GetFld()->GetTyp()->Which() )
180 // --> OD 2007-09-06 #i81002#
181 // ((SwGetRefField*)GetFld())->UpdateField();
182 dynamic_cast<SwGetRefField
*>(GetFld())->UpdateField( pTxtAttr
);
186 case RES_DOCPOS_UPDATE
:
187 // Je nach DocPos aktualisieren (SwTxtFrm::Modify())
188 pTxtNd
->Modify( pNew
, this );
191 case RES_ATTRSET_CHG
:
193 pTxtNd
->Modify( pOld
, pNew
);
198 switch (GetFld()->GetTyp()->Which())
200 case RES_HIDDENPARAFLD
:
201 if( !pOld
|| RES_HIDDENPARA_PRINT
!= pOld
->Which() )
203 case RES_DBSETNUMBERFLD
:
204 case RES_DBNUMSETFLD
:
205 case RES_DBNEXTSETFLD
:
207 pTxtNd
->Modify( 0, pNew
);
211 if( RES_USERFLD
== GetFld()->GetTyp()->Which() )
213 SwUserFieldType
* pType
= (SwUserFieldType
*)GetFld()->GetTyp();
214 if(!pType
->IsValid())
216 SwCalc
aCalc( *pTxtNd
->GetDoc() );
217 pType
->GetValue( aCalc
);
223 BOOL
SwFmtFld::GetInfo( SfxPoolItem
& rInfo
) const
225 const SwTxtNode
* pTxtNd
;
226 if( RES_AUTOFMT_DOCNODE
!= rInfo
.Which() ||
227 !pTxtAttr
|| 0 == ( pTxtNd
= pTxtAttr
->GetpTxtNode() ) ||
228 &pTxtNd
->GetNodes() != ((SwAutoFmtGetDocNode
&)rInfo
).pNodes
)
231 ((SwAutoFmtGetDocNode
&)rInfo
).pCntntNode
= pTxtNd
;
236 BOOL
SwFmtFld::IsFldInDoc() const
238 const SwTxtNode
* pTxtNd
;
239 return pTxtAttr
&& 0 != ( pTxtNd
= pTxtAttr
->GetpTxtNode() ) &&
240 pTxtNd
->GetNodes().IsDocNodes();
243 BOOL
SwFmtFld::IsProtect() const
245 const SwTxtNode
* pTxtNd
;
246 return pTxtAttr
&& 0 != ( pTxtNd
= pTxtAttr
->GetpTxtNode() ) &&
250 /*************************************************************************
252 |* SwTxtFld::SwTxtFld()
254 |* Beschreibung Attribut fuer automatischen Text, Ctor
255 |* Ersterstellung BP 30.04.92
256 |* Letzte Aenderung JP 15.08.94
258 *************************************************************************/
260 SwTxtFld::SwTxtFld( SwFmtFld
& rAttr
, xub_StrLen nStartPos
)
261 : SwTxtAttr( rAttr
, nStartPos
)
262 , m_aExpand( rAttr
.GetFld()->Expand() )
265 rAttr
.pTxtAttr
= this;
266 SetHasDummyChar(true);
269 SwTxtFld::~SwTxtFld( )
273 /*************************************************************************
275 |* SwTxtFld::Expand()
277 |* Beschreibung exandiert das Feld und tauscht den Text im Node
278 |* Ersterstellung BP 30.04.92
279 |* Letzte Aenderung JP 15.08.94
281 *************************************************************************/
283 void SwTxtFld::Expand() const
285 // Wenn das expandierte Feld sich nicht veraendert hat, wird returnt
286 ASSERT( m_pTxtNode
, "SwTxtFld: where is my TxtNode?" );
288 const SwField
* pFld
= GetFld().GetFld();
289 XubString
aNewExpand( pFld
->Expand() );
291 if( aNewExpand
== m_aExpand
)
293 // Bei Seitennummernfeldern
294 const USHORT nWhich
= pFld
->GetTyp()->Which();
295 if( RES_CHAPTERFLD
!= nWhich
&& RES_PAGENUMBERFLD
!= nWhich
&&
296 RES_REFPAGEGETFLD
!= nWhich
&&
297 // --> FME 2005-05-23 #122919# Page count fields to not use aExpand
298 // during formatting, therefore an invalidation of the text frame
299 // has to be triggered even if aNewExpand == aExpand:
300 ( RES_DOCSTATFLD
!= nWhich
|| DS_PAGE
!= static_cast<const SwDocStatField
*>(pFld
)->GetSubType() ) &&
302 ( RES_GETEXPFLD
!= nWhich
|| ((SwGetExpField
*)pFld
)->IsInBodyTxt() ) )
304 // BP: das muesste man noch optimieren!
305 //JP 12.06.97: stimmt, man sollte auf jedenfall eine Status-
306 // aenderung an die Frames posten
307 if( m_pTxtNode
->CalcHiddenParaField() )
309 m_pTxtNode
->Modify( 0, 0 );
315 m_aExpand
= aNewExpand
;
317 // 0, this for formatting
318 m_pTxtNode
->Modify( 0, const_cast<SwFmtFld
*>( &GetFld() ) );
321 /*************************************************************************
322 * SwTxtFld::CopyFld()
323 *************************************************************************/
325 void SwTxtFld::CopyFld( SwTxtFld
*pDest
) const
327 ASSERT( m_pTxtNode
, "SwTxtFld: where is my TxtNode?" );
328 ASSERT( pDest
->m_pTxtNode
, "SwTxtFld: where is pDest's TxtNode?" );
330 IDocumentFieldsAccess
* pIDFA
= m_pTxtNode
->getIDocumentFieldsAccess();
331 IDocumentFieldsAccess
* pDestIDFA
= pDest
->m_pTxtNode
->getIDocumentFieldsAccess();
333 SwFmtFld
& rFmtFld
= (SwFmtFld
&)pDest
->GetFld();
334 const USHORT nFldWhich
= rFmtFld
.GetFld()->GetTyp()->Which();
336 if( pIDFA
!= pDestIDFA
)
338 // Die Hints stehen in unterschiedlichen Dokumenten,
339 // der Feldtyp muss im neuen Dokument angemeldet werden.
340 // Z.B: Kopieren ins ClipBoard.
341 SwFieldType
* pFldType
;
342 if( nFldWhich
!= RES_DBFLD
&& nFldWhich
!= RES_USERFLD
&&
343 nFldWhich
!= RES_SETEXPFLD
&& nFldWhich
!= RES_DDEFLD
&&
344 RES_AUTHORITY
!= nFldWhich
)
345 pFldType
= pDestIDFA
->GetSysFldType( nFldWhich
);
347 pFldType
= pDestIDFA
->InsertFldType( *rFmtFld
.GetFld()->GetTyp() );
349 // Sonderbehandlung fuer DDE-Felder
350 if( RES_DDEFLD
== nFldWhich
)
352 if( rFmtFld
.GetTxtFld() )
353 ((SwDDEFieldType
*)rFmtFld
.GetFld()->GetTyp())->DecRefCnt();
354 ((SwDDEFieldType
*)pFldType
)->IncRefCnt();
357 ASSERT( pFldType
, "unbekannter FieldType" );
358 pFldType
->Add( &rFmtFld
); // ummelden
359 rFmtFld
.GetFld()->ChgTyp( pFldType
);
362 // Expressionfelder Updaten
363 if( nFldWhich
== RES_SETEXPFLD
|| nFldWhich
== RES_GETEXPFLD
||
364 nFldWhich
== RES_HIDDENTXTFLD
)
366 SwTxtFld
* pFld
= (SwTxtFld
*)this;
367 pDestIDFA
->UpdateExpFlds( pFld
, true );
369 // Tabellenfelder auf externe Darstellung
370 else if( RES_TABLEFLD
== nFldWhich
&&
371 ((SwTblField
*)rFmtFld
.GetFld())->IsIntrnlName() )
373 // erzeuge aus der internen (fuer CORE) die externe (fuer UI) Formel
374 const SwTableNode
* pTblNd
= m_pTxtNode
->FindTableNode();
375 if( pTblNd
) // steht in einer Tabelle
376 ((SwTblField
*)rFmtFld
.GetFld())->PtrToBoxNm( &pTblNd
->GetTable() );
380 /* -----------------26.06.2003 13:54-----------------
382 --------------------------------------------------*/
383 void SwTxtFld::NotifyContentChange(SwFmtFld
& rFmtFld
)
385 //if not in undo section notify the change
386 if (m_pTxtNode
&& m_pTxtNode
->GetNodes().IsDocNodes())
388 m_pTxtNode
->Modify(0, &rFmtFld
);