xref: /trunk/main/sd/source/core/sdpage2.cxx (revision 79aad27f)
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 |*
266 |* das Gliederungstextobjekt bei den Vorlagen fuer die Gliederungsebenen
267 |* abmelden
268 |*
269 \************************************************************************/
270 
271 void SdPage::EndListenOutlineText()
272 {
273 	SdrObject* pOutlineTextObj = GetPresObj(PRESOBJ_OUTLINE);
274 
275 	if (pOutlineTextObj)
276 	{
277 		SdStyleSheetPool* pSPool = (SdStyleSheetPool*)pModel->GetStyleSheetPool();
278 		DBG_ASSERT(pSPool, "StyleSheetPool nicht gefunden");
279 		String aTrueLayoutName(maLayoutName);
280 		aTrueLayoutName.Erase( aTrueLayoutName.SearchAscii( SD_LT_SEPARATOR ));
281 		List* pOutlineStyles = pSPool->CreateOutlineSheetList(aTrueLayoutName);
282 		for (SfxStyleSheet* pSheet = (SfxStyleSheet*)pOutlineStyles->First();
283 			 pSheet;
284 			 pSheet = (SfxStyleSheet*)pOutlineStyles->Next())
285 			{
286 				pOutlineTextObj->EndListening(*pSheet);
287 			}
288 
289 		delete pOutlineStyles;
290 	}
291 }
292 
293 /*************************************************************************
294 |*
295 |* Neues Model setzen
296 |*
297 \************************************************************************/
298 
299 void SdPage::SetModel(SdrModel* pNewModel)
300 {
301 	DisconnectLink();
302 
303 	// Model umsetzen
304 	FmFormPage::SetModel(pNewModel);
305 
306 	ConnectLink();
307 }
308 
309 /*************************************************************************
310 |*
311 |* Ist die Seite read-only?
312 |*
313 \************************************************************************/
314 
315 FASTBOOL SdPage::IsReadOnly() const
316 {
317 	return sal_False;
318 }
319 
320 /*************************************************************************
321 |*
322 |* Beim sfx2::LinkManager anmelden
323 |*
324 \************************************************************************/
325 
326 void SdPage::ConnectLink()
327 {
328 	sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL;
329 
330 	if (pLinkManager && !mpPageLink && maFileName.Len() && maBookmarkName.Len() &&
331 		mePageKind==PK_STANDARD && !IsMasterPage() &&
332 		( (SdDrawDocument*) pModel)->IsNewOrLoadCompleted())
333 	{
334 		/**********************************************************************
335 		* Anmelden
336 		* Nur Standardseiten duerfen gelinkt sein
337 		**********************************************************************/
338 		::sd::DrawDocShell* pDocSh = ((SdDrawDocument*) pModel)->GetDocSh();
339 
340 		if (!pDocSh || pDocSh->GetMedium()->GetOrigURL() != maFileName)
341 		{
342 			// Keine Links auf Dokument-eigene Seiten!
343 			mpPageLink = new SdPageLink(this, maFileName, maBookmarkName);
344 			String aFilterName(SdResId(STR_IMPRESS));
345 			pLinkManager->InsertFileLink(*mpPageLink, OBJECT_CLIENT_FILE,
346 										 maFileName, &aFilterName, &maBookmarkName);
347 			mpPageLink->Connect();
348 		}
349 	}
350 }
351 
352 
353 /*************************************************************************
354 |*
355 |* Beim sfx2::LinkManager abmelden
356 |*
357 \************************************************************************/
358 
359 void SdPage::DisconnectLink()
360 {
361 	sfx2::LinkManager* pLinkManager = pModel!=NULL ? pModel->GetLinkManager() : NULL;
362 
363 	if (pLinkManager && mpPageLink)
364 	{
365 		/**********************************************************************
366 		* Abmelden
367 		* (Bei Remove wird *pGraphicLink implizit deleted)
368 		**********************************************************************/
369 		pLinkManager->Remove(mpPageLink);
370 		mpPageLink=NULL;
371 	}
372 }
373 
374 /*************************************************************************
375 |*
376 |* Copy-Ctor
377 |*
378 \************************************************************************/
379 
380 SdPage::SdPage(const SdPage& rSrcPage)
381 :	FmFormPage(rSrcPage)
382 ,	SdrObjUserCall()
383 ,	mpItems(NULL)
384 {
385 	mePageKind           = rSrcPage.mePageKind;
386 	meAutoLayout         = rSrcPage.meAutoLayout;
387 
388 	SdrObject* pObj = 0;
389 	while((pObj = rSrcPage.maPresentationShapeList.getNextShape(pObj)) != 0)
390 		InsertPresObj(GetObj(pObj->GetOrdNum()), rSrcPage.GetPresObjKind(pObj));
391 
392 	mbSelected           = sal_False;
393 	mnTransitionType	= rSrcPage.mnTransitionType;
394 	mnTransitionSubtype = rSrcPage.mnTransitionSubtype;
395 	mbTransitionDirection = rSrcPage.mbTransitionDirection;
396 	mnTransitionFadeColor = rSrcPage.mnTransitionFadeColor;
397 	mfTransitionDuration = rSrcPage.mfTransitionDuration;
398 	mePresChange			= rSrcPage.mePresChange;
399 	mnTime               = rSrcPage.mnTime;
400 	mbSoundOn            = rSrcPage.mbSoundOn;
401 	mbExcluded           = rSrcPage.mbExcluded;
402 
403 	maLayoutName         = rSrcPage.maLayoutName;
404 	maSoundFile          = rSrcPage.maSoundFile;
405 	mbLoopSound			 = rSrcPage.mbLoopSound;
406 	mbStopSound			 = rSrcPage.mbStopSound;
407 	maCreatedPageName    = String();
408 	maFileName           = rSrcPage.maFileName;
409 	maBookmarkName       = rSrcPage.maBookmarkName;
410 	mbScaleObjects       = rSrcPage.mbScaleObjects;
411 	mbBackgroundFullSize = rSrcPage.mbBackgroundFullSize;
412 	meCharSet            = rSrcPage.meCharSet;
413 	mnPaperBin           = rSrcPage.mnPaperBin;
414 	meOrientation        = rSrcPage.meOrientation;
415 
416 	// header footer
417 	setHeaderFooterSettings( rSrcPage.getHeaderFooterSettings() );
418 
419 	mpPageLink           = NULL;    // Wird beim Einfuegen ueber ConnectLink() gesetzt
420 }
421 
422 
423 
424 /*************************************************************************
425 |*
426 |* Clone
427 |*
428 \************************************************************************/
429 
430 SdrPage* SdPage::Clone() const
431 {
432 	return Clone(NULL);
433 }
434 
435 SdrPage* SdPage::Clone(SdrModel* pNewModel) const
436 {
437 	DBG_ASSERT( pNewModel == 0, "sd::SdPage::Clone(), new page ignored, please check code! CL" );
438 	(void)pNewModel;
439 
440 	SdPage* pNewPage = new SdPage(*this);
441 
442 	cloneAnimations( *pNewPage );
443 
444 	// fix user calls for duplicated slide
445 	SdrObjListIter aSourceIter( *this, IM_DEEPWITHGROUPS );
446 	SdrObjListIter aTargetIter( *pNewPage, IM_DEEPWITHGROUPS );
447 
448 	while( aSourceIter.IsMore() && aTargetIter.IsMore() )
449 	{
450 		SdrObject* pSource = aSourceIter.Next();
451 		SdrObject* pTarget = aTargetIter.Next();
452 
453 		if( pSource->GetUserCall() )
454 			pTarget->SetUserCall( pNewPage );
455 	}
456 
457 	return pNewPage;
458 }
459 
460 /*************************************************************************
461 |*
462 |* GetTextStyleSheetForObject
463 |*
464 \************************************************************************/
465 
466 
467 SfxStyleSheet* SdPage::GetTextStyleSheetForObject( SdrObject* pObj ) const
468 {
469 	const PresObjKind eKind = ((SdPage*)this)->GetPresObjKind(pObj);
470 	if( eKind != PRESOBJ_NONE )
471 	{
472 		return ((SdPage*)this)->GetStyleSheetForPresObj(eKind);
473 	}
474 
475 	return FmFormPage::GetTextStyleSheetForObject( pObj );
476 }
477 
478 SfxItemSet* SdPage::getOrCreateItems()
479 {
480 	if( mpItems == NULL )
481 		mpItems = new SfxItemSet( pModel->GetItemPool(), SDRATTR_XMLATTRIBUTES, SDRATTR_XMLATTRIBUTES );
482 
483 	return mpItems;
484 }
485 
486 
487 sal_Bool SdPage::setAlienAttributes( const com::sun::star::uno::Any& rAttributes )
488 {
489 	SfxItemSet* pSet = getOrCreateItems();
490 
491 	SvXMLAttrContainerItem aAlienAttributes( SDRATTR_XMLATTRIBUTES );
492 	if( aAlienAttributes.PutValue( rAttributes, 0 ) )
493 	{
494 		pSet->Put( aAlienAttributes );
495 		return sal_True;
496 	}
497 
498 	return sal_False;
499 }
500 
501 void SdPage::getAlienAttributes( com::sun::star::uno::Any& rAttributes )
502 {
503 	const SfxPoolItem* pItem;
504 
505 	if( (mpItems == NULL) || ( SFX_ITEM_SET != mpItems->GetItemState( SDRATTR_XMLATTRIBUTES, sal_False, &pItem ) ) )
506 	{
507 		SvXMLAttrContainerItem aAlienAttributes;
508 		aAlienAttributes.QueryValue( rAttributes, 0 );
509 	}
510 	else
511 	{
512 		((SvXMLAttrContainerItem*)pItem)->QueryValue( rAttributes, 0 );
513 	}
514 }
515 
516 void SdPage::RemoveEmptyPresentationObjects()
517 {
518 	SdrObjListIter	aShapeIter( *this, IM_DEEPWITHGROUPS );
519 
520 	SdrObject* pShape;
521 	for( pShape = aShapeIter.Next(); pShape; pShape = aShapeIter.Next() )
522 	{
523 		if( pShape && pShape->IsEmptyPresObj() )
524         {
525 			RemoveObject( pShape->GetOrdNum() );
526             SdrObject::Free( pShape );
527         }
528 
529 	}
530 }
531 
532 sal_Int16 SdPage::getTransitionType (void) const
533 {
534     return mnTransitionType;
535 }
536 
537 void SdPage::setTransitionType( sal_Int16 nTransitionType )
538 {
539     mnTransitionType = nTransitionType;
540     ActionChanged();
541 }
542 
543 sal_Int16 SdPage::getTransitionSubtype (void) const
544 {
545     return mnTransitionSubtype;
546 }
547 
548 void SdPage::setTransitionSubtype ( sal_Int16 nTransitionSubtype )
549 {
550     mnTransitionSubtype = nTransitionSubtype;
551     ActionChanged();
552 }
553 
554 sal_Bool SdPage::getTransitionDirection (void) const
555 {
556     return mbTransitionDirection;
557 }
558 
559 void SdPage::setTransitionDirection ( sal_Bool bTransitionbDirection )
560 {
561     mbTransitionDirection = bTransitionbDirection;
562     ActionChanged();
563 }
564 
565 sal_Int32 SdPage::getTransitionFadeColor (void) const
566 {
567     return mnTransitionFadeColor;
568 }
569 
570 void SdPage::setTransitionFadeColor ( sal_Int32 nTransitionFadeColor )
571 {
572     mnTransitionFadeColor = nTransitionFadeColor;
573     ActionChanged();
574 }
575 
576 double SdPage::getTransitionDuration (void) const
577 {
578     return mfTransitionDuration;
579 }
580 
581 void SdPage::setTransitionDuration ( double fTranstionDuration )
582 {
583     mfTransitionDuration = fTranstionDuration;
584     ActionChanged();
585 }
586 
587 namespace sd {
588 extern void createAnnotation( Reference< XAnnotation >& xAnnotation, SdPage* pPage );
589 extern SdrUndoAction* CreateUndoInsertOrRemoveAnnotation( const Reference< XAnnotation >& xAnnotation, bool bInsert );
590 }
591 
592 void SdPage::createAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
593 {
594     sd::createAnnotation( xAnnotation, this );
595 }
596 
597 void SdPage::addAnnotation( const Reference< XAnnotation >& xAnnotation, int nIndex )
598 {
599     if( (nIndex == -1) || (nIndex > (int)maAnnotations.size()) )
600     {
601 	    maAnnotations.push_back( xAnnotation );
602 	}
603 	else
604 	{
605 	    maAnnotations.insert( maAnnotations.begin() + nIndex, xAnnotation );
606 	}
607 
608 	if( pModel && pModel->IsUndoEnabled() )
609 	{
610 	    SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, true );
611 	    if( pAction )
612 	        pModel->AddUndo( pAction );
613 	}
614 
615 	SetChanged();
616 
617 	if( pModel )
618 	{
619 		pModel->SetChanged();
620 		Reference< XInterface > xSource( xAnnotation, UNO_QUERY );
621 	    NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationInserted" ) ), xSource );
622 	}
623 }
624 
625 void SdPage::removeAnnotation( const Reference< XAnnotation >& xAnnotation )
626 {
627 	if( pModel && pModel->IsUndoEnabled() )
628 	{
629 	    SdrUndoAction* pAction = CreateUndoInsertOrRemoveAnnotation( xAnnotation, false );
630 	    if( pAction )
631 	        pModel->AddUndo( pAction );
632 	}
633 
634 	AnnotationVector::iterator iter = std::find( maAnnotations.begin(), maAnnotations.end(), xAnnotation );
635 	if( iter != maAnnotations.end() )
636 		maAnnotations.erase( iter );
637 
638 	if( pModel )
639 	{
640 		pModel->SetChanged();
641 		Reference< XInterface > xSource( xAnnotation, UNO_QUERY );
642 	    NotifyDocumentEvent( static_cast< SdDrawDocument* >( pModel ), rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnAnnotationRemoved" ) ), xSource );
643 	}
644 }
645