xref: /AOO41X/main/sd/source/core/sdpage2.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
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 
SetPresentationLayout(const String & rLayoutName,sal_Bool bReplaceStyleSheets,sal_Bool bSetMasterPage,sal_Bool bReverseOrder)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 
EndListenOutlineText()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 
SetModel(SdrModel * pNewModel)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 
IsReadOnly() const315 FASTBOOL SdPage::IsReadOnly() const
316 {
317     return sal_False;
318 }
319 
320 /*************************************************************************
321 |*
322 |* Beim sfx2::LinkManager anmelden
323 |*
324 \************************************************************************/
325 
ConnectLink()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 
DisconnectLink()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 
SdPage(const SdPage & rSrcPage)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 
Clone() const430 SdrPage* SdPage::Clone() const
431 {
432     return Clone(NULL);
433 }
434 
Clone(SdrModel * pNewModel) const435 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 
GetTextStyleSheetForObject(SdrObject * pObj) const467 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 
getOrCreateItems()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 
setAlienAttributes(const com::sun::star::uno::Any & rAttributes)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 
getAlienAttributes(com::sun::star::uno::Any & rAttributes)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 
RemoveEmptyPresentationObjects()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 
getTransitionType(void) const532 sal_Int16 SdPage::getTransitionType (void) const
533 {
534     return mnTransitionType;
535 }
536 
setTransitionType(sal_Int16 nTransitionType)537 void SdPage::setTransitionType( sal_Int16 nTransitionType )
538 {
539     mnTransitionType = nTransitionType;
540     ActionChanged();
541 }
542 
getTransitionSubtype(void) const543 sal_Int16 SdPage::getTransitionSubtype (void) const
544 {
545     return mnTransitionSubtype;
546 }
547 
setTransitionSubtype(sal_Int16 nTransitionSubtype)548 void SdPage::setTransitionSubtype ( sal_Int16 nTransitionSubtype )
549 {
550     mnTransitionSubtype = nTransitionSubtype;
551     ActionChanged();
552 }
553 
getTransitionDirection(void) const554 sal_Bool SdPage::getTransitionDirection (void) const
555 {
556     return mbTransitionDirection;
557 }
558 
setTransitionDirection(sal_Bool bTransitionbDirection)559 void SdPage::setTransitionDirection ( sal_Bool bTransitionbDirection )
560 {
561     mbTransitionDirection = bTransitionbDirection;
562     ActionChanged();
563 }
564 
getTransitionFadeColor(void) const565 sal_Int32 SdPage::getTransitionFadeColor (void) const
566 {
567     return mnTransitionFadeColor;
568 }
569 
setTransitionFadeColor(sal_Int32 nTransitionFadeColor)570 void SdPage::setTransitionFadeColor ( sal_Int32 nTransitionFadeColor )
571 {
572     mnTransitionFadeColor = nTransitionFadeColor;
573     ActionChanged();
574 }
575 
getTransitionDuration(void) const576 double SdPage::getTransitionDuration (void) const
577 {
578     return mfTransitionDuration;
579 }
580 
setTransitionDuration(double fTranstionDuration)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 
createAnnotation(::com::sun::star::uno::Reference<::com::sun::star::office::XAnnotation> & xAnnotation)592 void SdPage::createAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
593 {
594     sd::createAnnotation( xAnnotation, this );
595 }
596 
addAnnotation(const Reference<XAnnotation> & xAnnotation,int nIndex)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 
removeAnnotation(const Reference<XAnnotation> & xAnnotation)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