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