xref: /trunk/main/sd/source/core/sdpage2.cxx (revision ffd38472365e95f6a578737bc9a5eb0fac624a86)
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_sd.hxx"
26 #include <sfx2/docfile.hxx>
27 #include <vcl/svapp.hxx>
28 #include <editeng/outliner.hxx>
29 #ifndef _SVXLINK_HXX
30 #include <sfx2/linkmgr.hxx>
31 #endif
32 #include <svx/svdotext.hxx>
33 #include <tools/urlobj.hxx>
34 #include <editeng/outlobj.hxx>
35 #include <svl/urihelper.hxx>
36 #include <editeng/xmlcnitm.hxx>
37 #include <svx/svditer.hxx>
38 #include <tools/list.hxx>
39 
40 #include "sdresid.hxx"
41 #include "sdpage.hxx"
42 #include "glob.hxx"
43 #include "glob.hrc"
44 #include "drawdoc.hxx"
45 #include "stlpool.hxx"
46 //#include "sdiocmpt.hxx"
47 #include "pglink.hxx"
48 //#include "strmname.h"
49 #include "anminfo.hxx"
50 
51 #include "../ui/inc/strings.hrc"
52 #include "../ui/inc/DrawDocShell.hxx"
53 
54 // #90477#
55 #include <tools/tenccvt.hxx>
56 #include <svl/itemset.hxx>
57 
58 using namespace ::sd;
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::office;
62 
63 extern void NotifyDocumentEvent( SdDrawDocument* pDocument, const rtl::OUString& rEventName, const Reference< XInterface >& xSource );
64 
65 /*************************************************************************
66 |*
67 |* SetPresentationLayout, setzt: Layoutnamen, Masterpage-Verkn�pfung und
68 |* Vorlagen fuer Praesentationsobjekte
69 |*
70 |* Vorraussetzungen: - Die Seite muss bereits das richtige Model kennen!
71 |*                   - Die entsprechende Masterpage muss bereits im Model sein.
72 |*                   - Die entsprechenden StyleSheets muessen bereits im
73 |*                     im StyleSheetPool sein.
74 |*
75 |*  bReplaceStyleSheets = sal_True : Benannte StyleSheets werden ausgetauscht
76 |*                        sal_False: Alle StyleSheets werden neu zugewiesen
77 |*
78 |*  bSetMasterPage      = sal_True : MasterPage suchen und zuweisen
79 |*
80 |*  bReverseOrder       = sal_False: MasterPages von vorn nach hinten suchen
81 |*                        sal_True : MasterPages von hinten nach vorn suchen (fuer Undo-Action)
82 |*
83 \************************************************************************/
84 
85 void SdPage::SetPresentationLayout(const String& rLayoutName,
86                                    sal_Bool bReplaceStyleSheets,
87                                    sal_Bool bSetMasterPage,
88                                    sal_Bool bReverseOrder)
89 {
90     /*********************************************************************
91     |* Layoutname der Seite
92     \********************************************************************/
93     String aOldLayoutName(maLayoutName); // merken
94     maLayoutName = rLayoutName;
95     maLayoutName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( SD_LT_SEPARATOR ));
96     maLayoutName += String(SdResId(STR_LAYOUT_OUTLINE));
97 
98     /*********************************************************************
99     |* ggf. Masterpage suchen und setzen
100     \********************************************************************/
101     if (bSetMasterPage && !IsMasterPage())
102     {
103         SdPage* pMaster;
104         SdPage* pFoundMaster = 0;
105         sal_uInt16 nMaster = 0;
106         sal_uInt16 nMasterCount = pModel->GetMasterPageCount();
107 
108         if( !bReverseOrder )
109         {
110             for ( nMaster = 0; nMaster < nMasterCount; nMaster++ )
111             {
112                 pMaster = static_cast<SdPage*>(pModel->GetMasterPage(nMaster));
113                 if (pMaster->GetPageKind() == mePageKind && pMaster->GetLayoutName() == maLayoutName)
114                 {
115                     pFoundMaster = pMaster;
116                     break;
117                 }
118             }
119         }
120         else
121         {
122             for ( nMaster = nMasterCount; nMaster > 0; nMaster-- )
123             {
124                 pMaster = static_cast<SdPage*>(pModel->GetMasterPage(nMaster - 1));
125                 if (pMaster->GetPageKind() == mePageKind && pMaster->GetLayoutName() == maLayoutName)
126                 {
127                     pFoundMaster = pMaster;
128                     break;
129                 }
130             }
131         }
132 
133         DBG_ASSERT(pFoundMaster, "Masterpage for presentation layout not found!");
134 
135         // this should never happen, but we play failsafe here
136         if( pFoundMaster == 0 )
137             pFoundMaster = static_cast< SdDrawDocument *>(pModel)->GetSdPage( 0, mePageKind );
138 
139         if( pFoundMaster )
140             TRG_SetMasterPage(*pFoundMaster);
141     }
142 
143     /*********************************************************************
144     |* Vorlagen fuer Praesentationsobjekte
145     \********************************************************************/
146     // Listen mit:
147     // - Vorlagenzeigern fuer Gliederungstextobjekt (alte und neue Vorlagen)
148     // - Replacedaten fuer OutlinerParaObject
149     List aOutlineStyles;
150     List aOldOutlineStyles;
151     List aReplList;
152     sal_Bool bListsFilled = sal_False;
153 
154     sal_uLong nObjCount = GetObjCount();
155 
156     for (sal_uLong nObj = 0; nObj < nObjCount; nObj++)
157     {
158         SdrTextObj* pObj = (SdrTextObj*) GetObj(nObj);
159 
160         if (pObj->GetObjInventor() == SdrInventor &&
161             pObj->GetObjIdentifier() == OBJ_OUTLINETEXT)
162         {
163             if (!bListsFilled || !bReplaceStyleSheets)
164             {
165                 String aFullName;
166                 String aOldFullName;
167                 SfxStyleSheetBase* pSheet = NULL;
168                 SfxStyleSheetBasePool* pStShPool = pModel->GetStyleSheetPool();
169 
170                 for (sal_Int16 i = -1; i < 9; i++)
171                 {
172                     aFullName = maLayoutName;
173                     aOldFullName = aOldLayoutName;
174                     aFullName += sal_Unicode( ' ' );
175                     aFullName += String::CreateFromInt32( (sal_Int32) (i <= 0 ) ? 1 : i + 1);
176                     aOldFullName += sal_Unicode( ' ' );
177                     aOldFullName += String::CreateFromInt32( (sal_Int32) (i <= 0 ) ? 1 : i + 1 );
178 
179                     pSheet = pStShPool->Find(aOldFullName, SD_STYLE_FAMILY_MASTERPAGE);
180                     DBG_ASSERT(pSheet, "alte Gliederungsvorlage nicht gefunden");
181                     aOldOutlineStyles.Insert(pSheet, LIST_APPEND);
182 
183                     pSheet = pStShPool->Find(aFullName, SD_STYLE_FAMILY_MASTERPAGE);
184                     DBG_ASSERT(pSheet, "neue Gliederungsvorlage nicht gefunden");
185                     aOutlineStyles.Insert(pSheet, LIST_APPEND);
186 
187                     if (bReplaceStyleSheets && pSheet)
188                     {
189                         // Replace anstatt Set
190                         StyleReplaceData* pReplData = new StyleReplaceData;
191                         pReplData->nNewFamily = pSheet->GetFamily();
192                         pReplData->nFamily    = pSheet->GetFamily();
193                         pReplData->aNewName   = aFullName;
194                         pReplData->aName      = aOldFullName;
195                         aReplList.Insert(pReplData, LIST_APPEND);
196                     }
197                     else
198                     {
199                         OutlinerParaObject* pOPO = ((SdrTextObj*)pObj)->GetOutlinerParaObject();
200 
201                         if( pOPO )
202                             pOPO->SetStyleSheets( i, aFullName, SD_STYLE_FAMILY_MASTERPAGE );
203                     }
204                 }
205 
206                 bListsFilled = sal_True;
207             }
208 
209             SfxStyleSheet* pSheet = (SfxStyleSheet*)aOutlineStyles.First();
210             SfxStyleSheet* pOldSheet = (SfxStyleSheet*)aOldOutlineStyles.First();
211             while (pSheet)
212             {
213                 if (pSheet != pOldSheet)
214                 {
215                     pObj->EndListening(*pOldSheet);
216 
217                     if (!pObj->IsListening(*pSheet))
218                         pObj->StartListening(*pSheet);
219                 }
220 
221                 pSheet = (SfxStyleSheet*)aOutlineStyles.Next();
222                 pOldSheet = (SfxStyleSheet*)aOldOutlineStyles.Next();
223             }
224 
225             OutlinerParaObject* pOPO = ((SdrTextObj*)pObj)->GetOutlinerParaObject();
226             if ( bReplaceStyleSheets && pOPO )
227             {
228                 StyleReplaceData* pReplData = (StyleReplaceData*) aReplList.First();
229 
230                 while( pReplData )
231                 {
232                     pOPO->ChangeStyleSheets( pReplData->aName, pReplData->nFamily, pReplData->aNewName, pReplData->nNewFamily );
233                     pReplData = (StyleReplaceData*) aReplList.Next();
234                 }
235             }
236         }
237         else if (pObj->GetObjInventor() == SdrInventor &&
238                  pObj->GetObjIdentifier() == OBJ_TITLETEXT)
239         {
240             // PresObjKind nicht ueber GetPresObjKind() holen, da dort nur
241             // die PresObjListe beruecksichtigt wird. Es sollen aber alle
242             // "Titelobjekte" hier beruecksichtigt werden (Paste aus Clipboard usw.)
243             SfxStyleSheet* pSheet = GetStyleSheetForPresObj(PRESOBJ_TITLE);
244 
245             if (pSheet)
246                 pObj->SetStyleSheet(pSheet, sal_True);
247         }
248         else
249         {
250             SfxStyleSheet* pSheet = GetStyleSheetForPresObj(GetPresObjKind(pObj));
251 
252             if (pSheet)
253                 pObj->SetStyleSheet(pSheet, sal_True);
254         }
255     }
256 
257     for (sal_uLong i = 0; i < aReplList.Count(); i++)
258     {
259         delete (StyleReplaceData*) aReplList.GetObject(i);
260     }
261 }
262 
263 
264 /*************************************************************************
265 |* das Gliederungstextobjekt bei den Vorlagen fuer die Gliederungsebenen
266 |* abmelden
267 \************************************************************************/
268 
269 void SdPage::EndListenOutlineText()
270 {
271     SdrObject* pOutlineTextObj = GetPresObj(PRESOBJ_OUTLINE);
272 
273     if (pOutlineTextObj)
274     {
275         SdStyleSheetPool* pSPool = (SdStyleSheetPool*)pModel->GetStyleSheetPool();
276         DBG_ASSERT(pSPool, "StyleSheetPool nicht gefunden");
277         String aTrueLayoutName(maLayoutName);
278         aTrueLayoutName.Erase( aTrueLayoutName.SearchAscii( SD_LT_SEPARATOR ));
279         List* pOutlineStyles = pSPool->CreateOutlineSheetList(aTrueLayoutName);
280         for (SfxStyleSheet* pSheet = (SfxStyleSheet*)pOutlineStyles->First();
281              pSheet;
282              pSheet = (SfxStyleSheet*)pOutlineStyles->Next())
283             {
284                 pOutlineTextObj->EndListening(*pSheet);
285             }
286 
287         delete pOutlineStyles;
288     }
289 }
290 
291 /*************************************************************************
292 |* Neues Modell setzen
293 \************************************************************************/
294 
295 void SdPage::SetModel(SdrModel* pNewModel)
296 {
297     DisconnectLink();
298 
299     // Model umsetzen
300     FmFormPage::SetModel(pNewModel);
301 
302     ConnectLink();
303 }
304 
305 /*************************************************************************
306 |* Ist die Seite read-only?
307 \************************************************************************/
308 
309 FASTBOOL SdPage::IsReadOnly() const
310 {
311     return sal_False;
312 }
313 
314 /*************************************************************************
315 |* Beim sfx2::LinkManager anmelden
316 \************************************************************************/
317 
318 void SdPage::ConnectLink()
319 {
320     sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL;
321 
322     if (pLinkManager && !mpPageLink && maFileName.Len() && maBookmarkName.Len() &&
323         mePageKind==PK_STANDARD && !IsMasterPage() &&
324         ( (SdDrawDocument*) pModel)->IsNewOrLoadCompleted())
325     {
326         /**********************************************************************
327         * Anmelden
328         * Nur Standardseiten duerfen gelinkt sein
329         **********************************************************************/
330         ::sd::DrawDocShell* pDocSh = ((SdDrawDocument*) pModel)->GetDocSh();
331 
332         if (!pDocSh || pDocSh->GetMedium()->GetOrigURL() != maFileName)
333         {
334             // Keine Links auf Dokument-eigene Seiten!
335             mpPageLink = new SdPageLink(this, maFileName, maBookmarkName);
336             String aFilterName(SdResId(STR_IMPRESS));
337             pLinkManager->InsertFileLink(*mpPageLink, OBJECT_CLIENT_FILE,
338                                          maFileName, &aFilterName, &maBookmarkName);
339             mpPageLink->Connect();
340         }
341     }
342 }
343 
344 
345 /*************************************************************************
346 |* Beim sfx2::LinkManager abmelden
347 \************************************************************************/
348 
349 void SdPage::DisconnectLink()
350 {
351     sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL;
352 
353     if (pLinkManager && mpPageLink)
354     {
355         /**********************************************************************
356         * Abmelden
357         * (Bei Remove wird *pGraphicLink implizit deleted)
358         **********************************************************************/
359         pLinkManager->Remove(mpPageLink);
360         mpPageLink=NULL;
361     }
362 }
363 
364 /*************************************************************************
365 |* Copy-Ctor
366 \************************************************************************/
367 
368 SdPage::SdPage(const SdPage& rSrcPage)
369 :   FmFormPage(rSrcPage)
370 ,   SdrObjUserCall()
371 ,   mpItems(NULL)
372 {
373     mePageKind              = rSrcPage.mePageKind;
374     meAutoLayout            = rSrcPage.meAutoLayout;
375 
376     SdrObject* pObj = 0;
377     while((pObj = rSrcPage.maPresentationShapeList.getNextShape(pObj)) != 0)
378         InsertPresObj(GetObj(pObj->GetOrdNum()), rSrcPage.GetPresObjKind(pObj));
379 
380     mbSelected              = sal_False;
381     mnTransitionType        = rSrcPage.mnTransitionType;
382     mnTransitionSubtype     = rSrcPage.mnTransitionSubtype;
383     mbTransitionDirection   = rSrcPage.mbTransitionDirection;
384     mnTransitionFadeColor   = rSrcPage.mnTransitionFadeColor;
385     mfTransitionDuration    = rSrcPage.mfTransitionDuration;
386     mePresChange            = rSrcPage.mePresChange;
387     mnTime                  = rSrcPage.mnTime;
388     mbSoundOn               = rSrcPage.mbSoundOn;
389     mbExcluded              = rSrcPage.mbExcluded;
390 
391     maLayoutName            = rSrcPage.maLayoutName;
392     maSoundFile             = rSrcPage.maSoundFile;
393     mbLoopSound             = rSrcPage.mbLoopSound;
394     mbStopSound             = rSrcPage.mbStopSound;
395     maCreatedPageName       = String();
396     maFileName              = rSrcPage.maFileName;
397     maBookmarkName          = rSrcPage.maBookmarkName;
398     mbScaleObjects          = rSrcPage.mbScaleObjects;
399     mbBackgroundFullSize    = rSrcPage.mbBackgroundFullSize;
400     meCharSet               = rSrcPage.meCharSet;
401     mnPaperBin              = rSrcPage.mnPaperBin;
402     meOrientation           = rSrcPage.meOrientation;
403 
404     // header footer
405     setHeaderFooterSettings( rSrcPage.getHeaderFooterSettings() );
406 
407     mpPageLink              = NULL; // Wird beim Einfuegen ueber ConnectLink() gesetzt
408 }
409 
410 
411 
412 /*************************************************************************
413 |* Clone
414 \************************************************************************/
415 
416 SdrPage* SdPage::Clone() const
417 {
418     return Clone(NULL);
419 }
420 
421 SdrPage* SdPage::Clone(SdrModel* pNewModel) const
422 {
423     DBG_ASSERT( pNewModel == 0, "sd::SdPage::Clone(), new page ignored, please check code! CL" );
424     (void)pNewModel;
425 
426     SdPage* pNewPage = new SdPage(*this);
427 
428     cloneAnimations( *pNewPage );
429 
430     // fix user calls for duplicated slide
431     SdrObjListIter aSourceIter( *this, IM_DEEPWITHGROUPS );
432     SdrObjListIter aTargetIter( *pNewPage, IM_DEEPWITHGROUPS );
433 
434     while( aSourceIter.IsMore() && aTargetIter.IsMore() )
435     {
436         SdrObject* pSource = aSourceIter.Next();
437         SdrObject* pTarget = aTargetIter.Next();
438 
439         if( pSource->GetUserCall() )
440             pTarget->SetUserCall( pNewPage );
441     }
442 
443     return pNewPage;
444 }
445 
446 /*************************************************************************
447 |* GetTextStyleSheetForObject
448 \************************************************************************/
449 
450 
451 SfxStyleSheet* SdPage::GetTextStyleSheetForObject( SdrObject* pObj ) const
452 {
453     const PresObjKind eKind = ((SdPage*)this)->GetPresObjKind(pObj);
454     if( eKind != PRESOBJ_NONE )
455     {
456         return ((SdPage*)this)->GetStyleSheetForPresObj(eKind);
457     }
458 
459     return FmFormPage::GetTextStyleSheetForObject( pObj );
460 }
461 
462 SfxItemSet* SdPage::getOrCreateItems()
463 {
464     if( mpItems == NULL )
465         mpItems = new SfxItemSet( pModel->GetItemPool(), SDRATTR_XMLATTRIBUTES, SDRATTR_XMLATTRIBUTES );
466 
467     return mpItems;
468 }
469 
470 
471 sal_Bool SdPage::setAlienAttributes( const com::sun::star::uno::Any& rAttributes )
472 {
473     SfxItemSet* pSet = getOrCreateItems();
474 
475     SvXMLAttrContainerItem aAlienAttributes( SDRATTR_XMLATTRIBUTES );
476     if( aAlienAttributes.PutValue( rAttributes, 0 ) )
477     {
478         pSet->Put( aAlienAttributes );
479         return sal_True;
480     }
481 
482     return sal_False;
483 }
484 
485 void SdPage::getAlienAttributes( com::sun::star::uno::Any& rAttributes )
486 {
487     const SfxPoolItem* pItem;
488 
489     if( (mpItems == NULL) || ( SFX_ITEM_SET != mpItems->GetItemState( SDRATTR_XMLATTRIBUTES, sal_False, &pItem ) ) )
490     {
491         SvXMLAttrContainerItem aAlienAttributes;
492         aAlienAttributes.QueryValue( rAttributes, 0 );
493     }
494     else
495     {
496         ((SvXMLAttrContainerItem*)pItem)->QueryValue( rAttributes, 0 );
497     }
498 }
499 
500 void SdPage::RemoveEmptyPresentationObjects()
501 {
502     SdrObjListIter  aShapeIter( *this, IM_DEEPWITHGROUPS );
503 
504     SdrObject* pShape;
505     for( pShape = aShapeIter.Next(); pShape; pShape = aShapeIter.Next() )
506     {
507         if( pShape && pShape->IsEmptyPresObj() )
508         {
509             RemoveObject( pShape->GetOrdNum() );
510             SdrObject::Free( pShape );
511         }
512 
513     }
514 }
515 
516 sal_Int16 SdPage::getTransitionType (void) const
517 {
518     return mnTransitionType;
519 }
520 
521 void SdPage::setTransitionType( sal_Int16 nTransitionType )
522 {
523     mnTransitionType = nTransitionType;
524     ActionChanged();
525 }
526 
527 sal_Int16 SdPage::getTransitionSubtype (void) const
528 {
529     return mnTransitionSubtype;
530 }
531 
532 void SdPage::setTransitionSubtype ( sal_Int16 nTransitionSubtype )
533 {
534     mnTransitionSubtype = nTransitionSubtype;
535     ActionChanged();
536 }
537 
538 sal_Bool SdPage::getTransitionDirection (void) const
539 {
540     return mbTransitionDirection;
541 }
542 
543 void SdPage::setTransitionDirection ( sal_Bool bTransitionbDirection )
544 {
545     mbTransitionDirection = bTransitionbDirection;
546     ActionChanged();
547 }
548 
549 sal_Int32 SdPage::getTransitionFadeColor (void) const
550 {
551     return mnTransitionFadeColor;
552 }
553 
554 void SdPage::setTransitionFadeColor ( sal_Int32 nTransitionFadeColor )
555 {
556     mnTransitionFadeColor = nTransitionFadeColor;
557     ActionChanged();
558 }
559 
560 double SdPage::getTransitionDuration (void) const
561 {
562     return mfTransitionDuration;
563 }
564 
565 void SdPage::setTransitionDuration ( double fTranstionDuration )
566 {
567     mfTransitionDuration = fTranstionDuration;
568     ActionChanged();
569 }
570 
571 namespace sd {
572 extern void createAnnotation( Reference< XAnnotation >& xAnnotation, SdPage* pPage );
573 extern SdrUndoAction* CreateUndoInsertOrRemoveAnnotation( const Reference< XAnnotation >& xAnnotation, bool bInsert );
574 }
575 
576 void SdPage::createAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
577 {
578     sd::createAnnotation( xAnnotation, this );
579 }
580 
581 void SdPage::addAnnotation( const Reference< XAnnotation >& xAnnotation, int nIndex )
582 {
583     if( (nIndex == -1) || (nIndex > (int)maAnnotations.size()) )
584     {
585         maAnnotations.push_back( xAnnotation );
586     }
587     else
588     {
589         maAnnotations.insert( maAnnotations.begin() + nIndex, xAnnotation );
590     }
591 
592     if( pModel && pModel->IsUndoEnabled() )
593     {
594         SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, true );
595         if( pAction )
596             pModel->AddUndo( pAction );
597     }
598 
599     SetChanged();
600 
601     if( pModel )
602     {
603         pModel->SetChanged();
604         Reference< XInterface > xSource( xAnnotation, UNO_QUERY );
605         NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationInserted" ) ), xSource );
606     }
607 }
608 
609 void SdPage::removeAnnotation( const Reference< XAnnotation >& xAnnotation )
610 {
611     if( pModel && pModel->IsUndoEnabled() )
612     {
613         SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, false );
614         if( pAction )
615             pModel->AddUndo( pAction );
616     }
617 
618     AnnotationVector::iterator iter = std::find( maAnnotations.begin(), maAnnotations.end(), xAnnotation );
619     if( iter != maAnnotations.end() )
620         maAnnotations.erase( iter );
621 
622     if( pModel )
623     {
624         pModel->SetChanged();
625         Reference< XInterface > xSource( xAnnotation, UNO_QUERY );
626         NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationRemoved" ) ), xSource );
627     }
628 }
629