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