xref: /AOO41X/main/sd/source/ui/annotations/annotationmanager.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 
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 
GetAnnotationPool()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 
getBindings(ViewShellBase & rBase)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 
getDispatcher(ViewShellBase & rBase)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 
getCurrentDateTime()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 
getAnnotationDateTimeString(const Reference<XAnnotation> & xAnnotation)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 
AnnotationManagerImpl(ViewShellBase & rViewShellBase)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 
init()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
disposing()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
notifyEvent(const::com::sun::star::document::EventObject & aEvent)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 
disposing(const::com::sun::star::lang::EventObject &)265 void SAL_CALL AnnotationManagerImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
266 {
267 }
268 
ShowAnnotations(bool bShow)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 
ExecuteAnnotation(SfxRequest & rReq)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 
ExecuteInsertAnnotation(SfxRequest &)313 void AnnotationManagerImpl::ExecuteInsertAnnotation(SfxRequest& /*rReq*/)
314 {
315     ShowAnnotations(true);
316     InsertAnnotation();
317 }
318 
319 // --------------------------------------------------------------------
320 
ExecuteDeleteAnnotation(SfxRequest & rReq)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 
InsertAnnotation()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 
ExecuteReplyToAnnotation(SfxRequest & rReq)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 
DeleteAnnotation(Reference<XAnnotation> xAnnotation)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 
DeleteAnnotationsByAuthor(const rtl::OUString & sAuthor)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 
DeleteAllAnnotations()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 
GetAnnotationState(SfxItemSet & rSet)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 
SelectNextAnnotation(bool bForeward)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 arround.
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 
onTagSelected(AnnotationTag & rTag)756 void AnnotationManagerImpl::onTagSelected(  AnnotationTag& rTag )
757 {
758     mxSelectedAnnotation = rTag.GetAnnotation();
759     invalidateSlots();
760 }
761 
762 // --------------------------------------------------------------------
763 
onTagDeselected(AnnotationTag & rTag)764 void AnnotationManagerImpl::onTagDeselected( AnnotationTag& rTag )
765 {
766     if( rTag.GetAnnotation() == mxSelectedAnnotation )
767     {
768         mxSelectedAnnotation.clear();
769         invalidateSlots();
770     }
771 }
772 
773 // --------------------------------------------------------------------
774 
SelectAnnotation(::com::sun::star::uno::Reference<::com::sun::star::office::XAnnotation> xAnnotation,bool bEdit)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 
GetSelectedAnnotation(::com::sun::star::uno::Reference<::com::sun::star::office::XAnnotation> & xAnnotation)793 void AnnotationManagerImpl::GetSelectedAnnotation( ::com::sun::star::uno::Reference< ::com::sun::star::office::XAnnotation >& xAnnotation )
794 {
795     xAnnotation = mxSelectedAnnotation;
796 }
797 
invalidateSlots()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 
onSelectionChanged()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 
UpdateTags(bool bSynchron)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 
IMPL_LINK(AnnotationManagerImpl,UpdateTagsHdl,void *,EMPTYARG)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 
CreateTags()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 
DisposeTags()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 
addListener()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 
removeListener()939 void AnnotationManagerImpl::removeListener()
940 {
941     Link aLink( LINK(this,AnnotationManagerImpl,EventMultiplexerListener) );
942     mrBase.GetEventMultiplexer()->RemoveEventListener( aLink );
943 }
944 
945 // --------------------------------------------------------------------
946 
IMPL_LINK(AnnotationManagerImpl,EventMultiplexerListener,tools::EventMultiplexerEvent *,pEvent)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 
ExecuteAnnotationContextMenu(Reference<XAnnotation> xAnnotation,::Window * pParent,const Rectangle & rContextRect,bool bButtonMenu)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 
GetColor(sal_uInt16 aAuthorIndex)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 
GetColorLight(sal_uInt16 aAuthorIndex)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 
GetColorDark(sal_uInt16 aAuthorIndex)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 
GetNextPage(SdPage * pPage,bool bForeward)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 
GetFirstPage()1224 SdPage* AnnotationManagerImpl::GetFirstPage()
1225 {
1226     // return first drawing page
1227     return mpDoc->GetSdPage(0, PK_STANDARD );
1228 }
1229 
GetLastPage()1230 SdPage* AnnotationManagerImpl::GetLastPage()
1231 {
1232     return mpDoc->GetMasterSdPage( mpDoc->GetMasterSdPageCount(PK_STANDARD) - 1, PK_STANDARD );
1233 }
1234 
GetCurrentPage()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 
AnnotationManager(ViewShellBase & rViewShellBase)1247 AnnotationManager::AnnotationManager( ViewShellBase& rViewShellBase )
1248 : mxImpl( new AnnotationManagerImpl( rViewShellBase ) )
1249 {
1250     mxImpl->init();
1251 }
1252 
~AnnotationManager()1253 AnnotationManager::~AnnotationManager()
1254 {
1255     mxImpl->dispose();
1256 }
1257 
ExecuteAnnotation(SfxRequest & rRequest)1258 void AnnotationManager::ExecuteAnnotation(SfxRequest& rRequest)
1259 {
1260     mxImpl->ExecuteAnnotation( rRequest );
1261 }
1262 
GetAnnotationState(SfxItemSet & rItemSet)1263 void AnnotationManager::GetAnnotationState(SfxItemSet& rItemSet)
1264 {
1265     mxImpl->GetAnnotationState(rItemSet);
1266 }
1267 
1268 }
1269