xref: /trunk/main/sw/source/core/txtnode/atrfld.cxx (revision 20379b72)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include "fldbas.hxx"          // fuer FieldType
28 #include <fmtfld.hxx>
29 #include <txtfld.hxx>
30 #include <txtannotationfld.hxx>
31 #include <docfld.hxx>
32 #include <docufld.hxx>
33 #include <doc.hxx>
34 
35 #include "reffld.hxx"
36 #include "ddefld.hxx"
37 #include "usrfld.hxx"
38 #include "expfld.hxx"
39 #include "swfont.hxx"       // fuer GetFldsColor
40 #include "ndtxt.hxx"        // SwTxtNode
41 #include "calc.hxx"         // Update fuer UserFields
42 #include "hints.hxx"
43 #include <IDocumentFieldsAccess.hxx>
44 #include <fieldhint.hxx>
45 #include <svl/smplhint.hxx>
46 
47 TYPEINIT3( SwFmtFld, SfxPoolItem, SwClient,SfxBroadcaster)
48 TYPEINIT1(SwFmtFldHint, SfxHint);
49 
50 /****************************************************************************
51  *
52  *  class SwFmtFld
53  *
54  ****************************************************************************/
55 
56 // constructor for default item in attribute-pool
SwFmtFld(sal_uInt16 nWhich)57 SwFmtFld::SwFmtFld( sal_uInt16 nWhich )
58     : SfxPoolItem( nWhich )
59     , SwClient()
60     , SfxBroadcaster()
61     , mpField( NULL )
62     , mpTxtFld( NULL )
63 {
64 }
65 
SwFmtFld(const SwField & rFld)66 SwFmtFld::SwFmtFld( const SwField &rFld )
67     : SfxPoolItem( RES_TXTATR_FIELD )
68     , SwClient( rFld.GetTyp() )
69     , SfxBroadcaster()
70     , mpField( rFld.CopyField() )
71     , mpTxtFld( NULL )
72 {
73     if ( GetField()->GetTyp()->Which() == RES_INPUTFLD )
74     {
75         // input field in-place editing
76         SetWhich( RES_TXTATR_INPUTFIELD );
77         dynamic_cast<SwInputField*>(GetField())->SetFmtFld( *this );
78     }
79     else if ( GetField()->GetTyp()->Which() == RES_POSTITFLD )
80     {
81         // text annotation field
82         SetWhich( RES_TXTATR_ANNOTATION );
83     }
84 }
85 
86 // #i24434#
87 // Since Items are used in ItemPool and in default constructed ItemSets with
88 // full pool range, all items need to be clonable. Thus, this one needed to be
89 // corrected
SwFmtFld(const SwFmtFld & rAttr)90 SwFmtFld::SwFmtFld( const SwFmtFld& rAttr )
91     : SfxPoolItem( RES_TXTATR_FIELD )
92     , SwClient()
93     , SfxBroadcaster()
94     , mpField( NULL )
95     , mpTxtFld( NULL )
96 {
97     if ( rAttr.GetField() )
98     {
99         rAttr.GetField()->GetTyp()->Add(this);
100         mpField = rAttr.GetField()->CopyField();
101         if ( GetField()->GetTyp()->Which() == RES_INPUTFLD )
102         {
103             // input field in-place editing
104             SetWhich( RES_TXTATR_INPUTFIELD );
105             dynamic_cast<SwInputField*>(GetField())->SetFmtFld( *this );
106         }
107         else if ( GetField()->GetTyp()->Which() == RES_POSTITFLD )
108         {
109             // text annotation field
110             SetWhich( RES_TXTATR_ANNOTATION );
111         }
112     }
113 }
114 
~SwFmtFld()115 SwFmtFld::~SwFmtFld()
116 {
117 	SwFieldType* pType = mpField ? mpField->GetTyp() : 0;
118 
119 	if (pType && pType->Which() == RES_DBFLD)
120 		pType = 0;	// DB-Feldtypen zerstoeren sich selbst
121 
122 	Broadcast( SwFmtFldHint( this, SWFMTFLD_REMOVED ) );
123 	delete mpField;
124 
125 	// bei einige FeldTypen muessen wir den FeldTypen noch loeschen
126 	if( pType && pType->IsLastDepend() )
127 	{
128 		sal_Bool bDel = sal_False;
129 		switch( pType->Which() )
130 		{
131 		case RES_USERFLD:
132 			bDel = ((SwUserFieldType*)pType)->IsDeleted();
133 			break;
134 
135 		case RES_SETEXPFLD:
136 			bDel = ((SwSetExpFieldType*)pType)->IsDeleted();
137 			break;
138 
139 		case RES_DDEFLD:
140 			bDel = ((SwDDEFieldType*)pType)->IsDeleted();
141 			break;
142 		}
143 
144 		if( bDel )
145 		{
146 			// vorm loeschen erstmal austragen
147 			pType->Remove( this );
148 			delete pType;
149 		}
150 	}
151 }
152 
RegisterToFieldType(SwFieldType & rType)153 void SwFmtFld::RegisterToFieldType( SwFieldType& rType )
154 {
155     rType.Add(this);
156 }
157 
158 
159 // #111840#
SetField(SwField * _pField)160 void SwFmtFld::SetField(SwField * _pField)
161 {
162     if (NULL != mpField)
163         delete mpField;
164 
165     mpField = _pField;
166     if ( GetField()->GetTyp()->Which() == RES_INPUTFLD )
167     {
168         dynamic_cast<SwInputField* >(GetField())->SetFmtFld( *this );
169     }
170     Broadcast( SwFmtFldHint( this, SWFMTFLD_CHANGED ) );
171 }
172 
SetTxtFld(SwTxtFld & rTxtFld)173 void SwFmtFld::SetTxtFld( SwTxtFld& rTxtFld )
174 {
175     mpTxtFld = &rTxtFld;
176 }
177 
ClearTxtFld()178 void SwFmtFld::ClearTxtFld()
179 {
180     mpTxtFld = NULL;
181 }
182 
operator ==(const SfxPoolItem & rAttr) const183 int SwFmtFld::operator==( const SfxPoolItem& rAttr ) const
184 {
185 	ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
186     return ( ( mpField && ((SwFmtFld&)rAttr).GetField()
187                && mpField->GetTyp() == ((SwFmtFld&)rAttr).GetField()->GetTyp()
188                && mpField->GetFormat() == ((SwFmtFld&)rAttr).GetField()->GetFormat() ) )
189              || ( !mpField && !((SwFmtFld&)rAttr).GetField() );
190 }
191 
Clone(SfxItemPool *) const192 SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const
193 {
194 	return new SwFmtFld( *this );
195 }
196 
SwClientNotify(const SwModify &,const SfxHint & rHint)197 void SwFmtFld::SwClientNotify( const SwModify&, const SfxHint& rHint )
198 {
199     if( !mpTxtFld )
200         return;
201 
202     const SwFieldHint* pHint = dynamic_cast<const SwFieldHint*>( &rHint );
203     if ( pHint )
204     {
205         // replace field content by text
206         SwPaM* pPaM = pHint->GetPaM();
207         SwDoc* pDoc = pPaM->GetDoc();
208         const SwTxtNode& rTxtNode = mpTxtFld->GetTxtNode();
209         pPaM->GetPoint()->nNode = rTxtNode;
210         pPaM->GetPoint()->nContent.Assign( (SwTxtNode*)&rTxtNode, *mpTxtFld->GetStart() );
211 
212         String const aEntry( GetField()->ExpandField( pDoc->IsClipBoard() ) );
213         pPaM->SetMark();
214         pPaM->Move( fnMoveForward );
215         pDoc->DeleteRange( *pPaM );
216         pDoc->InsertString( *pPaM, aEntry );
217     }
218 }
219 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)220 void SwFmtFld::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
221 {
222     if ( mpTxtFld == NULL )
223         return;
224 
225     if( pNew != NULL
226         && pNew->Which() == RES_OBJECTDYING )
227     {
228         // don't do anything, especially not expand!
229         return;
230     }
231 
232     SwTxtNode* pTxtNd = (SwTxtNode*) &mpTxtFld->GetTxtNode();
233     ASSERT( pTxtNd, "wo ist denn mein Node?" );
234     if ( pNew )
235     {
236         switch (pNew->Which())
237         {
238         case RES_TXTATR_FLDCHG:
239             // "Farbe hat sich geaendert !"
240             // this, this fuer "nur Painten"
241             pTxtNd->ModifyNotification( this, this );
242             return;
243 
244         case RES_REFMARKFLD_UPDATE:
245             // GetReferenz-Felder aktualisieren
246             if ( RES_GETREFFLD == GetField()->GetTyp()->Which() )
247             {
248                 dynamic_cast<SwGetRefField*>(GetField())->UpdateField( mpTxtFld );
249             }
250             break;
251 
252         case RES_DOCPOS_UPDATE:
253             // Je nach DocPos aktualisieren (SwTxtFrm::Modify())
254             pTxtNd->ModifyNotification( pNew, this );
255             return;
256 
257         case RES_ATTRSET_CHG:
258             case RES_FMT_CHG:
259             pTxtNd->ModifyNotification( pOld, pNew );
260             return;
261 
262             default:
263             break;
264         }
265     }
266 
267     switch (GetField()->GetTyp()->Which())
268     {
269     case RES_HIDDENPARAFLD:
270         if ( !pOld || RES_HIDDENPARA_PRINT != pOld->Which() )
271             break;
272     case RES_DBSETNUMBERFLD:
273     case RES_DBNUMSETFLD:
274     case RES_DBNEXTSETFLD:
275     case RES_DBNAMEFLD:
276         pTxtNd->ModifyNotification( 0, pNew );
277         return;
278     }
279 
280     if ( RES_USERFLD == GetField()->GetTyp()->Which() )
281     {
282         SwUserFieldType* pType = (SwUserFieldType*) GetField()->GetTyp();
283         if ( !pType->IsValid() )
284         {
285             SwCalc aCalc( *pTxtNd->GetDoc() );
286             pType->GetValue( aCalc );
287         }
288     }
289 
290     const bool bForceNotify = (pOld == NULL) && (pNew == NULL);
291     mpTxtFld->ExpandTxtFld( bForceNotify );
292 }
293 
GetInfo(SfxPoolItem & rInfo) const294 sal_Bool SwFmtFld::GetInfo( SfxPoolItem& rInfo ) const
295 {
296 	const SwTxtNode* pTxtNd;
297 	if( RES_AUTOFMT_DOCNODE != rInfo.Which() ||
298 		!mpTxtFld || 0 == ( pTxtNd = mpTxtFld->GetpTxtNode() ) ||
299 		&pTxtNd->GetNodes() != ((SwAutoFmtGetDocNode&)rInfo).pNodes )
300 		return sal_True;
301 
302 	((SwAutoFmtGetDocNode&)rInfo).pCntntNode = pTxtNd;
303 	return sal_False;
304 }
305 
306 
IsFldInDoc() const307 bool SwFmtFld::IsFldInDoc() const
308 {
309     return mpTxtFld != NULL
310            && mpTxtFld->IsFldInDoc();
311 }
312 
IsProtect() const313 sal_Bool SwFmtFld::IsProtect() const
314 {
315     return mpTxtFld != NULL
316            && mpTxtFld->GetpTxtNode() != NULL
317            && mpTxtFld->GetpTxtNode()->IsProtect();
318 }
319 
320 
321 
322 
SwTxtFld(SwFmtFld & rAttr,xub_StrLen const nStartPos,const bool bIsClipboardDoc)323 SwTxtFld::SwTxtFld(
324     SwFmtFld & rAttr,
325     xub_StrLen const nStartPos,
326     const bool bIsClipboardDoc )
327     : SwTxtAttr( rAttr, nStartPos )
328     , m_aExpand( rAttr.GetField()->ExpandField( bIsClipboardDoc ) )
329     , m_pTxtNode( NULL )
330 {
331     rAttr.SetTxtFld( *this );
332     SetHasDummyChar(true);
333 }
334 
~SwTxtFld()335 SwTxtFld::~SwTxtFld( )
336 {
337     SwFmtFld & rFmtFld( static_cast<SwFmtFld &>(GetAttr()) );
338     if ( this == rFmtFld.GetTxtFld() )
339     {
340         rFmtFld.ClearTxtFld();
341     }
342 }
343 
344 
IsFldInDoc() const345 bool SwTxtFld::IsFldInDoc() const
346 {
347     return GetpTxtNode() != NULL
348            && GetpTxtNode()->GetNodes().IsDocNodes();
349 }
350 
ExpandTxtFld(const bool bForceNotify) const351 void SwTxtFld::ExpandTxtFld( const bool bForceNotify ) const
352 {
353     ASSERT( m_pTxtNode, "SwTxtFld: where is my TxtNode?" );
354 
355     const SwField* pFld = GetFmtFld().GetField();
356     const XubString aNewExpand( pFld->ExpandField(m_pTxtNode->GetDoc()->IsClipBoard()) );
357 
358     if ( aNewExpand == m_aExpand )
359     {
360         // Bei Seitennummernfeldern
361         const sal_uInt16 nWhich = pFld->GetTyp()->Which();
362         if ( RES_CHAPTERFLD != nWhich
363              && RES_PAGENUMBERFLD != nWhich
364              && RES_REFPAGEGETFLD != nWhich
365              // Page count fields to not use aExpand during formatting,
366              // therefore an invalidation of the text frame has to be triggered even if aNewExpand == aExpand:
367              && ( RES_DOCSTATFLD != nWhich || DS_PAGE != static_cast<const SwDocStatField*>(pFld)->GetSubType() )
368              && ( RES_GETEXPFLD != nWhich || ((SwGetExpField*)pFld)->IsInBodyTxt() ) )
369         {
370             if( m_pTxtNode->CalcHiddenParaField() )
371             {
372                 m_pTxtNode->ModifyNotification( 0, 0 );
373             }
374             if ( !bForceNotify )
375             {
376                 // done, if no further notification forced.
377                 return;
378             }
379         }
380     }
381 
382     m_aExpand = aNewExpand;
383 
384     const_cast<SwTxtFld*>(this)->NotifyContentChange( const_cast<SwFmtFld&>(GetFmtFld()) );
385 }
386 
387 
CopyTxtFld(SwTxtFld * pDest) const388 void SwTxtFld::CopyTxtFld( SwTxtFld *pDest ) const
389 {
390     ASSERT( m_pTxtNode, "SwTxtFld: where is my TxtNode?" );
391     ASSERT( pDest->m_pTxtNode, "SwTxtFld: where is pDest's TxtNode?" );
392 
393     IDocumentFieldsAccess* pIDFA = m_pTxtNode->getIDocumentFieldsAccess();
394     IDocumentFieldsAccess* pDestIDFA = pDest->m_pTxtNode->getIDocumentFieldsAccess();
395 
396     SwFmtFld& rDestFmtFld = (SwFmtFld&)pDest->GetFmtFld();
397     const sal_uInt16 nFldWhich = rDestFmtFld.GetField()->GetTyp()->Which();
398 
399     if( pIDFA != pDestIDFA )
400     {
401         // Die Hints stehen in unterschiedlichen Dokumenten,
402         // der Feldtyp muss im neuen Dokument angemeldet werden.
403         // Z.B: Kopieren ins ClipBoard.
404         SwFieldType* pFldType;
405         if( nFldWhich != RES_DBFLD
406             && nFldWhich != RES_USERFLD
407             && nFldWhich != RES_SETEXPFLD
408             && nFldWhich != RES_DDEFLD
409             && RES_AUTHORITY != nFldWhich )
410         {
411             pFldType = pDestIDFA->GetSysFldType( nFldWhich );
412         }
413         else
414         {
415             pFldType = pDestIDFA->InsertFldType( *rDestFmtFld.GetField()->GetTyp() );
416         }
417 
418         // Sonderbehandlung fuer DDE-Felder
419         if( RES_DDEFLD == nFldWhich )
420         {
421             if( rDestFmtFld.GetTxtFld() )
422             {
423                 ((SwDDEFieldType*)rDestFmtFld.GetField()->GetTyp())->DecRefCnt();
424             }
425             ((SwDDEFieldType*)pFldType)->IncRefCnt();
426         }
427 
428         ASSERT( pFldType, "unbekannter FieldType" );
429         pFldType->Add( &rDestFmtFld );          // ummelden
430         rDestFmtFld.GetField()->ChgTyp( pFldType );
431     }
432 
433     // Expressionfelder Updaten
434     if( nFldWhich == RES_SETEXPFLD
435         || nFldWhich == RES_GETEXPFLD
436         || nFldWhich == RES_HIDDENTXTFLD )
437     {
438         SwTxtFld* pFld = (SwTxtFld*)this;
439         pDestIDFA->UpdateExpFlds( pFld, true );
440     }
441     // Tabellenfelder auf externe Darstellung
442     else if( RES_TABLEFLD == nFldWhich
443              && ((SwTblField*)rDestFmtFld.GetField())->IsIntrnlName() )
444     {
445         // erzeuge aus der internen (fuer CORE) die externe (fuer UI) Formel
446         const SwTableNode* pTblNd = m_pTxtNode->FindTableNode();
447         if( pTblNd )		// steht in einer Tabelle
448             ((SwTblField*)rDestFmtFld.GetField())->PtrToBoxNm( &pTblNd->GetTable() );
449     }
450 }
451 
452 
NotifyContentChange(SwFmtFld & rFmtFld)453 void SwTxtFld::NotifyContentChange(SwFmtFld& rFmtFld)
454 {
455     //if not in undo section notify the change
456     if (m_pTxtNode && m_pTxtNode->GetNodes().IsDocNodes())
457     {
458         m_pTxtNode->ModifyNotification(0, &rFmtFld);
459     }
460 }
461 
462 
463 /*static*/
GetPamForTxtFld(const SwTxtFld & rTxtFld,boost::shared_ptr<SwPaM> & rPamForTxtFld)464 void SwTxtFld::GetPamForTxtFld(
465     const SwTxtFld& rTxtFld,
466     boost::shared_ptr< SwPaM >& rPamForTxtFld )
467 {
468     if ( rTxtFld.GetpTxtNode() == NULL )
469     {
470         ASSERT( false, "<SwTxtFld::GetPamForField> - missing <SwTxtNode>" );
471         return;
472     }
473 
474     const SwTxtNode& rTxtNode = rTxtFld.GetTxtNode();
475 
476     rPamForTxtFld.reset( new SwPaM( rTxtNode,
477                                     ( (rTxtFld.End() != NULL) ? *(rTxtFld.End()) : ( *(rTxtFld.GetStart()) + 1 ) ),
478                                     rTxtNode,
479                                     *(rTxtFld.GetStart()) ) );
480 
481 }
482 
483 
484 /*static*/
DeleteTxtFld(const SwTxtFld & rTxtFld)485 void SwTxtFld::DeleteTxtFld( const SwTxtFld& rTxtFld )
486 {
487     if ( rTxtFld.GetpTxtNode() != NULL )
488     {
489         boost::shared_ptr< SwPaM > pPamForTxtFld;
490         GetPamForTxtFld( rTxtFld, pPamForTxtFld );
491         if ( pPamForTxtFld.get() != NULL )
492         {
493             rTxtFld.GetTxtNode().GetDoc()->DeleteAndJoin( *pPamForTxtFld );
494         }
495     }
496 }
497 
498 
499 
500 // input field in-place editing
SwTxtInputFld(SwFmtFld & rAttr,xub_StrLen const nStart,xub_StrLen const nEnd,const bool bIsClipboardDoc)501 SwTxtInputFld::SwTxtInputFld(
502     SwFmtFld & rAttr,
503     xub_StrLen const nStart,
504     xub_StrLen const nEnd,
505     const bool bIsClipboardDoc )
506 
507     : SwTxtFld( rAttr, nStart, bIsClipboardDoc )
508     , m_nEnd( nEnd )
509     , m_bLockNotifyContentChange( false )
510 {
511     SetHasDummyChar( false );
512     SetHasContent( true );
513 
514     SetDontExpand( true );
515     SetLockExpandFlag( true );
516     SetDontExpandStartAttr( true );
517 
518     SetNesting( true );
519 }
520 
~SwTxtInputFld()521 SwTxtInputFld::~SwTxtInputFld()
522 {
523 }
524 
GetEnd()525 xub_StrLen* SwTxtInputFld::GetEnd()
526 {
527     return &m_nEnd;
528 }
529 
530 
LockNotifyContentChange()531 void SwTxtInputFld::LockNotifyContentChange()
532 {
533     m_bLockNotifyContentChange = true;
534 }
535 
536 
UnlockNotifyContentChange()537 void SwTxtInputFld::UnlockNotifyContentChange()
538 {
539     m_bLockNotifyContentChange = false;
540 }
541 
542 
NotifyContentChange(SwFmtFld & rFmtFld)543 void SwTxtInputFld::NotifyContentChange( SwFmtFld& rFmtFld )
544 {
545     if ( !m_bLockNotifyContentChange )
546     {
547         LockNotifyContentChange();
548 
549         SwTxtFld::NotifyContentChange( rFmtFld );
550         UpdateTextNodeContent( GetFieldContent() );
551 
552         UnlockNotifyContentChange();
553     }
554 }
555 
GetFieldContent() const556 const String SwTxtInputFld::GetFieldContent() const
557 {
558     return GetFmtFld().GetField()->ExpandField(false);
559 }
560 
UpdateFieldContent()561 void SwTxtInputFld::UpdateFieldContent()
562 {
563     if ( IsFldInDoc()
564          && (*GetStart()) != (*End()) )
565     {
566         ASSERT( (*End()) - (*GetStart()) >= 2,
567                 "<SwTxtInputFld::UpdateFieldContent()> - Are CH_TXT_ATR_INPUTFIELDSTART and/or CH_TXT_ATR_INPUTFIELDEND missing?" );
568         // skip CH_TXT_ATR_INPUTFIELDSTART character
569         const xub_StrLen nIdx = (*GetStart()) + 1;
570         // skip CH_TXT_ATR_INPUTFIELDEND character
571         const xub_StrLen nLen = static_cast<xub_StrLen>(std::max( 0, ( (*End()) - 1 - nIdx ) ));
572         const String aNewFieldContent = GetTxtNode().GetExpandTxt( nIdx, nLen );
573 
574         const SwInputField* pInputFld = dynamic_cast<const SwInputField*>(GetFmtFld().GetField());
575         ASSERT( pInputFld != NULL,
576                 "<SwTxtInputFld::GetContent()> - Missing <SwInputFld> instance!" );
577         if ( pInputFld != NULL )
578         {
579             const_cast<SwInputField*>(pInputFld)->applyFieldContent( aNewFieldContent );
580             // trigger update of fields for scenarios in which the Input Field's content is part of e.g. a table formula
581             GetTxtNode().GetDoc()->GetUpdtFlds().SetFieldsDirty( sal_True );
582         }
583     }
584 }
585 
UpdateTextNodeContent(const String & rNewContent)586 void SwTxtInputFld::UpdateTextNodeContent( const String& rNewContent )
587 {
588     if ( !IsFldInDoc() )
589     {
590         ASSERT( false, "<SwTxtInputFld::UpdateTextNodeContent(..)> - misusage as Input Field is not in document content." );
591         return;
592     }
593 
594     ASSERT( (*End()) - (*GetStart()) >= 2,
595             "<SwTxtInputFld::UpdateTextNodeContent(..)> - Are CH_TXT_ATR_INPUTFIELDSTART and/or CH_TXT_ATR_INPUTFIELDEND missing?" );
596     // skip CH_TXT_ATR_INPUTFIELDSTART character
597     const xub_StrLen nIdx = (*GetStart()) + 1;
598     // skip CH_TXT_ATR_INPUTFIELDEND character
599     const xub_StrLen nDelLen = static_cast<xub_StrLen>(std::max( 0, ( (*End()) - 1 - nIdx ) ));
600     SwIndex aIdx( &GetTxtNode(), nIdx );
601     GetTxtNode().ReplaceText( aIdx, nDelLen, rNewContent );
602 }
603 
604 
605 
606 
607 // text annotation field
SwTxtAnnotationFld(SwFmtFld & rAttr,xub_StrLen const nStart,const bool bIsClipboardDoc)608 SwTxtAnnotationFld::SwTxtAnnotationFld(
609     SwFmtFld & rAttr,
610     xub_StrLen const nStart,
611     const bool bIsClipboardDoc )
612     : SwTxtFld( rAttr, nStart, bIsClipboardDoc )
613 {
614 }
615 
~SwTxtAnnotationFld()616 SwTxtAnnotationFld::~SwTxtAnnotationFld()
617 {
618 }
619 
620 
GetAnnotationMark(SwDoc * pDoc) const621 ::sw::mark::IMark* SwTxtAnnotationFld::GetAnnotationMark(
622     SwDoc* pDoc ) const
623 {
624     const SwPostItField* pPostItField = dynamic_cast<const SwPostItField*>(GetFmtFld().GetField());
625     ASSERT( pPostItField != NULL, "<SwTxtAnnotationFld::GetAnnotationMark()> - field missing" );
626     if ( pPostItField == NULL )
627     {
628         return NULL;
629     }
630 
631     if ( pDoc == NULL )
632     {
633         pDoc = static_cast<const SwPostItFieldType*>(pPostItField->GetTyp())->GetDoc();
634     }
635     ASSERT( pDoc != NULL, "<SwTxtAnnotationFld::GetAnnotationMark()> - missing document" );
636     if ( pDoc == NULL )
637     {
638         return NULL;
639     }
640 
641     IDocumentMarkAccess* pMarksAccess = pDoc->getIDocumentMarkAccess();
642     IDocumentMarkAccess::const_iterator_t pMark = pMarksAccess->findAnnotationMark( pPostItField->GetName() );
643     return pMark != pMarksAccess->getAnnotationMarksEnd()
644            ? pMark->get()
645            : NULL;
646 }
647 
648