xref: /trunk/main/sd/source/ui/slideshow/slideshowimpl.cxx (revision 0deba7fbda3d9908785c25a443701a293b6f4e71)
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             //IAccessibility2 Implementation 2009-----
1100             // Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly.
1101             //mpShowWindow->GrabFocus();
1102             //-----IAccessibility2 Implementation 2009
1103 
1104             std::vector<beans::PropertyValue> aProperties;
1105             aProperties.reserve( 4 );
1106 
1107             aProperties.push_back(
1108                 beans::PropertyValue(
1109                     OUString( RTL_CONSTASCII_USTRINGPARAM("AdvanceOnClick") ),
1110                     -1, Any( ! (maPresSettings.mbLockedPages != sal_False) ),
1111                     beans::PropertyState_DIRECT_VALUE ) );
1112 
1113             aProperties.push_back(
1114                 beans::PropertyValue(
1115                     OUString( RTL_CONSTASCII_USTRINGPARAM("ImageAnimationsAllowed") ),
1116                     -1, Any( maPresSettings.mbAnimationAllowed != sal_False ),
1117                     beans::PropertyState_DIRECT_VALUE ) );
1118 
1119             const sal_Bool bZOrderEnabled(
1120                 SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsSlideshowRespectZOrder() );
1121             aProperties.push_back(
1122                 beans::PropertyValue(
1123                     OUString( RTL_CONSTASCII_USTRINGPARAM("DisableAnimationZOrder") ),
1124                     -1, Any( bZOrderEnabled == sal_False ),
1125                     beans::PropertyState_DIRECT_VALUE ) );
1126 
1127 /*
1128             aProperties.push_back(
1129                 beans::PropertyValue(
1130                     OUString( RTL_CONSTASCII_USTRINGPARAM("MouseVisible") ),
1131                     -1, Any( maPresSettings.mbMouseVisible != sal_False ),
1132                     beans::PropertyState_DIRECT_VALUE ) );
1133 */
1134             aProperties.push_back(
1135                 beans::PropertyValue(
1136                     OUString( RTL_CONSTASCII_USTRINGPARAM("ForceManualAdvance") ),
1137                     -1, Any( maPresSettings.mbManual != sal_False ),
1138                     beans::PropertyState_DIRECT_VALUE ) );
1139 
1140             if( mbUsePen )
1141             {
1142                 aProperties.push_back(
1143                     beans::PropertyValue(
1144                         OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintColor") ),
1145                         // User paint color is black by default.
1146                         -1, Any( mnUserPaintColor ),
1147                         beans::PropertyState_DIRECT_VALUE ) );
1148 
1149                 aProperties.push_back(
1150                     beans::PropertyValue(
1151                         OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintStrokeWidth") ),
1152                         // User paint color is black by default.
1153                         -1, Any( mdUserPaintStrokeWidth ),
1154                         beans::PropertyState_DIRECT_VALUE ) );
1155             }
1156 
1157             if (mbRehearseTimings) {
1158                 aProperties.push_back(
1159                     beans::PropertyValue(
1160                         OUString( RTL_CONSTASCII_USTRINGPARAM("RehearseTimings") ),
1161                         -1, Any(true), beans::PropertyState_DIRECT_VALUE ) );
1162             }
1163 
1164             bRet = startShowImpl( Sequence<beans::PropertyValue>(
1165                                       &aProperties[0], aProperties.size() ) );
1166 
1167         }
1168 
1169         setActiveXToolbarsVisible( sal_False );
1170     }
1171     catch( Exception& e )
1172     {
1173         (void)e;
1174         DBG_ERROR(
1175             (OString("sd::SlideshowImpl::startShow(), "
1176                      "exception caught: ") +
1177              rtl::OUStringToOString(
1178                  comphelper::anyToString( cppu::getCaughtException() ),
1179                  RTL_TEXTENCODING_UTF8 )).getStr() );
1180         bRet = false;
1181     }
1182 
1183     return bRet;
1184 }
1185 
1186 bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProperties )
1187 {
1188     try
1189     {
1190         mxShow = Reference< XSlideShow >( createSlideShow(), UNO_QUERY_THROW );
1191         mxView = mxView.createFromQuery( new SlideShowView(
1192                                              *mpShowWindow,
1193                                              mpDoc,
1194                                              meAnimationMode,
1195                                              this,
1196                                              maPresSettings.mbFullScreen) );
1197 
1198         // try add wait symbol to properties:
1199         const Reference<rendering::XSpriteCanvas> xSpriteCanvas(
1200             mxView->getCanvas() );
1201         if (xSpriteCanvas.is())
1202         {
1203             BitmapEx waitSymbolBitmap( SdResId(BMP_WAIT_ICON) );
1204             const Reference<rendering::XBitmap> xBitmap(
1205                 vcl::unotools::xBitmapFromBitmapEx(
1206                     xSpriteCanvas->getDevice(), waitSymbolBitmap ) );
1207             if (xBitmap.is())
1208             {
1209                 mxShow->setProperty(
1210                     beans::PropertyValue(
1211                         OUString( RTL_CONSTASCII_USTRINGPARAM("WaitSymbolBitmap") ),
1212                         -1,
1213                         makeAny( xBitmap ),
1214                         beans::PropertyState_DIRECT_VALUE ) );
1215             }
1216         }
1217 
1218         const sal_Int32 nCount = aProperties.getLength();
1219         sal_Int32 nIndex;
1220         for( nIndex = 0; nIndex < nCount; nIndex++ )
1221             mxShow->setProperty( aProperties[nIndex] );
1222 
1223         mxShow->addView( mxView.getRef() );
1224 
1225         mxListenerProxy.set( new SlideShowListenerProxy( this, mxShow ) );
1226         mxListenerProxy->addAsSlideShowListener();
1227 
1228 
1229         NotifyDocumentEvent( mpDoc, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OnStartPresentation") ) );
1230         displaySlideIndex( mpSlideController->getStartSlideIndex() );
1231 
1232         return true;
1233     }
1234     catch( Exception& e )
1235     {
1236         (void)e;
1237         DBG_ERROR(
1238             (OString("sd::SlideshowImpl::startShowImpl(), "
1239                      "exception caught: ") +
1240              rtl::OUStringToOString(
1241                  comphelper::anyToString( cppu::getCaughtException() ),
1242                  RTL_TEXTENCODING_UTF8 )).getStr() );
1243         return false;
1244     }
1245 }
1246 
1247 /** called only by the slideshow view when the first paint event occurs.
1248     This actually starts the slideshow. */
1249 void SlideshowImpl::onFirstPaint()
1250 {
1251     if( mpShowWindow )
1252     {
1253         /*
1254         mpShowWindow->SetBackground( Wallpaper( Color( COL_BLACK ) ) );
1255         mpShowWindow->Erase();
1256         mpShowWindow->SetBackground();
1257         */
1258     }
1259 
1260     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1261     maUpdateTimer.SetTimeout( (sal_uLong)100 );
1262     maUpdateTimer.Start();
1263 }
1264 
1265 void SlideshowImpl::paint( const Rectangle& /* rRect */ )
1266 {
1267     if( mxView.is() ) try
1268     {
1269         awt::PaintEvent aEvt;
1270         // aEvt.UpdateRect = TODO
1271         mxView->paint( aEvt );
1272     }
1273     catch( Exception& e )
1274     {
1275         static_cast<void>(e);
1276         DBG_ERROR(
1277             (OString("sd::SlideshowImpl::paint(), "
1278                     "exception caught: ") +
1279             rtl::OUStringToOString(
1280                 comphelper::anyToString( cppu::getCaughtException() ),
1281                 RTL_TEXTENCODING_UTF8 )).getStr() );
1282     }
1283 }
1284 
1285 // --------------------------------------------------------------------
1286 
1287 void SAL_CALL SlideshowImpl::addSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException)
1288 {
1289     if( mxListenerProxy.is() )
1290         mxListenerProxy->addSlideShowListener( xListener );
1291 }
1292 
1293 // --------------------------------------------------------------------
1294 
1295 void SAL_CALL SlideshowImpl::removeSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException)
1296 {
1297     if( mxListenerProxy.is() )
1298         mxListenerProxy->removeSlideShowListener( xListener );
1299 }
1300 
1301 // ---------------------------------------------------------
1302 
1303 void SlideshowImpl::slideEnded(const bool bReverse)
1304 {
1305     if (bReverse)
1306         gotoPreviousSlide(true);
1307     else
1308         gotoNextSlide();
1309 }
1310 
1311 // ---------------------------------------------------------
1312 
1313 void SlideshowImpl::removeShapeEvents()
1314 {
1315     if( mxShow.is() && mxListenerProxy.is() ) try
1316     {
1317         WrappedShapeEventImplMap::iterator aIter;
1318         const WrappedShapeEventImplMap::iterator aEnd( maShapeEventMap.end() );
1319 
1320         for( aIter = maShapeEventMap.begin(); aIter != aEnd; aIter++ )
1321         {
1322             mxListenerProxy->removeShapeEventListener( (*aIter).first );
1323             mxShow->setShapeCursor( (*aIter).first, awt::SystemPointer::ARROW );
1324         }
1325 
1326         maShapeEventMap.clear();
1327     }
1328     catch( Exception& e )
1329     {
1330         (void)e;
1331         DBG_ERROR(
1332             (OString("sd::SlideshowImpl::removeShapeEvents(), "
1333                      "exception caught: ") +
1334              rtl::OUStringToOString(
1335                  comphelper::anyToString( cppu::getCaughtException() ),
1336                  RTL_TEXTENCODING_UTF8 )).getStr() );
1337     }
1338 }
1339 
1340 // ---------------------------------------------------------
1341 
1342 void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber)
1343 {
1344     if( nSlideNumber >= 0 ) try
1345     {
1346         Reference< XDrawPagesSupplier > xDrawPages( mxModel, UNO_QUERY_THROW );
1347         Reference< XIndexAccess > xPages( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
1348 
1349         Reference< XShapes > xDrawPage;
1350         xPages->getByIndex(nSlideNumber) >>= xDrawPage;
1351 
1352         if( xDrawPage.is() )
1353         {
1354             Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
1355             if( xMasterPageTarget.is() )
1356             {
1357                 Reference< XShapes > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
1358                 if( xMasterPage.is() )
1359                     registerShapeEvents( xMasterPage );
1360             }
1361             registerShapeEvents( xDrawPage );
1362         }
1363     }
1364     catch( Exception& e )
1365     {
1366         (void)e;
1367         DBG_ERROR(
1368             (OString("sd::SlideshowImpl::registerShapeEvents(), "
1369                      "exception caught: ") +
1370              rtl::OUStringToOString(
1371                  comphelper::anyToString( cppu::getCaughtException() ),
1372                  RTL_TEXTENCODING_UTF8 )).getStr() );
1373     }
1374 }
1375 
1376 // ---------------------------------------------------------
1377 
1378 void SlideshowImpl::registerShapeEvents( Reference< XShapes >& xShapes ) throw( Exception )
1379 {
1380     try
1381     {
1382         const sal_Int32 nShapeCount = xShapes->getCount();
1383         sal_Int32 nShape;
1384         for( nShape = 0; nShape < nShapeCount; nShape++ )
1385         {
1386             Reference< XShape > xShape;
1387             xShapes->getByIndex( nShape ) >>= xShape;
1388 
1389             if( xShape.is() &&
1390                 xShape->getShapeType().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.GroupShape") ) )
1391             {
1392                 Reference< XShapes > xSubShapes( xShape, UNO_QUERY );
1393                 if( xSubShapes.is() )
1394                     registerShapeEvents( xSubShapes );
1395             }
1396 
1397             Reference< XPropertySet > xSet( xShape, UNO_QUERY );
1398             if( !xSet.is() )
1399                 continue;
1400 
1401             Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1402             if( !xSetInfo.is() || !xSetInfo->hasPropertyByName( msOnClick ) )
1403                 continue;
1404 
1405             WrappedShapeEventImplPtr pEvent( new WrappedShapeEventImpl );
1406             xSet->getPropertyValue( msOnClick ) >>= pEvent->meClickAction;
1407 
1408             switch( pEvent->meClickAction )
1409             {
1410             case ClickAction_PREVPAGE:
1411             case ClickAction_NEXTPAGE:
1412             case ClickAction_FIRSTPAGE:
1413             case ClickAction_LASTPAGE:
1414             case ClickAction_STOPPRESENTATION:
1415                 break;
1416             case ClickAction_BOOKMARK:
1417                 if( xSetInfo->hasPropertyByName( msBookmark ) )
1418                     xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1419                 if( getSlideNumberForBookmark( pEvent->maStrBookmark ) == -1 )
1420                     continue;
1421                 break;
1422             case ClickAction_DOCUMENT:
1423             case ClickAction_SOUND:
1424             case ClickAction_PROGRAM:
1425             case ClickAction_MACRO:
1426                 if( xSetInfo->hasPropertyByName( msBookmark ) )
1427                     xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
1428                 break;
1429             case ClickAction_VERB:
1430                 if( xSetInfo->hasPropertyByName( msVerb ) )
1431                     xSet->getPropertyValue( msVerb ) >>= pEvent->mnVerb;
1432                 break;
1433             default:
1434                 continue; // skip all others
1435             }
1436 
1437             maShapeEventMap[ xShape ] = pEvent;
1438 
1439             if( mxListenerProxy.is() )
1440                 mxListenerProxy->addShapeEventListener( xShape );
1441             mxShow->setShapeCursor( xShape, awt::SystemPointer::REFHAND );
1442         }
1443     }
1444     catch( Exception& e )
1445     {
1446         static_cast<void>(e);
1447         DBG_ERROR(
1448             (OString("sd::SlideshowImpl::registerShapeEvents(), "
1449                     "exception caught: ") +
1450             rtl::OUStringToOString(
1451                 comphelper::anyToString( cppu::getCaughtException() ),
1452                 RTL_TEXTENCODING_UTF8 )).getStr() );
1453     }
1454 }
1455 
1456 // ---------------------------------------------------------
1457 
1458 void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects)
1459 {
1460     stopSound();
1461     removeShapeEvents();
1462 
1463     if( mpSlideController.get() && mxShow.is() )
1464     {
1465         Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(),
1466                                                     UNO_QUERY_THROW );
1467         mpSlideController->displayCurrentSlide( mxShow, xDrawPages, bSkipAllMainSequenceEffects );
1468         registerShapeEvents(mpSlideController->getCurrentSlideNumber());
1469         update();
1470 
1471         SfxBindings* pBindings = getBindings();
1472         if( pBindings )
1473         {
1474             pBindings->Invalidate( SID_NAVIGATOR_STATE );
1475             pBindings->Invalidate( SID_NAVIGATOR_PAGENAME );
1476         }
1477     }
1478     //IAccessibility2 Implementation 2009-----
1479     // send out page change event and notity to update all acc info for current page
1480     if (mpViewShell)
1481     {
1482         sal_Int32 currentPageIndex = getCurrentSlideIndex();
1483         mpViewShell->fireSwitchCurrentPage(currentPageIndex);
1484         mpViewShell->NotifyAccUpdate();
1485     }
1486     //-----IAccessibility2 Implementation 2009
1487 }
1488 
1489 // ---------------------------------------------------------
1490 
1491 void SlideshowImpl::endPresentation()
1492 {
1493 /*
1494     if( maPresSettings.mbMouseAsPen)
1495     {
1496         Reference< XMultiServiceFactory > xDocFactory(mpDoc->getUnoModel(), UNO_QUERY );
1497         if( xDocFactory.is() )
1498             mxShow->registerUserPaintPolygons(xDocFactory);
1499     }
1500 */
1501     if( !mnEndShowEvent )
1502         mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) );
1503 }
1504 
1505 // ---------------------------------------------------------
1506 
1507 IMPL_LINK( SlideshowImpl, endPresentationHdl, void*, EMPTYARG )
1508 {
1509     mnEndShowEvent = 0;
1510 
1511     if( mxPresentation.is() )
1512         mxPresentation->end();
1513     return 0;
1514 }
1515 
1516 // ---------------------------------------------------------
1517 
1518 void SAL_CALL SlideshowImpl::pause() throw (RuntimeException)
1519 {
1520     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1521 
1522     if( !mbIsPaused ) try
1523     {
1524         mbIsPaused = sal_True;
1525         if( mxShow.is() )
1526         {
1527             mxShow->pause(sal_True);
1528 
1529             if( mxListenerProxy.is() )
1530                 mxListenerProxy->paused();
1531         }
1532     }
1533     catch( Exception& e )
1534     {
1535         static_cast<void>(e);
1536         DBG_ERROR(
1537             (OString("sd::SlideshowImpl::pause(), "
1538                     "exception caught: ") +
1539             rtl::OUStringToOString(
1540                 comphelper::anyToString( cppu::getCaughtException() ),
1541                 RTL_TEXTENCODING_UTF8 )).getStr() );
1542     }
1543 }
1544 
1545 // ---------------------------------------------------------
1546 
1547 void SAL_CALL SlideshowImpl::resume() throw (RuntimeException)
1548 {
1549     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1550 
1551     if( mbIsPaused ) try
1552     {
1553         if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
1554         {
1555             mpShowWindow->RestartShow();
1556         }
1557         else
1558         {
1559             mbIsPaused = sal_False;;
1560             if( mxShow.is() )
1561             {
1562                 mxShow->pause(sal_False);
1563                 update();
1564 
1565                 if( mxListenerProxy.is() )
1566                     mxListenerProxy->resumed();
1567             }
1568         }
1569     }
1570     catch( Exception& e )
1571     {
1572         static_cast<void>(e);
1573         DBG_ERROR(
1574             (OString("sd::SlideshowImpl::resume(), "
1575                     "exception caught: ") +
1576             rtl::OUStringToOString(
1577                 comphelper::anyToString( cppu::getCaughtException() ),
1578                 RTL_TEXTENCODING_UTF8 )).getStr() );
1579     }
1580 }
1581 
1582 // ---------------------------------------------------------
1583 
1584 sal_Bool SAL_CALL SlideshowImpl::isPaused() throw (RuntimeException)
1585 {
1586     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1587     return mbIsPaused;
1588 }
1589 
1590 // ---------------------------------------------------------
1591 
1592 void SAL_CALL SlideshowImpl::blankScreen( sal_Int32 nColor ) throw (RuntimeException)
1593 {
1594     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1595 
1596     if( mpShowWindow && mpSlideController )
1597     {
1598         if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), nColor ) )
1599         {
1600             pause();
1601         }
1602     }
1603 }
1604 
1605 // ---------------------------------------------------------
1606 // XShapeEventListener
1607 // ---------------------------------------------------------
1608 
1609 void SlideshowImpl::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& /* aOriginalEvent */ )
1610 {
1611     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1612 
1613     WrappedShapeEventImplPtr pEvent = maShapeEventMap[xShape];
1614     if( !pEvent.get() )
1615         return;
1616 
1617     switch( pEvent->meClickAction )
1618     {
1619     case ClickAction_PREVPAGE:          gotoPreviousSlide();        break;
1620     case ClickAction_NEXTPAGE:          gotoNextSlide();            break;
1621     case ClickAction_FIRSTPAGE:         gotoFirstSlide();           break;
1622     case ClickAction_LASTPAGE:          gotoLastSlide();            break;
1623     case ClickAction_STOPPRESENTATION:  endPresentation();          break;
1624     case ClickAction_BOOKMARK:
1625     {
1626         gotoBookmark( pEvent->maStrBookmark );
1627     }
1628     break;
1629     case ClickAction_SOUND:
1630     {
1631         try
1632         {
1633             mxPlayer.set(avmedia::MediaWindow::createPlayer(pEvent->maStrBookmark), uno::UNO_QUERY_THROW );
1634             mxPlayer->start();
1635         }
1636         catch( uno::Exception& e )
1637         {
1638             (void)e;
1639             DBG_ERROR("sd::SlideshowImpl::click(), exception caught!" );
1640         }
1641     }
1642     break;
1643 
1644     case ClickAction_DOCUMENT:
1645     {
1646         OUString aBookmark( pEvent->maStrBookmark );
1647 
1648         sal_Int32 nPos = aBookmark.indexOf( sal_Unicode('#') );
1649         if( nPos >= 0 )
1650         {
1651             OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1652             OUString aName( aBookmark.copy( nPos+1 ) );
1653             aURL += getUiNameFromPageApiNameImpl( aName );
1654             aBookmark = aURL;
1655         }
1656 
1657         mpDocSh->OpenBookmark( aBookmark );
1658     }
1659     break;
1660 
1661     case ClickAction_PROGRAM:
1662     {
1663         INetURLObject aURL(
1664             ::URIHelper::SmartRel2Abs(
1665                 INetURLObject(mpDocSh->GetMedium()->GetBaseURL()),
1666                 pEvent->maStrBookmark, ::URIHelper::GetMaybeFileHdl(), true,
1667                 false, INetURLObject::WAS_ENCODED,
1668                 INetURLObject::DECODE_UNAMBIGUOUS ) );
1669 
1670         if( INET_PROT_FILE == aURL.GetProtocol() )
1671         {
1672             SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
1673             SfxBoolItem aBrowsing( SID_BROWSE, sal_True );
1674 
1675             SfxViewFrame* pViewFrm = SfxViewFrame::Current();
1676             if (pViewFrm)
1677                 pViewFrm->GetDispatcher()->Execute( SID_OPENDOC,
1678                                             SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
1679                                             &aUrl,
1680                                             &aBrowsing,
1681                                             0L );
1682         }
1683     }
1684     break;
1685 
1686     case presentation::ClickAction_MACRO:
1687     {
1688         const String aMacro( pEvent->maStrBookmark );
1689 
1690         if ( SfxApplication::IsXScriptURL( aMacro ) )
1691         {
1692             Any aRet;
1693             Sequence< sal_Int16 > aOutArgsIndex;
1694             Sequence< Any > aOutArgs;
1695             Sequence< Any >* pInArgs = new Sequence< Any >(0);
1696             mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs);
1697         }
1698         else
1699         {
1700             // aMacro has the following syntax:
1701             // "Macroname.Modulname.Libname.Dokumentname" or
1702             // "Macroname.Modulname.Libname.Applikationsname"
1703             String aMacroName = aMacro.GetToken(0, sal_Unicode('.'));
1704             String aModulName = aMacro.GetToken(1, sal_Unicode('.'));
1705             String aLibName   = aMacro.GetToken(2, sal_Unicode('.'));
1706             String aDocName   = aMacro.GetToken(3, sal_Unicode('.'));
1707 
1708             // todo: is the limitation still given that only
1709             // Modulname+Macroname can be used here?
1710             String aExecMacro(aModulName);
1711             aExecMacro.Append( sal_Unicode('.') );
1712             aExecMacro.Append( aMacroName );
1713             mpDocSh->GetBasic()->Call(aExecMacro);
1714         }
1715     }
1716     break;
1717 
1718     case ClickAction_VERB:
1719     {
1720         // todo, better do it async?
1721         SdrObject* pObj = GetSdrObjectFromXShape( xShape );
1722         SdrOle2Obj* pOleObject = PTR_CAST(SdrOle2Obj, pObj);
1723         if (pOleObject && mpViewShell )
1724             mpViewShell->ActivateObject(pOleObject, pEvent->mnVerb);
1725     }
1726     break;
1727     default:
1728         break;
1729     }
1730 }
1731 
1732 // ---------------------------------------------------------
1733 
1734 sal_Int32 SlideshowImpl::getSlideNumberForBookmark( const OUString& rStrBookmark )
1735 {
1736     sal_Bool bIsMasterPage;
1737     OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark );
1738     sal_uInt16 nPgNum = mpDoc->GetPageByName( aBookmark, bIsMasterPage );
1739 
1740     if( nPgNum == SDRPAGE_NOTFOUND )
1741     {
1742         // Ist das Bookmark ein Objekt?
1743         SdrObject* pObj = mpDoc->GetObj( aBookmark );
1744 
1745         if( pObj )
1746         {
1747             nPgNum = pObj->GetPage()->GetPageNum();
1748             bIsMasterPage = (sal_Bool)pObj->GetPage()->IsMasterPage();
1749         }
1750     }
1751 
1752     if( (nPgNum == SDRPAGE_NOTFOUND) || bIsMasterPage || static_cast<SdPage*>(mpDoc->GetPage(nPgNum))->GetPageKind() != PK_STANDARD )
1753         return -1;
1754 
1755     return ( nPgNum - 1) >> 1;
1756 }
1757 
1758 // ---------------------------------------------------------
1759 
1760 void SlideshowImpl::hyperLinkClicked( rtl::OUString const& aHyperLink ) throw (RuntimeException)
1761 {
1762     OUString aBookmark( aHyperLink );
1763 
1764     sal_Int32 nPos = aBookmark.indexOf( sal_Unicode('#') );
1765     if( nPos >= 0 )
1766     {
1767         OUString aURL( aBookmark.copy( 0, nPos+1 ) );
1768         OUString aName( aBookmark.copy( nPos+1 ) );
1769         aURL += getUiNameFromPageApiNameImpl( aName );
1770         aBookmark = aURL;
1771     }
1772 
1773     mpDocSh->OpenBookmark( aBookmark );
1774 }
1775 
1776 // ---------------------------------------------------------
1777 
1778 void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber )
1779 {
1780     if( mpSlideController.get() )
1781     {
1782         if( mpSlideController->jumpToSlideNumber( nSlideNumber ) )
1783         {
1784             displayCurrentSlide();
1785         }
1786     }
1787 }
1788 
1789 // ---------------------------------------------------------
1790 
1791 /** nSlideIndex == -1 displays current slide again */
1792 void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex )
1793 {
1794     if( mpSlideController.get() )
1795     {
1796         if( (nSlideIndex == -1) || mpSlideController->jumpToSlideIndex( nSlideIndex ) )
1797         {
1798             displayCurrentSlide();
1799         }
1800     }
1801 }
1802 
1803 // ---------------------------------------------------------
1804 
1805 void SlideshowImpl::jumpToBookmark( const String& sBookmark )
1806 {
1807     sal_Int32 nSlideNumber = getSlideNumberForBookmark( sBookmark );
1808     if( nSlideNumber != -1 )
1809         displaySlideNumber( nSlideNumber );
1810 }
1811 
1812 // ---------------------------------------------------------
1813 
1814 sal_Int32 SlideshowImpl::getCurrentSlideNumber()
1815 {
1816     return mpSlideController.get() ? mpSlideController->getCurrentSlideNumber() : -1;
1817 }
1818 
1819 // ---------------------------------------------------------
1820 
1821 sal_Int32 SlideshowImpl::getFirstSlideNumber()
1822 {
1823     sal_Int32 nRet = 0;
1824     if( mpSlideController.get() )
1825     {
1826         sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
1827         if( nSlideIndexCount >= 0 )
1828         {
1829             nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
1830             while( nSlideIndexCount-- )
1831             {
1832                 sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
1833                 if( nRet > nTemp )
1834                     nRet = nTemp;
1835             }
1836         }
1837     }
1838 
1839     return nRet;
1840 }
1841 
1842 // ---------------------------------------------------------
1843 
1844 sal_Int32 SlideshowImpl::getLastSlideNumber()
1845 {
1846     sal_Int32 nRet = 0;
1847     if( mpSlideController.get() )
1848     {
1849         sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
1850         if( nSlideIndexCount >= 0 )
1851         {
1852             nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
1853             while( nSlideIndexCount-- )
1854             {
1855                 sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
1856                 if( nRet < nTemp )
1857                     nRet = nTemp;
1858             }
1859         }
1860     }
1861 
1862     return nRet;
1863 }
1864 
1865 // ---------------------------------------------------------
1866 
1867 sal_Bool SAL_CALL SlideshowImpl::isEndless() throw( RuntimeException )
1868 {
1869     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1870     return maPresSettings.mbEndless;
1871 }
1872 
1873 // ---------------------------------------------------------
1874 
1875 double SlideshowImpl::update()
1876 {
1877     startUpdateTimer();
1878     return -1;
1879 }
1880 
1881 // ---------------------------------------------------------
1882 
1883 void SlideshowImpl::startUpdateTimer()
1884 {
1885     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1886     maUpdateTimer.SetTimeout( 0 );
1887     maUpdateTimer.Start();
1888 }
1889 
1890 // ---------------------------------------------------------
1891 
1892 /** this timer is called 20ms after a new slide was displayed.
1893     This is used to unfreeze user input that was disabled after
1894     slide change to skip input that was buffered during slide
1895     transition preperation */
1896 IMPL_LINK( SlideshowImpl, ReadyForNextInputHdl, Timer*, EMPTYARG )
1897 {
1898     mbInputFreeze = false;
1899     return 0;
1900 }
1901 
1902 // ---------------------------------------------------------
1903 
1904 /** if I catch someone someday who calls this method by hand
1905     and not by using the timer, I will personaly punish this
1906     person seriously, even if this person is me.
1907 */
1908 IMPL_LINK( SlideshowImpl, updateHdl, Timer*, EMPTYARG )
1909 {
1910     mnUpdateEvent = 0;
1911 
1912     return updateSlideShow();
1913 }
1914 
1915 
1916 
1917 
1918 IMPL_LINK( SlideshowImpl, PostYieldListener, void*, EMPTYARG )
1919 {
1920     Application::EnableNoYieldMode(false);
1921     Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1922 
1923     if (mbDisposed)
1924         return 0;
1925 
1926     // Call Reschedule() but make sure that we are not destroyed during its
1927     // execution (we still can be disposed, though.)
1928     const rtl::Reference<SlideshowImpl> pSelf (this);
1929     Application::Reschedule(true);
1930 
1931     // Update the slide show if we are still alive.
1932     if ( ! mbDisposed)
1933         return updateSlideShow();
1934     else
1935         return 0;
1936 }
1937 
1938 
1939 
1940 
1941 sal_Int32 SlideshowImpl::updateSlideShow (void)
1942 {
1943     // doing some nMagic
1944     const rtl::Reference<SlideshowImpl> this_(this);
1945 
1946     Reference< XSlideShow > xShow( mxShow );
1947     if ( ! xShow.is())
1948         return 0;
1949 
1950     try
1951     {
1952         // TODO(Q3): Evaluate under various systems and setups,
1953         // whether this is really necessary. Under WinXP and Matrox
1954         // G550, the frame rates were much more steadier with this
1955         // tweak, although.
1956 
1957 // currently no solution, because this kills sound (at least on Windows)
1958 //         // Boost our prio, as long as we're in the render loop
1959 //         ::canvas::tools::PriorityBooster aBooster(2);
1960 
1961         double fUpdate = 0.0;
1962         if( !xShow->update(fUpdate) )
1963             fUpdate = -1.0;
1964 
1965         if (mxShow.is() && (fUpdate >= 0.0))
1966         {
1967             if (::basegfx::fTools::equalZero(fUpdate))
1968             {
1969                 // Use post yield listener for short update intervalls.
1970                 Application::EnableNoYieldMode(true);
1971                 Application::AddPostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1972             }
1973             else
1974             {
1975                 // Avoid busy loop when the previous call to update()
1976                 // returns a small positive number but not 0 (which is
1977                 // handled above).  Also, make sure that calls to update()
1978                 // have a minimum frequency.
1979                 // => Allow up to 60 frames per second.  Call at least once
1980                 // every 4 seconds.
1981                 const static sal_Int32 mnMaximumFrameCount (60);
1982                 const static double mnMinimumTimeout (1.0 / mnMaximumFrameCount);
1983                 const static double mnMaximumTimeout (4.0);
1984                 fUpdate = ::basegfx::clamp(fUpdate, mnMinimumTimeout, mnMaximumTimeout);
1985 
1986                 // Make sure that the maximum frame count has not been set
1987                 // too high (only then conversion to milliseconds and long
1988                 // integer may lead to zero value.)
1989                 OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0);
1990 
1991                 Application::EnableNoYieldMode(false);
1992                 Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
1993 
1994                 // Use a timer for the asynchronous callback.
1995                 maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
1996                 maUpdateTimer.Start();
1997             }
1998         }
1999     }
2000     catch( Exception& e )
2001     {
2002         static_cast<void>(e);
2003         DBG_ERROR(
2004             (OString("sd::SlideshowImpl::updateSlideShow(), exception caught: ")
2005                 + rtl::OUStringToOString(
2006                     comphelper::anyToString( cppu::getCaughtException() ),
2007                     RTL_TEXTENCODING_UTF8 )).getStr() );
2008     }
2009     return 0;
2010 }
2011 
2012 // ---------------------------------------------------------
2013 
2014 bool SlideshowImpl::keyInput(const KeyEvent& rKEvt)
2015 {
2016     if( !mxShow.is() || mbInputFreeze )
2017         return false;
2018 
2019     bool bRet = true;
2020 
2021     try
2022     {
2023         const int nKeyCode = rKEvt.GetKeyCode().GetCode();
2024         switch( nKeyCode )
2025         {
2026             case awt::Key::CONTEXTMENU:
2027                 if( !mnContextMenuEvent )
2028                 {
2029                     if( mpShowWindow )
2030                         maPopupMousePos = mpShowWindow->GetPointerState().maPos;
2031                     mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2032                 }
2033                 break;
2034 
2035             // cancel show
2036             case KEY_ESCAPE:
2037             case KEY_SUBTRACT:
2038                 // in case the user cancels the presentation, switch to current slide
2039                 // in edit mode
2040                 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2041                 {
2042                     if( mpSlideController->getCurrentSlideNumber() != -1 )
2043                         mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2044                 }
2045                 endPresentation();
2046                 break;
2047 
2048             // advance show
2049             case KEY_PAGEDOWN:
2050                 if(rKEvt.GetKeyCode().IsMod2())
2051                 {
2052                     gotoNextSlide();
2053                     break;
2054                 }
2055                 // warning, fall through!
2056             case KEY_SPACE:
2057             case KEY_RIGHT:
2058             case KEY_DOWN:
2059             case KEY_N:
2060                 gotoNextEffect();
2061                 break;
2062 
2063             case KEY_RETURN:
2064             {
2065                 if( maCharBuffer.Len() )
2066                 {
2067                     if( mpSlideController.get() )
2068                     {
2069                         if( mpSlideController->jumpToSlideNumber( maCharBuffer.ToInt32() - 1 ) )
2070                             displayCurrentSlide();
2071                     }
2072                     maCharBuffer.Erase();
2073                 }
2074                 else
2075                 {
2076                     gotoNextEffect();
2077                 }
2078             }
2079             break;
2080 
2081             // numeric: add to buffer
2082             case KEY_0:
2083             case KEY_1:
2084             case KEY_2:
2085             case KEY_3:
2086             case KEY_4:
2087             case KEY_5:
2088             case KEY_6:
2089             case KEY_7:
2090             case KEY_8:
2091             case KEY_9:
2092                 maCharBuffer.Append( rKEvt.GetCharCode() );
2093                 break;
2094 
2095             case KEY_PAGEUP:
2096                 if(rKEvt.GetKeyCode().IsMod2())
2097                 {
2098                     gotoPreviousSlide();
2099                     break;
2100                 }
2101                 // warning, fall through!
2102             case KEY_LEFT:
2103             case KEY_UP:
2104             case KEY_P:
2105             case KEY_BACKSPACE:
2106                 gotoPreviousEffect();
2107                 break;
2108 
2109             case KEY_HOME:
2110                 gotoFirstSlide();
2111                 break;
2112 
2113             case KEY_END:
2114                 gotoLastSlide();
2115                 break;
2116 
2117             case KEY_B:
2118             case KEY_W:
2119             case KEY_POINT:
2120             case KEY_COMMA:
2121             {
2122                 blankScreen( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? 0x00ffffff : 0x00000000 );
2123             }
2124             break;
2125 
2126             default:
2127                 bRet = false;
2128             break;
2129         }
2130     }
2131     catch( Exception& e )
2132     {
2133         bRet = false;
2134         static_cast<void>(e);
2135         DBG_ERROR(
2136             (OString("sd::SlideshowImpl::keyInput(), "
2137                     "exception caught: ") +
2138             rtl::OUStringToOString(
2139                 comphelper::anyToString( cppu::getCaughtException() ),
2140                 RTL_TEXTENCODING_UTF8 )).getStr() );
2141     }
2142 
2143     return bRet;
2144 }
2145 
2146 IMPL_LINK( SlideshowImpl, EventListenerHdl, VclSimpleEvent*, pEvent )
2147 {
2148     if( !mxShow.is() || mbInputFreeze )
2149         return 0;
2150 
2151     if( pEvent && (pEvent->GetId() == VCLEVENT_WINDOW_COMMAND) && static_cast<VclWindowEvent*>(pEvent)->GetData() )
2152     {
2153         const CommandEvent& rEvent = *(const CommandEvent*)static_cast<VclWindowEvent*>(pEvent)->GetData();
2154 
2155         if( rEvent.GetCommand() == COMMAND_MEDIA )
2156         {
2157             switch( rEvent.GetMediaCommand() )
2158             {
2159 #if defined( QUARTZ )
2160             case MEDIA_COMMAND_MENU:
2161                 if( !mnContextMenuEvent )
2162                 {
2163                 if( mpShowWindow )
2164                     maPopupMousePos = mpShowWindow->GetPointerState().maPos;
2165                 mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2166                 }
2167                 break;
2168             case MEDIA_COMMAND_VOLUME_DOWN:
2169                 gotoPreviousSlide();
2170                 break;
2171             case MEDIA_COMMAND_VOLUME_UP:
2172                 gotoNextEffect();
2173                 break;
2174 #endif
2175             case MEDIA_COMMAND_NEXTTRACK:
2176                 gotoNextEffect();
2177                 break;
2178             case MEDIA_COMMAND_PAUSE:
2179                 if( !mbIsPaused )
2180                     blankScreen(0);
2181                 break;
2182             case MEDIA_COMMAND_PLAY:
2183                 if( mbIsPaused )
2184                     resume();
2185                 break;
2186 
2187             case MEDIA_COMMAND_PLAY_PAUSE:
2188                 if( mbIsPaused )
2189                     resume();
2190                 else
2191                     blankScreen(0);
2192                 break;
2193             case MEDIA_COMMAND_PREVIOUSTRACK:
2194                 gotoPreviousSlide();
2195                 break;
2196             case MEDIA_COMMAND_NEXTTRACK_HOLD:
2197                 gotoLastSlide();
2198                 break;
2199 
2200             case MEDIA_COMMAND_REWIND:
2201                 gotoFirstSlide();
2202                 break;
2203             case MEDIA_COMMAND_STOP:
2204                 // in case the user cancels the presentation, switch to current slide
2205                 // in edit mode
2206                 if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2207                 {
2208                     if( mpSlideController->getCurrentSlideNumber() != -1 )
2209                         mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2210                 }
2211                 endPresentation();
2212                 break;
2213             }
2214         }
2215     }
2216 
2217     return 0;
2218 }
2219 
2220 // ---------------------------------------------------------
2221 
2222 void SlideshowImpl::mouseButtonUp(const MouseEvent& rMEvt)
2223 {
2224     if( rMEvt.IsRight() && !mnContextMenuEvent )
2225     {
2226         maPopupMousePos = rMEvt.GetPosPixel();
2227         mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
2228     }
2229 }
2230 
2231 // ---------------------------------------------------------
2232 
2233 IMPL_LINK( SlideshowImpl, ContextMenuHdl, void*, EMPTYARG )
2234 {
2235     mnContextMenuEvent = 0;
2236 
2237     if( mpSlideController.get() == 0 )
2238         return 0;
2239 
2240     mbWasPaused = mbIsPaused;
2241     if( !mbWasPaused )
2242         pause();
2243 
2244     PopupMenu* pMenu = new PopupMenu( SdResId( RID_SLIDESHOW_CONTEXTMENU ) );
2245 
2246     // Adding button to display if in Pen  mode
2247     pMenu->CheckItem( CM_PEN_MODE, mbUsePen);
2248 
2249     const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2250     pMenu->EnableItem( CM_NEXT_SLIDE, ( mpSlideController->getNextSlideIndex() != -1 ) );
2251     pMenu->EnableItem( CM_PREV_SLIDE, ( mpSlideController->getPreviousSlideIndex() != -1 ) || (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) );
2252 
2253     PopupMenu* pPageMenu = pMenu->GetPopupMenu( CM_GOTO );
2254 
2255     SfxViewFrame* pViewFrame = getViewFrame();
2256     if( pViewFrame )
2257     {
2258         Reference< ::com::sun::star::frame::XFrame > xFrame( pViewFrame->GetFrame().GetFrameInterface() );
2259         if( xFrame.is() )
2260         {
2261             pMenu->SetItemImage( CM_NEXT_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10617") ), sal_False, sal_False ) );
2262             pMenu->SetItemImage( CM_PREV_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10618") ), sal_False, sal_False ) );
2263 
2264             if( pPageMenu )
2265             {
2266                 pPageMenu->SetItemImage( CM_FIRST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10616") ), sal_False, sal_False ) );
2267                 pPageMenu->SetItemImage( CM_LAST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10619") ), sal_False, sal_False ) );
2268             }
2269         }
2270     }
2271 
2272     // populate slide goto list
2273     if( pPageMenu )
2274     {
2275         const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount();
2276         if( nPageNumberCount <= 1 )
2277         {
2278             pMenu->EnableItem( CM_GOTO, sal_False );
2279         }
2280         else
2281         {
2282             sal_Int32 nCurrentSlideNumber = mpSlideController->getCurrentSlideNumber();
2283             if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2284                 nCurrentSlideNumber = -1;
2285 
2286             pPageMenu->EnableItem( CM_FIRST_SLIDE, ( mpSlideController->getSlideNumber(0) != nCurrentSlideNumber ) );
2287             pPageMenu->EnableItem( CM_LAST_SLIDE, ( mpSlideController->getSlideNumber( mpSlideController->getSlideIndexCount() - 1) != nCurrentSlideNumber ) );
2288 
2289             sal_Int32 nPageNumber;
2290 
2291             for( nPageNumber = 0; nPageNumber < nPageNumberCount; nPageNumber++ )
2292             {
2293                 if( mpSlideController->isVisibleSlideNumber( nPageNumber ) )
2294                 {
2295                     SdPage* pPage = mpDoc->GetSdPage((sal_uInt16)nPageNumber, PK_STANDARD);
2296                     if (pPage)
2297                     {
2298                         pPageMenu->InsertItem( (sal_uInt16)(CM_SLIDES + nPageNumber), pPage->GetName() );
2299                         if( nPageNumber == nCurrentSlideNumber )
2300                             pPageMenu->CheckItem( (sal_uInt16)(CM_SLIDES + nPageNumber) );
2301                     }
2302                 }
2303             }
2304         }
2305     }
2306 
2307     if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2308     {
2309         PopupMenu* pBlankMenu = pMenu->GetPopupMenu( CM_SCREEN );
2310         if( pBlankMenu )
2311         {
2312             pBlankMenu->CheckItem( ( mpShowWindow->GetBlankColor() == Color( COL_WHITE ) ) ? CM_SCREEN_WHITE : CM_SCREEN_BLACK  );
2313         }
2314     }
2315 
2316     PopupMenu* pWidthMenu = pMenu->GetPopupMenu( CM_WIDTH_PEN);
2317 
2318     // populate color width list
2319     if( pWidthMenu )
2320     {
2321         sal_Int32 nIterator;
2322         double nWidth;
2323 
2324         nWidth = 4.0;
2325         for( nIterator = 1; nIterator < 6; nIterator++)
2326         {
2327             switch(nIterator)
2328             {
2329                 case 1:
2330                     nWidth = 4.0;
2331                     break;
2332                 case 2:
2333                     nWidth = 100.0;
2334                     break;
2335                 case 3:
2336                     nWidth = 150.0;
2337                     break;
2338                 case 4:
2339                     nWidth = 200.0;
2340                     break;
2341                 case 5:
2342                     nWidth = 400.0;
2343                     break;
2344                 default:
2345                     break;
2346             }
2347 
2348             pWidthMenu->EnableItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator), sal_True);
2349             if( nWidth ==  mdUserPaintStrokeWidth)
2350                 pWidthMenu->CheckItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator) );
2351         }
2352     }
2353 
2354     pMenu->SetSelectHdl( LINK( this, SlideshowImpl, ContextMenuSelectHdl ) );
2355     pMenu->Execute( mpShowWindow, maPopupMousePos );
2356     delete pMenu;
2357 
2358     if( mxView.is() )
2359         mxView->ignoreNextMouseReleased();
2360 
2361     if( !mbWasPaused )
2362         resume();
2363     return 0;
2364 }
2365 
2366 // ---------------------------------------------------------
2367 
2368 IMPL_LINK( SlideshowImpl, ContextMenuSelectHdl, Menu *, pMenu )
2369 {
2370     if( pMenu )
2371     {
2372         sal_uInt16 nMenuId = pMenu->GetCurItemId();
2373 
2374         switch( nMenuId )
2375         {
2376         case CM_PREV_SLIDE:
2377             gotoPreviousSlide();
2378             mbWasPaused = false;
2379             break;
2380         case CM_NEXT_SLIDE:
2381             gotoNextSlide();
2382             mbWasPaused = false;
2383             break;
2384         case CM_FIRST_SLIDE:
2385             gotoFirstSlide();
2386             mbWasPaused = false;
2387             break;
2388         case CM_LAST_SLIDE:
2389             gotoLastSlide();
2390             mbWasPaused = false;
2391             break;
2392         case CM_SCREEN_BLACK:
2393         case CM_SCREEN_WHITE:
2394         {
2395             const Color aBlankColor( (nMenuId == CM_SCREEN_WHITE) ? COL_WHITE : COL_BLACK );
2396             if( mbWasPaused )
2397             {
2398                 if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
2399                 {
2400                     if( mpShowWindow->GetBlankColor() == aBlankColor )
2401                     {
2402                         mbWasPaused = false;
2403                         mpShowWindow->RestartShow();
2404                         break;
2405                     }
2406                 }
2407                 mpShowWindow->RestartShow();
2408             }
2409             if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) )
2410             {
2411                 pause();
2412                 mbWasPaused = true;
2413             }
2414         }
2415         break;
2416         case CM_COLOR_PEN:
2417             {
2418                 //Open a color picker based on SvColorDialog
2419                 ::Color aColor( mnUserPaintColor );
2420                 SvColorDialog aColorDlg( mpShowWindow);
2421                 aColorDlg.SetColor( aColor );
2422 
2423                 if (aColorDlg.Execute() )
2424                 {
2425                     aColor = aColorDlg.GetColor();
2426                     setPenColor(aColor.GetColor());
2427                 }
2428                 mbWasPaused = false;
2429             }
2430             break;
2431 
2432         case CM_WIDTH_PEN_VERY_THIN:
2433             {
2434                 setPenWidth(4.0);
2435                 mbWasPaused = false;
2436             }
2437             break;
2438 
2439         case CM_WIDTH_PEN_THIN:
2440             {
2441                 setPenWidth(100.0);
2442                 mbWasPaused = false;
2443             }
2444             break;
2445 
2446         case CM_WIDTH_PEN_NORMAL:
2447             {
2448                 setPenWidth(150.0);
2449                 mbWasPaused = false;
2450             }
2451             break;
2452 
2453         case CM_WIDTH_PEN_THICK:
2454             {
2455                 setPenWidth(200.0);
2456                 mbWasPaused = false;
2457             }
2458             break;
2459 
2460         case CM_WIDTH_PEN_VERY_THICK:
2461             {
2462                 setPenWidth(400.0);
2463                 mbWasPaused = false;
2464             }
2465             break;
2466         case CM_ERASE_ALLINK:
2467             {
2468                 setEraseAllInk(true);
2469                 mbWasPaused = false;
2470             }
2471             break;
2472         case CM_PEN_MODE:
2473             {
2474                 setUsePen(!mbUsePen);
2475                 mbWasPaused = false;
2476             }
2477             break;
2478         case CM_ENDSHOW:
2479             // in case the user cancels the presentation, switch to current slide
2480             // in edit mode
2481             if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
2482             {
2483                 if( mpSlideController->getCurrentSlideNumber() != -1 )
2484                 {
2485                     mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
2486                 }
2487             }
2488             endPresentation();
2489             break;
2490         default:
2491             sal_Int32 nPageNumber = nMenuId - CM_SLIDES;
2492             const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
2493             if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
2494             {
2495                 mpShowWindow->RestartShow( nPageNumber );
2496             }
2497             else if( nPageNumber != mpSlideController->getCurrentSlideNumber() )
2498             {
2499                 displaySlideNumber( nPageNumber );
2500             }
2501             mbWasPaused = false;
2502             break;
2503         }
2504     }
2505 
2506     return 0;
2507 }
2508 
2509 // ---------------------------------------------------------
2510 
2511 Reference< XSlideShow > SlideshowImpl::createSlideShow() const
2512 {
2513     Reference< XSlideShow > xShow;
2514 
2515     try
2516     {
2517         Reference< lang::XMultiServiceFactory > xFactory(
2518             ::comphelper::getProcessServiceFactory(),
2519             UNO_QUERY_THROW );
2520 
2521         Reference< XInterface > xInt( xFactory->createInstance(
2522                 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.SlideShow")) ) );
2523 
2524         xShow.set( xInt, UNO_QUERY_THROW );
2525     }
2526     catch( uno::Exception& e )
2527     {
2528         (void)e;
2529         DBG_ERROR(
2530             (OString("sd::SlideshowImpl::createSlideShow(), "
2531                      "exception caught: ") +
2532              rtl::OUStringToOString(
2533                  comphelper::anyToString( cppu::getCaughtException() ),
2534                  RTL_TEXTENCODING_UTF8 )).getStr() );
2535     }
2536 
2537     return xShow;
2538 }
2539 
2540 // ---------------------------------------------------------
2541 
2542 void SlideshowImpl::createSlideList( bool bAll, bool bStartWithActualSlide, const String& rPresSlide )
2543 {
2544     const long nSlideCount = mpDoc->GetSdPageCount( PK_STANDARD );
2545 
2546     if( nSlideCount )
2547     {
2548         SdCustomShow*   pCustomShow;
2549 
2550         if( !bStartWithActualSlide && mpDoc->GetCustomShowList() && maPresSettings.mbCustomShow )
2551             pCustomShow = (SdCustomShow*) mpDoc->GetCustomShowList()->GetCurObject();
2552         else
2553             pCustomShow = NULL;
2554 
2555         // create animation slide controller
2556         AnimationSlideController::Mode eMode =
2557             ( pCustomShow && pCustomShow->Count() ) ? AnimationSlideController::CUSTOM :
2558                 (bAll ? AnimationSlideController::ALL : AnimationSlideController::FROM);
2559 
2560         Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
2561         Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
2562         mpSlideController.reset( new AnimationSlideController( xSlides, eMode ) );
2563 
2564         if( eMode != AnimationSlideController::CUSTOM )
2565         {
2566             sal_Int32 nFirstSlide = 0;
2567 
2568             // normale Praesentation
2569             if( eMode == AnimationSlideController::FROM )
2570             {
2571                 if( rPresSlide.Len() )
2572                 {
2573                     sal_Int32 nSlide;
2574                     sal_Bool bTakeNextAvailable = sal_False;
2575 
2576                     for( nSlide = 0, nFirstSlide = -1; ( nSlide < nSlideCount ) && ( -1 == nFirstSlide ); nSlide++ )
2577                     {
2578                         SdPage* pTestSlide = mpDoc->GetSdPage( (sal_uInt16)nSlide, PK_STANDARD );
2579 
2580                         if( pTestSlide->GetName() == rPresSlide )
2581                         {
2582                             if( pTestSlide->IsExcluded() )
2583                                 bTakeNextAvailable = sal_True;
2584                             else
2585                                 nFirstSlide = nSlide;
2586                         }
2587                         else if( bTakeNextAvailable && !pTestSlide->IsExcluded() )
2588                             nFirstSlide = nSlide;
2589                     }
2590 
2591                     if( -1 == nFirstSlide )
2592                         nFirstSlide = 0;
2593                 }
2594             }
2595 
2596             for( sal_Int32 i = 0; i < nSlideCount; i++ )
2597             {
2598                 bool bVisible = ( mpDoc->GetSdPage( (sal_uInt16)i, PK_STANDARD ) )->IsExcluded() ? false : true;
2599                 if( bVisible || (eMode == AnimationSlideController::ALL) )
2600                     mpSlideController->insertSlideNumber( i, bVisible );
2601             }
2602 
2603             mpSlideController->setStartSlideNumber( nFirstSlide );
2604         }
2605         else
2606         {
2607             if( meAnimationMode != ANIMATIONMODE_SHOW && rPresSlide.Len() )
2608             {
2609                 sal_Int32 nSlide;
2610                 for( nSlide = 0; nSlide < nSlideCount; nSlide++ )
2611                     if( rPresSlide == mpDoc->GetSdPage( (sal_uInt16) nSlide, PK_STANDARD )->GetName() )
2612                         break;
2613 
2614                 if( nSlide < nSlideCount )
2615                     mpSlideController->insertSlideNumber( (sal_uInt16) nSlide );
2616             }
2617 
2618             void* pCustomSlide;
2619             sal_Int32 nSlideIndex;
2620             for( pCustomSlide = pCustomShow->First(),nSlideIndex=0; pCustomSlide; pCustomSlide = pCustomShow->Next(), nSlideIndex++ )
2621             {
2622                 const sal_uInt16 nSdSlide = ( ( (SdPage*) pCustomSlide )->GetPageNum() - 1 ) / 2;
2623 
2624                 if( !( mpDoc->GetSdPage( nSdSlide, PK_STANDARD ) )->IsExcluded())
2625                     mpSlideController->insertSlideNumber( nSdSlide );
2626             }
2627         }
2628     }
2629 }
2630 
2631 // ---------------------------------------------------------
2632 
2633 typedef sal_uInt16 (*FncGetChildWindowId)();
2634 
2635 FncGetChildWindowId aShowChilds[] =
2636 {
2637     &AnimationChildWindow::GetChildWindowId,
2638     &Svx3DChildWindow::GetChildWindowId,
2639     &SvxFontWorkChildWindow::GetChildWindowId,
2640     &SvxColorChildWindow::GetChildWindowId,
2641     &SvxSearchDialogWrapper::GetChildWindowId,
2642     &SvxBmpMaskChildWindow::GetChildWindowId,
2643     &SvxIMapDlgChildWindow::GetChildWindowId,
2644     &SvxHyperlinkDlgWrapper::GetChildWindowId,
2645     &SvxHlinkDlgWrapper::GetChildWindowId,
2646     &SfxTemplateDialogWrapper::GetChildWindowId,
2647     &GalleryChildWindow::GetChildWindowId
2648 };
2649 
2650 #define NAVIGATOR_CHILD_MASK        0x80000000UL
2651 
2652 void SlideshowImpl::hideChildWindows()
2653 {
2654     mnChildMask = 0UL;
2655 
2656     if( ANIMATIONMODE_SHOW == meAnimationMode )
2657     {
2658         SfxViewFrame* pViewFrame = getViewFrame();
2659 
2660         if( pViewFrame )
2661         {
2662             if( pViewFrame->GetChildWindow( SID_NAVIGATOR ) != NULL )
2663                 mnChildMask |= NAVIGATOR_CHILD_MASK;
2664 
2665             for( sal_uLong i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
2666             {
2667                 const sal_uInt16 nId = ( *aShowChilds[ i ] )();
2668 
2669                 if( pViewFrame->GetChildWindow( nId ) )
2670                 {
2671                     pViewFrame->SetChildWindow( nId, sal_False );
2672                     mnChildMask |= 1 << i;
2673                 }
2674             }
2675         }
2676     }
2677 }
2678 
2679 // ---------------------------------------------------------
2680 
2681 void SlideshowImpl::showChildWindows()
2682 {
2683     if( ANIMATIONMODE_SHOW == meAnimationMode )
2684     {
2685         SfxViewFrame* pViewFrame = getViewFrame();
2686         if( pViewFrame )
2687         {
2688             pViewFrame->SetChildWindow( SID_NAVIGATOR, ( mnChildMask & NAVIGATOR_CHILD_MASK ) != 0 );
2689 
2690             for( sal_uLong i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
2691             {
2692                 if( mnChildMask & ( 1 << i ) )
2693                     pViewFrame->SetChildWindow( ( *aShowChilds[ i ] )(), sal_True );
2694             }
2695         }
2696     }
2697 }
2698 
2699 // ---------------------------------------------------------
2700 
2701 SfxViewFrame* SlideshowImpl::getViewFrame() const
2702 {
2703     return mpViewShell ? mpViewShell->GetViewFrame() : 0;
2704 }
2705 
2706 // ---------------------------------------------------------
2707 
2708 SfxDispatcher* SlideshowImpl::getDispatcher() const
2709 {
2710     return (mpViewShell && mpViewShell->GetViewFrame()) ? mpViewShell->GetViewFrame()->GetDispatcher() : 0;
2711 }
2712 
2713 // ---------------------------------------------------------
2714 
2715 SfxBindings* SlideshowImpl::getBindings() const
2716 {
2717     return (mpViewShell && mpViewShell->GetViewFrame()) ? &mpViewShell->GetViewFrame()->GetBindings() : 0;
2718 }
2719 
2720 // ---------------------------------------------------------
2721 
2722 void SlideshowImpl::resize( const Size& rSize )
2723 {
2724     maPresSize = rSize;
2725 
2726     if( mpShowWindow && (ANIMATIONMODE_VIEW != meAnimationMode) )
2727     {
2728         mpShowWindow->SetSizePixel( maPresSize );
2729         mpShowWindow->Show();
2730 
2731         // Call ToTop() to bring the window to top if
2732         // a) the old size is not degenerate (then the window will be closed
2733         // soon) and
2734         // b) the animation mode is not that of a preview (on the one hand
2735         // this leaves the old behaviour for the slide show mode unmodified
2736         // and on the other hand does not move the focus from the document
2737         // to the (preview) window; the ToTop() seems not to be necessary at
2738         // least for the preview).
2739 //        if( !aOldSize.Width() && !aOldSize.Height() )
2740 //          mpShowWindow->ToTop();
2741     }
2742 
2743     if( mxView.is() ) try
2744     {
2745         awt::WindowEvent aEvt;
2746         mxView->windowResized(aEvt);
2747     }
2748     catch( Exception& e )
2749     {
2750         static_cast<void>(e);
2751         DBG_ERROR(
2752             (OString("sd::SlideshowImpl::resize(), "
2753                     "exception caught: ") +
2754             rtl::OUStringToOString(
2755                 comphelper::anyToString( cppu::getCaughtException() ),
2756                 RTL_TEXTENCODING_UTF8 )).getStr() );
2757     }
2758 }
2759 
2760 // -----------------------------------------------------------------------------
2761 
2762 void SlideshowImpl::setActiveXToolbarsVisible( sal_Bool bVisible )
2763 {
2764     // in case of ActiveX control the toolbars should not be visible if slide show runs in window mode
2765     // actually it runs always in window mode in case of ActiveX control
2766     if ( !maPresSettings.mbFullScreen && mpDocSh && mpDocSh->GetMedium() )
2767     {
2768         SFX_ITEMSET_ARG( mpDocSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
2769         if ( pItem && pItem->GetValue() )
2770         {
2771             // this is a plugin/activex mode, no toolbars should be visible during slide show
2772             // after the end of slide show they should be visible again
2773             SfxViewFrame* pViewFrame = getViewFrame();
2774             if( pViewFrame )
2775             {
2776                 try
2777                 {
2778                     Reference< frame::XLayoutManager > xLayoutManager;
2779                     Reference< beans::XPropertySet > xFrameProps( pViewFrame->GetFrame().GetTopFrame().GetFrameInterface(), UNO_QUERY_THROW );
2780                     if ( ( xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) )
2781                                 >>= xLayoutManager )
2782                       && xLayoutManager.is() )
2783                     {
2784                         xLayoutManager->setVisible( bVisible );
2785                     }
2786                 }
2787                 catch( uno::Exception& )
2788                 {}
2789             }
2790         }
2791     }
2792 }
2793 
2794 // -----------------------------------------------------------------------------
2795 
2796 void SAL_CALL SlideshowImpl::activate() throw (RuntimeException)
2797 {
2798     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2799 
2800     maDeactivateTimer.Stop();
2801 
2802     if( !mbActive && mxShow.is() )
2803     {
2804         mbActive = sal_True;
2805 
2806         if( ANIMATIONMODE_SHOW == meAnimationMode )
2807         {
2808             if( mbAutoSaveWasOn )
2809                 setAutoSaveState( false );
2810 
2811             if( mpShowWindow )
2812             {
2813                 SfxViewFrame* pViewFrame = getViewFrame();
2814                 SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : 0;
2815 
2816                 hideChildWindows();
2817 
2818                 if( pDispatcher )
2819                 {
2820                     // filter all forbiden slots
2821                     pDispatcher->SetSlotFilter( sal_True, sizeof(pAllowed) / sizeof(sal_uInt16), pAllowed );
2822                 }
2823 
2824                 if( getBindings() )
2825                     getBindings()->InvalidateAll(sal_True);
2826 
2827                 mpShowWindow->GrabFocus();
2828             }
2829         }
2830 
2831         resume();
2832     }
2833 }
2834 
2835 // -----------------------------------------------------------------------------
2836 
2837 void SAL_CALL SlideshowImpl::deactivate() throw (RuntimeException)
2838 {
2839     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2840 
2841     if( mbActive && mxShow.is() )
2842     {
2843         maDeactivateTimer.Start();
2844     }
2845 }
2846 
2847 // -----------------------------------------------------------------------------
2848 
2849 IMPL_LINK( SlideshowImpl, deactivateHdl, Timer*, EMPTYARG )
2850 {
2851     if( mbActive && mxShow.is() )
2852     {
2853         mbActive = sal_False;
2854 
2855         pause();
2856 
2857         if( ANIMATIONMODE_SHOW == meAnimationMode )
2858         {
2859             if( mbAutoSaveWasOn )
2860                 setAutoSaveState( true );
2861 
2862             if( mpShowWindow )
2863             {
2864                 showChildWindows();
2865             }
2866         }
2867     }
2868     return 0;
2869 }
2870 
2871 // ---------------------------------------------------------
2872 
2873 sal_Bool SAL_CALL SlideshowImpl::isActive() throw (RuntimeException)
2874 {
2875     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2876     return mbActive;
2877 }
2878 
2879 // -----------------------------------------------------------------------------
2880 
2881 void SlideshowImpl::receiveRequest(SfxRequest& rReq)
2882 {
2883     const SfxItemSet* pArgs      = rReq.GetArgs();
2884 
2885     switch ( rReq.GetSlot() )
2886     {
2887         case SID_NAVIGATOR_PEN:
2888             setUsePen(!mbUsePen);
2889         break;
2890 
2891         case SID_NAVIGATOR_PAGE:
2892         {
2893             PageJump    eJump = (PageJump)((SfxAllEnumItem&) pArgs->Get(SID_NAVIGATOR_PAGE)).GetValue();
2894             switch( eJump )
2895             {
2896                 case PAGE_FIRST:        gotoFirstSlide(); break;
2897                 case PAGE_LAST:         gotoLastSlide(); break;
2898                 case PAGE_NEXT:         gotoNextSlide(); break;
2899                 case PAGE_PREVIOUS:     gotoPreviousSlide(); break;
2900                 case PAGE_NONE:         break;
2901             }
2902         }
2903         break;
2904 
2905         case SID_NAVIGATOR_OBJECT:
2906         {
2907             const String aTarget( ((SfxStringItem&) pArgs->Get(SID_NAVIGATOR_OBJECT)).GetValue() );
2908 
2909             // is the bookmark a Slide?
2910             sal_Bool        bIsMasterPage;
2911             sal_uInt16      nPgNum = mpDoc->GetPageByName( aTarget, bIsMasterPage );
2912             SdrObject*  pObj   = NULL;
2913 
2914             if( nPgNum == SDRPAGE_NOTFOUND )
2915             {
2916                 // is the bookmark an object?
2917                 pObj = mpDoc->GetObj( aTarget );
2918 
2919                 if( pObj )
2920                     nPgNum = pObj->GetPage()->GetPageNum();
2921             }
2922 
2923             if( nPgNum != SDRPAGE_NOTFOUND )
2924             {
2925                 nPgNum = ( nPgNum - 1 ) >> 1;
2926                 displaySlideNumber( nPgNum );
2927             }
2928         }
2929         break;
2930     }
2931 }
2932 
2933 // ---------------------------------------------------------
2934 
2935 void SlideshowImpl::setAutoSaveState( bool bOn)
2936 {
2937     try
2938     {
2939         uno::Reference<lang::XMultiServiceFactory> xFac( ::comphelper::getProcessServiceFactory() );
2940 
2941         uno::Reference< util::XURLTransformer > xParser(
2942             xFac->createInstance( OUString::createFromAscii("com.sun.star.util.URLTransformer" ) ),
2943                 uno::UNO_QUERY_THROW);
2944         util::URL aURL;
2945         aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/setAutoSaveState");
2946         xParser->parseStrict(aURL);
2947 
2948         Sequence< beans::PropertyValue > aArgs(1);
2949         aArgs[0].Name = OUString::createFromAscii("AutoSaveState");
2950         aArgs[0].Value <<= bOn ? sal_True : sal_False;
2951 
2952         uno::Reference< frame::XDispatch > xAutoSave(
2953             xFac->createInstance(OUString::createFromAscii("com.sun.star.frame.AutoRecovery")),
2954             uno::UNO_QUERY_THROW);
2955         xAutoSave->dispatch(aURL, aArgs);
2956     }
2957     catch( Exception& )
2958     {
2959         DBG_ERROR("sd::SlideshowImpl::setAutoSaveState(), exception caught!");
2960     }
2961 }
2962 
2963 // ---------------------------------------------------------
2964 
2965 Reference< XDrawPage > SAL_CALL SlideshowImpl::getCurrentSlide() throw (RuntimeException)
2966 {
2967     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2968 
2969     Reference< XDrawPage > xSlide;
2970     if( mxShow.is() && mpSlideController.get() )
2971     {
2972         sal_Int32 nSlide = getCurrentSlideNumber();
2973         if( (nSlide >= 0) && (nSlide < mpSlideController->getSlideNumberCount() ) )
2974             xSlide = mpSlideController->getSlideByNumber( nSlide );
2975     }
2976 
2977     return xSlide;
2978 }
2979 
2980 // ---------------------------------------------------------
2981 
2982 sal_Int32 SAL_CALL SlideshowImpl::getNextSlideIndex() throw (RuntimeException)
2983 {
2984     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
2985 
2986     if( mxShow.is() )
2987     {
2988         return mpSlideController->getNextSlideIndex();
2989     }
2990     else
2991     {
2992         return -1;
2993     }
2994 }
2995 
2996 // ---------------------------------------------------------
2997 
2998 sal_Int32 SAL_CALL SlideshowImpl::getCurrentSlideIndex() throw (RuntimeException)
2999 {
3000     return mpSlideController.get() ? mpSlideController->getCurrentSlideIndex() : -1;
3001 }
3002 
3003 // --------------------------------------------------------------------
3004 // ::com::sun::star::presentation::XSlideShowController:
3005 // --------------------------------------------------------------------
3006 
3007 ::sal_Int32 SAL_CALL SlideshowImpl::getSlideCount() throw (RuntimeException)
3008 {
3009     return mpSlideController.get() ? mpSlideController->getSlideIndexCount() : 0;
3010 }
3011 
3012 // --------------------------------------------------------------------
3013 
3014 Reference< XDrawPage > SAL_CALL SlideshowImpl::getSlideByIndex(::sal_Int32 Index) throw (RuntimeException, css::lang::IndexOutOfBoundsException)
3015 {
3016     if( (mpSlideController.get() == 0 ) || (Index < 0) || (Index >= mpSlideController->getSlideIndexCount() ) )
3017         throw IndexOutOfBoundsException();
3018 
3019     return mpSlideController->getSlideByNumber( mpSlideController->getSlideNumber( Index ) );
3020 }
3021 
3022 sal_Bool SAL_CALL SlideshowImpl::getAlwaysOnTop() throw (RuntimeException)
3023 {
3024     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3025     return maPresSettings.mbAlwaysOnTop;
3026 }
3027 
3028 // --------------------------------------------------------------------
3029 
3030 void SAL_CALL SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways ) throw (RuntimeException)
3031 {
3032     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3033     if( maPresSettings.mbAlwaysOnTop != bAlways )
3034     {
3035         maPresSettings.mbAlwaysOnTop = bAlways;
3036         // todo, can this be changed while running?
3037     }
3038 }
3039 
3040 // --------------------------------------------------------------------
3041 
3042 sal_Bool SAL_CALL SlideshowImpl::isFullScreen() throw (RuntimeException)
3043 {
3044     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3045     return maPresSettings.mbFullScreen;
3046 }
3047 
3048 // --------------------------------------------------------------------
3049 
3050 sal_Bool SAL_CALL SlideshowImpl::getMouseVisible() throw (RuntimeException)
3051 {
3052     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3053     return maPresSettings.mbMouseVisible;
3054 }
3055 
3056 // --------------------------------------------------------------------
3057 
3058 void SAL_CALL SlideshowImpl::setMouseVisible( sal_Bool bVisible ) throw (RuntimeException)
3059 {
3060     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3061     if( maPresSettings.mbMouseVisible != bVisible )
3062     {
3063         maPresSettings.mbMouseVisible = bVisible;
3064         if( mpShowWindow )
3065             mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
3066     }
3067 }
3068 
3069 // --------------------------------------------------------------------
3070 
3071 sal_Bool SAL_CALL SlideshowImpl::getUsePen() throw (RuntimeException)
3072 {
3073     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3074     return mbUsePen;
3075 }
3076 
3077 // --------------------------------------------------------------------
3078 
3079 void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen ) throw (RuntimeException)
3080 {
3081     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3082     mbUsePen = bMouseAsPen;
3083     if( mxShow.is() ) try
3084     {
3085         // For Pencolor;
3086         Any aValue;
3087         if( mbUsePen )
3088             aValue <<= mnUserPaintColor;
3089         beans::PropertyValue aPenProp;
3090         aPenProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintColor" ));
3091         aPenProp.Value = aValue;
3092         mxShow->setProperty( aPenProp );
3093 
3094         //for StrokeWidth :
3095         if( mbUsePen )
3096         {
3097             beans::PropertyValue aPenPropWidth;
3098             aPenPropWidth.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintStrokeWidth" ));
3099             aPenPropWidth.Value <<= mdUserPaintStrokeWidth;
3100             mxShow->setProperty( aPenPropWidth );
3101 
3102             // for Pen Mode
3103             beans::PropertyValue aPenPropSwitchPenMode;
3104             aPenPropSwitchPenMode.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SwitchPenMode" ));
3105             aPenPropSwitchPenMode.Value <<= sal_True;
3106             mxShow->setProperty( aPenPropSwitchPenMode );
3107         }
3108     }
3109     catch( Exception& e )
3110     {
3111         static_cast<void>(e);
3112         DBG_ERROR(
3113             (OString("sd::SlideshowImpl::setUsePen(), "
3114                     "exception caught: ") +
3115             rtl::OUStringToOString(
3116                 comphelper::anyToString( cppu::getCaughtException() ),
3117                 RTL_TEXTENCODING_UTF8 )).getStr() );
3118     }
3119 }
3120 
3121 // --------------------------------------------------------------------
3122 
3123 double SAL_CALL SlideshowImpl::getPenWidth() throw (RuntimeException)
3124 {
3125     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3126     return mdUserPaintStrokeWidth;
3127 }
3128 
3129 // --------------------------------------------------------------------
3130 
3131 void SAL_CALL SlideshowImpl::setPenWidth( double dStrokeWidth ) throw (RuntimeException)
3132 {
3133     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3134     mdUserPaintStrokeWidth = dStrokeWidth;
3135     setUsePen( true ); // enable pen mode, update color and width
3136 }
3137 
3138 // --------------------------------------------------------------------
3139 
3140 sal_Int32 SAL_CALL SlideshowImpl::getPenColor() throw (RuntimeException)
3141 {
3142     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3143     return mnUserPaintColor;
3144 }
3145 
3146 // --------------------------------------------------------------------
3147 
3148 void SAL_CALL SlideshowImpl::setPenColor( sal_Int32 nColor ) throw (RuntimeException)
3149 {
3150     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3151     mnUserPaintColor = nColor;
3152     setUsePen( true ); // enable pen mode, update color
3153 }
3154 
3155 // --------------------------------------------------------------------
3156 
3157 void SAL_CALL SlideshowImpl::setUseEraser( ::sal_Bool /*_usepen*/ ) throw (css::uno::RuntimeException)
3158 {
3159 }
3160 
3161 // --------------------------------------------------------------------
3162 
3163 void SAL_CALL SlideshowImpl::setPenMode( bool bSwitchPenMode ) throw (RuntimeException)
3164 {
3165     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3166     setUsePen( bSwitchPenMode ); // SwitchPen Mode
3167 
3168 }
3169 
3170 // --------------------------------------------------------------------
3171 
3172 void SAL_CALL SlideshowImpl::setEraseAllInk(bool bEraseAllInk) throw (RuntimeException)
3173 {
3174     if( bEraseAllInk )
3175     {
3176         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3177         if( mxShow.is() ) try
3178         {
3179             beans::PropertyValue aPenPropEraseAllInk;
3180             aPenPropEraseAllInk.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EraseAllInk" ));
3181             aPenPropEraseAllInk.Value <<= bEraseAllInk;
3182             mxShow->setProperty( aPenPropEraseAllInk );
3183         }
3184         catch( Exception& e )
3185         {
3186             static_cast<void>(e);
3187             DBG_ERROR(
3188                 (OString("sd::SlideshowImpl::setEraseAllInk(), "
3189                         "exception caught: ") +
3190                 rtl::OUStringToOString(
3191                     comphelper::anyToString( cppu::getCaughtException() ),
3192                     RTL_TEXTENCODING_UTF8 )).getStr() );
3193         }
3194     }
3195 }
3196 
3197 void SAL_CALL SlideshowImpl::setEraseInk( sal_Int32 /*nEraseInkSize*/ ) throw (css::uno::RuntimeException)
3198 {
3199 }
3200 
3201 void SAL_CALL SlideshowImpl::setEraserMode( bool /*bSwitchEraserMode*/ ) throw (css::uno::RuntimeException)
3202 {
3203 }
3204 
3205 // --------------------------------------------------------------------
3206 // XSlideShowController Methods
3207 // --------------------------------------------------------------------
3208 
3209 sal_Bool SAL_CALL SlideshowImpl::isRunning(  ) throw (RuntimeException)
3210 {
3211     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3212     return mxShow.is();
3213 }
3214 
3215 // --------------------------------------------------------------------
3216 
3217 void SAL_CALL SlideshowImpl::gotoNextEffect(  ) throw (RuntimeException)
3218 {
3219     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3220 
3221     if( mxShow.is() && mpSlideController.get() && mpShowWindow )
3222     {
3223         if( mbIsPaused )
3224             resume();
3225 
3226         const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3227         if( eMode == SHOWWINDOWMODE_END )
3228         {
3229             endPresentation();
3230         }
3231         else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3232         {
3233             mpShowWindow->RestartShow();
3234         }
3235         else
3236         {
3237             mxShow->nextEffect();
3238             update();
3239         }
3240     }
3241 }
3242 
3243 // --------------------------------------------------------------------
3244 
3245 void SAL_CALL SlideshowImpl::gotoPreviousEffect(  ) throw (RuntimeException)
3246 {
3247     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3248 
3249     if( mxShow.is() && mpSlideController.get() && mpShowWindow )
3250     {
3251         if( mbIsPaused )
3252             resume();
3253 
3254         const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3255         if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3256         {
3257             mpShowWindow->RestartShow();
3258         }
3259         else
3260         {
3261             mxShow->previousEffect();
3262             update();
3263         }
3264     }
3265 }
3266 
3267 // --------------------------------------------------------------------
3268 
3269 void SAL_CALL SlideshowImpl::gotoFirstSlide(  ) throw (RuntimeException)
3270 {
3271     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3272 
3273     if( mpShowWindow && mpSlideController.get() )
3274     {
3275         if( mbIsPaused )
3276             resume();
3277 
3278         if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
3279         {
3280             if( mpSlideController->getSlideIndexCount() )
3281                 mpShowWindow->RestartShow( 0);
3282         }
3283         else
3284         {
3285             displaySlideIndex( 0 );
3286         }
3287     }
3288 }
3289 
3290 // --------------------------------------------------------------------
3291 
3292 void SAL_CALL SlideshowImpl::gotoNextSlide(  ) throw (RuntimeException)
3293 {
3294     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3295 
3296     if( mbIsPaused )
3297         resume();
3298 
3299     const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3300     if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3301     {
3302         mpShowWindow->RestartShow();
3303     }
3304     else
3305     {
3306         // if this is a show, ignore user inputs and
3307         // start 20ms timer to reenable inputs to fiter
3308         // buffered inputs during slide transition
3309         if( meAnimationMode == ANIMATIONMODE_SHOW )
3310         {
3311             mbInputFreeze = true;
3312             maInputFreezeTimer.Start();
3313         }
3314 
3315         if( mpSlideController.get() )
3316         {
3317             if( mpSlideController->nextSlide() )
3318             {
3319                 displayCurrentSlide();
3320             }
3321             else
3322             {
3323                 stopSound();
3324 
3325                 if( meAnimationMode == ANIMATIONMODE_PREVIEW )
3326                 {
3327                     endPresentation();
3328                 }
3329                 else if( maPresSettings.mbEndless )
3330                 {
3331                     if( maPresSettings.mnPauseTimeout )
3332                     {
3333                         if( mpShowWindow )
3334                         {
3335                             if ( maPresSettings.mbShowPauseLogo )
3336                             {
3337                                 Graphic aGraphic;
3338                                 Image aImage;
3339                                 bool bLoad = vcl::ImageRepository::loadBrandingImage(
3340                                     rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "logo" ) ),
3341                                     aImage );
3342                                 OSL_ENSURE( bLoad, "Can't load logo image");
3343                                 if ( bLoad )
3344                                     aGraphic = Graphic(aImage.GetBitmapEx());
3345                                 mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout, &aGraphic );
3346                             }
3347                             else
3348                                 mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout );
3349                         }
3350                     }
3351                     else
3352                     {
3353                         displaySlideIndex( 0 );
3354                     }
3355                 }
3356                 else
3357                 {
3358                     if( mpShowWindow )
3359                     {
3360                         mpShowWindow->SetEndMode();
3361                         pause();
3362                     }
3363                 }
3364             }
3365         }
3366     }
3367 }
3368 
3369 // --------------------------------------------------------------------
3370 
3371 void SAL_CALL SlideshowImpl::gotoPreviousSlide(  ) throw (RuntimeException)
3372 {
3373     gotoPreviousSlide(false);
3374 }
3375 
3376 void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects)
3377 {
3378     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3379 
3380     if( mxShow.is() && mpSlideController.get() ) try
3381     {
3382         if( mbIsPaused )
3383             resume();
3384 
3385         const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
3386         if( eMode == SHOWWINDOWMODE_END )
3387         {
3388             const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1;
3389             if( nLastSlideIndex >= 0 )
3390                 mpShowWindow->RestartShow( nLastSlideIndex );
3391         }
3392         else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
3393         {
3394             mpShowWindow->RestartShow();
3395         }
3396         else
3397         {
3398             if( mpSlideController->previousSlide())
3399                 displayCurrentSlide(bSkipAllMainSequenceEffects);
3400             else if (bSkipAllMainSequenceEffects)
3401             {
3402                 // We could not go to the previous slide (probably because
3403                 // the current slide is already the first one).  We still
3404                 // have to call displayCurrentSlide because the calling
3405                 // slideshow can not determine whether there is a previous
3406                 // slide or not and has already prepared for a slide change.
3407                 // This slide change has to be completed now, even when
3408                 // changing to the same slide.
3409                 // Note that in this special case we do NOT pass
3410                 // bSkipAllMainSequenceEffects because we display the same
3411                 // slide as before and do not want to show all its effects.
3412                 displayCurrentSlide(false);
3413             }
3414         }
3415     }
3416     catch( Exception& e )
3417     {
3418         static_cast<void>(e);
3419         DBG_ERROR(
3420             (OString("sd::SlideshowImpl::gotoPreviousSlide(), "
3421                     "exception caught: ") +
3422             rtl::OUStringToOString(
3423                 comphelper::anyToString( cppu::getCaughtException() ),
3424                 RTL_TEXTENCODING_UTF8 )).getStr() );
3425     }
3426 }
3427 
3428 // --------------------------------------------------------------------
3429 
3430 void SAL_CALL SlideshowImpl::gotoLastSlide() throw (RuntimeException)
3431 {
3432     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3433 
3434     if( mpSlideController.get() )
3435     {
3436         if( mbIsPaused )
3437             resume();
3438 
3439         const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1;
3440         if( nLastSlideIndex >= 0 )
3441         {
3442             if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
3443             {
3444                 mpShowWindow->RestartShow( nLastSlideIndex );
3445             }
3446             else
3447             {
3448                 displaySlideIndex( nLastSlideIndex );
3449             }
3450         }
3451     }
3452 }
3453 
3454 // --------------------------------------------------------------------
3455 
3456 void SAL_CALL SlideshowImpl::gotoBookmark( const OUString& rBookmark ) throw (RuntimeException)
3457 {
3458     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3459 
3460     if( mbIsPaused )
3461         resume();
3462 
3463     sal_Int32 nSlideNumber = getSlideNumberForBookmark( rBookmark );
3464     if( nSlideNumber != -1 )
3465         displaySlideNumber( nSlideNumber );
3466 }
3467 
3468 // --------------------------------------------------------------------
3469 
3470 void SAL_CALL SlideshowImpl::gotoSlide( const Reference< XDrawPage >& xSlide )
3471     throw(IllegalArgumentException, RuntimeException)
3472 {
3473     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3474 
3475     if( mpSlideController.get() && xSlide.is() )
3476     {
3477         if( mbIsPaused )
3478             resume();
3479 
3480         const sal_Int32 nSlideCount = mpSlideController->getSlideNumberCount();
3481         for( sal_Int32 nSlide = 0; nSlide < nSlideCount; nSlide++ )
3482         {
3483             if( mpSlideController->getSlideByNumber( nSlide ) == xSlide )
3484             {
3485                 displaySlideNumber( nSlide );
3486             }
3487         }
3488     }
3489 }
3490 
3491 // --------------------------------------------------------------------
3492 
3493 void SAL_CALL SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex ) throw (RuntimeException)
3494 {
3495     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3496 
3497     if( mbIsPaused )
3498         resume();
3499 
3500     displaySlideIndex( nIndex );
3501 }
3502 
3503 // --------------------------------------------------------------------
3504 
3505 void SAL_CALL SlideshowImpl::stopSound(  ) throw (RuntimeException)
3506 {
3507     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3508 
3509     try
3510     {
3511         if( mxPlayer.is() )
3512         {
3513             mxPlayer->stop();
3514             mxPlayer.clear();
3515         }
3516     }
3517     catch( Exception& e )
3518     {
3519         static_cast<void>(e);
3520         DBG_ERROR(
3521             (OString("sd::SlideshowImpl::stopSound(), "
3522                     "exception caught: ") +
3523             rtl::OUStringToOString(
3524                 comphelper::anyToString( cppu::getCaughtException() ),
3525                 RTL_TEXTENCODING_UTF8 )).getStr() );
3526     }
3527 }
3528 
3529 // --------------------------------------------------------------------
3530 // XIndexAccess
3531 // --------------------------------------------------------------------
3532 
3533 ::sal_Int32 SAL_CALL SlideshowImpl::getCount(  ) throw (::com::sun::star::uno::RuntimeException)
3534 {
3535     return getSlideCount();
3536 }
3537 
3538 // --------------------------------------------------------------------
3539 
3540 ::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)
3541 {
3542     return Any( getSlideByIndex( Index ) );
3543 }
3544 
3545 // --------------------------------------------------------------------
3546 
3547 ::com::sun::star::uno::Type SAL_CALL SlideshowImpl::getElementType(  ) throw (::com::sun::star::uno::RuntimeException)
3548 {
3549     return XDrawPage::static_type();
3550 }
3551 
3552 // --------------------------------------------------------------------
3553 
3554 ::sal_Bool SAL_CALL SlideshowImpl::hasElements(  ) throw (::com::sun::star::uno::RuntimeException)
3555 {
3556     return getSlideCount() != 0;
3557 }
3558 
3559 // --------------------------------------------------------------------
3560 
3561 Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() throw (RuntimeException)
3562 {
3563     return mxShow;
3564 }
3565 
3566 // --------------------------------------------------------------------
3567 
3568 
3569 PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx& r )
3570 : PresentationSettings( r )
3571 , mbRehearseTimings(r.mbRehearseTimings)
3572 , mbPreview(r.mbPreview)
3573 , mpParentWindow( 0 )
3574 {
3575 }
3576 
3577 PresentationSettingsEx::PresentationSettingsEx( PresentationSettings& r )
3578 : PresentationSettings( r )
3579 , mbRehearseTimings(sal_False)
3580 , mbPreview(sal_False)
3581 , mpParentWindow(0)
3582 {
3583 }
3584 
3585 void PresentationSettingsEx::SetArguments( const Sequence< PropertyValue >& rArguments ) throw (IllegalArgumentException)
3586 {
3587     sal_Int32 nArguments = rArguments.getLength();
3588     const PropertyValue* pValue = rArguments.getConstArray();
3589 
3590     while( nArguments-- )
3591     {
3592         SetPropertyValue( pValue->Name, pValue->Value );
3593         pValue++;
3594     }
3595 }
3596 
3597 void PresentationSettingsEx::SetPropertyValue( const OUString& rProperty, const Any& rValue ) throw (IllegalArgumentException)
3598 {
3599     if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("RehearseTimings") ) )
3600     {
3601         if( rValue >>= mbRehearseTimings )
3602             return;
3603     }
3604     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Preview") ) )
3605     {
3606         if( rValue >>= mbPreview )
3607             return;
3608     }
3609     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AnimationNode") ) )
3610     {
3611         if( rValue >>= mxAnimationNode )
3612             return;
3613     }
3614     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ) )
3615     {
3616         Reference< XWindow > xWindow;
3617         if( rValue >>= xWindow )
3618         {
3619             mpParentWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) : 0;
3620             return;
3621         }
3622     }
3623     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AllowAnimations") ) )
3624     {
3625         if( rValue >>= mbAnimationAllowed )
3626             return;
3627     }
3628     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AllowAnimations") ) )
3629     {
3630         if( rValue >>= mbAnimationAllowed )
3631             return;
3632     }
3633     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FirstPage") ) )
3634     {
3635         OUString aPresPage;
3636         if( rValue >>= aPresPage )
3637         {
3638             maPresPage = getUiNameFromPageApiNameImpl(aPresPage);
3639             mbCustomShow = sal_False;
3640             mbAll = sal_False;
3641             return;
3642         }
3643         else
3644         {
3645             if( rValue >>= mxStartPage )
3646                 return;
3647         }
3648     }
3649     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsAlwaysOnTop") ) )
3650     {
3651         if( rValue >>= mbAlwaysOnTop )
3652             return;
3653     }
3654     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsAutomatic") ) )
3655     {
3656         if( rValue >>= mbManual )
3657             return;
3658     }
3659     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsEndless") ) )
3660     {
3661         if( rValue >>= mbEndless )
3662             return;
3663     }
3664     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsFullScreen") ) )
3665     {
3666         if( rValue >>= mbFullScreen )
3667             return;
3668     }
3669     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsMouseVisible") ) )
3670     {
3671         if( rValue >>= mbMouseVisible )
3672             return;
3673     }
3674     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Pause") ) )
3675     {
3676         sal_Int32 nPause = -1;
3677         if( (rValue >>= nPause) && (nPause >= 0) )
3678         {
3679             mnPauseTimeout = nPause;
3680             return;
3681         }
3682     }
3683     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("StartWithNavigator") ) )
3684     {
3685         if( rValue >>= mbStartWithNavigator )
3686             return;
3687     }
3688     else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UsePen") ) )
3689     {
3690         if( rValue >>= mbMouseAsPen )
3691             return;
3692     }
3693     throw IllegalArgumentException();
3694 }
3695 
3696 ////////////////////////////////
3697 
3698 // ---------------------------------------------------------
3699 // XAnimationListener
3700 // ---------------------------------------------------------
3701 
3702 SlideShowListenerProxy::SlideShowListenerProxy( const rtl::Reference< SlideshowImpl >& xController, const css::uno::Reference< css::presentation::XSlideShow >& xSlideShow )
3703 : maListeners( m_aMutex )
3704 , mxController( xController )
3705 , mxSlideShow( xSlideShow )
3706 {
3707 }
3708 
3709 // ---------------------------------------------------------
3710 
3711 SlideShowListenerProxy::~SlideShowListenerProxy()
3712 {
3713 }
3714 
3715 // ---------------------------------------------------------
3716 
3717 void SlideShowListenerProxy::addAsSlideShowListener()
3718 {
3719     if( mxSlideShow.is() )
3720     {
3721         Reference< XSlideShowListener > xSlideShowListener( this );
3722         mxSlideShow->addSlideShowListener( xSlideShowListener );
3723     }
3724 }
3725 
3726 // ---------------------------------------------------------
3727 
3728 void SlideShowListenerProxy::removeAsSlideShowListener()
3729 {
3730     if( mxSlideShow.is() )
3731     {
3732         Reference< XSlideShowListener > xSlideShowListener( this );
3733         mxSlideShow->removeSlideShowListener( xSlideShowListener );
3734     }
3735 }
3736 
3737 // ---------------------------------------------------------
3738 
3739 void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3740 {
3741     if( mxSlideShow.is() )
3742     {
3743         Reference< XShapeEventListener > xListener( this );
3744         mxSlideShow->addShapeEventListener( xListener, xShape );
3745     }
3746 }
3747 
3748 // ---------------------------------------------------------
3749 
3750 void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
3751 {
3752     if( mxSlideShow.is() )
3753     {
3754         Reference< XShapeEventListener > xListener( this );
3755         mxSlideShow->removeShapeEventListener( xListener, xShape );
3756     }
3757 }
3758 
3759 // ---------------------------------------------------------
3760 
3761 void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3762 {
3763     maListeners.addInterface(xListener);
3764 }
3765 
3766 // ---------------------------------------------------------
3767 
3768 void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
3769 {
3770     maListeners.removeInterface(xListener);
3771 }
3772 
3773 // ---------------------------------------------------------
3774 
3775 void SAL_CALL SlideShowListenerProxy::beginEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException)
3776 {
3777     ::osl::MutexGuard aGuard( m_aMutex );
3778 
3779     if( maListeners.getLength() >= 0 )
3780         maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::beginEvent, _1,  boost::cref(xNode) ));
3781 }
3782 
3783 // ---------------------------------------------------------
3784 
3785 void SAL_CALL SlideShowListenerProxy::endEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException)
3786 {
3787     ::osl::MutexGuard aGuard( m_aMutex );
3788 
3789     if( maListeners.getLength() >= 0 )
3790         maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::endEvent, _1, boost::cref(xNode) ));
3791 }
3792 
3793 // ---------------------------------------------------------
3794 
3795 void SAL_CALL SlideShowListenerProxy::repeat( const Reference< XAnimationNode >& xNode, ::sal_Int32 nRepeat ) throw (RuntimeException)
3796 {
3797     ::osl::MutexGuard aGuard( m_aMutex );
3798 
3799     if( maListeners.getLength() >= 0 )
3800         maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::repeat, _1,  boost::cref(xNode), boost::cref(nRepeat) ));
3801 }
3802 
3803 // ---------------------------------------------------------
3804 // ::com::sun::star::presentation::XSlideShowListener:
3805 // ---------------------------------------------------------
3806 
3807 void SAL_CALL SlideShowListenerProxy::paused(  ) throw (::com::sun::star::uno::RuntimeException)
3808 {
3809     ::osl::MutexGuard aGuard( m_aMutex );
3810 
3811     if( maListeners.getLength() >= 0 )
3812         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::paused ) );
3813 }
3814 
3815 // ---------------------------------------------------------
3816 
3817 void SAL_CALL SlideShowListenerProxy::resumed(  ) throw (::com::sun::star::uno::RuntimeException)
3818 {
3819     ::osl::MutexGuard aGuard( m_aMutex );
3820 
3821     if( maListeners.getLength() >= 0 )
3822         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::resumed ) );
3823 }
3824 
3825 // ---------------------------------------------------------
3826 
3827 void SAL_CALL SlideShowListenerProxy::slideTransitionStarted( ) throw (RuntimeException)
3828 {
3829     ::osl::MutexGuard aGuard( m_aMutex );
3830 
3831     if( maListeners.getLength() >= 0 )
3832         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionStarted ) );
3833 }
3834 
3835 // ---------------------------------------------------------
3836 
3837 void SAL_CALL SlideShowListenerProxy::slideTransitionEnded( ) throw (::com::sun::star::uno::RuntimeException)
3838 {
3839     ::osl::MutexGuard aGuard( m_aMutex );
3840 
3841     if( maListeners.getLength() >= 0 )
3842         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionEnded ) );
3843 }
3844 
3845 // ---------------------------------------------------------
3846 
3847 void SAL_CALL SlideShowListenerProxy::slideAnimationsEnded(  ) throw (::com::sun::star::uno::RuntimeException)
3848 {
3849     ::osl::MutexGuard aGuard( m_aMutex );
3850 
3851     if( maListeners.getLength() >= 0 )
3852         maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideAnimationsEnded ) );
3853 }
3854 
3855 // ---------------------------------------------------------
3856 
3857 void SlideShowListenerProxy::slideEnded(sal_Bool bReverse) throw (RuntimeException)
3858 {
3859     {
3860         ::osl::MutexGuard aGuard( m_aMutex );
3861 
3862         if( maListeners.getLength() >= 0 )
3863             maListeners.forEach<XSlideShowListener>(
3864                 boost::bind( &XSlideShowListener::slideEnded, _1, bReverse) );
3865     }
3866 
3867     {
3868         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3869         if( mxController.is() )
3870             mxController->slideEnded(bReverse);
3871     }
3872 }
3873 
3874 // ---------------------------------------------------------
3875 
3876 void SlideShowListenerProxy::hyperLinkClicked( rtl::OUString const& aHyperLink ) throw (RuntimeException)
3877 {
3878     {
3879         ::osl::MutexGuard aGuard( m_aMutex );
3880 
3881         if( maListeners.getLength() >= 0 )
3882             maListeners.forEach<XSlideShowListener>( boost::bind( &XSlideShowListener::hyperLinkClicked, _1, boost::cref(aHyperLink) ));
3883     }
3884 
3885     {
3886         ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3887         if( mxController.is() )
3888             mxController->hyperLinkClicked(aHyperLink);
3889     }
3890 }
3891 
3892 // ---------------------------------------------------------
3893 // XEventListener
3894 // ---------------------------------------------------------
3895 
3896 void SAL_CALL SlideShowListenerProxy::disposing( const ::com::sun::star::lang::EventObject& aDisposeEvent ) throw (RuntimeException)
3897 {
3898     maListeners.disposeAndClear( aDisposeEvent );
3899     mxController.clear();
3900     mxSlideShow.clear();
3901 }
3902 
3903 // ---------------------------------------------------------
3904 // XShapeEventListener
3905 // ---------------------------------------------------------
3906 
3907 void SAL_CALL SlideShowListenerProxy::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& aOriginalEvent ) throw (RuntimeException)
3908 {
3909     ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
3910     if( mxController.is() )
3911         mxController->click(xShape, aOriginalEvent );
3912 }
3913 
3914 } // namespace ::sd
3915