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