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 57 SwFmtFld::SwFmtFld( sal_uInt16 nWhich ) 58 : SfxPoolItem( nWhich ) 59 , SwClient() 60 , SfxBroadcaster() 61 , mpField( NULL ) 62 , mpTxtFld( NULL ) 63 { 64 } 65 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 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 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 153 void SwFmtFld::RegisterToFieldType( SwFieldType& rType ) 154 { 155 rType.Add(this); 156 } 157 158 159 // #111840# 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 173 void SwFmtFld::SetTxtFld( SwTxtFld& rTxtFld ) 174 { 175 mpTxtFld = &rTxtFld; 176 } 177 178 void SwFmtFld::ClearTxtFld() 179 { 180 mpTxtFld = NULL; 181 } 182 183 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 192 SfxPoolItem* SwFmtFld::Clone( SfxItemPool* ) const 193 { 194 return new SwFmtFld( *this ); 195 } 196 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 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 294 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 307 bool SwFmtFld::IsFldInDoc() const 308 { 309 return mpTxtFld != NULL 310 && mpTxtFld->IsFldInDoc(); 311 } 312 313 sal_Bool SwFmtFld::IsProtect() const 314 { 315 return mpTxtFld != NULL 316 && mpTxtFld->GetpTxtNode() != NULL 317 && mpTxtFld->GetpTxtNode()->IsProtect(); 318 } 319 320 321 322 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 335 SwTxtFld::~SwTxtFld( ) 336 { 337 SwFmtFld & rFmtFld( static_cast<SwFmtFld &>(GetAttr()) ); 338 if ( this == rFmtFld.GetTxtFld() ) 339 { 340 rFmtFld.ClearTxtFld(); 341 } 342 } 343 344 345 bool SwTxtFld::IsFldInDoc() const 346 { 347 return GetpTxtNode() != NULL 348 && GetpTxtNode()->GetNodes().IsDocNodes(); 349 } 350 351 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 388 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 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*/ 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*/ 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 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 521 SwTxtInputFld::~SwTxtInputFld() 522 { 523 } 524 525 xub_StrLen* SwTxtInputFld::GetEnd() 526 { 527 return &m_nEnd; 528 } 529 530 531 void SwTxtInputFld::LockNotifyContentChange() 532 { 533 m_bLockNotifyContentChange = true; 534 } 535 536 537 void SwTxtInputFld::UnlockNotifyContentChange() 538 { 539 m_bLockNotifyContentChange = false; 540 } 541 542 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 556 const String SwTxtInputFld::GetFieldContent() const 557 { 558 return GetFmtFld().GetField()->ExpandField(false); 559 } 560 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 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 608 SwTxtAnnotationFld::SwTxtAnnotationFld( 609 SwFmtFld & rAttr, 610 xub_StrLen const nStart, 611 const bool bIsClipboardDoc ) 612 : SwTxtFld( rAttr, nStart, bIsClipboardDoc ) 613 { 614 } 615 616 SwTxtAnnotationFld::~SwTxtAnnotationFld() 617 { 618 } 619 620 621 ::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