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