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