merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / txtnode / atrfld.cxx
blob5248100afd7b3e011ae28cb604c1b3210b15f1f2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
35 #include <fmtfld.hxx>
36 #include <txtfld.hxx>
37 #include <docufld.hxx>
39 #include "reffld.hxx"
40 #include "ddefld.hxx"
41 #include "usrfld.hxx"
42 #include "expfld.hxx"
43 #include "swfont.hxx" // fuer GetFldsColor
44 #include "ndtxt.hxx" // SwTxtNode
45 #include "calc.hxx" // Update fuer UserFields
46 #include "hints.hxx"
47 #include <IDocumentFieldsAccess.hxx>
49 #include <svtools/smplhint.hxx>
51 TYPEINIT3( SwFmtFld, SfxPoolItem, SwClient,SfxBroadcaster)
52 TYPEINIT1(SwFmtFldHint, SfxHint);
54 /****************************************************************************
56 * class SwFmtFld
58 ****************************************************************************/
60 // Konstruktor fuers Default vom Attribut-Pool
61 SwFmtFld::SwFmtFld()
62 : SfxPoolItem( RES_TXTATR_FIELD ),
63 SwClient( 0 ),
64 pField( 0 ),
65 pTxtAttr( 0 )
69 SwFmtFld::SwFmtFld( const SwField &rFld )
70 : SfxPoolItem( RES_TXTATR_FIELD ),
71 SwClient( rFld.GetTyp() ),
72 pTxtAttr( 0 )
74 pField = rFld.Copy();
77 // #i24434#
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
80 // corrected
81 SwFmtFld::SwFmtFld( const SwFmtFld& rAttr )
82 : SfxPoolItem( RES_TXTATR_FIELD ), SwClient(), SfxBroadcaster(),
83 pField( 0 ),
84 pTxtAttr( 0 )
86 if(rAttr.GetFld())
88 rAttr.GetFld()->GetTyp()->Add(this);
89 pField = rAttr.GetFld()->Copy();
93 SwFmtFld::~SwFmtFld()
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 ) );
101 delete pField;
103 // bei einige FeldTypen muessen wir den FeldTypen noch loeschen
104 if( pType && pType->IsLastDepend() )
106 BOOL bDel = FALSE;
107 switch( pType->Which() )
109 case RES_USERFLD:
110 bDel = ((SwUserFieldType*)pType)->IsDeleted();
111 break;
113 case RES_SETEXPFLD:
114 bDel = ((SwSetExpFieldType*)pType)->IsDeleted();
115 break;
117 case RES_DDEFLD:
118 bDel = ((SwDDEFieldType*)pType)->IsDeleted();
119 break;
122 if( bDel )
124 // vorm loeschen erstmal austragen
125 pType->Remove( this );
126 delete pType;
131 // #111840#
132 void SwFmtFld::SetFld(SwField * _pField)
134 if (NULL != pField)
135 delete pField;
137 pField = _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 )
160 if( !pTxtAttr )
161 return;
163 SwTxtNode* pTxtNd = (SwTxtNode*)&pTxtAttr->GetTxtNode();
164 ASSERT( pTxtNd, "wo ist denn mein Node?" );
165 if( pNew )
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 );
175 return;
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 );
183 // <--
185 break;
186 case RES_DOCPOS_UPDATE:
187 // Je nach DocPos aktualisieren (SwTxtFrm::Modify())
188 pTxtNd->Modify( pNew, this );
189 return;
191 case RES_ATTRSET_CHG:
192 case RES_FMT_CHG:
193 pTxtNd->Modify( pOld, pNew );
194 return;
198 switch (GetFld()->GetTyp()->Which())
200 case RES_HIDDENPARAFLD:
201 if( !pOld || RES_HIDDENPARA_PRINT != pOld->Which() )
202 break;
203 case RES_DBSETNUMBERFLD:
204 case RES_DBNUMSETFLD:
205 case RES_DBNEXTSETFLD:
206 case RES_DBNAMEFLD:
207 pTxtNd->Modify( 0, pNew);
208 return;
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 );
220 pTxtAttr->Expand();
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 )
229 return TRUE;
231 ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pTxtNd;
232 return FALSE;
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() ) &&
247 pTxtNd->IsProtect();
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() )
263 , m_pTxtNode( 0 )
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() ) &&
301 // <--
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 );
311 return;
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 );
346 else
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);