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