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