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 
31 #include "sddll.hxx"
32 
33 //#include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <com/sun/star/beans/XMultiPropertyStates.hpp>
35 #include <com/sun/star/frame/XController.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <com/sun/star/view/XSelectionSupplier.hpp>
38 #include <com/sun/star/geometry/RealPoint2D.hpp>
39 #include <com/sun/star/text/XText.hpp>
40 #include <com/sun/star/document/XEventBroadcaster.hpp>
41 #include <svx/svxids.hrc>
42 #include <vcl/menu.hxx>
43 #include <vcl/msgbox.hxx>
44 
45 #include <svl/style.hxx>
46 #include <svl/itempool.hxx>
47 #include <unotools/useroptions.hxx>
48 #include <unotools/syslocale.hxx>
49 #include <unotools/saveopt.hxx>
50 
51 #include <tools/datetime.hxx>
52 
53 #include <sfx2/imagemgr.hxx>
54 #include <sfx2/viewfrm.hxx>
55 #include <sfx2/bindings.hxx>
56 #include <sfx2/app.hxx>
57 #include <sfx2/request.hxx>
58 #include <sfx2/dispatch.hxx>
59 #include <sfx2/objface.hxx>
60 #include <sfx2/imagemgr.hxx>
61 
62 #include <editeng/editeng.hxx>
63 #include <editeng/eeitem.hxx>
64 #include <editeng/fontitem.hxx>
65 #include <editeng/fhgtitem.hxx>
66 #include <editeng/outlobj.hxx>
67 #include <editeng/postitem.hxx>
68 #include <editeng/wghtitem.hxx>
69 #include <editeng/udlnitem.hxx>
70 #include <editeng/crsditem.hxx>
71 
72 #include <svx/svdetc.hxx>
73 
74 #include "annotationmanager.hxx"
75 #include "annotationmanagerimpl.hxx"
76 #include "annotationwindow.hxx"
77 #include "annotations.hrc"
78 
79 #include "ToolBarManager.hxx"
80 #include "DrawDocShell.hxx"
81 #include "DrawViewShell.hxx"
82 #include "DrawController.hxx"
83 #include "glob.hrc"
84 #include "sdresid.hxx"
85 #include "EventMultiplexer.hxx"
86 #include "ViewShellManager.hxx"
87 #include "helpids.h"
88 #include "sdpage.hxx"
89 #include "drawdoc.hxx"
90 #include "textapi.hxx"
91 #include "optsitem.hxx"
92 
93 #define C2U(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
94 using ::rtl::OUString;
95 using namespace ::com::sun::star;
96 using namespace ::com::sun::star::uno;
97 using namespace ::com::sun::star::drawing;
98 using namespace ::com::sun::star::document;
99 using namespace ::com::sun::star::geometry;
100 using namespace ::com::sun::star::container;
101 using namespace ::com::sun::star::beans;
102 using namespace ::com::sun::star::text;
103 using namespace ::com::sun::star::view;
104 using namespace ::com::sun::star::style;
105 using namespace ::com::sun::star::frame;
106 using namespace ::com::sun::star::lang;
107 using namespace ::com::sun::star::ui;
108 using namespace ::com::sun::star::task;
109 using namespace ::com::sun::star::office;
110 
111 namespace sd {
112 
113 // --------------------------------------------------------------------
114 
115 extern TextApiObject* getTextApiObject( const Reference< XAnnotation >& xAnnotation );
116 
117 // --------------------------------------------------------------------
118 
119 SfxItemPool* GetAnnotationPool()
120 {
121     static SfxItemPool* mpAnnotationPool = 0;
122 	if( mpAnnotationPool == 0 )
123 	{
124 		mpAnnotationPool = EditEngine::CreatePool( sal_False );
125 		mpAnnotationPool->SetPoolDefaultItem(SvxFontHeightItem(423,100,EE_CHAR_FONTHEIGHT));
126 
127 		Font aAppFont( Application::GetSettings().GetStyleSettings().GetAppFont() );
128 		String EMPTYSTRING;
129 		mpAnnotationPool->SetPoolDefaultItem(SvxFontItem(aAppFont.GetFamily(),aAppFont.GetName(), EMPTYSTRING,PITCH_DONTKNOW,RTL_TEXTENCODING_DONTKNOW,EE_CHAR_FONTINFO));
130 	}
131 
132 	return mpAnnotationPool;
133 }
134 
135 // --------------------------------------------------------------------
136 
137 static SfxBindings* getBindings( ViewShellBase& rBase )
138 {
139 	if( rBase.GetMainViewShell().get() && rBase.GetMainViewShell()->GetViewFrame() )
140 		return &rBase.GetMainViewShell()->GetViewFrame()->GetBindings();
141 	else
142 		return 0;
143 }
144 
145 // --------------------------------------------------------------------
146 
147 static SfxDispatcher* getDispatcher( ViewShellBase& rBase )
148 {
149 	if( rBase.GetMainViewShell().get() && rBase.GetMainViewShell()->GetViewFrame() )
150 		return rBase.GetMainViewShell()->GetViewFrame()->GetDispatcher();
151 	else
152 		return 0;
153 }
154 
155 com::sun::star::util::DateTime getCurrentDateTime()
156 {
157     DateTime aCurrentDate;
158     return com::sun::star::util::DateTime( 0, aCurrentDate.GetSec(), aCurrentDate.GetMin(), aCurrentDate.GetHour(), aCurrentDate.GetDay(), aCurrentDate.GetMonth(), aCurrentDate.GetYear() );
159 }
160 
161 OUString getAnnotationDateTimeString( const Reference< XAnnotation >& xAnnotation )
162 {
163     OUString sRet;
164     if( xAnnotation.is() )
165     {
166 	    const LocaleDataWrapper& rLocalData = SvtSysLocale().GetLocaleData();
167 
168         com::sun::star::util::DateTime aDateTime( xAnnotation->getDateTime() );
169 
170 	    Date aDate = Date( aDateTime.Day, aDateTime.Month, aDateTime.Year );
171 	    if (aDate==Date())
172 		    sRet = sRet + String(SdResId(STR_ANNOTATION_TODAY));
173 	    else
174 	    if (aDate == Date(Date()-1))
175 		    sRet = sRet + String(SdResId(STR_ANNOTATION_YESTERDAY));
176 	    else
177 	    if (aDate.IsValid() )
178 		    sRet = sRet + rLocalData.getDate(aDate);
179 
180         Time aTime( aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.HundredthSeconds );
181 	    if(aTime.GetTime() != 0)
182 		    sRet = sRet + rtl::OUString::createFromAscii(" ")  + rLocalData.getTime( aTime,false );
183     }
184     return sRet;
185 }
186 
187 // --------------------------------------------------------------------
188 
189 AnnotationManagerImpl::AnnotationManagerImpl( ViewShellBase& rViewShellBase )
190 : AnnotationManagerImplBase( m_aMutex )
191 , mrBase( rViewShellBase )
192 , mpDoc( rViewShellBase.GetDocument() )
193 , mbShowAnnotations( true )
194 , mnUpdateTagsEvent( 0 )
195 {
196 	SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
197 	if( pOptions )
198 	    mbShowAnnotations = pOptions->IsShowComments() == sal_True;
199 }
200 
201 // --------------------------------------------------------------------
202 
203 void AnnotationManagerImpl::init()
204 {
205 	// get current controller and initialize listeners
206 	try
207 	{
208 		addListener();
209 		mxView = Reference< XDrawView >::query(mrBase.GetController());
210 	}
211 	catch( Exception& e )
212 	{
213 		(void)e;
214 		DBG_ERROR( "sd::AnnotationManagerImpl::AnnotationManagerImpl(), Exception caught!" );
215 	}
216 
217     try
218     {
219         Reference<XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), UNO_QUERY_THROW );
220         Reference<XEventListener> xListener( this );
221         xModel->addEventListener( xListener );
222     }
223     catch( Exception& )
224     {
225     }
226 }
227 
228 // --------------------------------------------------------------------
229 
230 // WeakComponentImplHelper1
231 void SAL_CALL AnnotationManagerImpl::disposing ()
232 {
233     try
234     {
235         Reference<XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), UNO_QUERY_THROW );
236         Reference<XEventListener> xListener( this );
237         xModel->removeEventListener( xListener );
238     }
239     catch( Exception& )
240     {
241     }
242 
243 	removeListener();
244 	DisposeTags();
245 
246     if( mnUpdateTagsEvent )
247     {
248         Application::RemoveUserEvent( mnUpdateTagsEvent );
249         mnUpdateTagsEvent = 0;
250     }
251 
252     mxView.clear();
253     mxCurrentPage.clear();
254 }
255 
256 // --------------------------------------------------------------------
257 
258 // XEventListener
259 void SAL_CALL AnnotationManagerImpl::notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException)
260 {
261     if( aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnAnnotationInserted") ) ||
262         aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnAnnotationRemoved") ) ||
263         aEvent.EventName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OnAnnotationChanged" )) )
264     {
265         UpdateTags();
266     }
267 }
268 
269 void SAL_CALL AnnotationManagerImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
270 {
271 }
272 
273 void AnnotationManagerImpl::ShowAnnotations( bool bShow )
274 {
275     // enforce show annotations if a new annotation is inserted
276     if( mbShowAnnotations != bShow )
277     {
278         mbShowAnnotations = bShow;
279 
280         SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
281        	if( pOptions )
282 	        pOptions->SetShowComments( mbShowAnnotations ? sal_True : sal_False );
283 
284         UpdateTags();
285 	}
286 }
287 
288 // --------------------------------------------------------------------
289 
290 void AnnotationManagerImpl::ExecuteAnnotation(SfxRequest& rReq )
291 {
292     switch( rReq.GetSlot() )
293     {
294     case SID_INSERT_POSTIT:
295         ExecuteInsertAnnotation( rReq );
296         break;
297 	case SID_DELETE_POSTIT:
298 	case SID_DELETEALL_POSTIT:
299 	case SID_DELETEALLBYAUTHOR_POSTIT:
300 	    ExecuteDeleteAnnotation( rReq );
301         break;
302 	case SID_PREVIOUS_POSTIT:
303 	case SID_NEXT_POSTIT:
304 	    SelectNextAnnotation( rReq.GetSlot() == SID_NEXT_POSTIT );
305         break;
306     case SID_REPLYTO_POSTIT:
307         ExecuteReplyToAnnotation( rReq );
308         break;
309     case SID_SHOW_POSTIT:
310         ShowAnnotations( !mbShowAnnotations );
311         break;
312     }
313 }
314 
315 // --------------------------------------------------------------------
316 
317 void AnnotationManagerImpl::ExecuteInsertAnnotation(SfxRequest& /*rReq*/)
318 {
319     ShowAnnotations(true);
320     InsertAnnotation();
321 }
322 
323 // --------------------------------------------------------------------
324 
325 void AnnotationManagerImpl::ExecuteDeleteAnnotation(SfxRequest& rReq)
326 {
327     ShowAnnotations( true );
328 
329     const SfxItemSet* pArgs = rReq.GetArgs();
330 
331     switch( rReq.GetSlot() )
332     {
333     case SID_DELETEALL_POSTIT:
334         DeleteAllAnnotations();
335         break;
336     case SID_DELETEALLBYAUTHOR_POSTIT:
337         if( pArgs )
338         {
339 	        const SfxPoolItem*  pPoolItem = NULL;
340 	        if( SFX_ITEM_SET == pArgs->GetItemState( SID_DELETEALLBYAUTHOR_POSTIT, sal_True, &pPoolItem ) )
341 	        {
342 	            OUString sAuthor( (( const SfxStringItem* ) pPoolItem )->GetValue() );
343 		        DeleteAnnotationsByAuthor( sAuthor );
344 		    }
345         }
346         break;
347     case SID_DELETE_POSTIT:
348         {
349             Reference< XAnnotation > xAnnotation;
350 
351             if( rReq.GetSlot() == SID_DELETE_POSTIT )
352             {
353                 if( pArgs )
354                 {
355                     const SfxPoolItem*  pPoolItem = NULL;
356                     if( SFX_ITEM_SET == pArgs->GetItemState( SID_DELETE_POSTIT, sal_True, &pPoolItem ) )
357                         ( ( const SfxUnoAnyItem* ) pPoolItem )->GetValue() >>= xAnnotation;
358                 }
359             }
360 
361             if( !xAnnotation.is() )
362                 GetSelectedAnnotation( xAnnotation );
363 
364             DeleteAnnotation( xAnnotation );
365         }
366         break;
367     }
368 
369     UpdateTags();
370 }
371 
372 // --------------------------------------------------------------------
373 
374 void AnnotationManagerImpl::InsertAnnotation()
375 {
376     SdPage* pPage = GetCurrentPage();
377     if( pPage )
378     {
379         if( mpDoc->IsUndoEnabled() )
380             mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_INSERT ) ) );
381 
382         // find free space for new annotation
383         int y = 0, x = 0;
384 
385        	AnnotationVector aAnnotations( pPage->getAnnotations() );
386        	if( !aAnnotations.empty() )
387    	    {
388        	    const int page_width = pPage->GetSize().Width();
389             const int width = 1000;
390             const int height = 800;
391             Rectangle aTagRect;
392 
393        	    while( true )
394        	    {
395                 Rectangle aNewRect( x, y, x + width - 1, y + height - 1 );
396        	        bool bFree = true;
397 
398        	        for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
399        	        {
400        	            RealPoint2D aPoint( (*iter)->getPosition() );
401        	            aTagRect.nLeft   = sal::static_int_cast< long >( aPoint.X * 100.0 );
402        	            aTagRect.nTop    = sal::static_int_cast< long >( aPoint.Y * 100.0 );
403        	            aTagRect.nRight  = aTagRect.nLeft + width - 1;
404        	            aTagRect.nBottom = aTagRect.nTop + height - 1;
405 
406        	            if( aNewRect.IsOver( aTagRect ) )
407        	            {
408        	                bFree = false;
409        	                break;
410        	            }
411        	        }
412 
413        	        if( bFree == false)
414        	        {
415        	            x += width;
416        	            if( x > page_width )
417        	            {
418        	                x = 0;
419        	                y += height;
420        	            }
421        	        }
422        	        else
423        	        {
424        	            break;
425        	        }
426        	    }
427        	}
428 
429         Reference< XAnnotation > xAnnotation;
430         pPage->createAnnotation( xAnnotation );
431 
432         // set current author to new annotation
433         SvtUserOptions aUserOptions;
434         xAnnotation->setAuthor( aUserOptions.GetFullName() );
435 
436         // set current time to new annotation
437         xAnnotation->setDateTime( getCurrentDateTime() );
438 
439         // set position
440         RealPoint2D aPos( ((double)x) / 100.0, ((double)y) / 100.0 );
441         xAnnotation->setPosition( aPos );
442 
443         if( mpDoc->IsUndoEnabled() )
444             mpDoc->EndUndo();
445 
446         UpdateTags(true);
447         SelectAnnotation( xAnnotation, true );
448     }
449 }
450 
451 // --------------------------------------------------------------------
452 
453 void AnnotationManagerImpl::ExecuteReplyToAnnotation( SfxRequest& rReq )
454 {
455     Reference< XAnnotation > xAnnotation;
456     const SfxItemSet* pArgs = rReq.GetArgs();
457     if( pArgs )
458     {
459         const SfxPoolItem*  pPoolItem = NULL;
460         if( SFX_ITEM_SET == pArgs->GetItemState( rReq.GetSlot(), sal_True, &pPoolItem ) )
461 	        ( ( const SfxUnoAnyItem* ) pPoolItem )->GetValue() >>= xAnnotation;
462     }
463 
464 
465     TextApiObject* pTextApi = getTextApiObject( xAnnotation );
466     if( pTextApi )
467     {
468 	    std::auto_ptr< ::Outliner > pOutliner( new ::Outliner(GetAnnotationPool(),OUTLINERMODE_TEXTOBJECT) );
469 
470 	    mpDoc->SetCalcFieldValueHdl( pOutliner.get() );
471 	    pOutliner->SetUpdateMode( sal_True );
472 
473 	    String aStr(SdResId(STR_ANNOTATION_REPLY));
474 	    OUString sAuthor( xAnnotation->getAuthor() );
475 	    if( sAuthor.getLength() == 0 )
476 	        sAuthor = String( SdResId( STR_ANNOTATION_NOAUTHOR ) );
477 
478         aStr.SearchAndReplaceAscii("%1", sAuthor);
479 
480         aStr.Append( String(RTL_CONSTASCII_USTRINGPARAM(" (") ) );
481         aStr.Append( String( getAnnotationDateTimeString( xAnnotation ) ) );
482         aStr.Append( String(RTL_CONSTASCII_USTRINGPARAM("): \"") ) );
483 
484         String sQuote( pTextApi->GetText() );
485 
486         if( sQuote.Len() == 0 )
487             sQuote = String( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
488         aStr.Append( sQuote );
489         aStr.Append( String(RTL_CONSTASCII_USTRINGPARAM("\"\n") ) );
490 
491         sal_uInt16 nParaCount = aStr.GetTokenCount( '\n' );
492         for( sal_uInt16 nPara = 0; nPara < nParaCount; nPara++ )
493             pOutliner->Insert( aStr.GetToken( nPara, '\n' ), LIST_APPEND, -1 );
494 
495         if( pOutliner->GetParagraphCount() > 1 )
496         {
497 	        SfxItemSet aAnswerSet( pOutliner->GetEmptyItemSet() );
498 	        aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
499 
500 	        ESelection aSel;
501 	        aSel.nEndPara = (sal_uInt16)pOutliner->GetParagraphCount()-2;
502 	        aSel.nEndPos = pOutliner->GetText( pOutliner->GetParagraph( aSel.nEndPara ) ).Len();
503 
504             pOutliner->QuickSetAttribs( aAnswerSet, aSel );
505         }
506 
507         std::auto_ptr< OutlinerParaObject > pOPO( pOutliner->CreateParaObject() );
508         pTextApi->SetText( *pOPO.get() );
509 
510         SvtUserOptions aUserOptions;
511         xAnnotation->setAuthor( aUserOptions.GetFullName() );
512 
513         // set current time to reply
514         xAnnotation->setDateTime( getCurrentDateTime() );
515 
516         UpdateTags(true);
517         SelectAnnotation( xAnnotation, true );
518 	}
519 }
520 
521 // --------------------------------------------------------------------
522 
523 void AnnotationManagerImpl::DeleteAnnotation( Reference< XAnnotation > xAnnotation )
524 {
525     SdPage* pPage = GetCurrentPage();
526 
527     if( xAnnotation.is() && pPage )
528     {
529         if( mpDoc->IsUndoEnabled() )
530             mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE ) ) );
531 
532         pPage->removeAnnotation( xAnnotation );
533 
534         if( mpDoc->IsUndoEnabled() )
535             mpDoc->EndUndo();
536 
537         UpdateTags();
538     }
539 }
540 
541 void AnnotationManagerImpl::DeleteAnnotationsByAuthor( const rtl::OUString& sAuthor )
542 {
543     if( mpDoc->IsUndoEnabled() )
544         mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE ) ) );
545 
546     SdPage* pPage = 0;
547 	do
548 	{
549 	    pPage = GetNextPage( pPage, true );
550 
551         if( pPage && !pPage->getAnnotations().empty() )
552         {
553             AnnotationVector aAnnotations( pPage->getAnnotations() );
554             for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
555             {
556                 Reference< XAnnotation > xAnnotation( *iter );
557                 if( xAnnotation->getAuthor() == sAuthor )
558                 {
559                     if( mxSelectedAnnotation == xAnnotation )
560                         mxSelectedAnnotation.clear();
561                     pPage->removeAnnotation( xAnnotation );
562                 }
563             }
564          }
565     } while( pPage );
566 
567     if( mpDoc->IsUndoEnabled() )
568         mpDoc->EndUndo();
569 }
570 
571 void AnnotationManagerImpl::DeleteAllAnnotations()
572 {
573     if( mpDoc->IsUndoEnabled() )
574         mpDoc->BegUndo( String( SdResId( STR_ANNOTATION_UNDO_DELETE ) ) );
575 
576     SdPage* pPage = 0;
577 	do
578 	{
579 	    pPage = GetNextPage( pPage, true );
580 
581         if( pPage && !pPage->getAnnotations().empty() )
582         {
583 
584             AnnotationVector aAnnotations( pPage->getAnnotations() );
585             for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
586             {
587                 pPage->removeAnnotation( (*iter) );
588             }
589          }
590     }
591     while( pPage );
592 
593     mxSelectedAnnotation.clear();
594 
595     if( mpDoc->IsUndoEnabled() )
596         mpDoc->EndUndo();
597 }
598 
599 // --------------------------------------------------------------------
600 
601 void AnnotationManagerImpl::GetAnnotationState(SfxItemSet& rSet)
602 {
603     SdPage* pCurrentPage = GetCurrentPage();
604 
605     const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
606     const bool bWrongPageKind = (pCurrentPage == 0) || (pCurrentPage->GetPageKind() != PK_STANDARD);
607 
608     const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() );
609 
610     if( bReadOnly || bWrongPageKind || (nCurrentODFVersion != SvtSaveOptions::ODFVER_LATEST) )
611         rSet.DisableItem( SID_INSERT_POSTIT );
612 
613     rSet.Put(SfxBoolItem(SID_SHOW_POSTIT, mbShowAnnotations));
614 
615     Reference< XAnnotation > xAnnotation;
616     GetSelectedAnnotation( xAnnotation );
617 
618     if( !xAnnotation.is() || bReadOnly )
619         rSet.DisableItem( SID_DELETE_POSTIT );
620 
621 	SdPage* pPage = 0;
622 
623 	bool bHasAnnotations = false;
624 	do
625 	{
626 	    pPage = GetNextPage( pPage, true );
627 
628         if( pPage && !pPage->getAnnotations().empty() )
629             bHasAnnotations = true;
630     }
631     while( pPage && !bHasAnnotations );
632 
633     if( !bHasAnnotations || bReadOnly )
634     {
635 	    rSet.DisableItem( SID_DELETEALL_POSTIT );
636     }
637 
638     if( bWrongPageKind || !bHasAnnotations )
639     {
640 	    rSet.DisableItem( SID_PREVIOUS_POSTIT );
641 	    rSet.DisableItem( SID_NEXT_POSTIT );
642 	}
643 }
644 
645 // --------------------------------------------------------------------
646 
647 void AnnotationManagerImpl::SelectNextAnnotation(bool bForeward)
648 {
649     ShowAnnotations( true );
650 
651     Reference< XAnnotation > xCurrent;
652     GetSelectedAnnotation( xCurrent );
653     SdPage* pPage = GetCurrentPage();
654     if( !pPage )
655         return;
656 
657    	AnnotationVector aAnnotations( pPage->getAnnotations() );
658 
659     if( bForeward )
660     {
661         if( xCurrent.is() )
662         {
663    	        for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
664    	        {
665    	            if( (*iter) == xCurrent )
666    	            {
667    	                iter++;
668    	                if( iter != aAnnotations.end() )
669    	                {
670    	                    SelectAnnotation( (*iter) );
671    	                    return;
672    	                }
673    	                break;
674    	            }
675    	        }
676         }
677         else if( !aAnnotations.empty() )
678         {
679             SelectAnnotation( *(aAnnotations.begin()) );
680             return;
681         }
682     }
683     else
684     {
685         if( xCurrent.is() )
686         {
687    	        for( AnnotationVector::iterator iter = aAnnotations.begin(); iter != aAnnotations.end(); iter++ )
688    	        {
689    	            if( (*iter) == xCurrent )
690    	            {
691    	                if( iter != aAnnotations.begin() )
692    	                {
693    	                    iter--;
694                         SelectAnnotation( (*iter) );
695                         return;
696 
697    	                }
698    	                break;
699    	            }
700    	        }
701         }
702         else if( !aAnnotations.empty() )
703         {
704             AnnotationVector::iterator iter( aAnnotations.end() );
705             SelectAnnotation( *(--iter) );
706             return;
707         }
708     }
709 
710     mxSelectedAnnotation.clear();
711     do
712     {
713         do
714         {
715             pPage = GetNextPage( pPage, bForeward );
716 
717             if( pPage && !pPage->getAnnotations().empty() )
718             {
719                 // switch to next/previous slide with annotations
720                 ::boost::shared_ptr<DrawViewShell> pDrawViewShell(::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
721                 if (pDrawViewShell.get() != NULL)
722                 {
723                     pDrawViewShell->ChangeEditMode(pPage->IsMasterPage() ? EM_MASTERPAGE : EM_PAGE, sal_False);
724                     pDrawViewShell->SwitchPage((pPage->GetPageNum() - 1) >> 1);
725 
726                     SfxDispatcher* pDispatcher = getDispatcher( mrBase );
727                     if( pDispatcher )
728                         pDispatcher->Execute( bForeward ? SID_NEXT_POSTIT : SID_PREVIOUS_POSTIT );
729 
730                     return;
731                 }
732             }
733         }
734         while( pPage );
735 
736         // The question text depends on the search direction.
737         bool bImpress = mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS;
738         sal_uInt16 nStringId;
739         if(bForeward)
740             nStringId = bImpress ? STR_ANNOTATION_WRAP_FORWARD : STR_ANNOTATION_WRAP_FORWARD_DRAW;
741         else
742             nStringId = bImpress ? STR_ANNOTATION_WRAP_BACKWARD : STR_ANNOTATION_WRAP_BACKWARD_DRAW;
743 
744         // Pop up question box that asks the user whether to wrap arround.
745         // The dialog is made modal with respect to the whole application.
746         QueryBox aQuestionBox (
747             NULL,
748             WB_YES_NO | WB_DEF_YES,
749             String(SdResId(nStringId)));
750         aQuestionBox.SetImage (QueryBox::GetStandardImage());
751         sal_uInt16 nBoxResult = aQuestionBox.Execute();
752         if(nBoxResult != BUTTONID_YES)
753             break;
754     }
755     while( true );
756 }
757 
758 // --------------------------------------------------------------------
759 
760 void AnnotationManagerImpl::onTagSelected(	AnnotationTag& rTag )
761 {
762     mxSelectedAnnotation = rTag.GetAnnotation();
763     invalidateSlots();
764 }
765 
766 // --------------------------------------------------------------------
767 
768 void AnnotationManagerImpl::onTagDeselected( AnnotationTag& rTag )
769 {
770     if( rTag.GetAnnotation() == mxSelectedAnnotation )
771     {
772         mxSelectedAnnotation.clear();
773         invalidateSlots();
774     }
775 }
776 
777 // --------------------------------------------------------------------
778 
779 void AnnotationManagerImpl::SelectAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation > xAnnotation, bool bEdit /* = sal_False */ )
780 {
781     mxSelectedAnnotation = xAnnotation;
782 
783     for( AnnotationTagVector::iterator iter( maTagVector.begin() ); iter != maTagVector.end(); iter++ )
784     {
785         if( (*iter)->GetAnnotation() == xAnnotation )
786         {
787        		SmartTagReference xTag( (*iter).get() );
788             mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
789             (*iter)->OpenPopup( bEdit );
790             break;
791         }
792     }
793 }
794 
795 // --------------------------------------------------------------------
796 
797 void AnnotationManagerImpl::GetSelectedAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
798 {
799     xAnnotation = mxSelectedAnnotation;
800 }
801 
802 void AnnotationManagerImpl::invalidateSlots()
803 {
804     SfxBindings* pBindings = getBindings( mrBase );
805     if( pBindings )
806     {
807         pBindings->Invalidate( SID_INSERT_POSTIT );
808         pBindings->Invalidate( SID_DELETE_POSTIT );
809         pBindings->Invalidate( SID_DELETEALL_POSTIT );
810         pBindings->Invalidate( SID_PREVIOUS_POSTIT );
811         pBindings->Invalidate( SID_NEXT_POSTIT );
812         pBindings->Invalidate( SID_UNDO );
813         pBindings->Invalidate( SID_REDO );
814     }
815 }
816 
817 // --------------------------------------------------------------------
818 
819 void AnnotationManagerImpl::onSelectionChanged()
820 {
821 	if( mxView.is() && mrBase.GetDrawView() ) try
822 	{
823 		Reference< XAnnotationAccess > xPage( mxView->getCurrentPage(), UNO_QUERY );
824 
825 		if( xPage != mxCurrentPage )
826 		{
827 			mxCurrentPage = xPage;
828 
829 			UpdateTags(true);
830 	    }
831 	}
832 	catch( Exception& )
833 	{
834 		DBG_ERROR( "sd::AnnotationManagerImpl::onSelectionChanged(), exception caught!" );
835 	}
836 }
837 
838 void AnnotationManagerImpl::UpdateTags( bool bSynchron )
839 {
840     if( bSynchron )
841     {
842         if( mnUpdateTagsEvent )
843             Application::RemoveUserEvent( mnUpdateTagsEvent );
844 
845             UpdateTagsHdl(0);
846     }
847     else
848     {
849         if( !mnUpdateTagsEvent && mxView.is() )
850             mnUpdateTagsEvent = Application::PostUserEvent( LINK( this, AnnotationManagerImpl, UpdateTagsHdl ) );
851     }
852 }
853 
854 IMPL_LINK(AnnotationManagerImpl,UpdateTagsHdl, void *, EMPTYARG)
855 {
856     mnUpdateTagsEvent  = 0;
857     DisposeTags();
858 
859     if( mbShowAnnotations )
860         CreateTags();
861 
862     if(  mrBase.GetDrawView() )
863         static_cast< ::sd::View* >( mrBase.GetDrawView() )->updateHandles();
864 
865     invalidateSlots();
866 
867     return 0;
868 }
869 
870 void AnnotationManagerImpl::CreateTags()
871 {
872 
873     if( mxCurrentPage.is() && mpDoc ) try
874     {
875 	    int nIndex = 1;
876 	    maFont = Application::GetSettings().GetStyleSettings().GetAppFont();
877 
878         rtl::Reference< AnnotationTag > xSelectedTag;
879 
880 	    Reference< XAnnotationEnumeration > xEnum( mxCurrentPage->createAnnotationEnumeration() );
881 	    while( xEnum->hasMoreElements() )
882 	    {
883 	        Reference< XAnnotation > xAnnotation( xEnum->nextElement() );
884 	        Color aColor( GetColorLight( mpDoc->GetAnnotationAuthorIndex( xAnnotation->getAuthor() ) ) );
885 		    rtl::Reference< AnnotationTag > xTag( new AnnotationTag( *this, *mrBase.GetMainViewShell()->GetView(), xAnnotation, aColor, nIndex++, maFont  ) );
886 		    maTagVector.push_back(xTag);
887 
888 		    if( xAnnotation == mxSelectedAnnotation )
889 		    {
890 		        xSelectedTag = xTag;
891 		    }
892 	    }
893 
894 	    if( xSelectedTag.is() )
895 	    {
896        		SmartTagReference xTag( xSelectedTag.get() );
897             mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
898 	    }
899 	    else
900 	    {
901 	        // no tag, no selection!
902 	        mxSelectedAnnotation.clear();
903 	    }
904     }
905     catch( Exception& )
906     {
907         DBG_ERROR( "sd::AnnotationManagerImpl::onSelectionChanged(), exception caught!" );
908     }
909 }
910 
911 // --------------------------------------------------------------------
912 
913 void AnnotationManagerImpl::DisposeTags()
914 {
915 	if( !maTagVector.empty() )
916 	{
917 		AnnotationTagVector::iterator iter = maTagVector.begin();
918 		do
919 		{
920 			(*iter++)->Dispose();
921 		}
922 		while( iter != maTagVector.end() );
923 
924 		maTagVector.clear();
925 	}
926 }
927 
928 // --------------------------------------------------------------------
929 
930 void AnnotationManagerImpl::addListener()
931 {
932 	Link aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
933     mrBase.GetEventMultiplexer()->AddEventListener (
934         aLink,
935         tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION
936         | tools::EventMultiplexerEvent::EID_CURRENT_PAGE
937         | tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
938         | tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED);
939 }
940 
941 // --------------------------------------------------------------------
942 
943 void AnnotationManagerImpl::removeListener()
944 {
945 	Link aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
946     mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
947 }
948 
949 // --------------------------------------------------------------------
950 
951 IMPL_LINK(AnnotationManagerImpl,EventMultiplexerListener,
952     tools::EventMultiplexerEvent*,pEvent)
953 {
954     switch (pEvent->meEventId)
955     {
956         case tools::EventMultiplexerEvent::EID_CURRENT_PAGE:
957         case tools::EventMultiplexerEvent::EID_EDIT_VIEW_SELECTION:
958             onSelectionChanged();
959             break;
960 
961         case tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
962             mxView = Reference<XDrawView>();
963             onSelectionChanged();
964             break;
965 
966         case tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
967             mxView = Reference<XDrawView>::query( mrBase.GetController() );
968             onSelectionChanged();
969             break;
970     }
971     return 0;
972 }
973 #if 0
974 OUString AnnotationManagerImpl::GetHelpText( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
975 {
976     OUString sRet;
977     if( xAnnotation.is() )
978     {
979 	    OUString sAuthor( xAnnotation->getAuthor() );
980 	    if( sAuthor.getLength() != 0 )
981 	    {
982 	        sRet += sAuthor;
983 	    }
984 	    sRet += OUString( RTL_CONSTASCII_USTRINGPARAM( " [" ) );
985 
986 	    sRet += getAnnotationDateTimeString( xAnnotation );
987 	    sRet += OUString( RTL_CONSTASCII_USTRINGPARAM( "]\n" ) );
988 
989 	    Reference< XText > xText( xAnnotation->getTextRange() );
990 	    if( xText.is() )
991 	        sRet += xText->getString();
992     }
993 
994     return sRet;
995 }
996 #endif
997 
998 void AnnotationManagerImpl::ExecuteAnnotationContextMenu( Reference< XAnnotation > xAnnotation, ::Window* pParent, const Rectangle& rContextRect, bool bButtonMenu /* = false */ )
999 {
1000     SfxDispatcher* pDispatcher( getDispatcher( mrBase ) );
1001     if( !pDispatcher )
1002         return;
1003 
1004     const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
1005 
1006     AnnotationWindow* pAnnotationWindow = bButtonMenu ? 0 : dynamic_cast< AnnotationWindow* >( pParent );
1007 
1008     if( bReadOnly && !pAnnotationWindow )
1009         return;
1010 
1011 	std::auto_ptr< PopupMenu > pMenu( new PopupMenu( SdResId( pAnnotationWindow ? RID_ANNOTATION_CONTEXTMENU : RID_ANNOTATION_TAG_CONTEXTMENU ) ) );
1012 
1013     SvtUserOptions aUserOptions;
1014     OUString sCurrentAuthor( aUserOptions.GetFullName() );
1015     OUString sAuthor( xAnnotation->getAuthor() );
1016 
1017     String aStr( pMenu->GetItemText( SID_DELETEALLBYAUTHOR_POSTIT ) ), aReplace( sAuthor );
1018     if( aReplace.Len() == 0 )
1019         aReplace = String( SdResId( STR_ANNOTATION_NOAUTHOR ) );
1020     aStr.SearchAndReplaceAscii("%1", aReplace);
1021     pMenu->SetItemText( SID_DELETEALLBYAUTHOR_POSTIT, aStr );
1022     pMenu->EnableItem( SID_REPLYTO_POSTIT, (sAuthor != sCurrentAuthor) && !bReadOnly );
1023     pMenu->EnableItem( SID_DELETE_POSTIT, (xAnnotation.is() && !bReadOnly) ? sal_True : sal_False );
1024     pMenu->EnableItem( SID_DELETEALLBYAUTHOR_POSTIT, !bReadOnly );
1025     pMenu->EnableItem( SID_DELETEALL_POSTIT, !bReadOnly );
1026 
1027     if( pAnnotationWindow )
1028     {
1029         if( pAnnotationWindow->IsProtected() || bReadOnly )
1030         {
1031             pMenu->EnableItem( SID_ATTR_CHAR_WEIGHT, sal_False );
1032             pMenu->EnableItem( SID_ATTR_CHAR_POSTURE, sal_False );
1033             pMenu->EnableItem( SID_ATTR_CHAR_UNDERLINE, sal_False );
1034             pMenu->EnableItem( SID_ATTR_CHAR_STRIKEOUT, sal_False );
1035             pMenu->EnableItem( SID_PASTE, sal_False );
1036         }
1037         else
1038         {
1039             SfxItemSet aSet(pAnnotationWindow->getView()->GetAttribs());
1040 
1041 	        if ( aSet.GetItemState( EE_CHAR_WEIGHT ) == SFX_ITEM_ON )
1042 	        {
1043 		        if( ((const SvxWeightItem&)aSet.Get( EE_CHAR_WEIGHT )).GetWeight() == WEIGHT_BOLD )
1044 		            pMenu->CheckItem( SID_ATTR_CHAR_WEIGHT );
1045 		    }
1046 
1047 	        if ( aSet.GetItemState( EE_CHAR_ITALIC ) == SFX_ITEM_ON )
1048 	        {
1049 		        if( ((const SvxPostureItem&)aSet.Get( EE_CHAR_ITALIC )).GetPosture() != ITALIC_NONE )
1050 		            pMenu->CheckItem( SID_ATTR_CHAR_POSTURE );
1051 
1052 		    }
1053 	        if ( aSet.GetItemState( EE_CHAR_UNDERLINE ) == SFX_ITEM_ON )
1054 	        {
1055 		        if( ((const SvxUnderlineItem&)aSet.Get( EE_CHAR_UNDERLINE )).GetLineStyle() != UNDERLINE_NONE )
1056 		            pMenu->CheckItem( SID_ATTR_CHAR_UNDERLINE );
1057 	        }
1058 
1059 	        if ( aSet.GetItemState( EE_CHAR_STRIKEOUT ) == SFX_ITEM_ON )
1060 	        {
1061 		        if( ((const SvxCrossedOutItem&)aSet.Get( EE_CHAR_STRIKEOUT )).GetStrikeout() != STRIKEOUT_NONE )
1062 		            pMenu->CheckItem( SID_ATTR_CHAR_STRIKEOUT );
1063 	        }
1064             TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pAnnotationWindow ) );
1065             pMenu->EnableItem( SID_PASTE, aDataHelper.GetFormatCount() != 0 );
1066 	    }
1067 
1068         pMenu->EnableItem( SID_COPY, pAnnotationWindow->getView()->HasSelection() );
1069     }
1070 
1071     sal_uInt16 nId = 0;
1072 
1073     // set slot images
1074     Reference< ::com::sun::star::frame::XFrame > xFrame( mrBase.GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface() );
1075     if( xFrame.is() )
1076     {
1077         const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
1078         for( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ )
1079         {
1080             nId = pMenu->GetItemId( nPos );
1081             if( pMenu->IsItemEnabled( nId ) )
1082             {
1083                 OUString sSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" ));
1084                 sSlotURL += OUString::valueOf( sal_Int32( nId ));
1085 
1086                 Image aImage( GetImage( xFrame, sSlotURL, false, bHighContrast ) );
1087                 if( !!aImage )
1088                     pMenu->SetItemImage( nId, aImage );
1089             }
1090         }
1091     }
1092 
1093     nId = pMenu->Execute( pParent, rContextRect, POPUPMENU_EXECUTE_DOWN|POPUPMENU_NOMOUSEUPCLOSE );
1094 	switch( nId )
1095 	{
1096     case SID_REPLYTO_POSTIT:
1097     {
1098 		const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( xAnnotation ) );
1099 		pDispatcher->Execute( SID_REPLYTO_POSTIT, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
1100         break;
1101     }
1102     case SID_DELETE_POSTIT:
1103     {
1104 		const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( xAnnotation ) );
1105 		pDispatcher->Execute( SID_DELETE_POSTIT, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
1106         break;
1107     }
1108     case SID_DELETEALLBYAUTHOR_POSTIT:
1109     {
1110 		const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor );
1111 		pDispatcher->Execute( SID_DELETEALLBYAUTHOR_POSTIT, SFX_CALLMODE_ASYNCHRON, &aItem, 0 );
1112         break;
1113     }
1114     case SID_DELETEALL_POSTIT:
1115         pDispatcher->Execute( SID_DELETEALL_POSTIT );
1116         break;
1117     case SID_COPY:
1118     case SID_PASTE:
1119     case SID_ATTR_CHAR_WEIGHT:
1120     case SID_ATTR_CHAR_POSTURE:
1121     case SID_ATTR_CHAR_UNDERLINE:
1122     case SID_ATTR_CHAR_STRIKEOUT:
1123         if( pAnnotationWindow )
1124             pAnnotationWindow->ExecuteSlot( nId );
1125         break;
1126 	}
1127 }
1128 
1129 // ====================================================================
1130 
1131 Color AnnotationManagerImpl::GetColor(sal_uInt16 aAuthorIndex)
1132 {
1133 	if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1134 	{
1135 		static const Color aArrayNormal[] = {
1136 			COL_AUTHOR1_NORMAL,		COL_AUTHOR2_NORMAL,		COL_AUTHOR3_NORMAL,
1137 			COL_AUTHOR4_NORMAL,		COL_AUTHOR5_NORMAL,		COL_AUTHOR6_NORMAL,
1138 			COL_AUTHOR7_NORMAL,		COL_AUTHOR8_NORMAL,		COL_AUTHOR9_NORMAL };
1139 
1140 		return Color( aArrayNormal[ aAuthorIndex % (sizeof( aArrayNormal )/ sizeof( aArrayNormal[0] ))]);
1141 	}
1142 	else
1143 		return Color(COL_WHITE);
1144 }
1145 
1146 Color AnnotationManagerImpl::GetColorLight(sal_uInt16 aAuthorIndex)
1147 {
1148 	if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1149 	{
1150 		static const Color aArrayLight[] = {
1151 			COL_AUTHOR1_LIGHT,		COL_AUTHOR2_LIGHT,		COL_AUTHOR3_LIGHT,
1152 			COL_AUTHOR4_LIGHT,		COL_AUTHOR5_LIGHT,		COL_AUTHOR6_LIGHT,
1153 			COL_AUTHOR7_LIGHT,		COL_AUTHOR8_LIGHT,		COL_AUTHOR9_LIGHT };
1154 
1155 		return Color( aArrayLight[ aAuthorIndex % (sizeof( aArrayLight )/ sizeof( aArrayLight[0] ))]);
1156 	}
1157 	else
1158 		return Color(COL_WHITE);
1159 }
1160 
1161 Color AnnotationManagerImpl::GetColorDark(sal_uInt16 aAuthorIndex)
1162 {
1163 	if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
1164 	{
1165 		static const Color aArrayAnkor[] = {
1166 			COL_AUTHOR1_DARK,		COL_AUTHOR2_DARK,		COL_AUTHOR3_DARK,
1167 			COL_AUTHOR4_DARK,		COL_AUTHOR5_DARK,		COL_AUTHOR6_DARK,
1168 			COL_AUTHOR7_DARK,		COL_AUTHOR8_DARK,		COL_AUTHOR9_DARK };
1169 
1170 		return Color( aArrayAnkor[  aAuthorIndex % (sizeof( aArrayAnkor )	/ sizeof( aArrayAnkor[0] ))]);
1171 	}
1172 	else
1173 		return Color(COL_WHITE);
1174 }
1175 
1176 SdPage* AnnotationManagerImpl::GetNextPage( SdPage* pPage, bool bForeward )
1177 {
1178     if( pPage == 0 )
1179         return bForeward ? GetFirstPage() : GetLastPage();
1180 
1181     sal_uInt16 nPageNum = (pPage->GetPageNum() - 1) >> 1;
1182 
1183     // first all non master pages
1184     if( !pPage->IsMasterPage() )
1185     {
1186         if( bForeward )
1187         {
1188             if( nPageNum >= mpDoc->GetSdPageCount(PK_STANDARD)-1 )
1189             {
1190                 // we reached end of draw pages, start with master pages (skip handout master for draw)
1191                 return mpDoc->GetMasterSdPage( (mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? 0 : 1, PK_STANDARD );
1192             }
1193             nPageNum++;
1194         }
1195         else
1196         {
1197             if( nPageNum == 0 )
1198                 return 0; // we are already on the first draw page, finished
1199 
1200             nPageNum--;
1201         }
1202         return mpDoc->GetSdPage(nPageNum, PK_STANDARD);
1203     }
1204     else
1205     {
1206         if( bForeward )
1207         {
1208             if( nPageNum >= mpDoc->GetMasterSdPageCount(PK_STANDARD)-1 )
1209             {
1210                 return 0;   // we reached the end, there is nothing more to see here
1211             }
1212             nPageNum++;
1213         }
1214         else
1215         {
1216             if( nPageNum == (mpDoc->GetDocumentType() == DOCUMENT_TYPE_IMPRESS) ? 0 : 1 )
1217             {
1218                 // we reached beginning of master pages, start with end if pages
1219                 return mpDoc->GetSdPage( mpDoc->GetSdPageCount(PK_STANDARD)-1, PK_STANDARD );
1220             }
1221 
1222             nPageNum--;
1223         }
1224         return mpDoc->GetMasterSdPage(nPageNum,PK_STANDARD);
1225     }
1226 }
1227 
1228 SdPage* AnnotationManagerImpl::GetFirstPage()
1229 {
1230     // return first drawing page
1231     return mpDoc->GetSdPage(0, PK_STANDARD );
1232 }
1233 
1234 SdPage* AnnotationManagerImpl::GetLastPage()
1235 {
1236     return mpDoc->GetMasterSdPage( mpDoc->GetMasterSdPageCount(PK_STANDARD) - 1, PK_STANDARD );
1237 }
1238 
1239 SdPage* AnnotationManagerImpl::GetCurrentPage()
1240 {
1241 /*
1242     ::boost::shared_ptr<DrawViewShell> pDrawViewShell(::boost::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()));
1243     if (pDrawViewShell.get() != NULL)
1244         return pDrawViewShell->GetActualPage();
1245 */
1246     return mrBase.GetMainViewShell()->getCurrentPage();
1247 }
1248 
1249 // ====================================================================
1250 
1251 AnnotationManager::AnnotationManager( ViewShellBase& rViewShellBase )
1252 : mxImpl( new AnnotationManagerImpl( rViewShellBase ) )
1253 {
1254     mxImpl->init();
1255 }
1256 
1257 AnnotationManager::~AnnotationManager()
1258 {
1259     mxImpl->dispose();
1260 }
1261 
1262 void AnnotationManager::ExecuteAnnotation(SfxRequest& rRequest)
1263 {
1264     mxImpl->ExecuteAnnotation( rRequest );
1265 }
1266 
1267 void AnnotationManager::GetAnnotationState(SfxItemSet& rItemSet)
1268 {
1269     mxImpl->GetAnnotationState(rItemSet);
1270 }
1271 
1272 }
1273