Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "fldbas.hxx" // fuer FieldType
31 : : #include <fmtfld.hxx>
32 : : #include <txtfld.hxx>
33 : : #include <docufld.hxx>
34 : : #include <doc.hxx>
35 : :
36 : : #include "reffld.hxx"
37 : : #include "ddefld.hxx"
38 : : #include "usrfld.hxx"
39 : : #include "expfld.hxx"
40 : : #include "swfont.hxx" // fuer GetFldsColor
41 : : #include "ndtxt.hxx" // SwTxtNode
42 : : #include "calc.hxx" // Update fuer UserFields
43 : : #include "hints.hxx"
44 : : #include <IDocumentFieldsAccess.hxx>
45 : : #include <fieldhint.hxx>
46 : : #include <svl/smplhint.hxx>
47 : :
48 [ + + ][ - + ]: 33107 : TYPEINIT3( SwFmtFld, SfxPoolItem, SwClient,SfxBroadcaster)
[ + + ][ - + ]
49 [ + + ][ - + ]: 729 : TYPEINIT1(SwFmtFldHint, SfxHint);
50 : :
51 : : /****************************************************************************
52 : : *
53 : : * class SwFmtFld
54 : : *
55 : : ****************************************************************************/
56 : :
57 : : // Konstruktor fuers Default vom Attribut-Pool
58 : 73 : SwFmtFld::SwFmtFld()
59 : : : SfxPoolItem( RES_TXTATR_FIELD ),
60 : : SwClient( 0 ),
61 : : pField( 0 ),
62 [ + - ][ + - ]: 73 : pTxtAttr( 0 )
63 : : {
64 : 73 : }
65 : :
66 : 1593 : SwFmtFld::SwFmtFld( const SwField &rFld )
67 : : : SfxPoolItem( RES_TXTATR_FIELD ),
68 : 1593 : SwClient( rFld.GetTyp() ),
69 [ + - ][ + - ]: 3186 : pTxtAttr( 0 )
70 : : {
71 [ + - ]: 1593 : pField = rFld.CopyField();
72 : 1593 : }
73 : :
74 : : // #i24434#
75 : : // Since Items are used in ItemPool and in default constructed ItemSets with
76 : : // full pool range, all items need to be clonable. Thus, this one needed to be
77 : : // corrected
78 : 4736 : SwFmtFld::SwFmtFld( const SwFmtFld& rAttr )
79 : : : SfxPoolItem( RES_TXTATR_FIELD ), SwClient(), SfxBroadcaster(),
80 : : pField( 0 ),
81 [ + - ]: 4736 : pTxtAttr( 0 )
82 : : {
83 [ + - ]: 4736 : if(rAttr.GetFld())
84 : : {
85 [ + - ]: 4736 : rAttr.GetFld()->GetTyp()->Add(this);
86 [ + - ]: 4736 : pField = rAttr.GetFld()->CopyField();
87 : : }
88 : 4736 : }
89 : :
90 [ + - ][ + - ]: 6395 : SwFmtFld::~SwFmtFld()
91 : : {
92 [ + + ]: 6395 : SwFieldType* pType = pField ? pField->GetTyp() : 0;
93 : :
94 [ + + ][ + + ]: 6395 : if (pType && pType->Which() == RES_DBFLD)
[ + + ]
95 : 38 : pType = 0; // DB-Feldtypen zerstoeren sich selbst
96 : :
97 [ + - ][ + - ]: 6395 : Broadcast( SwFmtFldHint( this, SWFMTFLD_REMOVED ) );
[ + - ]
98 [ + + ][ + - ]: 6395 : delete pField;
99 : :
100 : : // bei einige FeldTypen muessen wir den FeldTypen noch loeschen
101 [ + + ][ + + ]: 6395 : if( pType && pType->IsLastDepend() )
[ + + ]
102 : : {
103 : 71 : sal_Bool bDel = sal_False;
104 [ - + - + ]: 71 : switch( pType->Which() )
105 : : {
106 : : case RES_USERFLD:
107 : 0 : bDel = ((SwUserFieldType*)pType)->IsDeleted();
108 : 0 : break;
109 : :
110 : : case RES_SETEXPFLD:
111 : 3 : bDel = ((SwSetExpFieldType*)pType)->IsDeleted();
112 : 3 : break;
113 : :
114 : : case RES_DDEFLD:
115 : 0 : bDel = ((SwDDEFieldType*)pType)->IsDeleted();
116 : 0 : break;
117 : : }
118 : :
119 [ - + ]: 71 : if( bDel )
120 : : {
121 : : // vorm loeschen erstmal austragen
122 [ # # ]: 0 : pType->Remove( this );
123 [ # # ][ # # ]: 0 : delete pType;
124 : : }
125 : : }
126 [ - + ]: 11241 : }
127 : :
128 : 0 : void SwFmtFld::RegisterToFieldType( SwFieldType& rType )
129 : : {
130 : 0 : rType.Add(this);
131 : 0 : }
132 : :
133 : :
134 : : // #111840#
135 : 0 : void SwFmtFld::SetFld(SwField * _pField)
136 : : {
137 [ # # ]: 0 : delete pField;
138 : :
139 : 0 : pField = _pField;
140 [ # # ]: 0 : Broadcast( SwFmtFldHint( this, SWFMTFLD_CHANGED ) );
141 : 0 : }
142 : :
143 : 0 : int SwFmtFld::operator==( const SfxPoolItem& rAttr ) const
144 : : {
145 : : OSL_ENSURE( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
146 : : // OD 2004-05-14 #i29146# - correction: check, if <pField> and
147 : : // <((SwFmtFld&)rAttr).GetFld()> are set.
148 : : // OD 2004-05-14 #i29146# - items are equal, if both fields aren't set.
149 : 0 : return ( pField && ((SwFmtFld&)rAttr).GetFld() &&
150 : 0 : pField->GetTyp() == ((SwFmtFld&)rAttr).GetFld()->GetTyp() &&
151 : 0 : pField->GetFormat() == ((SwFmtFld&)rAttr).GetFld()->GetFormat() ) ||
152 [ # # # # : 0 : ( !pField && !((SwFmtFld&)rAttr).GetFld() );
# # # # ]
[ # # ][ # # ]
153 : : }
154 : :
155 : 4736 : SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const
156 : : {
157 [ + - ]: 4736 : return new SwFmtFld( *this );
158 : : }
159 : :
160 : 0 : void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint )
161 : : {
162 [ # # ]: 0 : if( !pTxtAttr )
163 : 0 : return;
164 : :
165 [ # # ]: 0 : const SwFieldHint* pHint = dynamic_cast<const SwFieldHint*>( &rHint );
166 [ # # ]: 0 : if ( pHint )
167 : : {
168 : : // replace field content by text
169 : 0 : SwPaM* pPaM = pHint->GetPaM();
170 : 0 : SwDoc* pDoc = pPaM->GetDoc();
171 : 0 : const SwTxtNode& rTxtNode = pTxtAttr->GetTxtNode();
172 [ # # ]: 0 : pPaM->GetPoint()->nNode = rTxtNode;
173 [ # # ]: 0 : pPaM->GetPoint()->nContent.Assign( (SwTxtNode*)&rTxtNode, *pTxtAttr->GetStart() );
174 : :
175 [ # # ]: 0 : String const aEntry( GetFld()->ExpandField( pDoc->IsClipBoard() ) );
176 [ # # ]: 0 : pPaM->SetMark();
177 [ # # ]: 0 : pPaM->Move( fnMoveForward );
178 [ # # ]: 0 : pDoc->DeleteRange( *pPaM );
179 [ # # ][ # # ]: 0 : pDoc->InsertString( *pPaM, aEntry );
180 : : }
181 : : }
182 : :
183 : 276 : void SwFmtFld::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
184 : : {
185 [ + + ]: 276 : if( !pTxtAttr )
186 : 10 : return;
187 : :
188 : : // don't do anything, especially not expand!
189 [ + + ][ - + ]: 266 : if( pNew && pNew->Which() == RES_OBJECTDYING )
[ - + ]
190 : 0 : return;
191 : :
192 : 266 : SwTxtNode* pTxtNd = (SwTxtNode*)&pTxtAttr->GetTxtNode();
193 : : OSL_ENSURE( pTxtNd, "wo ist denn mein Node?" );
194 [ + + ]: 266 : if( pNew )
195 : : {
196 [ - - + + : 22 : switch( pNew->Which() )
- ]
197 : : {
198 : : case RES_TXTATR_FLDCHG:
199 : : // "Farbe hat sich geaendert !"
200 : : // this, this fuer "nur Painten"
201 : 0 : pTxtNd->ModifyNotification( this, this );
202 : 0 : return;
203 : : case RES_REFMARKFLD_UPDATE:
204 : : // GetReferenz-Felder aktualisieren
205 [ # # ]: 0 : if( RES_GETREFFLD == GetFld()->GetTyp()->Which() )
206 : : {
207 : : // #i81002#
208 : : // ((SwGetRefField*)GetFld())->UpdateField();
209 [ # # ]: 0 : dynamic_cast<SwGetRefField*>(GetFld())->UpdateField( pTxtAttr );
210 : : }
211 : 0 : break;
212 : : case RES_DOCPOS_UPDATE:
213 : : // Je nach DocPos aktualisieren (SwTxtFrm::Modify())
214 : 15 : pTxtNd->ModifyNotification( pNew, this );
215 : 15 : return;
216 : :
217 : : case RES_ATTRSET_CHG:
218 : : case RES_FMT_CHG:
219 : 7 : pTxtNd->ModifyNotification( pOld, pNew );
220 : 7 : return;
221 : : default:
222 : 0 : break;
223 : : }
224 : : }
225 : :
226 [ - - + ]: 244 : switch (GetFld()->GetTyp()->Which())
227 : : {
228 : : case RES_HIDDENPARAFLD:
229 [ # # ][ # # ]: 0 : if( !pOld || RES_HIDDENPARA_PRINT != pOld->Which() )
[ # # ]
230 : 0 : break;
231 : : case RES_DBSETNUMBERFLD:
232 : : case RES_DBNUMSETFLD:
233 : : case RES_DBNEXTSETFLD:
234 : : case RES_DBNAMEFLD:
235 : 0 : pTxtNd->ModifyNotification( 0, pNew);
236 : 0 : return;
237 : : }
238 : :
239 [ - + ]: 244 : if( RES_USERFLD == GetFld()->GetTyp()->Which() )
240 : : {
241 : 0 : SwUserFieldType* pType = (SwUserFieldType*)GetFld()->GetTyp();
242 [ # # ]: 0 : if(!pType->IsValid())
243 : : {
244 [ # # ]: 0 : SwCalc aCalc( *pTxtNd->GetDoc() );
245 [ # # ][ # # ]: 0 : pType->GetValue( aCalc );
246 : : }
247 : : }
248 : 276 : pTxtAttr->Expand();
249 : : }
250 : :
251 : 9 : sal_Bool SwFmtFld::GetInfo( SfxPoolItem& rInfo ) const
252 : : {
253 : : const SwTxtNode* pTxtNd;
254 [ + - ][ + - ]: 18 : if( RES_AUTOFMT_DOCNODE != rInfo.Which() ||
[ + - - + ]
[ - + ]
255 : 18 : !pTxtAttr || 0 == ( pTxtNd = pTxtAttr->GetpTxtNode() ) ||
256 : 9 : &pTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes )
257 : 0 : return sal_True;
258 : :
259 : 9 : ((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pTxtNd;
260 : 9 : return sal_False;
261 : : }
262 : :
263 : :
264 : 120 : sal_Bool SwFmtFld::IsFldInDoc() const
265 : : {
266 : : const SwTxtNode* pTxtNd;
267 : 120 : return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
268 [ + - ][ + - ]: 120 : pTxtNd->GetNodes().IsDocNodes();
[ + - ]
269 : : }
270 : :
271 : 0 : sal_Bool SwFmtFld::IsProtect() const
272 : : {
273 : : const SwTxtNode* pTxtNd;
274 : 0 : return pTxtAttr && 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) &&
275 [ # # ][ # # ]: 0 : pTxtNd->IsProtect();
[ # # ]
276 : : }
277 : :
278 : : /*************************************************************************
279 : : |*
280 : : |* SwTxtFld::SwTxtFld()
281 : : |*
282 : : |* Beschreibung Attribut fuer automatischen Text, Ctor
283 : : |*
284 : : *************************************************************************/
285 : :
286 : 1549 : SwTxtFld::SwTxtFld(SwFmtFld & rAttr, xub_StrLen const nStartPos,
287 : : bool const bInClipboard)
288 : : : SwTxtAttr( rAttr, nStartPos )
289 : : // fdo#39694 the ExpandField here may not give the correct result in all cases,
290 : : // but is better than nothing
291 : : , m_aExpand( rAttr.GetFld()->ExpandField(bInClipboard) )
292 [ + - ]: 1549 : , m_pTxtNode( 0 )
293 : : {
294 : 1549 : rAttr.pTxtAttr = this;
295 : 1549 : SetHasDummyChar(true);
296 : 1549 : }
297 : :
298 [ + - ]: 1546 : SwTxtFld::~SwTxtFld( )
299 : : {
300 : 1546 : SwFmtFld & rFmtFld( static_cast<SwFmtFld &>(GetAttr()) );
301 [ + - ]: 1546 : if (this == rFmtFld.pTxtAttr)
302 : : {
303 : 1546 : rFmtFld.pTxtAttr = 0; // #i110140# invalidate!
304 : : }
305 [ - + ]: 3092 : }
306 : :
307 : : /*************************************************************************
308 : : |*
309 : : |* SwTxtFld::Expand()
310 : : |*
311 : : |* Beschreibung exandiert das Feld und tauscht den Text im Node
312 : : |*
313 : : *************************************************************************/
314 : :
315 : 306 : void SwTxtFld::Expand() const
316 : : {
317 : : // Wenn das expandierte Feld sich nicht veraendert hat, wird returnt
318 : : OSL_ENSURE( m_pTxtNode, "SwTxtFld: where is my TxtNode?" );
319 : :
320 : 306 : const SwField* pFld = GetFld().GetFld();
321 : : XubString aNewExpand(
322 [ + - ]: 306 : pFld->ExpandField(m_pTxtNode->GetDoc()->IsClipBoard()) );
323 : :
324 [ + - ][ + + ]: 306 : if( aNewExpand == m_aExpand )
325 : : {
326 : : // Bei Seitennummernfeldern
327 : 268 : const sal_uInt16 nWhich = pFld->GetTyp()->Which();
328 [ + - ][ + - ]: 268 : if( RES_CHAPTERFLD != nWhich && RES_PAGENUMBERFLD != nWhich &&
[ - + ][ # # ]
[ - + # # ]
[ + - ][ + - ]
329 : : RES_REFPAGEGETFLD != nWhich &&
330 : : // #122919# Page count fields to not use aExpand
331 : : // during formatting, therefore an invalidation of the text frame
332 : : // has to be triggered even if aNewExpand == aExpand:
333 [ # # ]: 0 : ( RES_DOCSTATFLD != nWhich || DS_PAGE != static_cast<const SwDocStatField*>(pFld)->GetSubType() ) &&
334 : 0 : ( RES_GETEXPFLD != nWhich || ((SwGetExpField*)pFld)->IsInBodyTxt() ) )
335 : : {
336 : : // BP: das muesste man noch optimieren!
337 : : //JP 12.06.97: stimmt, man sollte auf jedenfall eine Status-
338 : : // aenderung an die Frames posten
339 [ + - ][ - + ]: 268 : if( m_pTxtNode->CalcHiddenParaField() )
340 : : {
341 [ # # ]: 268 : m_pTxtNode->ModifyNotification( 0, 0 );
342 : : }
343 : 306 : return;
344 : : }
345 : : }
346 : :
347 [ + - ]: 38 : m_aExpand = aNewExpand;
348 : :
349 : : // 0, this for formatting
350 [ + - ][ + - ]: 306 : m_pTxtNode->ModifyNotification( 0, const_cast<SwFmtFld*>( &GetFld() ) );
[ + + ]
351 : : }
352 : :
353 : : /*************************************************************************
354 : : * SwTxtFld::CopyFld()
355 : : *************************************************************************/
356 : :
357 : 0 : void SwTxtFld::CopyFld( SwTxtFld *pDest ) const
358 : : {
359 : : OSL_ENSURE( m_pTxtNode, "SwTxtFld: where is my TxtNode?" );
360 : : OSL_ENSURE( pDest->m_pTxtNode, "SwTxtFld: where is pDest's TxtNode?" );
361 : :
362 : 0 : IDocumentFieldsAccess* pIDFA = m_pTxtNode->getIDocumentFieldsAccess();
363 : 0 : IDocumentFieldsAccess* pDestIDFA = pDest->m_pTxtNode->getIDocumentFieldsAccess();
364 : :
365 : 0 : SwFmtFld& rFmtFld = (SwFmtFld&)pDest->GetFld();
366 : 0 : const sal_uInt16 nFldWhich = rFmtFld.GetFld()->GetTyp()->Which();
367 : :
368 [ # # ]: 0 : if( pIDFA != pDestIDFA )
369 : : {
370 : : // Die Hints stehen in unterschiedlichen Dokumenten,
371 : : // der Feldtyp muss im neuen Dokument angemeldet werden.
372 : : // Z.B: Kopieren ins ClipBoard.
373 : : SwFieldType* pFldType;
374 [ # # ][ # # ]: 0 : if( nFldWhich != RES_DBFLD && nFldWhich != RES_USERFLD &&
[ # # ][ # # ]
[ # # ]
375 : : nFldWhich != RES_SETEXPFLD && nFldWhich != RES_DDEFLD &&
376 : : RES_AUTHORITY != nFldWhich )
377 : 0 : pFldType = pDestIDFA->GetSysFldType( nFldWhich );
378 : : else
379 : 0 : pFldType = pDestIDFA->InsertFldType( *rFmtFld.GetFld()->GetTyp() );
380 : :
381 : : // Sonderbehandlung fuer DDE-Felder
382 [ # # ]: 0 : if( RES_DDEFLD == nFldWhich )
383 : : {
384 [ # # ]: 0 : if( rFmtFld.GetTxtFld() )
385 : 0 : ((SwDDEFieldType*)rFmtFld.GetFld()->GetTyp())->DecRefCnt();
386 : 0 : ((SwDDEFieldType*)pFldType)->IncRefCnt();
387 : : }
388 : :
389 : : OSL_ENSURE( pFldType, "unbekannter FieldType" );
390 : 0 : pFldType->Add( &rFmtFld ); // ummelden
391 : 0 : rFmtFld.GetFld()->ChgTyp( pFldType );
392 : : }
393 : :
394 : : // Expressionfelder Updaten
395 [ # # ][ # # ]: 0 : if( nFldWhich == RES_SETEXPFLD || nFldWhich == RES_GETEXPFLD ||
[ # # ]
396 : : nFldWhich == RES_HIDDENTXTFLD )
397 : : {
398 : 0 : SwTxtFld* pFld = (SwTxtFld*)this;
399 : 0 : pDestIDFA->UpdateExpFlds( pFld, true );
400 : : }
401 : : // Tabellenfelder auf externe Darstellung
402 [ # # # # ]: 0 : else if( RES_TABLEFLD == nFldWhich &&
[ # # ]
403 : 0 : ((SwTblField*)rFmtFld.GetFld())->IsIntrnlName() )
404 : : {
405 : : // erzeuge aus der internen (fuer CORE) die externe (fuer UI) Formel
406 : 0 : const SwTableNode* pTblNd = m_pTxtNode->FindTableNode();
407 [ # # ]: 0 : if( pTblNd ) // steht in einer Tabelle
408 : 0 : ((SwTblField*)rFmtFld.GetFld())->PtrToBoxNm( &pTblNd->GetTable() );
409 : : }
410 : 0 : }
411 : :
412 : 4 : void SwTxtFld::NotifyContentChange(SwFmtFld& rFmtFld)
413 : : {
414 : : //if not in undo section notify the change
415 [ + - ][ + - ]: 4 : if (m_pTxtNode && m_pTxtNode->GetNodes().IsDocNodes())
[ + - ]
416 : : {
417 : 4 : m_pTxtNode->ModifyNotification(0, &rFmtFld);
418 : : }
419 : 4 : }
420 : :
421 : :
422 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|