xref: /AOO41X/main/sd/source/ui/slideshow/slideshowimpl.cxx (revision 83137a03adbb58b5b3bdafefefa1e93de35e0011)
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 
25 // MARKER(update_precomp.py): autogen include statement, do not remove
26 #include "precompiled_sd.hxx"
27 
28 #include <boost/scoped_ptr.hpp>
29 
30 #include "com/sun/star/frame/XComponentLoader.hpp"
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/document/XEventsSupplier.hpp>
33 #include <com/sun/star/drawing/XMasterPageTarget.hpp>
34 #include <com/sun/star/container/XNameReplace.hpp>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/beans/XPropertySetInfo.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/awt/SystemPointer.hpp>
39 #include <com/sun/star/util/XURLTransformer.hpp>
40 #include <com/sun/star/frame/XDispatch.hpp>
41 #include <com/sun/star/frame/XLayoutManager.hpp>
42 #include <vos/process.hxx>
43 #include <svl/aeitem.hxx>
44 #include <svl/urihelper.hxx>
45 
46 #include <toolkit/unohlp.hxx>
47 
48 #include <sfx2/imagemgr.hxx>
49 #include <sfx2/request.hxx>
50 #include <sfx2/docfile.hxx>
51 #include <svx/unoapi.hxx>
52 #include <svx/svdoole2.hxx>
53 
54 // for child window ids
55 #include <sfx2/templdlg.hxx>
56 #include <svx/f3dchild.hxx>
57 #include <svx/imapdlg.hxx>
58 #include <svx/fontwork.hxx>
59 #include <svx/SvxColorChildWindow.hxx>
60 #include <svx/bmpmask.hxx>
61 #include <svx/srchdlg.hxx>
62 #include <svx/hyprlink.hxx>
63 #include <svx/hyperdlg.hxx>
64 #include <svx/galbrws.hxx>
65 #include "NavigatorChildWindow.hxx"
66 #include "AnimationChildWindow.hxx"
67 #include <slideshowimpl.hxx>
68 #include <slideshowviewimpl.hxx>
69 #include <pgjump.hxx>
70 #include "PaneHider.hxx"
71 
72 #include "glob.hrc"
73 #include "res_bmp.hrc"
74 #include "sdresid.hxx"
75 #include "vcl/canvastools.hxx"
76 #include "comphelper/anytostring.hxx"
77 #include "cppuhelper/exc_hlp.hxx"
78 #include "rtl/ref.hxx"
79 #include "slideshow.hrc"
80 #include "canvas/elapsedtime.hxx"
81 #include "canvas/prioritybooster.hxx"
82 #include "avmedia/mediawindow.hxx"
83 #include  "svtools/colrdlg.hxx"
84 #include <vcl/imagerepository.hxx>
85 
86 #include <boost/noncopyable.hpp>
87 #include <boost/bind.hpp>
88 
89 using ::rtl::OUString;
90 using ::rtl::OString;
91 using ::cppu::OInterfaceContainerHelper;
92 using ::comphelper::ImplementationReference;
93 using ::com::sun::star::animations::XAnimationNode;
94 using ::com::sun::star::animations::XAnimationListener;
95 using ::com::sun::star::awt::XWindow;
96 using namespace ::com::sun::star;
97 using namespace ::com::sun::star::lang;
98 using namespace ::com::sun::star::uno;
99 using namespace ::com::sun::star::drawing;
100 using namespace ::com::sun::star::container;
101 using namespace ::com::sun::star::document;
102 using namespace ::com::sun::star::presentation;
103 using namespace ::com::sun::star::drawing;
104 using namespace ::com::sun::star::beans;
105 
106 extern void NotifyDocumentEvent( SdDrawDocument* pDocument, const rtl::OUString& rEventName );
107 extern String getUiNameFromPageApiNameImpl( const OUString& rApiName );
108 
109 namespace sd
110 {
111 ///////////////////////////////////////////////////////////////////////
112 
113 // Slots, welche im Sfx verwaltet werden und in der SlideShow disabled
114 // werden sollen (muss in Reihenfolge der SIDs geordnet sein)
115 static sal_uInt16 __READONLY_DATA pAllowed[] =
116 {
117     SID_OPENDOC                             , //     5501   // damit interne Spruenge klappen
118     SID_JUMPTOMARK                          , //     5598
119 //  SID_SHOWPOPUPS                          , //     5929
120 //    SID_GALLERY                             , //     5960
121     SID_OPENHYPERLINK                       , //     6676
122 //    SID_GALLERY_FORMATS                     , //    10280
123     SID_NAVIGATOR                           , //    10366
124 //  SID_FM_DESIGN_MODE                      , //    10629
125     SID_PRESENTATION_END                    , //    27218
126     SID_NAVIGATOR_PAGENAME                  , //    27287
127     SID_NAVIGATOR_STATE                     , //    27288
128     SID_NAVIGATOR_INIT                      , //    27289
129     SID_NAVIGATOR_PEN                       , //    27291
130     SID_NAVIGATOR_PAGE                      , //    27292
131     SID_NAVIGATOR_OBJECT                      //    27293
132 };
133 
134 ///////////////////////////////////////////////////////////////////////
135 
136 ///////////////////////////////////////////////////////////////////////
137 // AnimationSlideController
138 ///////////////////////////////////////////////////////////////////////
139 
140 class AnimationSlideController
141 {
142 public:
143     enum Mode { ALL, FROM, CUSTOM, PREVIEW };
144 
145 public:
146     AnimationSlideController( Reference< XIndexAccess > xSlides, Mode eMode );
147 
148     void setStartSlideNumber( sal_Int32 nSlideNumber ) { mnStartSlideNumber = nSlideNumber; }
149     sal_Int32 getStartSlideIndex() const;
150 
151     sal_Int32 getCurrentSlideNumber() const;
152     sal_Int32 getCurrentSlideIndex() const;
153 
154     sal_Int32 getSlideIndexCount() const { return maSlideNumbers.size(); }
155     sal_Int32 getSlideNumberCount() const { return mnSlideCount; }
156 
157     sal_Int32 getSlideNumber( sal_Int32 nSlideIndex ) const;
158 
159     void insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible = true );
160     void setPreviewNode( const Reference< XAnimationNode >& xPreviewNode );
161 
162     bool jumpToSlideIndex( sal_Int32 nNewSlideIndex );
163     bool jumpToSlideNumber( sal_Int32 nNewSlideIndex );
164 
165     bool nextSlide();
166     bool previousSlide();
167 
168     void displayCurrentSlide( const Reference< XSlideShow >& xShow,
169                               const Reference< XDrawPagesSupplier>& xDrawPages,
170                               const bool bSkipAllMainSequenceEffects );
171 
172     sal_Int32 getNextSlideIndex() const;
173     sal_Int32 getPreviousSlideIndex() const;
174 
175     bool isVisibleSlideNumber( sal_Int32 nSlideNumber ) const;
176 
177     Reference< XDrawPage > getSlideByNumber( sal_Int32 nSlideNumber ) const;
178 
179     sal_Int32 getNextSlideNumber() const;
180 
181     bool hasSlides() const { return !maSlideNumbers.empty(); }
182 
183 private:
184     bool getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode );
185     sal_Int32 findSlideIndex( sal_Int32 nSlideNumber ) const;
186 
187     bool isValidIndex( sal_Int32 nIndex ) const { return (nIndex >= 0) && (nIndex < (sal_Int32)maSlideNumbers.size()); }
188     bool isValidSlideNumber( sal_Int32 nSlideNumber ) const { return (nSlideNumber >= 0) && (nSlideNumber < mnSlideCount); }
189 
190 private:
191     Mode meMode;
192     sal_Int32 mnStartSlideNumber;
193     std::vector< sal_Int32 > maSlideNumbers;
194     std::vector< bool > maSlideVisible;
195     std::vector< bool > maSlideVisited;
196     Reference< XAnimationNode > mxPreviewNode;
197     sal_Int32 mnSlideCount;
198     sal_Int32 mnCurrentSlideIndex;
199     sal_Int32 mnHiddenSlideNumber;
200     Reference< XIndexAccess > mxSlides;
201 };
202 
203 Reference< XDrawPage > AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber ) const
204 {
205     Reference< XDrawPage > xSlide;
206     if( mxSlides.is() && (nSlideNumber >= 0) && (nSlideNumber < mxSlides->getCount()) )
207         mxSlides->getByIndex( nSlideNumber ) >>= xSlide;
208     return xSlide;
209 }
210 
211 bool AnimationSlideController::isVisibleSlideNumber( sal_Int32 nSlideNumber ) const
212 {
213     sal_Int32 nIndex = findSlideIndex( nSlideNumber );
214 
215     if( nIndex != -1 )
216         return maSlideVisible[ nIndex ];
217     else
218         return false;
219 }
220 
221 
222 void AnimationSlideController::setPreviewNode( const Reference< XAnimationNode >& xPreviewNode )
223 {
224     mxPreviewNode = xPreviewNode;
225 }
226 
227 AnimationSlideController::AnimationSlideController( Reference< XIndexAccess > xSlides, Mode eMode  )
228 :   meMode( eMode )
229 ,   mnStartSlideNumber(-1)
230 ,   mnSlideCount( 0 )
231 ,   mnCurrentSlideIndex(0)
232 ,   mnHiddenSlideNumber( -1 )
233 ,   mxSlides( xSlides )
234 {
235     if( mxSlides.is() )
236         mnSlideCount = xSlides->getCount();
237 }
238 
239 sal_Int32 AnimationSlideController::getStartSlideIndex() const
240 {
241     if( mnStartSlideNumber >= 0 )
242     {
243         sal_Int32 nIndex;
244         const sal_Int32 nCount = maSlideNumbers.size();
245 
246         for( nIndex = 0; nIndex < nCount; nIndex++ )
247         {
248             if( maSlideNumbers[nIndex] == mnStartSlideNumber )
249                 return nIndex;
250         }
251     }
252 
253     return 0;
254 }
255 
256 sal_Int32 AnimationSlideController::getCurrentSlideNumber() const
257 {
258     if( mnHiddenSlideNumber != -1 )
259         return mnHiddenSlideNumber;
260     else if( !maSlideNumbers.empty() )
261         return maSlideNumbers[mnCurrentSlideIndex];
262     else
263         return 0;
264 }
265 
266 sal_Int32 AnimationSlideController::getCurrentSlideIndex() const
267 {
268     if( mnHiddenSlideNumber != -1 )
269         return -1;
270     else
271         return mnCurrentSlideIndex;
272 }
273 
274 bool AnimationSlideController::jumpToSlideIndex( sal_Int32 nNewSlideIndex )
275 {
276     if( isValidIndex( nNewSlideIndex ) )
277     {
278         mnCurrentSlideIndex = nNewSlideIndex;
279         mnHiddenSlideNumber = -1;
280         maSlideVisited[mnCurrentSlideIndex] = true;
281         return true;
282     }
283     else
284     {
285         return false;
286     }
287 }
288 
289 bool AnimationSlideController::jumpToSlideNumber( sal_Int32 nNewSlideNumber )
290 {
291     sal_Int32 nIndex = findSlideIndex( nNewSlideNumber );
292     if( isValidIndex( nIndex ) )
293     {
294         return jumpToSlideIndex( nIndex );
295     }
296     else if( (nNewSlideNumber >= 0) && (nNewSlideNumber < mnSlideCount) )
297     {
298         // jump to a hidden slide
299         mnHiddenSlideNumber = nNewSlideNumber;
300         return true;
301     }
302     else
303     {
304         return false;
305     }
306 }
307 
308 sal_Int32 AnimationSlideController::getSlideNumber( sal_Int32 nSlideIndex ) const
309 {
310     if( isValidIndex( nSlideIndex ) )
311         return maSlideNumbers[nSlideIndex];
312     else
313         return -1;
314 }
315 
316 void AnimationSlideController::insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible /* = true */ )
317 {
318     DBG_ASSERT( isValidSlideNumber( nSlideNumber ), "sd::AnimationSlideController::insertSlideNumber(), illegal index" );
319     if( isValidSlideNumber( nSlideNumber ) )
320     {
321         maSlideNumbers.push_back( nSlideNumber );
322         maSlideVisible.push_back( bVisible );
323         maSlideVisited.push_back( false );
324     }
325 }
326 
327 bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode )
328 {
329     if( isValidSlideNumber( nSlideNumber ) ) try
330     {
331         xSlide = Reference< XDrawPage >( mxSlides->getByIndex(nSlideNumber), UNO_QUERY_THROW );
332 
333         if( meMode == PREVIEW )
334         {
335             xAnimNode = mxPreviewNode;
336         }
337         else
338         {
339             Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier( xSlide, UNO_QUERY_THROW );
340             xAnimNode = xAnimNodeSupplier->getAnimationNode();
341         }
342 
343         return true;
344     }
345     catch( Exception& e )
346     {
347         (void)e;
348         DBG_ERROR(
349             (OString("sd::AnimationSlideController::getSlideAPI(), "
350                     "exception caught: ") +
351             rtl::OUStringToOString(
352                 comphelper::anyToString( cppu::getCaughtException() ),
353                 RTL_TEXTENCODING_UTF8 )).getStr() );
354 
355     }
356 
357     return false;
358 }
359 
360 sal_Int32 AnimationSlideController::findSlideIndex( sal_Int32 nSlideNumber ) const
361 {
362     sal_Int32 nIndex;
363     const sal_Int32 nCount = maSlideNumbers.size();
364 
365     for( nIndex = 0; nIndex < nCount; nIndex++ )
366     {
367         if( maSlideNumbers[nIndex] == nSlideNumber )
368             return nIndex;
369     }
370 
371     return -1;
372 }
373 
374 sal_Int32 AnimationSlideController::getNextSlideIndex() const
375 {
376     switch( meMode )
377     {
378     case ALL:
379         {
380             sal_Int32 nNewSlideIndex = mnCurrentSlideIndex + 1;
381             if( isValidIndex( nNewSlideIndex ) )
382             {
383                 // if the current slide is not excluded, make sure the
384                 // next slide is also not excluded.
385                 // if the current slide is excluded, we want to go
386                 // to the next slide, even if this is also excluded.
387                 if( maSlideVisible[mnCurrentSlideIndex] )
388                 {
389                     while( isValidIndex( nNewSlideIndex ) )
390                     {
391                         if( maSlideVisible[nNewSlideIndex] )
392                             break;
393 
394                         nNewSlideIndex++;
395                     }
396                 }
397             }
398             return isValidIndex( nNewSlideIndex ) ? nNewSlideIndex : -1;
399         }
400 
401     case FROM:
402     case CUSTOM:
403         return mnHiddenSlideNumber == -1 ? mnCurrentSlideIndex + 1 : mnCurrentSlideIndex;
404 
405     default:
406     case PREVIEW:
407         return -1;
408 
409     }
410 }
411 
412 sal_Int32 AnimationSlideController::getNextSlideNumber() const
413 {
414     sal_Int32 nNextSlideIndex = getNextSlideIndex();
415     if( isValidIndex( nNextSlideIndex ) )
416     {
417         return maSlideNumbers[nNextSlideIndex];
418     }
419     else
420     {
421         return -1;
422     }
423 }
424 
425 
426 bool AnimationSlideController::nextSlide()
427 {
428     return jumpToSlideIndex( getNextSlideIndex() );
429 }
430 
431 sal_Int32 AnimationSlideController::getPreviousSlideIndex() const
432 {
433     sal_Int32 nNewSlideIndex = mnCurrentSlideIndex - 1;
434 
435     switch( meMode )
436     {
437         case ALL:
438         {
439             // make sure the previous slide is visible
440             // or was already visited
441             while( isValidIndex( nNewSlideIndex ) )
442             {
443                 if( maSlideVisible[nNewSlideIndex] || maSlideVisited[nNewSlideIndex] )
444                     break;
445 
446                 nNewSlideIndex--;
447             }
448 
449             break;
450         }
451 
452         case PREVIEW:
453             return -1;
454 
455         default:
456             break;
457     }
458 
459     return nNewSlideIndex;
460 }
461 
462 bool AnimationSlideController::previousSlide()
463 {
464     return jumpToSlideIndex( getPreviousSlideIndex() );
465 }
466 
467 void AnimationSlideController::displayCurrentSlide( const Reference< XSlideShow >& xShow,
468                                                     const Reference< XDrawPagesSupplier>& xDrawPages,
469                                                     const bool bSkipAllMainSequenceEffects )
470 {
471     const sal_Int32 nCurrentSlideNumber = getCurrentSlideNumber();
472 
473     if( xShow.is() && (nCurrentSlideNumber != -1 ) )
474     {
475         Reference< XDrawPage > xSlide;
476         Reference< XAnimationNode > xAnimNode;
477         ::std::vector<PropertyValue> aProperties;
478 
479         const sal_Int32 nNextSlideNumber = getNextSlideNumber();
480         if( getSlideAPI( nNextSlideNumber, xSlide, xAnimNode )  )
481         {
482             Sequence< Any > aValue(2);
483             aValue[0] <<= xSlide;
484             aValue[1] <<= xAnimNode;
485             aProperties.push_back(
486                 PropertyValue(
487                     OUString( RTL_CONSTASCII_USTRINGPARAM( "Prefetch" ) ),
488                     -1,
489                     Any(aValue),
490                     PropertyState_DIRECT_VALUE));
491         }
492         if (bSkipAllMainSequenceEffects)
493         {
494             // Add one property that prevents the slide transition from being
495             // shown (to speed up the transition to the previous slide) and
496             // one to show all main sequence effects so that the user can
497             // continue to undo effects.
498             aProperties.push_back(
499                 PropertyValue(
500                     OUString( RTL_CONSTASCII_USTRINGPARAM("SkipAllMainSequenceEffects")),
501                     -1,
502                     Any(sal_True),
503                     PropertyState_DIRECT_VALUE));
504             aProperties.push_back(
505                 PropertyValue(
506                     OUString( RTL_CONSTASCII_USTRINGPARAM("SkipSlideTransition")),
507                     -1,
508                     Any(sal_True),
509                     PropertyState_DIRECT_VALUE));
510         }
511 
512         // Convert vector into uno Sequence.
513         Sequence< PropertyValue > aPropertySequence (aProperties.size());
514         for (int nIndex=0,nCount=aProperties.size();nIndex<nCount; ++nIndex)
515             aPropertySequence[nIndex] = aProperties[nIndex];
516 
517         if( getSlideAPI( nCurrentSlideNumber, xSlide, xAnimNode ) )
518             xShow->displaySlide( xSlide, xDrawPages, xAnimNode, aPropertySequence );
519     }
520 }
521 
522 ///////////////////////////////////////////////////////////////////////
523 // class SlideshowImpl
524 ///////////////////////////////////////////////////////////////////////
525 
526 SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, ::Window* pParentWindow )
527 : SlideshowImplBase( m_aMutex )
528 , mxModel(pDoc->getUnoModel(),UNO_QUERY_THROW)
529 , mpView(pView)
530 , mpViewShell(pViewSh)
531 , mpDocSh(pDoc->GetDocSh())
532 , mpDoc(pDoc)
533 , mpNewAttr(0)
534 , mpParentWindow(pParentWindow)
535 , mpShowWindow(0)
536 , mpTimeButton(0)
537 , mnRestoreSlide(0)
538 , maPresSize( -1, -1 )
539 , meAnimationMode(ANIMATIONMODE_SHOW)
540 , mpOldActiveWindow(0)
541 , mnChildMask( 0 )
542 , mbGridVisible(false)
543 , mbBordVisible(false)
544 , mbSlideBorderVisible(false)
545 , mbSetOnlineSpelling(false)
546 , mbDisposed(false)
547 , mbRehearseTimings(false)
548 , mbDesignMode(false)
549 , mbIsPaused(false)
550 , mbInputFreeze(false)
551 , mbActive(sal_False)
552 , maPresSettings( pDoc->getPresentationSettings() )
553 , mnUserPaintColor( 0x80ff0000L )
554 , mbUsePen(false)
555 , mdUserPaintStrokeWidth ( 150.0 )
556 #ifdef ENABLE_ERASER_UI
557 , mbSwitchEraserMode(false)
558 , mnEraseInkSize(100)
559 #endif
560 , mnEntryCounter(0)
561 , mnLastSlideNumber(-1)
562 , msOnClick( RTL_CONSTASCII_USTRINGPARAM("OnClick") )
563 , msBookmark( RTL_CONSTASCII_USTRINGPARAM("Bookmark") )
564 , msVerb( RTL_CONSTASCII_USTRINGPARAM("Verb") )
565 , mnEndShowEvent(0)
566 , mnContextMenuEvent(0)
567 , mnUpdateEvent(0)
568 , mxPresentation( xPresentation )
569 {
570     if( mpViewShell )
571         mpOldActiveWindow = mpViewShell->GetActiveWindow();
572 
573     maUpdateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, updateHdl));
574 
575     maDeactivateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, deactivateHdl));
576     maDeactivateTimer.SetTimeout( 20 );
577 
578     maInputFreezeTimer.SetTimeoutHdl( LINK( this, SlideshowImpl, ReadyForNextInputHdl ) );
579     maInputFreezeTimer.SetTimeout( 20 );
580 
581     SvtSaveOptions aOptions;
582 
583         // no autosave during show
584     if( aOptions.IsAutoSave() )
585         mbAutoSaveWasOn = true;
586 
587     Application::AddEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );
588 
589     mbUsePen = maPresSettings.mbMouseAsPen;
590 
591     SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
592     if( pOptions )
593     {
594         mnUserPaintColor = pOptions->GetPresentationPenColor();
595         mdUserPaintStrokeWidth = pOptions->GetPresentationPenWidth();
596     }
597 }
598 
599 SlideshowImpl::~SlideshowImpl()
600 {
601     SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
602     if( pOptions )
603     {
604         pOptions->SetPresentationPenColor(mnUserPaintColor);
605         pOptions->SetPresentationPenWidth(mdUserPaintStrokeWidth);
606     }
607 
608     Application::RemoveEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );
609 
610     maDeactivateTimer.Stop();
611 
612     if( !mbDisposed )
613     {
614         DBG_ERROR("SlideshowImpl::~SlideshowImpl(), component was not disposed!");
615         disposing();
616     }
617 }
618 
619 void SAL_CALL SlideshowImpl::disposing()
620 {
621     if( mxShow.is() && mpDoc )
622         NotifyDocumentEvent( mpDoc, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OnEndPresentation") ) );
623 
624     if( mbAutoSaveWasOn )
625         setAutoSaveState( true );
626 
627     if( mnEndShowEvent )
628         Application::RemoveUserEvent( mnEndShowEvent );
629     if( mnContextMenuEvent )
630         Application::RemoveUserEvent( mnContextMenuEvent );
631 
632     maInputFreezeTimer.Stop();
633 
634     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
635 
636     if( !mxShow.is() )
637         return;
638 
639     if( mxPresentation.is() )
640         mxPresentation->end();
641 
642     maUpdateTimer.Stop();
643 
644     if( mnUpdateEvent )
645     {
646         Application::RemoveUserEvent( mnUpdateEvent );
647         mnUpdateEvent = 0;
648     }
649 
650     removeShapeEvents();
651 
652     if( mxListenerProxy.is() )
653         mxListenerProxy->removeAsSlideShowListener();
654 
655     try
656     {
657         if( mxView.is() )
658             mxShow->removeView( mxView.getRef() );
659 
660         Reference< XComponent > xComponent( mxShow, UNO_QUERY );
661         if( xComponent.is() )
662             xComponent->dispose();
663 
664         if( mxView.is() )
665             mxView->dispose();
666     }
667     catch( Exception& e )
668     {
669         static_cast<void>(e);
670         DBG_ERROR(
671             (OString("sd::SlideshowImpl::stop(), "
672                     "exception caught: ") +
673             rtl::OUStringToOString(
674                 comphelper::anyToString( cppu::getCaughtException() ),
675                 RTL_TEXTENCODING_UTF8 )).getStr() );
676 
677     }
678 
679     mxShow.clear();
680     mxView.reset();
681     mxListenerProxy.clear();
682     mpSlideController.reset();
683 
684     // der DrawView das Praesentationfenster wegnehmen und ihr dafuer ihre alten Fenster wiedergeben
685     if( mpShowWindow && mpView )
686         mpView->DeleteWindowFromPaintView( mpShowWindow );
687 
688     if( mpView )
689         mpView->SetAnimationPause( sal_False );
690 
691     if( mpViewShell )
692     {
693         mpViewShell->SetActiveWindow(mpOldActiveWindow);
694         mpShowWindow->SetViewShell( NULL );
695     }
696 
697     if( mpView )
698         mpView->InvalidateAllWin();
699 
700     if( maPresSettings.mbFullScreen )
701     {
702         // restore StarBASICErrorHdl
703         StarBASIC::SetGlobalErrorHdl(maStarBASICGlobalErrorHdl);
704         maStarBASICGlobalErrorHdl = Link();
705     }
706     else
707     {
708         if( mpShowWindow )
709             mpShowWindow->Hide();
710     }
711 
712     if( meAnimationMode == ANIMATIONMODE_SHOW )
713     {
714         mpDocSh->SetSlotFilter();
715         mpDocSh->ApplySlotFilter();
716 
717         Help::EnableContextHelp();
718         Help::EnableExtHelp();
719 
720         showChildWindows();
721         mnChildMask = 0UL;
722     }
723 
724     // aktuelle Fenster wieder einblenden
725     if( mpViewShell && !mpViewShell->ISA(PresentationViewShell))
726     {
727         if( meAnimationMode == ANIMATIONMODE_SHOW )
728         {
729             mpViewShell->GetViewShellBase().ShowUIControls (true);
730             mpPaneHider.reset();
731         }
732         else if( meAnimationMode == ANIMATIONMODE_PREVIEW )
733         {
734             mpViewShell->ShowUIControls (true);
735         }
736     }
737 
738     if( mpTimeButton )
739     {
740         mpTimeButton->Hide();
741         delete mpTimeButton;
742         mpTimeButton = 0;
743     }
744 
745     if( mpShowWindow )
746         mpShowWindow->Hide();
747 
748     if ( mpViewShell )
749     {
750         if( meAnimationMode == ANIMATIONMODE_SHOW )
751         {
752             ::sd::Window* pActWin = mpViewShell->GetActiveWindow();
753 
754             if (pActWin)
755             {
756                 Size aVisSizePixel = pActWin->GetOutputSizePixel();
757                 Rectangle aVisAreaWin = pActWin->PixelToLogic( Rectangle( Point(0,0), aVisSizePixel) );
758                 mpViewShell->VisAreaChanged(aVisAreaWin);
759                 mpView->VisAreaChanged(pActWin);
760                 pActWin->GrabFocus();
761             }
762         }
763 
764         // restart the custom show dialog if he started us
765         if( mpViewShell->IsStartShowWithDialog() && getDispatcher() )
766         {
767             mpViewShell->SetStartShowWithDialog( sal_False );
768             getDispatcher()->Execute( SID_CUSTOMSHOW_DLG, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
769         }
770 
771         mpViewShell->GetViewShellBase().UpdateBorder(true);
772     }
773 
774     if( mpShowWindow )
775     {
776         delete mpShowWindow;
777         mpShowWindow = 0;
778     }
779 
780     setActiveXToolbarsVisible( sal_True );
781 
782     Application::EnableNoYieldMode(false);
783     Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
784 
785     mbDisposed = true;
786 }
787 
788 bool SlideshowImpl::startPreview(
789         const Reference< XDrawPage >& xDrawPage,
790         const Reference< XAnimationNode >& xAnimationNode,
791         ::Window* pParent )
792 {
793     bool bRet = false;
794 
795     try
796     {
797         const Reference<lang::XServiceInfo> xServiceInfo( xDrawPage, UNO_QUERY );
798         if (xServiceInfo.is()) {
799             const Sequence<OUString> supportedServices(
800                 xServiceInfo->getSupportedServiceNames() );
801             for ( sal_Int32 pos = supportedServices.getLength(); pos--; ) {
802                 if (supportedServices[pos].equalsAsciiL(
803                         RTL_CONSTASCII_STRINGPARAM(
804                             "com.sun.star.drawing.MasterPage") )) {
805                     DBG_ERROR("sd::SlideshowImpl::startPreview() "
806                               "not allowed on master page!");
807                     return false;
808                 }
809             }
810         }
811 
812         mxPreviewDrawPage = xDrawPage;
813         mxPreviewAnimationNode = xAnimationNode;
814         meAnimationMode = ANIMATIONMODE_PREVIEW;
815 
816         maPresSettings.mbAll = sal_False;
817         maPresSettings.mbEndless = sal_False;
818         maPresSettings.mbCustomShow = sal_False;
819         maPresSettings.mbManual = sal_False;
820         maPresSettings.mbMouseVisible = sal_False;
821         maPresSettings.mbMouseAsPen = sal_False;
822         maPresSettings.mbLockedPages = sal_False;
823         maPresSettings.mbAlwaysOnTop = sal_False;
824         maPresSettings.mbFullScreen = sal_False;
825         maPresSettings.mbAnimationAllowed = sal_True;
826         maPresSettings.mnPauseTimeout = 0;
827         maPresSettings.mbShowPauseLogo = sal_False;
828         maPresSettings.mbStartWithNavigator = sal_False;
829 
830         Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
831         Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
832         mpSlideController.reset( new AnimationSlideController( xSlides, AnimationSlideController::PREVIEW ) );
833 
834         sal_Int32 nSlideNumber = 0;
835         Reference< XPropertySet > xSet( mxPreviewDrawPage, UNO_QUERY_THROW );
836         xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Number" ) ) ) >>= nSlideNumber;
837         mpSlideController->insertSlideNumber( nSlideNumber-1 );
838         mpSlideController->setPreviewNode( xAnimationNode );
839 
840         mpShowWindow = new ShowWindow( this, ((pParent == 0) && mpViewShell) ?  mpParentWindow : pParent );
841         if( mpViewShell )
842         {
843             mpViewShell->SetActiveWindow( mpShowWindow );
844             mpShowWindow->SetViewShell (mpViewShell);
845             mpViewShell->ShowUIControls (false);
846         }
847 
848         if( mpView )
849         {
850             mpView->AddWindowToPaintView( mpShowWindow );
851             mpView->SetAnimationPause( sal_True );
852         }
853 
854         // call resize handler
855         if( pParent )
856         {
857             maPresSize = pParent->GetSizePixel();
858         }
859         else if( mpViewShell )
860         {
861             Rectangle aContentRect (mpViewShell->GetViewShellBase().getClientRectangle());
862             if (Application::GetSettings().GetLayoutRTL())
863             {
864                 aContentRect.nLeft = aContentRect.nRight;
865                 aContentRect.nRight += aContentRect.nRight;
866             }
867             maPresSize = aContentRect.GetSize();
868             mpShowWindow->SetPosPixel( aContentRect.TopLeft() );
869         }
870         else
871         {
872             DBG_ERROR("sd::SlideshowImpl::startPreview(), I need either a parent window or a viewshell!");
873         }
874         resize( maPresSize );
875 
876         sal_Int32 nPropertyCount = 1;
877         if( mxPreviewAnimationNode.is() )
878             nPropertyCount++;
879 
880         Sequence< beans::PropertyValue > aProperties(nPropertyCount);
881         aProperties[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("AutomaticAdvancement") );
882         aProperties[0].Value = uno::makeAny( (double)1.0 ); // one second timeout
883 
884         if( mxPreviewAnimationNode.is() )
885         {
886             aProperties[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("NoSlideTransitions") );
887             aProperties[1].Value = uno::makeAny( sal_True );
888         }
889 
890         bRet = startShowImpl( aProperties );
891 
892         if( mpShowWindow != 0 && meAnimationMode == ANIMATIONMODE_PREVIEW )
893             mpShowWindow->SetPreviewMode();
894 
895     }
896     catch( Exception& e )
897     {
898         (void)e;
899         DBG_ERROR(
900             (OString("sd::SlideshowImpl::startPreview(), "
901                      "exception caught: ") +
902              rtl::OUStringToOString(
903                  comphelper::anyToString( cppu::getCaughtException() ),
904                  RTL_TEXTENCODING_UTF8 )).getStr() );
905         bRet = false;
906     }
907 
908     return bRet;
909 }
910 
911 bool SlideshowImpl::startShow( PresentationSettingsEx* pPresSettings )
912 {
913     const rtl::Reference<SlideshowImpl> this_(this);
914 
915     DBG_ASSERT( !mxShow.is(), "sd::SlideshowImpl::startShow(), called twice!" );
916     if( mxShow.is() )
917         return true;
918     DBG_ASSERT( mpParentWindow!=NULL, "sd::SlideshowImpl::startShow() called without parent window" );
919     if (mpParentWindow == NULL)
920         return false;
921 
922     bool bRet = false;
923 
924     try
925     {
926         if( pPresSettings )
927         {
928             maPresSettings = *pPresSettings;
929             mbRehearseTimings = pPresSettings->mbRehearseTimings;
930         }
931 
932         // ---
933 
934         String  aPresSlide( maPresSettings.maPresPage );
935         SdPage* pStartPage = mpViewShell ? mpViewShell->GetActualPage() : 0;
936         bool    bStartWithActualSlide =  pStartPage &&
937                                         ( (meAnimationMode != ANIMATIONMODE_SHOW) ||
938                                            SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsStartWithActualPage() );
939 
940         // sollen Zeiten gestoppt werden?
941         if( mbRehearseTimings )
942         {
943             maPresSettings.mbEndless = sal_False;
944             maPresSettings.mbManual = sal_True;
945             maPresSettings.mbMouseVisible = sal_True;
946             maPresSettings.mbMouseAsPen = sal_False;
947             maPresSettings.mnPauseTimeout = 0;
948             maPresSettings.mbShowPauseLogo = sal_False;
949             maPresSettings.mbStartWithNavigator = sal_False;
950         }
951 
952         if( pStartPage )
953         {
954             if( pStartPage->GetPageKind() == PK_NOTES )
955             {
956                 // we are in notes page mode, so get
957                 // the corresponding draw page
958                 const sal_uInt16 nPgNum = ( pStartPage->GetPageNum() - 2 ) >> 1;
959                 pStartPage = mpDoc->GetSdPage( nPgNum, PK_STANDARD );
960             }
961         }
962 
963         if( bStartWithActualSlide )
964         {
965             if( meAnimationMode != ANIMATIONMODE_SHOW )
966             {
967                 if( pStartPage->GetPageKind() == PK_STANDARD )
968                 {
969                     aPresSlide = pStartPage->GetName();
970                     maPresSettings.mbAll = false;
971                 }
972                 else
973                 {
974                     bStartWithActualSlide = false;
975                 }
976             }
977         }
978         else
979         {
980             if( pStartPage->GetPageKind() != PK_STANDARD )
981             {
982                 bStartWithActualSlide = false;
983             }
984         }
985 
986         // build page list
987         createSlideList( maPresSettings.mbAll, false, aPresSlide );
988 
989         if( bStartWithActualSlide )
990         {
991             sal_Int32 nSlideNum = ( pStartPage->GetPageNum() - 1 ) >> 1;
992 
993             if( !maPresSettings.mbAll && !maPresSettings.mbCustomShow )
994             {
995                 // its start from dia, find out if it is located before our current Slide
996                 const sal_Int32 nSlideCount = mpDoc->GetSdPageCount( PK_STANDARD );
997                 sal_Int32 nSlide;
998                 for( nSlide = 0; (nSlide < nSlideCount); nSlide++ )
999                 {
1000                     if( mpDoc->GetSdPage( (sal_uInt16) nSlide, PK_STANDARD )->GetName() == aPresSlide )
1001                         break;
1002                 }
1003 
1004                 if( nSlide > nSlideNum )
1005                     nSlideNum = -1;
1006             }
1007 
1008             if( nSlideNum != -1 )
1009                 mpSlideController->setStartSlideNumber( nSlideNum );
1010         }
1011 
1012         // remember Slide number from where the show was started
1013         if( pStartPage )
1014             mnRestoreSlide = ( pStartPage->GetPageNum() - 1 ) / 2;
1015 
1016         if( mpSlideController->hasSlides() )
1017         {
1018             // hide child windows
1019             hideChildWindows();
1020 
1021             mpShowWindow = new ShowWindow( this, mpParentWindow );
1022             mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
1023             if( mpViewShell )
1024             {
1025                 mpViewShell->SetActiveWindow( mpShowWindow );
1026                 mpShowWindow->SetViewShell (mpViewShell);
1027                 mpViewShell->GetViewShellBase().ShowUIControls (false);
1028                 // Hide the side panes for in-place presentations.
1029                 if ( ! maPresSettings.mbFullScreen)
1030                     mpPaneHider.reset(new PaneHider(*mpViewShell,this));
1031 
1032                 if( getViewFrame() )
1033                     getViewFrame()->SetChildWindow( SID_NAVIGATOR, maPresSettings.mbStartWithNavigator );
1034             }
1035 
1036             // these Slots are forbiden in other views for this document
1037             if( mpDocSh )
1038             {
1039                 mpDocSh->SetSlotFilter( sal_True, sizeof( pAllowed ) / sizeof( sal_uInt16 ), pAllowed );
1040                 mpDocSh->ApplySlotFilter();
1041             }
1042 
1043             Help::DisableContextHelp();
1044             Help::DisableExtHelp();
1045 
1046         //  mpTimeButton = new PushButton( mpShowWindow, SdResId( RID_TIME_BUTTON ) );
1047         //  maPencil = Pointer( POINTER_PEN );
1048         //  mpTimeButton->Hide();
1049 
1050             if( maPresSettings.mbFullScreen )
1051             {
1052                 // disable basic ide error handling
1053                 maStarBASICGlobalErrorHdl = StarBASIC::GetGlobalErrorHdl();
1054                 StarBASIC::SetGlobalErrorHdl( Link() );
1055             }
1056 
1057             // call resize handler
1058             maPresSize = mpParentWindow->GetSizePixel();
1059             if( !maPresSettings.mbFullScreen && mpViewShell )
1060             {
1061                 const Rectangle& aClientRect = mpViewShell->GetViewShellBase().getClientRectangle();
1062                 maPresSize = aClientRect.GetSize();
1063                 mpShowWindow->SetPosPixel( aClientRect.TopLeft() );
1064                 resize( maPresSize );
1065             }
1066 
1067             // #i41824#
1068             // Note: In FullScreen Mode the OS (window manager) sends a resize to
1069             // the WorkWindow once it actually resized it to full size.  The
1070             // WorkWindow propagates the resize to the DrawViewShell which calls
1071             // resize() at the SlideShow (this).  Calling resize here results in a
1072             // temporary display of a black window in the window's default size
1073 
1074 /*
1075             if ( mbRehearseTimings )
1076             {
1077                 Size  aButtonSizePixel( pTimeButton->GetSizePixel() );
1078                 Point aButtonPosPixel( aButtonSizePixel.Width() >> 1, pShowWindow->GetSizePixel().Height() - aButtonSizePixel.Height() * 5 / 2);
1079 
1080                 pTimeButton->SetPosPixel( aButtonPosPixel );
1081                 aTimer.SetTimeoutHdl( LINK( this,FuSlideShow, TimeButtonTimeOutHdl ) );
1082                 pTimeButton->SetClickHdl( LINK( this, FuSlideShow, TimeButtonHdl ) );
1083             }
1084 */
1085 
1086             if( mpView )
1087             {
1088                 mpView->AddWindowToPaintView( mpShowWindow );
1089                 mpView->SetAnimationPause( sal_True );
1090             }
1091 
1092             SfxBindings* pBindings = getBindings();
1093             if( pBindings )
1094             {
1095                 pBindings->Invalidate( SID_PRESENTATION );
1096                 pBindings->Invalidate( SID_REHEARSE_TIMINGS );
1097             }
1098 
1099             // Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly.
1100             //mpShowWindow->GrabFocus();
1101 
1102             std::vector<beans::PropertyValue> aProperties;
1103             aProperties.reserve( 4 );
1104 
1105             aProperties.push_back(
1106                 beans::PropertyValue(
1107                     OUString( RTL_CONSTASCII_USTRINGPARAM("AdvanceOnClick") ),
1108                     -1, Any( ! (maPresSettings.mbLockedPages != sal_False) ),
1109                     beans::PropertyState_DIRECT_VALUE ) );
1110 
1111             aProperties.push_back(
1112                 beans::PropertyValue(
1113                     OUString( RTL_CONSTASCII_USTRINGPARAM("ImageAnimationsAllowed") ),
1114                     -1, Any( maPresSettings.mbAnimationAllowed != sal_False ),
1115                     beans::PropertyState_DIRECT_VALUE ) );
1116 
1117             const sal_Bool bZOrderEnabled(
1118                 SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsSlideshowRespectZOrder() );
1119             aProperties.push_back(
1120                 beans::PropertyValue(
1121                     OUString( RTL_CONSTASCII_USTRINGPARAM("DisableAnimationZOrder") ),
1122                     -1, Any( bZOrderEnabled == sal_False ),
1123                     beans::PropertyState_DIRECT_VALUE ) );
1124 
1125 /*
1126             aProperties.push_back(
1127                 beans::PropertyValue(
1128                     OUString( RTL_CONSTASCII_USTRINGPARAM("MouseVisible") ),
1129                     -1, Any( maPresSettings.mbMouseVisible != sal_False ),
1130                     beans::PropertyState_DIRECT_VALUE ) );
1131 */
1132             aProperties.push_back(
1133                 beans::PropertyValue(
1134                     OUString( RTL_CONSTASCII_USTRINGPARAM("ForceManualAdvance") ),
1135                     -1, Any( maPresSettings.mbManual != sal_False ),
1136                     beans::PropertyState_DIRECT_VALUE ) );
1137 
1138             if( mbUsePen )
1139             {
1140                 aProperties.push_back(
1141                     beans::PropertyValue(
1142                         OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintColor") ),
1143                         // User paint color is black by default.
1144                         -1, Any( mnUserPaintColor ),
1145                         beans::PropertyState_DIRECT_VALUE ) );
1146 
1147                 aProperties.push_back(
1148                     beans::PropertyValue(
1149                         OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintStrokeWidth") ),
1150                         // User paint color is black by default.
1151                         -1, Any( mdUserPaintStrokeWidth ),
1152                         beans::PropertyState_DIRECT_VALUE ) );
1153             }
1154 
1155             if (mbRehearseTimings) {
1156                 aProperties.push_back(
1157                     beans::PropertyValue(
1158                         OUString( RTL_CONSTASCII_USTRINGPARAM("RehearseTimings") ),
1159                         -1, Any(true), beans::PropertyState_DIRECT_VALUE ) );
1160             }
1161 
1162             bRet = startShowImpl( Sequence<beans::PropertyValue>(
1163                                       &aProperties[0], aProperties.size() ) );
1164 
1165         }
1166 
1167         setActiveXToolbarsVisible( sal_False );
1168     }
1169     catch( Exception& e )
1170     {
1171         (void)e;
1172         DBG_ERROR(
1173             (OString("sd::SlideshowImpl::startShow(), "
1174                      "exception caught: ") +
1175              rtl::OUStringToOString(
1176                  comphelper::anyToString( cppu::getCaughtException() ),
1177                  RTL_TEXTENCODING_UTF8 )).getStr() );
1178         bRet = false;
1179     }
1180 
1181     return bRet;
1182 }
1183 
1184 bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProperties )
1185 {
1186     try
1187     {
1188         mxShow = Reference< XSlideShow >( createSlideShow(), UNO_QUERY_THROW );
1189         mxView = mxView.createFromQuery( new SlideShowView(
1190                                              *mpShowWindow,
1191                                              mpDoc,
1192                                              meAnimationMode,
1193                                              this,
1194                                              maPresSettings.mbFullScreen) );
1195 
1196         // try add wait symbol to properties:
1197         const Reference<rendering::XSpriteCanvas> xSpriteCanvas(
1198             mxView->getCanvas() );
1199         if (xSpriteCanvas.is())
1200         {
1201             BitmapEx waitSymbolBitmap( SdResId(BMP_WAIT_ICON) );
1202             const Reference<rendering::XBitmap> xBitmap(
1203                 vcl::unotools::xBitmapFromBitmapEx(
1204                     xSpriteCanvas->getDevice(), waitSymbolBitmap ) );
1205             if (xBitmap.is())
1206             {
1207                 mxShow->setProperty(
1208                     beans::PropertyValue(
1209                         OUString( RTL_CONSTASCII_USTRINGPARAM("WaitSymbolBitmap") ),
1210                         -1,
1211                         makeAny( xBitmap ),
1212                         beans::PropertyState_DIRECT_VALUE ) );
1213             }
1214         }
1215 
1216         const sal_Int32 nCount = aProperties.getLength();
1217         sal_Int32 nIndex;
1218         for( nIndex = 0; nIndex < nCount; nIndex++ )
1219             mxShow->setProperty( aProperties[nIndex] );
1220 
1221         mxShow->addView( mxView.getRef() );
1222 
1223         mxListenerProxy.set( new SlideShowListenerProxy( this, mxShow ) );
1224         mxListenerProxy->addAsSlideShowListener();
1225 
1226 
1227         NotifyDocumentEvent( mpDoc, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OnStartPresentation") ) );
1228         displaySlideIndex( mpSlideController->getStartSlideIndex() );
1229 
1230         return true;
1231     }
1232     catch( Exception& e )
1233     {
1234         (void)e;
1235         DBG_ERROR(
1236             (OString("sd::SlideshowImpl::startShowImpl(), "
1237                      "exception caught: ") +
1238              rtl::OUStringToOString(
1239                  comphelper::anyToString( cppu::getCaughtException() ),
1240                  RTL_TEXTENCODING_UTF8 )).getStr() );
1241         return false;
1242     }
1243 }
1244 
1245 /** called only by the slideshow view when the first paint event occurs.
1246     This actually starts the slideshow. */
1247 void SlideshowImpl::onFirstPaint()
1248 {
1249     if( mpShowWindow )
1250     {
1251         /*
1252         mpShowWindow->SetBackground( Wallpaper( Color( COL_BLACK ) ) );
1253         mpShowWindow->Erase();
1254         mpShowWindow->SetBackground();
1255         */
1256     }
1257 
1258     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1259     maUpdateTimer.SetTimeout( (sal_uLong)100 );
1260     maUpdateTimer.Start();
1261 }
1262 
1263 void SlideshowImpl::paint( const Rectangle& /* rRect */ )
1264 {
1265     if( mxView.is() ) try
1266     {
1267         awt::PaintEvent aEvt;
1268         // aEvt.UpdateRect = TODO
1269         mxView->paint( aEvt );
1270     }
1271     catch( Exception& e )
1272     {
1273         static_cast<void>(e);
1274         DBG_ERROR(
1275             (OString("sd::SlideshowImpl::paint(), "
1276                     "exception caught: ") +
1277             rtl::OUStringToOString(
1278                 comphelper::anyToString( cppu::getCaughtException() ),
1279                 RTL_TEXTENCODING_UTF8 )).getStr() );
1280     }
1281 }
1282 
1283 // --------------------------------------------------------------------
1284 
1285 void SAL_CALL SlideshowImpl::addSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException)
1286 {
1287     if( mxListenerProxy.is() )
1288         mxListenerProxy->addSlideShowListener( xListener );
1289 }
1290 
1291 // --------------------------------------------------------------------
1292 
1293 void SAL_CALL SlideshowImpl::removeSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException)
1294 {
1295     if( mxListenerProxy.is() )
1296         mxListenerProxy->removeSlideShowListener( xListener );
1297 }
1298 
1299 // ---------------------------------------------------------
1300 
1301 void SlideshowImpl::slideEnded(const bool bReverse)
1302 {
1303     if (bReverse)
1304         gotoPreviousSlide(true);
1305     else
1306         gotoNextSlide();
1307 }
1308 
1309 // ---------------------------------------------------------
1310 
1311 void SlideshowImpl::removeShapeEvents()
1312 {
1313     if( mxShow.is() && mxListenerProxy.is() ) try
1314     {
1315         WrappedShapeEventImplMap::iterator aIter;
1316         const WrappedShapeEventImplMap::iterator aEnd( maShapeEventMap.end() );
1317 
1318         for( aIter = maShapeEventMap.begin(); aIter != aEnd; aIter++ )
1319         {
1320             mxListenerProxy->removeShapeEventListener( (*aIter).first );
1321             mxShow->setShapeCursor( (*aIter).first, awt::SystemPointer::ARROW );
1322         }
1323 
1324         maShapeEventMap.clear();
1325     }
1326     catch( Exception& e )
1327     {
1328         (void)e;
1329         DBG_ERROR(
1330             (OString("sd::SlideshowImpl::removeShapeEvents(), "
1331                      "exception caught: ") +
1332              rtl::OUStringToOString(
1333                  comphelper::anyToString( cppu::getCaughtException() ),
1334                  RTL_TEXTENCODING_UTF8 )).getStr() );
1335     }
1336 }
1337 
1338 // ---------------------------------------------------------
1339 
1340 void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber)
1341 {
1342     if( nSlideNumber >= 0 ) try
1343     {
1344         Reference< XDrawPagesSupplier > xDrawPages( mxModel, UNO_QUERY_THROW );
1345         Reference< XIndexAccess > xPages( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
1346 
1347         Reference< XShapes > xDrawPage;
1348         xPages->getByIndex(nSlideNumber) >>= xDrawPage;
1349 
1350         if( xDrawPage.is() )
1351         {
1352             Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
1353             if( xMasterPageTarget.is() )
1354             {
1355                 Reference< XShapes > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
1356                 if( xMasterPage.is() )
1357                     registerShapeEvents( xMasterPage );
1358             }
1359             registerShapeEvents( xDrawPage );
1360         }
1361     }
1362     catch( Exception& e )
1363     {
1364         (void)e;
1365         DBG_ERROR(
1366             (OString("sd::SlideshowImpl::registerShapeEvents(), "
1367                      "exception caught: ") +
1368              rtl::OUStringToOString(
1369                  comphelper::anyToString( cppu::getCaughtException() ),
1370                  RTL_TEXTENCODING_UTF8 )).getStr() );
1371     }
1372 }
1373 
1374 // ---------------------------------------------------------
1375 
1376 void SlideshowImpl::registerShapeEvents( Reference< XShapes >& xShapes ) throw( Exception )
1377 {
1378     try
1379     {
1380         const sal_Int32 nShapeCount = xShapes->getCount();
1381         sal_Int32 nShape;
1382         for( nShape = 0; nShape < nShapeCount; nShape++ )
1383         {
1384             Reference< XShape > xShape;
1385             xShapes->getByIndex( nShape ) >>= xShape;
1386 
1387             if( xShape.is() &&
1388                 xShape->getShapeType().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.GroupShape") ) )
1389             {
1390                 Reference< XShapes > xSubShapes( xShape, UNO_QUERY );
1391                 if( xSubShapes.is() )
1392                     registerShapeEvents( xSubShapes );
1393             }
1394 
1395             Reference< XPropertySet > xSet( xShape, UNO_QUERY );
1396             if( !xSet.is() )
1397                 continue;
1398 
1399             Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1400             if( !xSetInfo.is() || !xSetInfo->hasPropertyByName( msOnClick ) )
1401                 continue;
1402 
1403             WrappedShapeEventImplPtr pEvent( new WrappedShapeEventImpl );
1404             xSet->getPropertyValue( msOnClick ) >>= pEvent->meClickAction;
1405 
1406             switch( pEvent->meClickAction )
1407             {
1408             case ClickAction_PREVPAGE:
1409             case ClickAction_NEXTPAGE:
1410             case ClickAction_FIRSTPAGE:
1411             case ClickAction_LASTPAGE:
1412             case ClickAction_STOPPRESENTATION:
1413                 break;
1414             case ClickAction_BOOKMARK:
1415                 if( xSetInfo->hasPropertyByName( msBookmark ) )
1416                     xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1417                 if( getSlideNumberForBookmark( pEvent->maStrBookmark ) == -1 )
1418                     continue;
1419                 break;
1420             case ClickAction_DOCUMENT:
1421             case ClickAction_SOUND:
1422             case ClickAction_PROGRAM:
1423             case ClickAction_MACRO:
1424                 if( xSetInfo->hasPropertyByName( msBookmark ) )
1425                     xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1426                 break;
1427             case ClickAction_VERB:
1428                 if( xSetInfo->hasPropertyByName( msVerb ) )
1429                     xSet->getPropertyValue( msVerb ) >>= pEvent->mnVerb;
1430                 break;
1431             default:
1432                 continue; // skip all others
1433             }
1434 
1435             maShapeEventMap[ xShape ] = pEvent;
1436 
1437             if( mxListenerProxy.is() )
1438                 mxListenerProxy->addShapeEventListener( xShape );
1439             mxShow->setShapeCursor( xShape, awt::SystemPointer::REFHAND );
1440         }
1441     }
1442     catch( Exception& e )
1443     {
1444         static_cast<void>(e);
1445         DBG_ERROR(
1446             (OString("sd::SlideshowImpl::registerShapeEvents(), "
1447                     "exception caught: ") +
1448             rtl::OUStringToOString(
1449                 comphelper::anyToString( cppu::getCaughtException() ),
1450                 RTL_TEXTENCODING_UTF8 )).getStr() );
1451     }
1452 }
1453 
1454 // ---------------------------------------------------------
1455 
1456 void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects)
1457 {
1458     stopSound();
1459     removeShapeEvents();
1460 
1461     if( mpSlideController.get() && mxShow.is() )
1462     {
1463         Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(),
1464                                                     UNO_QUERY_THROW );
1465         mpSlideController->displayCurrentSlide( mxShow, xDrawPages, bSkipAllMainSequenceEffects );
1466         registerShapeEvents(mpSlideController->getCurrentSlideNumber());
1467         update();
1468 
1469         SfxBindings* pBindings = getBindings();
1470         if( pBindings )
1471         {
1472             pBindings->Invalidate( SID_NAVIGATOR_STATE );
1473             pBindings->Invalidate( SID_NAVIGATOR_PAGENAME );
1474         }
1475     }
1476     // send out page change event and notity to update all acc info for current page
1477     if (mpViewShell)
1478     {
1479         sal_Int32 currentPageIndex = getCurrentSlideIndex();
1480         mpViewShell->fireSwitchCurrentPage(currentPageIndex);
1481         mpViewShell->NotifyAccUpdate();
1482     }
1483 }
1484 
1485 // ---------------------------------------------------------
1486 
1487 void SlideshowImpl::endPresentation()
1488 {
1489 /*
1490     if( maPresSettings.mbMouseAsPen)
1491     {
1492         Reference< XMultiServiceFactory > xDocFactory(mpDoc->getUnoModel(), UNO_QUERY );
1493         if( xDocFactory.is() )
1494             mxShow->registerUserPaintPolygons(xDocFactory);
1495     }
1496 */
1497     if( !mnEndShowEvent )
1498         mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) );
1499 }
1500 
1501 // ---------------------------------------------------------
1502 
1503 IMPL_LINK( SlideshowImpl, endPresentationHdl, void*, EMPTYARG )
1504 {
1505     mnEndShowEvent = 0;
1506 
1507     if( mxPresentation.is() )
1508         mxPresentation->end();
1509     return 0;
1510 }
1511 
1512 // ---------------------------------------------------------
1513 
1514 void SAL_CALL SlideshowImpl::pause() throw (RuntimeException)
1515 {
1516     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1517 
1518     if( !mbIsPaused ) try
1519     {
1520         mbIsPaused = sal_True;
1521         if( mxShow.is() )
1522         {
1523             mxShow->pause(sal_True);
1524 
1525             if( mxListenerProxy.is() )
1526                 mxListenerProxy->paused();
1527         }
1528     }
1529     catch( Exception& e )
1530     {
1531         static_cast<void>(e);
1532         DBG_ERROR(
1533             (OString("sd::SlideshowImpl::pause(), "
1534                     "exception caught: ") +
1535             rtl::OUStringToOString(
1536                 comphelper::anyToString( cppu::getCaughtException() ),
1537                 RTL_TEXTENCODING_UTF8 )).getStr() );
1538     }
1539 }
1540 
1541 // ---------------------------------------------------------
1542 
1543 void SAL_CALL SlideshowImpl::resume() throw (RuntimeException)
1544 {
1545     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1546 
1547     if( mbIsPaused ) try
1548     {
1549         if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
1550         {
1551             mpShowWindow->RestartShow();
1552         }
1553         else
1554         {
1555             mbIsPaused = sal_False;;
1556             if( mxShow.is() )
1557             {
1558                 mxShow->pause(sal_False);
1559                 update();
1560 
1561                 if( mxListenerProxy.is() )
1562                     mxListenerProxy->resumed();
1563             }
1564         }
1565     }
1566     catch( Exception& e )
1567     {
1568         static_cast<void>(e);
1569         DBG_ERROR(
1570             (OString("sd::SlideshowImpl::resume(), "
1571                     "exception caught: ") +
1572             rtl::OUStringToOString(
1573                 comphelper::anyToString( cppu::getCaughtException() ),
1574                 RTL_TEXTENCODING_UTF8 )).getStr() );
1575     }
1576 }
1577 
1578 // ---------------------------------------------------------
1579 
1580 sal_Bool SAL_CALL SlideshowImpl::isPaused() throw (RuntimeException)
1581 {
1582     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1583     return mbIsPaused;
1584 }
1585 
1586 // ---------------------------------------------------------
1587 
1588 void SAL_CALL SlideshowImpl::blankScreen( sal_Int32 nColor ) throw (RuntimeException)
1589 {
1590     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1591 
1592     if( mpShowWindow && mpSlideController )
1593     {
1594         if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), nColor ) )
1595         {
1596             pause();
1597         }
1598     }
1599 }
1600 
1601 // ---------------------------------------------------------
1602 // XShapeEventListener
1603 // ---------------------------------------------------------
1604 
1605 void SlideshowImpl::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& /* aOriginalEvent */ )
1606 {
1607     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1608 
1609     WrappedShapeEventImplPtr pEvent = maShapeEventMap[xShape];
1610     if( !pEvent.get() )
1611         return;
1612 
1613     switch( pEvent->meClickAction )
1614     {
1615     case ClickAction_PREVPAGE:          gotoPreviousSlide();        break;
1616     case ClickAction_NEXTPAGE:          gotoNextSlide();            break;
1617     case ClickAction_FIRSTPAGE:         gotoFirstSlide();           break;
1618     case ClickAction_LASTPAGE:          gotoLastSlide();            break;
1619     case ClickAction_STOPPRESENTATION:  endPresentation();          break;
1620     case ClickAction_BOOKMARK:
1621     {
1622         gotoBookmark( pEvent->maStrBookmark );
1623     }
1624     break;
1625     case ClickAction_SOUND:
1626     {
1627         try
1628         {
1629             mxPlayer.set(avmedia::MediaWindow::createPlayer(pEvent->maStrBookmark), uno::UNO_QUERY_THROW );
1630             mxPlayer->start();
1631         }
1632         catch( uno::Exception& e )
1633         {
1634             (void)e;
1635             DBG_ERROR("sd::SlideshowImpl::click(), exception caught!" );
1636         }
1637     }
1638     break;
1639 
1640     case ClickAction_DOCUMENT:
1641     {
1642         OUString aBookmark( pEvent->maStrBookmark );
1643 
1644         sal_Int32 nPos = aBookmark.indexOf( sal_Unicode('#') );
1645         if( nPos >= 0 )
1646         {
1647             OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1648             OUString aName( aBookmark.copy( nPos+1 ) );
1649             aURL += getUiNameFromPageApiNameImpl( aName );
1650             aBookmark = aURL;
1651         }
1652 
1653         mpDocSh->OpenBookmark( aBookmark );
1654     }
1655     break;
1656 
1657     case ClickAction_PROGRAM:
1658     {
1659         INetURLObject aURL(
1660             ::URIHelper::SmartRel2Abs(
1661                 INetURLObject(mpDocSh->GetMedium()->GetBaseURL()),
1662                 pEvent->maStrBookmark, ::URIHelper::GetMaybeFileHdl(), true,
1663                 false, INetURLObject::WAS_ENCODED,
1664                 INetURLObject::DECODE_UNAMBIGUOUS ) );
1665 
1666         if( INET_PROT_FILE == aURL.GetProtocol() )
1667         {
1668             SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
1669             SfxBoolItem aBrowsing( SID_BROWSE, sal_True );
1670 
1671             SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1672             if (pViewFrm)
1673                 pViewFrm->GetDispatcher()->Execute( SID_OPENDOC,
1674                                             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
1675                                             &aUrl,
1676                                             &aBrowsing,
1677                                             0L );
1678         }
1679     }
1680     break;
1681 
1682     case presentation::ClickAction_MACRO:
1683     {
1684         const String aMacro( pEvent->maStrBookmark );
1685 
1686         if ( SfxApplication::IsXScriptURL( aMacro ) )
1687         {
1688             Any aRet;
1689             Sequence< sal_Int16 > aOutArgsIndex;
1690             Sequence< Any > aOutArgs;
1691             Sequence< Any >* pInArgs = new Sequence< Any >(0);
1692             mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs);
1693         }
1694         else
1695         {
1696             // aMacro has the following syntax:
1697             // "Macroname.Modulname.Libname.Dokumentname" or
1698             // "Macroname.Modulname.Libname.Applikationsname"
1699             String aMacroName = aMacro.GetToken(0, sal_Unicode('.'));
1700             String aModulName = aMacro.GetToken(1, sal_Unicode('.'));
1701             String aLibName   = aMacro.GetToken(2, sal_Unicode('.'));
1702             String aDocName   = aMacro.GetToken(3, sal_Unicode('.'));
1703 
1704             // todo: is the limitation still given that only
1705             // Modulname+Macroname can be used here?
1706             String aExecMacro(aModulName);
1707             aExecMacro.Append( sal_Unicode('.') );
1708             aExecMacro.Append( aMacroName );
1709             mpDocSh->GetBasic()->Call(aExecMacro);
1710         }
1711     }
1712     break;
1713 
1714     case ClickAction_VERB:
1715     {
1716         // todo, better do it async?
1717         SdrObject* pObj = GetSdrObjectFromXShape( xShape );
1718         SdrOle2Obj* pOleObject = PTR_CAST(SdrOle2Obj, pObj);
1719         if (pOleObject && mpViewShell )
1720             mpViewShell->ActivateObject(pOleObject, pEvent->mnVerb);
1721     }
1722     break;
1723     default:
1724         break;
1725     }
1726 }
1727 
1728 // ---------------------------------------------------------
1729 
1730 sal_Int32 SlideshowImpl::getSlideNumberForBookmark( const OUString& rStrBookmark )
1731 {
1732     sal_Bool bIsMasterPage;
1733     OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark );
1734     sal_uInt16 nPgNum = mpDoc->GetPageByName( aBookmark, bIsMasterPage );
1735 
1736     if( nPgNum == SDRPAGE_NOTFOUND )
1737     {
1738         // Ist das Bookmark ein Objekt?
1739         SdrObject* pObj = mpDoc->GetObj( aBookmark );
1740 
1741         if( pObj )
1742         {
1743             nPgNum = pObj->GetPage()->GetPageNum();
1744             bIsMasterPage = (sal_Bool)pObj->GetPage()->IsMasterPage();
1745         }
1746     }
1747 
1748     if( (nPgNum == SDRPAGE_NOTFOUND) || bIsMasterPage || static_cast<SdPage*>(mpDoc->GetPage(nPgNum))->GetPageKind() != PK_STANDARD )
1749         return -1;
1750 
1751     return ( nPgNum - 1) >> 1;
1752 }
1753 
1754 // ---------------------------------------------------------
1755 
1756 void SlideshowImpl::hyperLinkClicked( rtl::OUString const& aHyperLink ) throw (RuntimeException)
1757 {
1758     OUString aBookmark( aHyperLink );
1759 
1760     sal_Int32 nPos = aBookmark.indexOf( sal_Unicode('#') );
1761     if( nPos >= 0 )
1762     {
1763         OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1764         OUString aName( aBookmark.copy( nPos+1 ) );
1765         aURL += getUiNameFromPageApiNameImpl( aName );
1766         aBookmark = aURL;
1767     }
1768 
1769     mpDocSh->OpenBookmark( aBookmark );
1770 }
1771 
1772 // ---------------------------------------------------------
1773 
1774 void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber )
1775 {
1776     if( mpSlideController.get() )
1777     {
1778         if( mpSlideController->jumpToSlideNumber( nSlideNumber ) )
1779         {
1780             displayCurrentSlide();
1781         }
1782     }
1783 }
1784 
1785 // ---------------------------------------------------------
1786 
1787 /** nSlideIndex == -1 displays current slide again */
1788 void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex )
1789 {
1790     if( mpSlideController.get() )
1791     {
1792         if( (nSlideIndex == -1) || mpSlideController->jumpToSlideIndex( nSlideIndex ) )
1793         {
1794             displayCurrentSlide();
1795         }
1796     }
1797 }
1798 
1799 // ---------------------------------------------------------
1800 
1801 void SlideshowImpl::jumpToBookmark( const String& sBookmark )
1802 {
1803     sal_Int32 nSlideNumber = getSlideNumberForBookmark( sBookmark );
1804     if( nSlideNumber != -1 )
1805         displaySlideNumber( nSlideNumber );
1806 }
1807 
1808 // ---------------------------------------------------------
1809 
1810 sal_Int32 SlideshowImpl::getCurrentSlideNumber()
1811 {
1812     return mpSlideController.get() ? mpSlideController->getCurrentSlideNumber() : -1;
1813 }
1814 
1815 // ---------------------------------------------------------
1816 
1817 sal_Int32 SlideshowImpl::getFirstSlideNumber()
1818 {
1819     sal_Int32 nRet = 0;
1820     if( mpSlideController.get() )
1821     {
1822         sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
1823         if( nSlideIndexCount >= 0 )
1824         {
1825             nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
1826             while( nSlideIndexCount-- )
1827             {
1828                 sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
1829                 if( nRet > nTemp )
1830                     nRet = nTemp;
1831             }
1832         }
1833     }
1834 
1835     return nRet;
1836 }
1837 
1838 // ---------------------------------------------------------
1839 
1840 sal_Int32 SlideshowImpl::getLastSlideNumber()
1841 {
1842     sal_Int32 nRet = 0;
1843     if( mpSlideController.get() )
1844     {
1845         sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
1846         if( nSlideIndexCount >= 0 )
1847         {
1848             nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
1849             while( nSlideIndexCount-- )
1850             {
1851                 sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
1852                 if( nRet < nTemp )
1853                     nRet = nTemp;
1854             }
1855         }
1856     }
1857 
1858     return nRet;
1859 }
1860 
1861 // ---------------------------------------------------------
1862 
1863 sal_Bool SAL_CALL SlideshowImpl::isEndless() throw( RuntimeException )
1864 {
1865     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1866     return maPresSettings.mbEndless;
1867 }
1868 
1869 // ---------------------------------------------------------
1870 
1871 double SlideshowImpl::update()
1872 {
1873     startUpdateTimer();
1874     return -1;
1875 }
1876 
1877 // ---------------------------------------------------------
1878 
1879 void SlideshowImpl::startUpdateTimer()
1880 {
1881     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1882     maUpdateTimer.SetTimeout( 0 );
1883     maUpdateTimer.Start();
1884 }
1885 
1886 // ---------------------------------------------------------
1887 
1888 /** this timer is called 20ms after a new slide was displayed.
1889     This is used to unfreeze user input that was disabled after
1890     slide change to skip input that was buffered during slide
1891     transition preperation */
1892 IMPL_LINK( SlideshowImpl, ReadyForNextInputHdl, Timer*, EMPTYARG )
1893 {
1894     mbInputFreeze = false;
1895     return 0;
1896 }
1897 
1898 // ---------------------------------------------------------
1899 
1900 /** if I catch someone someday who calls this method by hand
1901     and not by using the timer, I will personaly punish this
1902     person seriously, even if this person is me.
1903 */
1904 IMPL_LINK( SlideshowImpl, updateHdl, Timer*, EMPTYARG )
1905 {
1906     mnUpdateEvent = 0;
1907 
1908     return updateSlideShow();
1909 }
1910 
1911 
1912 
1913 
1914 IMPL_LINK( SlideshowImpl, PostYieldListener, void*, EMPTYARG )
1915 {
1916     Application::EnableNoYieldMode(false);
1917     Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1918 
1919     if (mbDisposed)
1920         return 0;
1921 
1922     // Call Reschedule() but make sure that we are not destroyed during its
1923     // execution (we still can be disposed, though.)
1924     const rtl::Reference<SlideshowImpl> pSelf (this);
1925     Application::Reschedule(true);
1926 
1927     // Update the slide show if we are still alive.
1928     if ( ! mbDisposed)
1929         return updateSlideShow();
1930     else
1931         return 0;
1932 }
1933 
1934 
1935 
1936 
1937 sal_Int32 SlideshowImpl::updateSlideShow (void)
1938 {
1939     // doing some nMagic
1940     const rtl::Reference<SlideshowImpl> this_(this);
1941 
1942     Reference< XSlideShow > xShow( mxShow );
1943     if ( ! xShow.is())
1944         return 0;
1945 
1946     try
1947     {
1948         // TODO(Q3): Evaluate under various systems and setups,
1949         // whether this is really necessary. Under WinXP and Matrox
1950         // G550, the frame rates were much more steadier with this
1951         // tweak, although.
1952 
1953 // currently no solution, because this kills sound (at least on Windows)
1954 //         // Boost our prio, as long as we're in the render loop
1955 //         ::canvas::tools::PriorityBooster aBooster(2);
1956 
1957         double fUpdate = 0.0;
1958         if( !xShow->update(fUpdate) )
1959             fUpdate = -1.0;
1960 
1961         if (mxShow.is() && (fUpdate >= 0.0))
1962         {
1963             if (::basegfx::fTools::equalZero(fUpdate))
1964             {
1965                 // Use post yield listener for short update intervalls.
1966                 Application::EnableNoYieldMode(true);
1967                 Application::AddPostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1968             }
1969             else
1970             {
1971                 // Avoid busy loop when the previous call to update()
1972                 // returns a small positive number but not 0 (which is
1973                 // handled above).  Also, make sure that calls to update()
1974                 // have a minimum frequency.
1975                 // => Allow up to 60 frames per second.  Call at least once
1976                 // every 4 seconds.
1977                 const static sal_Int32 mnMaximumFrameCount (60);
1978                 const static double mnMinimumTimeout (1.0 / mnMaximumFrameCount);
1979                 const static double mnMaximumTimeout (4.0);
1980                 fUpdate = ::basegfx::clamp(fUpdate, mnMinimumTimeout, mnMaximumTimeout);
1981 
1982                 // Make sure that the maximum frame count has not been set
1983                 // too high (only then conversion to milliseconds and long
1984                 // integer may lead to zero value.)
1985                 OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0);
1986 
1987                 Application::EnableNoYieldMode(false);
1988                 Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1989 
1990                 // Use a timer for the asynchronous callback.
1991                 maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
1992                 maUpdateTimer.Start();
1993             }
1994         }
1995     }
1996     catch( Exception& e )
1997     {
1998         static_cast<void>(e);
1999         DBG_ERROR(
2000             (OString("sd::SlideshowImpl::updateSlideShow(), exception caught: ")
2001                 + rtl::OUStringToOString(
2002                     comphelper::anyToString( cppu::getCaughtException() ),
2003                     RTL_TEXTENCODING_UTF8 )).getStr() );
2004     }
2005     return 0;
2006 }
2007 
2008 // ---------------------------------------------------------
2009 
2010 bool SlideshowImpl::keyInput(const KeyEvent& rKEvt)
2011 {
2012     if( !mxShow.is() || mbInputFreeze )
2013         return false;
2014 
2015     bool bRet = true;
2016 
2017     try
2018     {
2019         const int nKeyCode = rKEvt.GetKeyCode().GetCode();
2020         switch( nKeyCode )
2021         {
2022             case awt::Key::CONTEXTMENU:
2023                 if( !mnContextMenuEvent )
2024                 {
2025                     if( mpShowWindow )
2026                         maPopupMousePos = mpShowWindow->GetPointerState().maPos;
2027                     mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2028                 }
2029                 break;
2030 
2031             // cancel show
2032             case KEY_ESCAPE:
2033             case KEY_SUBTRACT:
2034                 // in case the user cancels the presentation, switch to current slide
2035                 // in edit mode
2036                 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2037                 {
2038                     if( mpSlideController->getCurrentSlideNumber() != -1 )
2039                         mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2040                 }
2041                 endPresentation();
2042                 break;
2043 
2044             // advance show
2045             case KEY_PAGEDOWN:
2046                 if(rKEvt.GetKeyCode().IsMod2())
2047                 {
2048                     gotoNextSlide();
2049                     break;
2050                 }
2051                 // warning, fall through!
2052             case KEY_SPACE:
2053             case KEY_RIGHT:
2054             case KEY_DOWN:
2055             case KEY_N:
2056                 gotoNextEffect();
2057                 break;
2058 
2059             case KEY_RETURN:
2060             {
2061                 if( maCharBuffer.Len() )
2062                 {
2063                     if( mpSlideController.get() )
2064                     {
2065                         if( mpSlideController->jumpToSlideNumber( maCharBuffer.ToInt32() - 1 ) )
2066                             displayCurrentSlide();
2067                     }
2068                     maCharBuffer.Erase();
2069                 }
2070                 else
2071                 {
2072                     gotoNextEffect();
2073                 }
2074             }
2075             break;
2076 
2077             // numeric: add to buffer
2078             case KEY_0:
2079             case KEY_1:
2080             case KEY_2:
2081             case KEY_3:
2082             case KEY_4:
2083             case KEY_5:
2084             case KEY_6:
2085             case KEY_7:
2086             case KEY_8:
2087             case KEY_9:
2088                 maCharBuffer.Append( rKEvt.GetCharCode() );
2089                 break;
2090 
2091             case KEY_PAGEUP:
2092                 if(rKEvt.GetKeyCode().IsMod2())
2093                 {
2094                     gotoPreviousSlide();
2095                     break;
2096                 }
2097                 // warning, fall through!
2098             case KEY_LEFT:
2099             case KEY_UP:
2100             case KEY_P:
2101             case KEY_BACKSPACE:
2102                 gotoPreviousEffect();
2103                 break;
2104 
2105             case KEY_HOME:
2106                 gotoFirstSlide();
2107                 break;
2108 
2109             case KEY_END:
2110                 gotoLastSlide();
2111                 break;
2112 
2113             case KEY_B:
2114             case KEY_W:
2115             case KEY_POINT:
2116             case KEY_COMMA:
2117             {
2118                 blankScreen( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? 0x00ffffff : 0x00000000 );
2119             }
2120             break;
2121 
2122             default:
2123                 bRet = false;
2124             break;
2125         }
2126     }
2127     catch( Exception& e )
2128     {
2129         bRet = false;
2130         static_cast<void>(e);
2131         DBG_ERROR(
2132             (OString("sd::SlideshowImpl::keyInput(), "
2133                     "exception caught: ") +
2134             rtl::OUStringToOString(
2135                 comphelper::anyToString( cppu::getCaughtException() ),
2136                 RTL_TEXTENCODING_UTF8 )).getStr() );
2137     }
2138 
2139     return bRet;
2140 }
2141 
2142 IMPL_LINK( SlideshowImpl, EventListenerHdl, VclSimpleEvent*, pEvent )
2143 {
2144     if( !mxShow.is() || mbInputFreeze )
2145         return 0;
2146 
2147     if( pEvent && (pEvent->GetId() == VCLEVENT_WINDOW_COMMAND) && static_cast<VclWindowEvent*>(pEvent)->GetData() )
2148     {
2149         const CommandEvent& rEvent = *(const CommandEvent*)static_cast<VclWindowEvent*>(pEvent)->GetData();
2150 
2151         if( rEvent.GetCommand() == COMMAND_MEDIA )
2152         {
2153             switch( rEvent.GetMediaCommand() )
2154             {
2155 #if defined( QUARTZ )
2156             case MEDIA_COMMAND_MENU:
2157                 if( !mnContextMenuEvent )
2158                 {
2159                 if( mpShowWindow )
2160                     maPopupMousePos = mpShowWindow->GetPointerState().maPos;
2161                 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2162                 }
2163                 break;
2164             case MEDIA_COMMAND_VOLUME_DOWN:
2165                 gotoPreviousSlide();
2166                 break;
2167             case MEDIA_COMMAND_VOLUME_UP:
2168                 gotoNextEffect();
2169                 break;
2170 #endif
2171             case MEDIA_COMMAND_NEXTTRACK:
2172                 gotoNextEffect();
2173                 break;
2174             case MEDIA_COMMAND_PAUSE:
2175                 if( !mbIsPaused )
2176                     blankScreen(0);
2177                 break;
2178             case MEDIA_COMMAND_PLAY:
2179                 if( mbIsPaused )
2180                     resume();
2181                 break;
2182 
2183             case MEDIA_COMMAND_PLAY_PAUSE:
2184                 if( mbIsPaused )
2185                     resume();
2186                 else
2187                     blankScreen(0);
2188                 break;
2189             case MEDIA_COMMAND_PREVIOUSTRACK:
2190                 gotoPreviousSlide();
2191                 break;
2192             case MEDIA_COMMAND_NEXTTRACK_HOLD:
2193                 gotoLastSlide();
2194                 break;
2195 
2196             case MEDIA_COMMAND_REWIND:
2197                 gotoFirstSlide();
2198                 break;
2199             case MEDIA_COMMAND_STOP:
2200                 // in case the user cancels the presentation, switch to current slide
2201                 // in edit mode
2202                 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2203                 {
2204                     if( mpSlideController->getCurrentSlideNumber() != -1 )
2205                         mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2206                 }
2207                 endPresentation();
2208                 break;
2209             }
2210         }
2211     }
2212 
2213     return 0;
2214 }
2215 
2216 // ---------------------------------------------------------
2217 
2218 void SlideshowImpl::mouseButtonUp(const MouseEvent& rMEvt)
2219 {
2220     if( rMEvt.IsRight() && !mnContextMenuEvent )
2221     {
2222         maPopupMousePos = rMEvt.GetPosPixel();
2223         mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2224     }
2225 }
2226 
2227 // ---------------------------------------------------------
2228 
2229 IMPL_LINK( SlideshowImpl, ContextMenuHdl, void*, EMPTYARG )
2230 {
2231     mnContextMenuEvent = 0;
2232 
2233     if( mpSlideController.get() == 0 )
2234         return 0;
2235 
2236     mbWasPaused = mbIsPaused;
2237     if( !mbWasPaused )
2238         pause();
2239 
2240     PopupMenu* pMenu = new PopupMenu( SdResId( RID_SLIDESHOW_CONTEXTMENU ) );
2241 
2242     // Adding button to display if in Pen  mode
2243     pMenu->CheckItem( CM_PEN_MODE, mbUsePen);
2244 
2245     const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2246     pMenu->EnableItem( CM_NEXT_SLIDE, ( mpSlideController->getNextSlideIndex() != -1 ) );
2247     pMenu->EnableItem( CM_PREV_SLIDE, ( mpSlideController->getPreviousSlideIndex() != -1 ) || (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) );
2248 
2249     PopupMenu* pPageMenu = pMenu->GetPopupMenu( CM_GOTO );
2250 
2251     SfxViewFrame* pViewFrame = getViewFrame();
2252     if( pViewFrame )
2253     {
2254         Reference< ::com::sun::star::frame::XFrame > xFrame( pViewFrame->GetFrame().GetFrameInterface() );
2255         if( xFrame.is() )
2256         {
2257             pMenu->SetItemImage( CM_NEXT_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10617") ), sal_False, sal_False ) );
2258             pMenu->SetItemImage( CM_PREV_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10618") ), sal_False, sal_False ) );
2259 
2260             if( pPageMenu )
2261             {
2262                 pPageMenu->SetItemImage( CM_FIRST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10616") ), sal_False, sal_False ) );
2263                 pPageMenu->SetItemImage( CM_LAST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10619") ), sal_False, sal_False ) );
2264             }
2265         }
2266     }
2267 
2268     // populate slide goto list
2269     if( pPageMenu )
2270     {
2271         const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount();
2272         if( nPageNumberCount <= 1 )
2273         {
2274             pMenu->EnableItem( CM_GOTO, sal_False );
2275         }
2276         else
2277         {
2278             sal_Int32 nCurrentSlideNumber = mpSlideController->getCurrentSlideNumber();
2279             if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2280                 nCurrentSlideNumber = -1;
2281 
2282             pPageMenu->EnableItem( CM_FIRST_SLIDE, ( mpSlideController->getSlideNumber(0) != nCurrentSlideNumber ) );
2283             pPageMenu->EnableItem( CM_LAST_SLIDE, ( mpSlideController->getSlideNumber( mpSlideController->getSlideIndexCount() - 1) != nCurrentSlideNumber ) );
2284 
2285             sal_Int32 nPageNumber;
2286 
2287             for( nPageNumber = 0; nPageNumber < nPageNumberCount; nPageNumber++ )
2288             {
2289                 if( mpSlideController->isVisibleSlideNumber( nPageNumber ) )
2290                 {
2291                     SdPage* pPage = mpDoc->GetSdPage((sal_uInt16)nPageNumber, PK_STANDARD);
2292                     if (pPage)
2293                     {
2294                         pPageMenu->InsertItem( (sal_uInt16)(CM_SLIDES + nPageNumber), pPage->GetName() );
2295                         if( nPageNumber == nCurrentSlideNumber )
2296                             pPageMenu->CheckItem( (sal_uInt16)(CM_SLIDES + nPageNumber) );
2297                     }
2298                 }
2299             }
2300         }
2301     }
2302 
2303     if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2304     {
2305         PopupMenu* pBlankMenu = pMenu->GetPopupMenu( CM_SCREEN );
2306         if( pBlankMenu )
2307         {
2308             pBlankMenu->CheckItem( ( mpShowWindow->GetBlankColor() == Color( COL_WHITE ) ) ? CM_SCREEN_WHITE : CM_SCREEN_BLACK  );
2309         }
2310     }
2311 
2312     PopupMenu* pWidthMenu = pMenu->GetPopupMenu( CM_WIDTH_PEN);
2313 
2314     // populate color width list
2315     if( pWidthMenu )
2316     {
2317         sal_Int32 nIterator;
2318         double nWidth;
2319 
2320         nWidth = 4.0;
2321         for( nIterator = 1; nIterator < 6; nIterator++)
2322         {
2323             switch(nIterator)
2324             {
2325                 case 1:
2326                     nWidth = 4.0;
2327                     break;
2328                 case 2:
2329                     nWidth = 100.0;
2330                     break;
2331                 case 3:
2332                     nWidth = 150.0;
2333                     break;
2334                 case 4:
2335                     nWidth = 200.0;
2336                     break;
2337                 case 5:
2338                     nWidth = 400.0;
2339                     break;
2340                 default:
2341                     break;
2342             }
2343 
2344             pWidthMenu->EnableItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator), sal_True);
2345             if( nWidth ==  mdUserPaintStrokeWidth)
2346                 pWidthMenu->CheckItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator) );
2347         }
2348     }
2349 
2350     pMenu->SetSelectHdl( LINK( this, SlideshowImpl, ContextMenuSelectHdl ) );
2351     pMenu->Execute( mpShowWindow, maPopupMousePos );
2352     delete pMenu;
2353 
2354     if( mxView.is() )
2355         mxView->ignoreNextMouseReleased();
2356 
2357     if( !mbWasPaused )
2358         resume();
2359     return 0;
2360 }
2361 
2362 // ---------------------------------------------------------
2363 
2364 IMPL_LINK( SlideshowImpl, ContextMenuSelectHdl, Menu *, pMenu )
2365 {
2366     if( pMenu )
2367     {
2368         sal_uInt16 nMenuId = pMenu->GetCurItemId();
2369 
2370         switch( nMenuId )
2371         {
2372         case CM_PREV_SLIDE:
2373             gotoPreviousSlide();
2374             mbWasPaused = false;
2375             break;
2376         case CM_NEXT_SLIDE:
2377             gotoNextSlide();
2378             mbWasPaused = false;
2379             break;
2380         case CM_FIRST_SLIDE:
2381             gotoFirstSlide();
2382             mbWasPaused = false;
2383             break;
2384         case CM_LAST_SLIDE:
2385             gotoLastSlide();
2386             mbWasPaused = false;
2387             break;
2388         case CM_SCREEN_BLACK:
2389         case CM_SCREEN_WHITE:
2390         {
2391             const Color aBlankColor( (nMenuId == CM_SCREEN_WHITE) ? COL_WHITE : COL_BLACK );
2392             if( mbWasPaused )
2393             {
2394                 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2395                 {
2396                     if( mpShowWindow->GetBlankColor() == aBlankColor )
2397                     {
2398                         mbWasPaused = false;
2399                         mpShowWindow->RestartShow();
2400                         break;
2401                     }
2402                 }
2403                 mpShowWindow->RestartShow();
2404             }
2405             if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) )
2406             {
2407                 pause();
2408                 mbWasPaused = true;
2409             }
2410         }
2411         break;
2412         case CM_COLOR_PEN:
2413             {
2414                 //Open a color picker based on SvColorDialog
2415                 ::Color aColor( mnUserPaintColor );
2416                 SvColorDialog aColorDlg( mpShowWindow);
2417                 aColorDlg.SetColor( aColor );
2418 
2419                 if (aColorDlg.Execute() )
2420                 {
2421                     aColor = aColorDlg.GetColor();
2422                     setPenColor(aColor.GetColor());
2423                 }
2424                 mbWasPaused = false;
2425             }
2426             break;
2427 
2428         case CM_WIDTH_PEN_VERY_THIN:
2429             {
2430                 setPenWidth(4.0);
2431                 mbWasPaused = false;
2432             }
2433             break;
2434 
2435         case CM_WIDTH_PEN_THIN:
2436             {
2437                 setPenWidth(100.0);
2438                 mbWasPaused = false;
2439             }
2440             break;
2441 
2442         case CM_WIDTH_PEN_NORMAL:
2443             {
2444                 setPenWidth(150.0);
2445                 mbWasPaused = false;
2446             }
2447             break;
2448 
2449         case CM_WIDTH_PEN_THICK:
2450             {
2451                 setPenWidth(200.0);
2452                 mbWasPaused = false;
2453             }
2454             break;
2455 
2456         case CM_WIDTH_PEN_VERY_THICK:
2457             {
2458                 setPenWidth(400.0);
2459                 mbWasPaused = false;
2460             }
2461             break;
2462         case CM_ERASE_ALLINK:
2463             {
2464                 setEraseAllInk(true);
2465                 mbWasPaused = false;
2466             }
2467             break;
2468         case CM_PEN_MODE:
2469             {
2470                 setUsePen(!mbUsePen);
2471                 mbWasPaused = false;
2472             }
2473             break;
2474         case CM_ENDSHOW:
2475             // in case the user cancels the presentation, switch to current slide
2476             // in edit mode
2477             if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2478             {
2479                 if( mpSlideController->getCurrentSlideNumber() != -1 )
2480                 {
2481                     mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2482                 }
2483             }
2484             endPresentation();
2485             break;
2486         default:
2487             sal_Int32 nPageNumber = nMenuId - CM_SLIDES;
2488             const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2489             if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2490             {
2491                 mpShowWindow->RestartShow( nPageNumber );
2492             }
2493             else if( nPageNumber != mpSlideController->getCurrentSlideNumber() )
2494             {
2495                 displaySlideNumber( nPageNumber );
2496             }
2497             mbWasPaused = false;
2498             break;
2499         }
2500     }
2501 
2502     return 0;
2503 }
2504 
2505 // ---------------------------------------------------------
2506 
2507 Reference< XSlideShow > SlideshowImpl::createSlideShow() const
2508 {
2509     Reference< XSlideShow > xShow;
2510 
2511     try
2512     {
2513         Reference< lang::XMultiServiceFactory > xFactory(
2514             ::comphelper::getProcessServiceFactory(),
2515             UNO_QUERY_THROW );
2516 
2517         Reference< XInterface > xInt( xFactory->createInstance(
2518                 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.SlideShow")) ) );
2519 
2520         xShow.set( xInt, UNO_QUERY_THROW );
2521     }
2522     catch( uno::Exception& e )
2523     {
2524         (void)e;
2525         DBG_ERROR(
2526             (OString("sd::SlideshowImpl::createSlideShow(), "
2527                      "exception caught: ") +
2528              rtl::OUStringToOString(
2529                  comphelper::anyToString( cppu::getCaughtException() ),
2530                  RTL_TEXTENCODING_UTF8 )).getStr() );
2531     }
2532 
2533     return xShow;
2534 }
2535 
2536 // ---------------------------------------------------------
2537 
2538 void SlideshowImpl::createSlideList( bool bAll, bool bStartWithActualSlide, const String& rPresSlide )
2539 {
2540     const long nSlideCount = mpDoc->GetSdPageCount( PK_STANDARD );
2541 
2542     if( nSlideCount )
2543     {
2544         SdCustomShow*   pCustomShow;
2545 
2546         if( !bStartWithActualSlide && mpDoc->GetCustomShowList() && maPresSettings.mbCustomShow )
2547             pCustomShow = (SdCustomShow*) mpDoc->GetCustomShowList()->GetCurObject();
2548         else
2549             pCustomShow = NULL;
2550 
2551         // create animation slide controller
2552         AnimationSlideController::Mode eMode =
2553             ( pCustomShow && pCustomShow->Count() ) ? AnimationSlideController::CUSTOM :
2554                 (bAll ? AnimationSlideController::ALL : AnimationSlideController::FROM);
2555 
2556         Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
2557         Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
2558         mpSlideController.reset( new AnimationSlideController( xSlides, eMode ) );
2559 
2560         if( eMode != AnimationSlideController::CUSTOM )
2561         {
2562             sal_Int32 nFirstSlide = 0;
2563 
2564             // normale Praesentation
2565             if( eMode == AnimationSlideController::FROM )
2566             {
2567                 if( rPresSlide.Len() )
2568                 {
2569                     sal_Int32 nSlide;
2570                     sal_Bool bTakeNextAvailable = sal_False;
2571 
2572                     for( nSlide = 0, nFirstSlide = -1; ( nSlide < nSlideCount ) && ( -1 == nFirstSlide ); nSlide++ )
2573                     {
2574                         SdPage* pTestSlide = mpDoc->GetSdPage( (sal_uInt16)nSlide, PK_STANDARD );
2575 
2576                         if( pTestSlide->GetName() == rPresSlide )
2577                         {
2578                             if( pTestSlide->IsExcluded() )
2579                                 bTakeNextAvailable = sal_True;
2580                             else
2581                                 nFirstSlide = nSlide;
2582                         }
2583                         else if( bTakeNextAvailable && !pTestSlide->IsExcluded() )
2584                             nFirstSlide = nSlide;
2585                     }
2586 
2587                     if( -1 == nFirstSlide )
2588                         nFirstSlide = 0;
2589                 }
2590             }
2591 
2592             for( sal_Int32 i = 0; i < nSlideCount; i++ )
2593             {
2594                 bool bVisible = ( mpDoc->GetSdPage( (sal_uInt16)i, PK_STANDARD ) )->IsExcluded() ? false : true;
2595                 if( bVisible || (eMode == AnimationSlideController::ALL) )
2596                     mpSlideController->insertSlideNumber( i, bVisible );
2597             }
2598 
2599             mpSlideController->setStartSlideNumber( nFirstSlide );
2600         }
2601         else
2602         {
2603             if( meAnimationMode != ANIMATIONMODE_SHOW && rPresSlide.Len() )
2604             {
2605                 sal_Int32 nSlide;
2606                 for( nSlide = 0; nSlide < nSlideCount; nSlide++ )
2607                     if( rPresSlide == mpDoc->GetSdPage( (sal_uInt16) nSlide, PK_STANDARD )->GetName() )
2608                         break;
2609 
2610                 if( nSlide < nSlideCount )
2611                     mpSlideController->insertSlideNumber( (sal_uInt16) nSlide );
2612             }
2613 
2614             void* pCustomSlide;
2615             sal_Int32 nSlideIndex;
2616             for( pCustomSlide = pCustomShow->First(),nSlideIndex=0; pCustomSlide; pCustomSlide = pCustomShow->Next(), nSlideIndex++ )
2617             {
2618                 const sal_uInt16 nSdSlide = ( ( (SdPage*) pCustomSlide )->GetPageNum() - 1 ) / 2;
2619 
2620                 if( !( mpDoc->GetSdPage( nSdSlide, PK_STANDARD ) )->IsExcluded())
2621                     mpSlideController->insertSlideNumber( nSdSlide );
2622             }
2623         }
2624     }
2625 }
2626 
2627 // ---------------------------------------------------------
2628 
2629 typedef sal_uInt16 (*FncGetChildWindowId)();
2630 
2631 FncGetChildWindowId aShowChilds[] =
2632 {
2633     &AnimationChildWindow::GetChildWindowId,
2634     &Svx3DChildWindow::GetChildWindowId,
2635     &SvxFontWorkChildWindow::GetChildWindowId,
2636     &SvxColorChildWindow::GetChildWindowId,
2637     &SvxSearchDialogWrapper::GetChildWindowId,
2638     &SvxBmpMaskChildWindow::GetChildWindowId,
2639     &SvxIMapDlgChildWindow::GetChildWindowId,
2640     &SvxHyperlinkDlgWrapper::GetChildWindowId,
2641     &SvxHlinkDlgWrapper::GetChildWindowId,
2642     &SfxTemplateDialogWrapper::GetChildWindowId,
2643     &GalleryChildWindow::GetChildWindowId
2644 };
2645 
2646 #define NAVIGATOR_CHILD_MASK        0x80000000UL
2647 
2648 void SlideshowImpl::hideChildWindows()
2649 {
2650     mnChildMask = 0UL;
2651 
2652     if( ANIMATIONMODE_SHOW == meAnimationMode )
2653     {
2654         SfxViewFrame* pViewFrame = getViewFrame();
2655 
2656         if( pViewFrame )
2657         {
2658             if( pViewFrame->GetChildWindow( SID_NAVIGATOR ) != NULL )
2659                 mnChildMask |= NAVIGATOR_CHILD_MASK;
2660 
2661             for( sal_uLong i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
2662             {
2663                 const sal_uInt16 nId = ( *aShowChilds[ i ] )();
2664 
2665                 if( pViewFrame->GetChildWindow( nId ) )
2666                 {
2667                     pViewFrame->SetChildWindow( nId, sal_False );
2668                     mnChildMask |= 1 << i;
2669                 }
2670             }
2671         }
2672     }
2673 }
2674 
2675 // ---------------------------------------------------------
2676 
2677 void SlideshowImpl::showChildWindows()
2678 {
2679     if( ANIMATIONMODE_SHOW == meAnimationMode )
2680     {
2681         SfxViewFrame* pViewFrame = getViewFrame();
2682         if( pViewFrame )
2683         {
2684             pViewFrame->SetChildWindow( SID_NAVIGATOR, ( mnChildMask & NAVIGATOR_CHILD_MASK ) != 0 );
2685 
2686             for( sal_uLong i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
2687             {
2688                 if( mnChildMask & ( 1 << i ) )
2689                     pViewFrame->SetChildWindow( ( *aShowChilds[ i ] )(), sal_True );
2690             }
2691         }
2692     }
2693 }
2694 
2695 // ---------------------------------------------------------
2696 
2697 SfxViewFrame* SlideshowImpl::getViewFrame() const
2698 {
2699     return mpViewShell ? mpViewShell->GetViewFrame() : 0;
2700 }
2701 
2702 // ---------------------------------------------------------
2703 
2704 SfxDispatcher* SlideshowImpl::getDispatcher() const
2705 {
2706     return (mpViewShell && mpViewShell->GetViewFrame()) ? mpViewShell->GetViewFrame()->GetDispatcher() : 0;
2707 }
2708 
2709 // ---------------------------------------------------------
2710 
2711 SfxBindings* SlideshowImpl::getBindings() const
2712 {
2713     return (mpViewShell && mpViewShell->GetViewFrame()) ? &mpViewShell->GetViewFrame()->GetBindings() : 0;
2714 }
2715 
2716 // ---------------------------------------------------------
2717 
2718 void SlideshowImpl::resize( const Size& rSize )
2719 {
2720     maPresSize = rSize;
2721 
2722     if( mpShowWindow && (ANIMATIONMODE_VIEW != meAnimationMode) )
2723     {
2724         mpShowWindow->SetSizePixel( maPresSize );
2725         mpShowWindow->Show();
2726 
2727         // Call ToTop() to bring the window to top if
2728         // a) the old size is not degenerate (then the window will be closed
2729         // soon) and
2730         // b) the animation mode is not that of a preview (on the one hand
2731         // this leaves the old behaviour for the slide show mode unmodified
2732         // and on the other hand does not move the focus from the document
2733         // to the (preview) window; the ToTop() seems not to be necessary at
2734         // least for the preview).
2735 //        if( !aOldSize.Width() && !aOldSize.Height() )
2736 //          mpShowWindow->ToTop();
2737     }
2738 
2739     if( mxView.is() ) try
2740     {
2741         awt::WindowEvent aEvt;
2742         mxView->windowResized(aEvt);
2743     }
2744     catch( Exception& e )
2745     {
2746         static_cast<void>(e);
2747         DBG_ERROR(
2748             (OString("sd::SlideshowImpl::resize(), "
2749                     "exception caught: ") +
2750             rtl::OUStringToOString(
2751                 comphelper::anyToString( cppu::getCaughtException() ),
2752                 RTL_TEXTENCODING_UTF8 )).getStr() );
2753     }
2754 }
2755 
2756 // -----------------------------------------------------------------------------
2757 
2758 void SlideshowImpl::setActiveXToolbarsVisible( sal_Bool bVisible )
2759 {
2760     // in case of ActiveX control the toolbars should not be visible if slide show runs in window mode
2761     // actually it runs always in window mode in case of ActiveX control
2762     if ( !maPresSettings.mbFullScreen && mpDocSh && mpDocSh->GetMedium() )
2763     {
2764         SFX_ITEMSET_ARG( mpDocSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
2765         if ( pItem && pItem->GetValue() )
2766         {
2767             // this is a plugin/activex mode, no toolbars should be visible during slide show
2768             // after the end of slide show they should be visible again
2769             SfxViewFrame* pViewFrame = getViewFrame();
2770             if( pViewFrame )
2771             {
2772                 try
2773                 {
2774                     Reference< frame::XLayoutManager > xLayoutManager;
2775                     Reference< beans::XPropertySet > xFrameProps( pViewFrame->GetFrame().GetTopFrame().GetFrameInterface(), UNO_QUERY_THROW );
2776                     if ( ( xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) )
2777                                 >>= xLayoutManager )
2778                       && xLayoutManager.is() )
2779                     {
2780                         xLayoutManager->setVisible( bVisible );
2781                     }
2782                 }
2783                 catch( uno::Exception& )
2784                 {}
2785             }
2786         }
2787     }
2788 }
2789 
2790 // -----------------------------------------------------------------------------
2791 
2792 void SAL_CALL SlideshowImpl::activate() throw (RuntimeException)
2793 {
2794     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2795 
2796     maDeactivateTimer.Stop();
2797 
2798     if( !mbActive && mxShow.is() )
2799     {
2800         mbActive = sal_True;
2801 
2802         if( ANIMATIONMODE_SHOW == meAnimationMode )
2803         {
2804             if( mbAutoSaveWasOn )
2805                 setAutoSaveState( false );
2806 
2807             if( mpShowWindow )
2808             {
2809                 SfxViewFrame* pViewFrame = getViewFrame();
2810                 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : 0;
2811 
2812                 hideChildWindows();
2813 
2814                 if( pDispatcher )
2815                 {
2816                     // filter all forbiden slots
2817                     pDispatcher->SetSlotFilter( sal_True, sizeof(pAllowed) / sizeof(sal_uInt16), pAllowed );
2818                 }
2819 
2820                 if( getBindings() )
2821                     getBindings()->InvalidateAll(sal_True);
2822 
2823                 mpShowWindow->GrabFocus();
2824             }
2825         }
2826 
2827         resume();
2828     }
2829 }
2830 
2831 // -----------------------------------------------------------------------------
2832 
2833 void SAL_CALL SlideshowImpl::deactivate() throw (RuntimeException)
2834 {
2835     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2836 
2837     if( mbActive && mxShow.is() )
2838     {
2839         maDeactivateTimer.Start();
2840     }
2841 }
2842 
2843 // -----------------------------------------------------------------------------
2844 
2845 IMPL_LINK( SlideshowImpl, deactivateHdl, Timer*, EMPTYARG )
2846 {
2847     if( mbActive && mxShow.is() )
2848     {
2849         mbActive = sal_False;
2850 
2851         pause();
2852 
2853         if( ANIMATIONMODE_SHOW == meAnimationMode )
2854         {
2855             if( mbAutoSaveWasOn )
2856                 setAutoSaveState( true );
2857 
2858             if( mpShowWindow )
2859             {
2860                 showChildWindows();
2861             }
2862         }
2863     }
2864     return 0;
2865 }
2866 
2867 // ---------------------------------------------------------
2868 
2869 sal_Bool SAL_CALL SlideshowImpl::isActive() throw (RuntimeException)
2870 {
2871     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2872     return mbActive;
2873 }
2874 
2875 // -----------------------------------------------------------------------------
2876 
2877 void SlideshowImpl::receiveRequest(SfxRequest& rReq)
2878 {
2879     const SfxItemSet* pArgs      = rReq.GetArgs();
2880 
2881     switch ( rReq.GetSlot() )
2882     {
2883         case SID_NAVIGATOR_PEN:
2884             setUsePen(!mbUsePen);
2885         break;
2886 
2887         case SID_NAVIGATOR_PAGE:
2888         {
2889             PageJump    eJump = (PageJump)((SfxAllEnumItem&) pArgs->Get(SID_NAVIGATOR_PAGE)).GetValue();
2890             switch( eJump )
2891             {
2892                 case PAGE_FIRST:        gotoFirstSlide(); break;
2893                 case PAGE_LAST:         gotoLastSlide(); break;
2894                 case PAGE_NEXT:         gotoNextSlide(); break;
2895                 case PAGE_PREVIOUS:     gotoPreviousSlide(); break;
2896                 case PAGE_NONE:         break;
2897             }
2898         }
2899         break;
2900 
2901         case SID_NAVIGATOR_OBJECT:
2902         {
2903             const String aTarget( ((SfxStringItem&) pArgs->Get(SID_NAVIGATOR_OBJECT)).GetValue() );
2904 
2905             // is the bookmark a Slide?
2906             sal_Bool        bIsMasterPage;
2907             sal_uInt16      nPgNum = mpDoc->GetPageByName( aTarget, bIsMasterPage );
2908             SdrObject*  pObj   = NULL;
2909 
2910             if( nPgNum == SDRPAGE_NOTFOUND )
2911             {
2912                 // is the bookmark an object?
2913                 pObj = mpDoc->GetObj( aTarget );
2914 
2915                 if( pObj )
2916                     nPgNum = pObj->GetPage()->GetPageNum();
2917             }
2918 
2919             if( nPgNum != SDRPAGE_NOTFOUND )
2920             {
2921                 nPgNum = ( nPgNum - 1 ) >> 1;
2922                 displaySlideNumber( nPgNum );
2923             }
2924         }
2925         break;
2926     }
2927 }
2928 
2929 // ---------------------------------------------------------
2930 
2931 void SlideshowImpl::setAutoSaveState( bool bOn)
2932 {
2933     try
2934     {
2935         uno::Reference<lang::XMultiServiceFactory> xFac( ::comphelper::getProcessServiceFactory() );
2936 
2937         uno::Reference< util::XURLTransformer > xParser(
2938             xFac->createInstance( OUString::createFromAscii("com.sun.star.util.URLTransformer" ) ),
2939                 uno::UNO_QUERY_THROW);
2940         util::URL aURL;
2941         aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/setAutoSaveState");
2942         xParser->parseStrict(aURL);
2943 
2944         Sequence< beans::PropertyValue > aArgs(1);
2945         aArgs[0].Name = OUString::createFromAscii("AutoSaveState");
2946         aArgs[0].Value <<= bOn ? sal_True : sal_False;
2947 
2948         uno::Reference< frame::XDispatch > xAutoSave(
2949             xFac->createInstance(OUString::createFromAscii("com.sun.star.frame.AutoRecovery")),
2950             uno::UNO_QUERY_THROW);
2951         xAutoSave->dispatch(aURL, aArgs);
2952     }
2953     catch( Exception& )
2954     {
2955         DBG_ERROR("sd::SlideshowImpl::setAutoSaveState(), exception caught!");
2956     }
2957 }
2958 
2959 // ---------------------------------------------------------
2960 
2961 Reference< XDrawPage > SAL_CALL SlideshowImpl::getCurrentSlide() throw (RuntimeException)
2962 {
2963     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2964 
2965     Reference< XDrawPage > xSlide;
2966     if( mxShow.is() && mpSlideController.get() )
2967     {
2968         sal_Int32 nSlide = getCurrentSlideNumber();
2969         if( (nSlide >= 0) && (nSlide < mpSlideController->getSlideNumberCount() ) )
2970             xSlide = mpSlideController->getSlideByNumber( nSlide );
2971     }
2972 
2973     return xSlide;
2974 }
2975 
2976 // ---------------------------------------------------------
2977 
2978 sal_Int32 SAL_CALL SlideshowImpl::getNextSlideIndex() throw (RuntimeException)
2979 {
2980     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2981 
2982     if( mxShow.is() )
2983     {
2984         return mpSlideController->getNextSlideIndex();
2985     }
2986     else
2987     {
2988         return -1;
2989     }
2990 }
2991 
2992 // ---------------------------------------------------------
2993 
2994 sal_Int32 SAL_CALL SlideshowImpl::getCurrentSlideIndex() throw (RuntimeException)
2995 {
2996     return mpSlideController.get() ? mpSlideController->getCurrentSlideIndex() : -1;
2997 }
2998 
2999 // --------------------------------------------------------------------
3000 // ::com::sun::star::presentation::XSlideShowController:
3001 // --------------------------------------------------------------------
3002 
3003 ::sal_Int32 SAL_CALL SlideshowImpl::getSlideCount() throw (RuntimeException)
3004 {
3005     return mpSlideController.get() ? mpSlideController->getSlideIndexCount() : 0;
3006 }
3007 
3008 // --------------------------------------------------------------------
3009 
3010 Reference< XDrawPage > SAL_CALL SlideshowImpl::getSlideByIndex(::sal_Int32 Index) throw (RuntimeException, css::lang::IndexOutOfBoundsException)
3011 {
3012     if( (mpSlideController.get() == 0 ) || (Index < 0) || (Index >= mpSlideController->getSlideIndexCount() ) )
3013         throw IndexOutOfBoundsException();
3014 
3015     return mpSlideController->getSlideByNumber( mpSlideController->getSlideNumber( Index ) );
3016 }
3017 
3018 sal_Bool SAL_CALL SlideshowImpl::getAlwaysOnTop() throw (RuntimeException)
3019 {
3020     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3021     return maPresSettings.mbAlwaysOnTop;
3022 }
3023 
3024 // --------------------------------------------------------------------
3025 
3026 void SAL_CALL SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways ) throw (RuntimeException)
3027 {
3028     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3029     if( maPresSettings.mbAlwaysOnTop != bAlways )
3030     {
3031         maPresSettings.mbAlwaysOnTop = bAlways;
3032         // todo, can this be changed while running?
3033     }
3034 }
3035 
3036 // --------------------------------------------------------------------
3037 
3038 sal_Bool SAL_CALL SlideshowImpl::isFullScreen() throw (RuntimeException)
3039 {
3040     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3041     return maPresSettings.mbFullScreen;
3042 }
3043 
3044 // --------------------------------------------------------------------
3045 
3046 sal_Bool SAL_CALL SlideshowImpl::getMouseVisible() throw (RuntimeException)
3047 {
3048     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3049     return maPresSettings.mbMouseVisible;
3050 }
3051 
3052 // --------------------------------------------------------------------
3053 
3054 void SAL_CALL SlideshowImpl::setMouseVisible( sal_Bool bVisible ) throw (RuntimeException)
3055 {
3056     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3057     if( maPresSettings.mbMouseVisible != bVisible )
3058     {
3059         maPresSettings.mbMouseVisible = bVisible;
3060         if( mpShowWindow )
3061             mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
3062     }
3063 }
3064 
3065 // --------------------------------------------------------------------
3066 
3067 sal_Bool SAL_CALL SlideshowImpl::getUsePen() throw (RuntimeException)
3068 {
3069     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3070     return mbUsePen;
3071 }
3072 
3073 // --------------------------------------------------------------------
3074 
3075 void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen ) throw (RuntimeException)
3076 {
3077     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3078     mbUsePen = bMouseAsPen;
3079     if( mxShow.is() ) try
3080     {
3081         // For Pencolor;
3082         Any aValue;
3083         if( mbUsePen )
3084             aValue <<= mnUserPaintColor;
3085         beans::PropertyValue aPenProp;
3086         aPenProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintColor" ));
3087         aPenProp.Value = aValue;
3088         mxShow->setProperty( aPenProp );
3089 
3090         //for StrokeWidth :
3091         if( mbUsePen )
3092         {
3093             beans::PropertyValue aPenPropWidth;
3094             aPenPropWidth.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintStrokeWidth" ));
3095             aPenPropWidth.Value <<= mdUserPaintStrokeWidth;
3096             mxShow->setProperty( aPenPropWidth );
3097 
3098             // for Pen Mode
3099             beans::PropertyValue aPenPropSwitchPenMode;
3100             aPenPropSwitchPenMode.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SwitchPenMode" ));
3101             aPenPropSwitchPenMode.Value <<= sal_True;
3102             mxShow->setProperty( aPenPropSwitchPenMode );
3103         }
3104     }
3105     catch( Exception& e )
3106     {
3107         static_cast<void>(e);
3108         DBG_ERROR(
3109             (OString("sd::SlideshowImpl::setUsePen(), "
3110                     "exception caught: ") +
3111             rtl::OUStringToOString(
3112                 comphelper::anyToString( cppu::getCaughtException() ),
3113                 RTL_TEXTENCODING_UTF8 )).getStr() );
3114     }
3115 }
3116 
3117 // --------------------------------------------------------------------
3118 
3119 double SAL_CALL SlideshowImpl::getPenWidth() throw (RuntimeException)
3120 {
3121     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3122     return mdUserPaintStrokeWidth;
3123 }
3124 
3125 // --------------------------------------------------------------------
3126 
3127 void SAL_CALL SlideshowImpl::setPenWidth( double dStrokeWidth ) throw (RuntimeException)
3128 {
3129     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3130     mdUserPaintStrokeWidth = dStrokeWidth;
3131     setUsePen( true ); // enable pen mode, update color and width
3132 }
3133 
3134 // --------------------------------------------------------------------
3135 
3136 sal_Int32 SAL_CALL SlideshowImpl::getPenColor() throw (RuntimeException)
3137 {
3138     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3139     return mnUserPaintColor;
3140 }
3141 
3142 // --------------------------------------------------------------------
3143 
3144 void SAL_CALL SlideshowImpl::setPenColor( sal_Int32 nColor ) throw (RuntimeException)
3145 {
3146     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3147     mnUserPaintColor = nColor;
3148     setUsePen( true ); // enable pen mode, update color
3149 }
3150 
3151 // --------------------------------------------------------------------
3152 
3153 void SAL_CALL SlideshowImpl::setUseEraser( ::sal_Bool /*_usepen*/ ) throw (css::uno::RuntimeException)
3154 {
3155 }
3156 
3157 // --------------------------------------------------------------------
3158 
3159 void SAL_CALL SlideshowImpl::setPenMode( bool bSwitchPenMode ) throw (RuntimeException)
3160 {
3161     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3162     setUsePen( bSwitchPenMode ); // SwitchPen Mode
3163 
3164 }
3165 
3166 // --------------------------------------------------------------------
3167 
3168 void SAL_CALL SlideshowImpl::setEraseAllInk(bool bEraseAllInk) throw (RuntimeException)
3169 {
3170     if( bEraseAllInk )
3171     {
3172         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3173         if( mxShow.is() ) try
3174         {
3175             beans::PropertyValue aPenPropEraseAllInk;
3176             aPenPropEraseAllInk.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EraseAllInk" ));
3177             aPenPropEraseAllInk.Value <<= bEraseAllInk;
3178             mxShow->setProperty( aPenPropEraseAllInk );
3179         }
3180         catch( Exception& e )
3181         {
3182             static_cast<void>(e);
3183             DBG_ERROR(
3184                 (OString("sd::SlideshowImpl::setEraseAllInk(), "
3185                         "exception caught: ") +
3186                 rtl::OUStringToOString(
3187                     comphelper::anyToString( cppu::getCaughtException() ),
3188                     RTL_TEXTENCODING_UTF8 )).getStr() );
3189         }
3190     }
3191 }
3192 
3193 void SAL_CALL SlideshowImpl::setEraseInk( sal_Int32 /*nEraseInkSize*/ ) throw (css::uno::RuntimeException)
3194 {
3195 }
3196 
3197 void SAL_CALL SlideshowImpl::setEraserMode( bool /*bSwitchEraserMode*/ ) throw (css::uno::RuntimeException)
3198 {
3199 }
3200 
3201 // --------------------------------------------------------------------
3202 // XSlideShowController Methods
3203 // --------------------------------------------------------------------
3204 
3205 sal_Bool SAL_CALL SlideshowImpl::isRunning(  ) throw (RuntimeException)
3206 {
3207     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3208     return mxShow.is();
3209 }
3210 
3211 // --------------------------------------------------------------------
3212 
3213 void SAL_CALL SlideshowImpl::gotoNextEffect(  ) throw (RuntimeException)
3214 {
3215     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3216 
3217     if( mxShow.is() && mpSlideController.get() && mpShowWindow )
3218     {
3219         if( mbIsPaused )
3220             resume();
3221 
3222         const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3223         if( eMode == SHOWWINDOWMODE_END )
3224         {
3225             endPresentation();
3226         }
3227         else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3228         {
3229             mpShowWindow->RestartShow();
3230         }
3231         else
3232         {
3233             mxShow->nextEffect();
3234             update();
3235         }
3236     }
3237 }
3238 
3239 // --------------------------------------------------------------------
3240 
3241 void SAL_CALL SlideshowImpl::gotoPreviousEffect(  ) throw (RuntimeException)
3242 {
3243     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3244 
3245     if( mxShow.is() && mpSlideController.get() && mpShowWindow )
3246     {
3247         if( mbIsPaused )
3248             resume();
3249 
3250         const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3251         if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3252         {
3253             mpShowWindow->RestartShow();
3254         }
3255         else
3256         {
3257             mxShow->previousEffect();
3258             update();
3259         }
3260     }
3261 }
3262 
3263 // --------------------------------------------------------------------
3264 
3265 void SAL_CALL SlideshowImpl::gotoFirstSlide(  ) throw (RuntimeException)
3266 {
3267     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3268 
3269     if( mpShowWindow && mpSlideController.get() )
3270     {
3271         if( mbIsPaused )
3272             resume();
3273 
3274         if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
3275         {
3276             if( mpSlideController->getSlideIndexCount() )
3277                 mpShowWindow->RestartShow( 0);
3278         }
3279         else
3280         {
3281             displaySlideIndex( 0 );
3282         }
3283     }
3284 }
3285 
3286 // --------------------------------------------------------------------
3287 
3288 void SAL_CALL SlideshowImpl::gotoNextSlide(  ) throw (RuntimeException)
3289 {
3290     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3291 
3292     if( mbIsPaused )
3293         resume();
3294 
3295     const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3296     if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3297     {
3298         mpShowWindow->RestartShow();
3299     }
3300     else
3301     {
3302         // if this is a show, ignore user inputs and
3303         // start 20ms timer to reenable inputs to fiter
3304         // buffered inputs during slide transition
3305         if( meAnimationMode == ANIMATIONMODE_SHOW )
3306         {
3307             mbInputFreeze = true;
3308             maInputFreezeTimer.Start();
3309         }
3310 
3311         if( mpSlideController.get() )
3312         {
3313             if( mpSlideController->nextSlide() )
3314             {
3315                 displayCurrentSlide();
3316             }
3317             else
3318             {
3319                 stopSound();
3320 
3321                 if( meAnimationMode == ANIMATIONMODE_PREVIEW )
3322                 {
3323                     endPresentation();
3324                 }
3325                 else if( maPresSettings.mbEndless )
3326                 {
3327                     if( maPresSettings.mnPauseTimeout )
3328                     {
3329                         if( mpShowWindow )
3330                         {
3331                             if ( maPresSettings.mbShowPauseLogo )
3332                             {
3333                                 Graphic aGraphic;
3334                                 Image aImage;
3335                                 bool bLoad = vcl::ImageRepository::loadBrandingImage(
3336                                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "logo" ) ),
3337                                     aImage );
3338                                 OSL_ENSURE( bLoad, "Can't load logo image");
3339                                 if ( bLoad )
3340                                     aGraphic = Graphic(aImage.GetBitmapEx());
3341                                 mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout, &aGraphic );
3342                             }
3343                             else
3344                                 mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout );
3345                         }
3346                     }
3347                     else
3348                     {
3349                         displaySlideIndex( 0 );
3350                     }
3351                 }
3352                 else
3353                 {
3354                     if( mpShowWindow )
3355                     {
3356                         mpShowWindow->SetEndMode();
3357                         pause();
3358                     }
3359                 }
3360             }
3361         }
3362     }
3363 }
3364 
3365 // --------------------------------------------------------------------
3366 
3367 void SAL_CALL SlideshowImpl::gotoPreviousSlide(  ) throw (RuntimeException)
3368 {
3369     gotoPreviousSlide(false);
3370 }
3371 
3372 void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects)
3373 {
3374     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3375 
3376     if( mxShow.is() && mpSlideController.get() ) try
3377     {
3378         if( mbIsPaused )
3379             resume();
3380 
3381         const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3382         if( eMode == SHOWWINDOWMODE_END )
3383         {
3384             const sal_Int32 nLastSlideIndex = mpSlideController->getCurrentSlideIndex();
3385             if( nLastSlideIndex >= 0 )
3386                 mpShowWindow->RestartShow( nLastSlideIndex );
3387         }
3388         else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3389         {
3390             mpShowWindow->RestartShow();
3391         }
3392         else
3393         {
3394             if( mpSlideController->previousSlide())
3395                 displayCurrentSlide(bSkipAllMainSequenceEffects);
3396             else if (bSkipAllMainSequenceEffects)
3397             {
3398                 // We could not go to the previous slide (probably because
3399                 // the current slide is already the first one).  We still
3400                 // have to call displayCurrentSlide because the calling
3401                 // slideshow can not determine whether there is a previous
3402                 // slide or not and has already prepared for a slide change.
3403                 // This slide change has to be completed now, even when
3404                 // changing to the same slide.
3405                 // Note that in this special case we do NOT pass
3406                 // bSkipAllMainSequenceEffects because we display the same
3407                 // slide as before and do not want to show all its effects.
3408                 displayCurrentSlide(false);
3409             }
3410         }
3411     }
3412     catch( Exception& e )
3413     {
3414         static_cast<void>(e);
3415         DBG_ERROR(
3416             (OString("sd::SlideshowImpl::gotoPreviousSlide(), "
3417                     "exception caught: ") +
3418             rtl::OUStringToOString(
3419                 comphelper::anyToString( cppu::getCaughtException() ),
3420                 RTL_TEXTENCODING_UTF8 )).getStr() );
3421     }
3422 }
3423 
3424 // --------------------------------------------------------------------
3425 
3426 void SAL_CALL SlideshowImpl::gotoLastSlide() throw (RuntimeException)
3427 {
3428     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3429 
3430     if( mpSlideController.get() )
3431     {
3432         if( mbIsPaused )
3433             resume();
3434 
3435         const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1;
3436         if( nLastSlideIndex >= 0 )
3437         {
3438             if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
3439             {
3440                 mpShowWindow->RestartShow( nLastSlideIndex );
3441             }
3442             else
3443             {
3444                 displaySlideIndex( nLastSlideIndex );
3445             }
3446         }
3447     }
3448 }
3449 
3450 // --------------------------------------------------------------------
3451 
3452 void SAL_CALL SlideshowImpl::gotoBookmark( const OUString& rBookmark ) throw (RuntimeException)
3453 {
3454     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3455 
3456     if( mbIsPaused )
3457         resume();
3458 
3459     sal_Int32 nSlideNumber = getSlideNumberForBookmark( rBookmark );
3460     if( nSlideNumber != -1 )
3461         displaySlideNumber( nSlideNumber );
3462 }
3463 
3464 // --------------------------------------------------------------------
3465 
3466 void SAL_CALL SlideshowImpl::gotoSlide( const Reference< XDrawPage >& xSlide )
3467     throw(IllegalArgumentException, RuntimeException)
3468 {
3469     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3470 
3471     if( mpSlideController.get() && xSlide.is() )
3472     {
3473         if( mbIsPaused )
3474             resume();
3475 
3476         const sal_Int32 nSlideCount = mpSlideController->getSlideNumberCount();
3477         for( sal_Int32 nSlide = 0; nSlide < nSlideCount; nSlide++ )
3478         {
3479             if( mpSlideController->getSlideByNumber( nSlide ) == xSlide )
3480             {
3481                 displaySlideNumber( nSlide );
3482             }
3483         }
3484     }
3485 }
3486 
3487 // --------------------------------------------------------------------
3488 
3489 void SAL_CALL SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex ) throw (RuntimeException)
3490 {
3491     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3492 
3493     if( mbIsPaused )
3494         resume();
3495 
3496     displaySlideIndex( nIndex );
3497 }
3498 
3499 // --------------------------------------------------------------------
3500 
3501 void SAL_CALL SlideshowImpl::stopSound(  ) throw (RuntimeException)
3502 {
3503     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3504 
3505     try
3506     {
3507         if( mxPlayer.is() )
3508         {
3509             mxPlayer->stop();
3510             mxPlayer.clear();
3511         }
3512     }
3513     catch( Exception& e )
3514     {
3515         static_cast<void>(e);
3516         DBG_ERROR(
3517             (OString("sd::SlideshowImpl::stopSound(), "
3518                     "exception caught: ") +
3519             rtl::OUStringToOString(
3520                 comphelper::anyToString( cppu::getCaughtException() ),
3521                 RTL_TEXTENCODING_UTF8 )).getStr() );
3522     }
3523 }
3524 
3525 // --------------------------------------------------------------------
3526 // XIndexAccess
3527 // --------------------------------------------------------------------
3528 
3529 ::sal_Int32 SAL_CALL SlideshowImpl::getCount(  ) throw (::com::sun::star::uno::RuntimeException)
3530 {
3531     return getSlideCount();
3532 }
3533 
3534 // --------------------------------------------------------------------
3535 
3536 ::com::sun::star::uno::Any SAL_CALL SlideshowImpl::getByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
3537 {
3538     return Any( getSlideByIndex( Index ) );
3539 }
3540 
3541 // --------------------------------------------------------------------
3542 
3543 ::com::sun::star::uno::Type SAL_CALL SlideshowImpl::getElementType(  ) throw (::com::sun::star::uno::RuntimeException)
3544 {
3545     return XDrawPage::static_type();
3546 }
3547 
3548 // --------------------------------------------------------------------
3549 
3550 ::sal_Bool SAL_CALL SlideshowImpl::hasElements(  ) throw (::com::sun::star::uno::RuntimeException)
3551 {
3552     return getSlideCount() != 0;
3553 }
3554 
3555 // --------------------------------------------------------------------
3556 
3557 Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() throw (RuntimeException)
3558 {
3559     return mxShow;
3560 }
3561 
3562 // --------------------------------------------------------------------
3563 
3564 
3565 PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx& r )
3566 : PresentationSettings( r )
3567 , mbRehearseTimings(r.mbRehearseTimings)
3568 , mbPreview(r.mbPreview)
3569 , mpParentWindow( 0 )
3570 {
3571 }
3572 
3573 PresentationSettingsEx::PresentationSettingsEx( PresentationSettings& r )
3574 : PresentationSettings( r )
3575 , mbRehearseTimings(sal_False)
3576 , mbPreview(sal_False)
3577 , mpParentWindow(0)
3578 {
3579 }
3580 
3581 void PresentationSettingsEx::SetArguments( const Sequence< PropertyValue >& rArguments ) throw (IllegalArgumentException)
3582 {
3583     sal_Int32 nArguments = rArguments.getLength();
3584     const PropertyValue* pValue = rArguments.getConstArray();
3585 
3586     while( nArguments-- )
3587     {
3588         SetPropertyValue( pValue->Name, pValue->Value );
3589         pValue++;
3590     }
3591 }
3592 
3593 void PresentationSettingsEx::SetPropertyValue( const OUString& rProperty, const Any& rValue ) throw (IllegalArgumentException)
3594 {
3595     if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("RehearseTimings") ) )
3596     {
3597         if( rValue >>= mbRehearseTimings )
3598             return;
3599     }
3600     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Preview") ) )
3601     {
3602         if( rValue >>= mbPreview )
3603             return;
3604     }
3605     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AnimationNode") ) )
3606     {
3607         if( rValue >>= mxAnimationNode )
3608             return;
3609     }
3610     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ) )
3611     {
3612         Reference< XWindow > xWindow;
3613         if( rValue >>= xWindow )
3614         {
3615             mpParentWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) : 0;
3616             return;
3617         }
3618     }
3619     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AllowAnimations") ) )
3620     {
3621         if( rValue >>= mbAnimationAllowed )
3622             return;
3623     }
3624     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AllowAnimations") ) )
3625     {
3626         if( rValue >>= mbAnimationAllowed )
3627             return;
3628     }
3629     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FirstPage") ) )
3630     {
3631         OUString aPresPage;
3632         if( rValue >>= aPresPage )
3633         {
3634             maPresPage = getUiNameFromPageApiNameImpl(aPresPage);
3635             mbCustomShow = sal_False;
3636             mbAll = sal_False;
3637             return;
3638         }
3639         else
3640         {
3641             if( rValue >>= mxStartPage )
3642                 return;
3643         }
3644     }
3645     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsAlwaysOnTop") ) )
3646     {
3647         if( rValue >>= mbAlwaysOnTop )
3648             return;
3649     }
3650     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsAutomatic") ) )
3651     {
3652         if( rValue >>= mbManual )
3653             return;
3654     }
3655     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsEndless") ) )
3656     {
3657         if( rValue >>= mbEndless )
3658             return;
3659     }
3660     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsFullScreen") ) )
3661     {
3662         if( rValue >>= mbFullScreen )
3663             return;
3664     }
3665     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsMouseVisible") ) )
3666     {
3667         if( rValue >>= mbMouseVisible )
3668             return;
3669     }
3670     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Pause") ) )
3671     {
3672         sal_Int32 nPause = -1;
3673         if( (rValue >>= nPause) && (nPause >= 0) )
3674         {
3675             mnPauseTimeout = nPause;
3676             return;
3677         }
3678     }
3679     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("StartWithNavigator") ) )
3680     {
3681         if( rValue >>= mbStartWithNavigator )
3682             return;
3683     }
3684     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UsePen") ) )
3685     {
3686         if( rValue >>= mbMouseAsPen )
3687             return;
3688     }
3689     throw IllegalArgumentException();
3690 }
3691 
3692 ////////////////////////////////
3693 
3694 // ---------------------------------------------------------
3695 // XAnimationListener
3696 // ---------------------------------------------------------
3697 
3698 SlideShowListenerProxy::SlideShowListenerProxy( const rtl::Reference< SlideshowImpl >& xController, const css::uno::Reference< css::presentation::XSlideShow >& xSlideShow )
3699 : maListeners( m_aMutex )
3700 , mxController( xController )
3701 , mxSlideShow( xSlideShow )
3702 {
3703 }
3704 
3705 // ---------------------------------------------------------
3706 
3707 SlideShowListenerProxy::~SlideShowListenerProxy()
3708 {
3709 }
3710 
3711 // ---------------------------------------------------------
3712 
3713 void SlideShowListenerProxy::addAsSlideShowListener()
3714 {
3715     if( mxSlideShow.is() )
3716     {
3717         Reference< XSlideShowListener > xSlideShowListener( this );
3718         mxSlideShow->addSlideShowListener( xSlideShowListener );
3719     }
3720 }
3721 
3722 // ---------------------------------------------------------
3723 
3724 void SlideShowListenerProxy::removeAsSlideShowListener()
3725 {
3726     if( mxSlideShow.is() )
3727     {
3728         Reference< XSlideShowListener > xSlideShowListener( this );
3729         mxSlideShow->removeSlideShowListener( xSlideShowListener );
3730     }
3731 }
3732 
3733 // ---------------------------------------------------------
3734 
3735 void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3736 {
3737     if( mxSlideShow.is() )
3738     {
3739         Reference< XShapeEventListener > xListener( this );
3740         mxSlideShow->addShapeEventListener( xListener, xShape );
3741     }
3742 }
3743 
3744 // ---------------------------------------------------------
3745 
3746 void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3747 {
3748     if( mxSlideShow.is() )
3749     {
3750         Reference< XShapeEventListener > xListener( this );
3751         mxSlideShow->removeShapeEventListener( xListener, xShape );
3752     }
3753 }
3754 
3755 // ---------------------------------------------------------
3756 
3757 void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3758 {
3759     maListeners.addInterface(xListener);
3760 }
3761 
3762 // ---------------------------------------------------------
3763 
3764 void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3765 {
3766     maListeners.removeInterface(xListener);
3767 }
3768 
3769 // ---------------------------------------------------------
3770 
3771 void SAL_CALL SlideShowListenerProxy::beginEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException)
3772 {
3773     ::osl::MutexGuard aGuard( m_aMutex );
3774 
3775     if( maListeners.getLength() >= 0 )
3776         maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::beginEvent, _1,  boost::cref(xNode) ));
3777 }
3778 
3779 // ---------------------------------------------------------
3780 
3781 void SAL_CALL SlideShowListenerProxy::endEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException)
3782 {
3783     ::osl::MutexGuard aGuard( m_aMutex );
3784 
3785     if( maListeners.getLength() >= 0 )
3786         maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::endEvent, _1, boost::cref(xNode) ));
3787 }
3788 
3789 // ---------------------------------------------------------
3790 
3791 void SAL_CALL SlideShowListenerProxy::repeat( const Reference< XAnimationNode >& xNode, ::sal_Int32 nRepeat ) throw (RuntimeException)
3792 {
3793     ::osl::MutexGuard aGuard( m_aMutex );
3794 
3795     if( maListeners.getLength() >= 0 )
3796         maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::repeat, _1,  boost::cref(xNode), boost::cref(nRepeat) ));
3797 }
3798 
3799 // ---------------------------------------------------------
3800 // ::com::sun::star::presentation::XSlideShowListener:
3801 // ---------------------------------------------------------
3802 
3803 void SAL_CALL SlideShowListenerProxy::paused(  ) throw (::com::sun::star::uno::RuntimeException)
3804 {
3805     ::osl::MutexGuard aGuard( m_aMutex );
3806 
3807     if( maListeners.getLength() >= 0 )
3808         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::paused ) );
3809 }
3810 
3811 // ---------------------------------------------------------
3812 
3813 void SAL_CALL SlideShowListenerProxy::resumed(  ) throw (::com::sun::star::uno::RuntimeException)
3814 {
3815     ::osl::MutexGuard aGuard( m_aMutex );
3816 
3817     if( maListeners.getLength() >= 0 )
3818         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::resumed ) );
3819 }
3820 
3821 // ---------------------------------------------------------
3822 
3823 void SAL_CALL SlideShowListenerProxy::slideTransitionStarted( ) throw (RuntimeException)
3824 {
3825     ::osl::MutexGuard aGuard( m_aMutex );
3826 
3827     if( maListeners.getLength() >= 0 )
3828         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionStarted ) );
3829 }
3830 
3831 // ---------------------------------------------------------
3832 
3833 void SAL_CALL SlideShowListenerProxy::slideTransitionEnded( ) throw (::com::sun::star::uno::RuntimeException)
3834 {
3835     ::osl::MutexGuard aGuard( m_aMutex );
3836 
3837     if( maListeners.getLength() >= 0 )
3838         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionEnded ) );
3839 }
3840 
3841 // ---------------------------------------------------------
3842 
3843 void SAL_CALL SlideShowListenerProxy::slideAnimationsEnded(  ) throw (::com::sun::star::uno::RuntimeException)
3844 {
3845     ::osl::MutexGuard aGuard( m_aMutex );
3846 
3847     if( maListeners.getLength() >= 0 )
3848         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideAnimationsEnded ) );
3849 }
3850 
3851 // ---------------------------------------------------------
3852 
3853 void SlideShowListenerProxy::slideEnded(sal_Bool bReverse) throw (RuntimeException)
3854 {
3855     {
3856         ::osl::MutexGuard aGuard( m_aMutex );
3857 
3858         if( maListeners.getLength() >= 0 )
3859             maListeners.forEach<XSlideShowListener>(
3860                 boost::bind( &XSlideShowListener::slideEnded, _1, bReverse) );
3861     }
3862 
3863     {
3864         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3865         if( mxController.is() )
3866             mxController->slideEnded(bReverse);
3867     }
3868 }
3869 
3870 // ---------------------------------------------------------
3871 
3872 void SlideShowListenerProxy::hyperLinkClicked( rtl::OUString const& aHyperLink ) throw (RuntimeException)
3873 {
3874     {
3875         ::osl::MutexGuard aGuard( m_aMutex );
3876 
3877         if( maListeners.getLength() >= 0 )
3878             maListeners.forEach<XSlideShowListener>( boost::bind( &XSlideShowListener::hyperLinkClicked, _1, boost::cref(aHyperLink) ));
3879     }
3880 
3881     {
3882         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3883         if( mxController.is() )
3884             mxController->hyperLinkClicked(aHyperLink);
3885     }
3886 }
3887 
3888 // ---------------------------------------------------------
3889 // XEventListener
3890 // ---------------------------------------------------------
3891 
3892 void SAL_CALL SlideShowListenerProxy::disposing( const ::com::sun::star::lang::EventObject& aDisposeEvent ) throw (RuntimeException)
3893 {
3894     maListeners.disposeAndClear( aDisposeEvent );
3895     mxController.clear();
3896     mxSlideShow.clear();
3897 }
3898 
3899 // ---------------------------------------------------------
3900 // XShapeEventListener
3901 // ---------------------------------------------------------
3902 
3903 void SAL_CALL SlideShowListenerProxy::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& aOriginalEvent ) throw (RuntimeException)
3904 {
3905     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3906     if( mxController.is() )
3907         mxController->click(xShape, aOriginalEvent );
3908 }
3909 
3910 } // namespace ::sd
3911