/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sd.hxx"

#include <boost/scoped_ptr.hpp>

#include "com/sun/star/frame/XComponentLoader.hpp"
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
#include <com/sun/star/container/XNameReplace.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/awt/SystemPointer.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <vos/process.hxx>
#include <svl/aeitem.hxx>
#include <svl/urihelper.hxx>

#include <toolkit/helper/vclunohelper.hxx>

#include <sfx2/imagemgr.hxx>
#include <sfx2/request.hxx>
#include <sfx2/docfile.hxx>
#include <svx/unoapi.hxx>
#include <svx/svdoole2.hxx>

// for child window ids
#include <sfx2/templdlg.hxx>
#include <svx/f3dchild.hxx>
#include <svx/imapdlg.hxx>
#include <svx/fontwork.hxx>
#include <svx/SvxColorChildWindow.hxx>
#include <svx/bmpmask.hxx>
#include <svx/srchdlg.hxx>
#include <svx/hyprlink.hxx>
#include <svx/hyperdlg.hxx>
#include <svx/galbrws.hxx>
#include "NavigatorChildWindow.hxx"
#include "AnimationChildWindow.hxx"
#include <slideshowimpl.hxx>
#include <slideshowviewimpl.hxx>
#include <pgjump.hxx>
#include "PaneHider.hxx"

#include "glob.hrc"
#include "res_bmp.hrc"
#include "sdresid.hxx"
#include "vcl/canvastools.hxx"
#include "comphelper/anytostring.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "rtl/ref.hxx"
#include "slideshow.hrc"
#include "canvas/elapsedtime.hxx"
#include "canvas/prioritybooster.hxx"
#include "avmedia/mediawindow.hxx"
#include  "svtools/colrdlg.hxx"
#include <vcl/imagerepository.hxx>

#include <boost/noncopyable.hpp>
#include <boost/bind.hpp>

using ::rtl::OUString;
using ::rtl::OString;
using ::cppu::OInterfaceContainerHelper;
using ::comphelper::ImplementationReference;
using ::com::sun::star::animations::XAnimationNode;
using ::com::sun::star::animations::XAnimationListener;
using ::com::sun::star::awt::XWindow;
using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::presentation;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::beans;

extern void NotifyDocumentEvent( SdDrawDocument* pDocument, const rtl::OUString& rEventName );
extern String getUiNameFromPageApiNameImpl( const OUString& rApiName );

namespace sd
{

// Slots, welche im Sfx verwaltet werden und in der SlideShow disabled
// werden sollen (muss in Reihenfolge der SIDs geordnet sein)
static sal_uInt16 __READONLY_DATA pAllowed[] =
{
	SID_OPENDOC								, //	 5501	// damit interne Sprünge klappen
	SID_JUMPTOMARK							, //	 5598
// 	SID_SHOWPOPUPS							, //	 5929
//	SID_GALLERY								, //	 5960
	SID_OPENHYPERLINK						, //	 6676
//	SID_GALLERY_FORMATS						, //	10280
	SID_NAVIGATOR							, //	10366
//	SID_FM_DESIGN_MODE						, //	10629
	SID_PRESENTATION_END					, //	27218
	SID_NAVIGATOR_PAGENAME					, //	27287
	SID_NAVIGATOR_STATE 					, //	27288
	SID_NAVIGATOR_INIT						, //	27289
	SID_NAVIGATOR_PEN						, //	27291
	SID_NAVIGATOR_PAGE						, //	27292
	SID_NAVIGATOR_OBJECT					  //	27293
};

// AnimationSlideController

class AnimationSlideController
{
public:
	enum Mode { ALL, FROM, CUSTOM, PREVIEW };

public:
	AnimationSlideController( Reference< XIndexAccess > xSlides, Mode eMode );

	void setStartSlideNumber( sal_Int32 nSlideNumber );
	sal_Int32 getStartSlideIndex() const;

	sal_Int32 getCurrentSlideNumber() const;
	sal_Int32 getCurrentSlideIndex() const;

	sal_Int32 getSlideIndexCount() const { return maSlideNumbers.size(); }
	sal_Int32 getSlideNumberCount() const { return mnSlideCount; }

	sal_Int32 getSlideNumber( sal_Int32 nSlideIndex ) const;

	void insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible = true );
	void setPreviewNode( const Reference< XAnimationNode >& xPreviewNode );

	bool jumpToSlideIndex( sal_Int32 nNewSlideIndex );
	bool jumpToSlideNumber( sal_Int32 nNewSlideIndex );

	bool nextSlide();
	bool previousSlide();

	void displayCurrentSlide( const Reference< XSlideShow >& xShow,
							  const Reference< XDrawPagesSupplier>& xDrawPages,
							  const bool bSkipAllMainSequenceEffects );

	sal_Int32 getNextSlideIndex() const;
	sal_Int32 getPreviousSlideIndex() const;

	bool isVisibleSlideNumber( sal_Int32 nSlideNumber ) const;

	Reference< XDrawPage > getSlideByNumber( sal_Int32 nSlideNumber ) const;

	sal_Int32 getNextSlideNumber() const;

	bool hasSlides() const { return !maSlideNumbers.empty(); }

private:
	bool getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode );
	sal_Int32 findSlideIndex( sal_Int32 nSlideNumber ) const;

	bool isValidIndex( sal_Int32 nIndex ) const { return (nIndex >= 0) && (nIndex < (sal_Int32)maSlideNumbers.size()); }
	bool isValidSlideNumber( sal_Int32 nSlideNumber ) const { return (nSlideNumber >= 0) && (nSlideNumber < mnSlideCount); }

private:
	Mode meMode;
	sal_Int32 mnStartSlideNumber;
	std::vector< sal_Int32 > maSlideNumbers;
	std::vector< bool > maSlideVisible;
	std::vector< bool > maSlideVisited;
	Reference< XAnimationNode > mxPreviewNode;
	sal_Int32 mnSlideCount;
	sal_Int32 mnCurrentSlideIndex;
	sal_Int32 mnHiddenSlideNumber;
	Reference< XIndexAccess > mxSlides;
};

Reference< XDrawPage > AnimationSlideController::getSlideByNumber( sal_Int32 nSlideNumber ) const
{
	Reference< XDrawPage > xSlide;
	if( mxSlides.is() && (nSlideNumber >= 0) && (nSlideNumber < mxSlides->getCount()) )
		mxSlides->getByIndex( nSlideNumber ) >>= xSlide;
	return xSlide;
}

bool AnimationSlideController::isVisibleSlideNumber( sal_Int32 nSlideNumber ) const
{
	sal_Int32 nIndex = findSlideIndex( nSlideNumber );

	if( nIndex != -1 )
		return maSlideVisible[ nIndex ];
	else
		return false;
}


void AnimationSlideController::setPreviewNode( const Reference< XAnimationNode >& xPreviewNode )
{
	mxPreviewNode = xPreviewNode;
}

AnimationSlideController::AnimationSlideController( Reference< XIndexAccess > xSlides, Mode eMode  )
:	meMode( eMode )
,	mnStartSlideNumber(-1)
,	mnSlideCount( 0 )
,	mnCurrentSlideIndex(0)
,	mnHiddenSlideNumber( -1 )
,	mxSlides( xSlides )
{
	if( mxSlides.is() )
		mnSlideCount = xSlides->getCount();
}

void AnimationSlideController::setStartSlideNumber( sal_Int32 nSlideNumber )
{
	mnStartSlideNumber = nSlideNumber;
	if ( maSlideVisible[mnStartSlideNumber] )
		return;
	// Search forward for the first visible slide
	for ( ; ( (size_t)mnStartSlideNumber < maSlideVisible.size() ) ;
		  mnStartSlideNumber++ ) {
		if ( maSlideVisible[mnStartSlideNumber] )
			return;
	}
	// Search backward for the first visible slide
	for (mnStartSlideNumber = nSlideNumber ;
		 ( mnStartSlideNumber >= 0 ) ; mnStartSlideNumber-- ) {
		if ( maSlideVisible[mnStartSlideNumber] )
			return;
	}
	// No visible slides! Surrender to the request
	mnStartSlideNumber = nSlideNumber;
}

sal_Int32 AnimationSlideController::getStartSlideIndex() const
{
	if( mnStartSlideNumber >= 0 )
	{
		sal_Int32 nIndex;
		const sal_Int32 nCount = maSlideNumbers.size();

		for( nIndex = 0; nIndex < nCount; nIndex++ )
		{
			if( maSlideNumbers[nIndex] == mnStartSlideNumber )
				return nIndex;
		}
	}

	return 0;
}

sal_Int32 AnimationSlideController::getCurrentSlideNumber() const
{
	if( mnHiddenSlideNumber != -1 )
		return mnHiddenSlideNumber;
	else if( !maSlideNumbers.empty() )
		return maSlideNumbers[mnCurrentSlideIndex];
	else
		return 0;
}

sal_Int32 AnimationSlideController::getCurrentSlideIndex() const
{
	if( mnHiddenSlideNumber != -1 )
		return -1;
	else
		return mnCurrentSlideIndex;
}

bool AnimationSlideController::jumpToSlideIndex( sal_Int32 nNewSlideIndex )
{
	if( isValidIndex( nNewSlideIndex ) )
	{
		mnCurrentSlideIndex = nNewSlideIndex;
		mnHiddenSlideNumber = -1;
		maSlideVisited[mnCurrentSlideIndex] = true;
		return true;
	}
	else
	{
		return false;
	}
}

bool AnimationSlideController::jumpToSlideNumber( sal_Int32 nNewSlideNumber )
{
	sal_Int32 nIndex = findSlideIndex( nNewSlideNumber );
	if( isValidIndex( nIndex ) )
	{
		return jumpToSlideIndex( nIndex );
	}
	else if( (nNewSlideNumber >= 0) && (nNewSlideNumber < mnSlideCount) )
	{
		// jump to a hidden slide
		mnHiddenSlideNumber = nNewSlideNumber;
		return true;
	}
	else
	{
		return false;
	}
}

sal_Int32 AnimationSlideController::getSlideNumber( sal_Int32 nSlideIndex ) const
{
	if( isValidIndex( nSlideIndex ) )
		return maSlideNumbers[nSlideIndex];
	else
		return -1;
}

void AnimationSlideController::insertSlideNumber( sal_Int32 nSlideNumber, bool bVisible /* = true */ )
{
	DBG_ASSERT( isValidSlideNumber( nSlideNumber ), "sd::AnimationSlideController::insertSlideNumber(), illegal index" );
	if( isValidSlideNumber( nSlideNumber ) )
	{
		maSlideNumbers.push_back( nSlideNumber );
		maSlideVisible.push_back( bVisible );
		maSlideVisited.push_back( false );
	}
}

bool AnimationSlideController::getSlideAPI( sal_Int32 nSlideNumber, Reference< XDrawPage >& xSlide, Reference< XAnimationNode >& xAnimNode )
{
	if( isValidSlideNumber( nSlideNumber ) ) try
	{
		xSlide = Reference< XDrawPage >( mxSlides->getByIndex(nSlideNumber), UNO_QUERY_THROW );

		if( meMode == PREVIEW )
		{
			xAnimNode = mxPreviewNode;
		}
		else
		{
	   		Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier( xSlide, UNO_QUERY_THROW );
			xAnimNode = xAnimNodeSupplier->getAnimationNode();
		}

		return true;
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::AnimationSlideController::getSlideAPI(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );

	}

	return false;
}

sal_Int32 AnimationSlideController::findSlideIndex( sal_Int32 nSlideNumber ) const
{
	sal_Int32 nIndex;
	const sal_Int32 nCount = maSlideNumbers.size();

	for( nIndex = 0; nIndex < nCount; nIndex++ )
	{
		if( maSlideNumbers[nIndex] == nSlideNumber )
			return nIndex;
	}

	return -1;
}

sal_Int32 AnimationSlideController::getNextSlideIndex() const
{
	switch( meMode )
	{
	case ALL:
		{
			sal_Int32 nNewSlideIndex = mnCurrentSlideIndex + 1;
			if( isValidIndex( nNewSlideIndex ) )
			{
				// if the current slide is not excluded, make sure the
				// next slide is also not excluded.
				// if the current slide is excluded, we want to go
				// to the next slide, even if this is also excluded.
				if( maSlideVisible[mnCurrentSlideIndex] )
				{
					while( isValidIndex( nNewSlideIndex ) )
					{
						if( maSlideVisible[nNewSlideIndex] )
							break;

						nNewSlideIndex++;
					}
				}
			}
			return isValidIndex( nNewSlideIndex ) ? nNewSlideIndex : -1;
		}

	case FROM:
	case CUSTOM:
		return mnHiddenSlideNumber == -1 ? mnCurrentSlideIndex + 1 : mnCurrentSlideIndex;

	default:
	case PREVIEW:
		return -1;

	}
}

sal_Int32 AnimationSlideController::getNextSlideNumber() const
{
	sal_Int32 nNextSlideIndex = getNextSlideIndex();
	if( isValidIndex( nNextSlideIndex ) )
	{
		return maSlideNumbers[nNextSlideIndex];
	}
	else
	{
		return -1;
	}
}


bool AnimationSlideController::nextSlide()
{
	return jumpToSlideIndex( getNextSlideIndex() );
}

sal_Int32 AnimationSlideController::getPreviousSlideIndex() const
{
	sal_Int32 nNewSlideIndex = mnCurrentSlideIndex - 1;

	switch( meMode )
	{
		case ALL:
		{
			// make sure the previous slide is visible
			// or was already visited
			while( isValidIndex( nNewSlideIndex ) )
			{
				if( maSlideVisible[nNewSlideIndex] || maSlideVisited[nNewSlideIndex] )
					break;

				nNewSlideIndex--;
			}

			break;
		}

		case PREVIEW:
			return -1;

		default:
			break;
	}

	return nNewSlideIndex;
}

bool AnimationSlideController::previousSlide()
{
	return jumpToSlideIndex( getPreviousSlideIndex() );
}

void AnimationSlideController::displayCurrentSlide( const Reference< XSlideShow >& xShow,
													const Reference< XDrawPagesSupplier>& xDrawPages,
													const bool bSkipAllMainSequenceEffects )
{
	const sal_Int32 nCurrentSlideNumber = getCurrentSlideNumber();

	if( xShow.is() && (nCurrentSlideNumber != -1 ) )
	{
		Reference< XDrawPage > xSlide;
		Reference< XAnimationNode > xAnimNode;
		::std::vector<PropertyValue> aProperties;

		const sal_Int32 nNextSlideNumber = getNextSlideNumber();
		if( getSlideAPI( nNextSlideNumber, xSlide, xAnimNode )  )
		{
			Sequence< Any > aValue(2);
			aValue[0] <<= xSlide;
			aValue[1] <<= xAnimNode;
			aProperties.push_back(
				PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM( "Prefetch" ) ),
					-1,
					Any(aValue),
					PropertyState_DIRECT_VALUE));
		}
		if (bSkipAllMainSequenceEffects)
		{
			// Add one property that prevents the slide transition from being
			// shown (to speed up the transition to the previous slide) and
			// one to show all main sequence effects so that the user can
			// continue to undo effects.
			aProperties.push_back(
				PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("SkipAllMainSequenceEffects")),
					-1,
					Any(sal_True),
					PropertyState_DIRECT_VALUE));
			aProperties.push_back(
				PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("SkipSlideTransition")),
					-1,
					Any(sal_True),
					PropertyState_DIRECT_VALUE));
		}

		// Convert vector into uno Sequence.
		Sequence< PropertyValue > aPropertySequence (aProperties.size());
		for (int nIndex=0,nCount=aProperties.size();nIndex<nCount; ++nIndex)
			aPropertySequence[nIndex] = aProperties[nIndex];

		if( getSlideAPI( nCurrentSlideNumber, xSlide, xAnimNode ) )
			xShow->displaySlide( xSlide, xDrawPages, xAnimNode, aPropertySequence );
	}
}

// class SlideshowImpl

SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, ::Window* pParentWindow )
: SlideshowImplBase( m_aMutex )
, mxModel(pDoc->getUnoModel(),UNO_QUERY_THROW)
, mpView(pView)
, mpViewShell(pViewSh)
, mpDocSh(pDoc->GetDocSh())
, mpDoc(pDoc)
, mpNewAttr(0)
, mpParentWindow(pParentWindow)
, mpShowWindow(0)
, mpTimeButton(0)
, mnRestoreSlide(0)
, maPresSize( -1, -1 )
, meAnimationMode(ANIMATIONMODE_SHOW)
, mpOldActiveWindow(0)
, mnChildMask( 0 )
, mbGridVisible(false)
, mbBordVisible(false)
, mbSlideBorderVisible(false)
, mbSetOnlineSpelling(false)
, mbDisposed(false)
, mbRehearseTimings(false)
, mbDesignMode(false)
, mbIsPaused(false)
, mbInputFreeze(false)
, mbActive(sal_False)
, maPresSettings( pDoc->getPresentationSettings() )
, mnUserPaintColor( 0x80ff0000L )
, mbUsePen(false)
, mdUserPaintStrokeWidth ( 150.0 )
#ifdef ENABLE_ERASER_UI
, mbSwitchEraserMode(false)
, mnEraseInkSize(100)
#endif
, mnEntryCounter(0)
, mnLastSlideNumber(-1)
, msOnClick( RTL_CONSTASCII_USTRINGPARAM("OnClick") )
, msBookmark( RTL_CONSTASCII_USTRINGPARAM("Bookmark") )
, msVerb( RTL_CONSTASCII_USTRINGPARAM("Verb") )
, mnEndShowEvent(0)
, mnContextMenuEvent(0)
, mnUpdateEvent(0)
, mxPresentation( xPresentation )
{
	if( mpViewShell )
		mpOldActiveWindow = mpViewShell->GetActiveWindow();

	maUpdateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, updateHdl));

	maDeactivateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, deactivateHdl));
	maDeactivateTimer.SetTimeout( 20 );

	maInputFreezeTimer.SetTimeoutHdl( LINK( this, SlideshowImpl, ReadyForNextInputHdl ) );
	maInputFreezeTimer.SetTimeout( 20 );

	SvtSaveOptions aOptions;

		// no autosave during show
	if( aOptions.IsAutoSave() )
		mbAutoSaveWasOn = true;

	Application::AddEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );

	mbUsePen = maPresSettings.mbMouseAsPen;

	SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
	if( pOptions )
	{
		mnUserPaintColor = pOptions->GetPresentationPenColor();
		mdUserPaintStrokeWidth = pOptions->GetPresentationPenWidth();
	}
}

SlideshowImpl::~SlideshowImpl()
{
	SdOptions* pOptions = SD_MOD()->GetSdOptions(DOCUMENT_TYPE_IMPRESS);
	if( pOptions )
	{
		pOptions->SetPresentationPenColor(mnUserPaintColor);
		pOptions->SetPresentationPenWidth(mdUserPaintStrokeWidth);
	}

	Application::RemoveEventListener( LINK( this, SlideshowImpl, EventListenerHdl ) );

	maDeactivateTimer.Stop();

	if( !mbDisposed )
	{
		DBG_ERROR("SlideshowImpl::~SlideshowImpl(), component was not disposed!");
		disposing();
	}
}

void SAL_CALL SlideshowImpl::disposing()
{
	if( mxShow.is() && mpDoc )
		NotifyDocumentEvent( mpDoc, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OnEndPresentation") ) );

	if( mbAutoSaveWasOn )
		setAutoSaveState( true );

	if( mnEndShowEvent )
		Application::RemoveUserEvent( mnEndShowEvent );
	if( mnContextMenuEvent )
		Application::RemoveUserEvent( mnContextMenuEvent );

	maInputFreezeTimer.Stop();

	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( !mxShow.is() )
		return;

	if( mxPresentation.is() )
		mxPresentation->end();

	maUpdateTimer.Stop();

	if( mnUpdateEvent )
	{
		Application::RemoveUserEvent( mnUpdateEvent );
		mnUpdateEvent = 0;
	}

	removeShapeEvents();

	if( mxListenerProxy.is() )
		mxListenerProxy->removeAsSlideShowListener();

	try
	{
		if( mxView.is() )
			mxShow->removeView( mxView.getRef() );

		Reference< XComponent > xComponent( mxShow, UNO_QUERY );
		if( xComponent.is() )
			xComponent->dispose();

		if( mxView.is() )
			mxView->dispose();
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::stop(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );

	}

	mxShow.clear();
	mxView.reset();
	mxListenerProxy.clear();
	mpSlideController.reset();

	// der DrawView das Praesentationfenster wegnehmen und ihr dafuer ihre alten Fenster wiedergeben
	if( mpShowWindow && mpView )
		mpView->DeleteWindowFromPaintView( mpShowWindow );

	if( mpView )
		mpView->SetAnimationPause( sal_False );

	if( mpViewShell )
	{
		mpViewShell->SetActiveWindow(mpOldActiveWindow);
		mpShowWindow->SetViewShell( NULL );
	}

	if( mpView )
		mpView->InvalidateAllWin();

	if( maPresSettings.mbFullScreen )
	{
		// restore StarBASICErrorHdl
		StarBASIC::SetGlobalErrorHdl(maStarBASICGlobalErrorHdl);
		maStarBASICGlobalErrorHdl = Link();
	}
	else
	{
		if( mpShowWindow )
			mpShowWindow->Hide();
	}

	if( meAnimationMode == ANIMATIONMODE_SHOW )
	{
		mpDocSh->SetSlotFilter();
		mpDocSh->ApplySlotFilter();

		Help::EnableContextHelp();
		Help::EnableExtHelp();

		showChildWindows();
		mnChildMask = 0UL;
	}

	// aktuelle Fenster wieder einblenden
	if( mpViewShell && !mpViewShell->ISA(PresentationViewShell))
	{
		if( meAnimationMode == ANIMATIONMODE_SHOW )
		{
			mpViewShell->GetViewShellBase().ShowUIControls (true);
			mpPaneHider.reset();
		}
		else if( meAnimationMode == ANIMATIONMODE_PREVIEW )
		{
			mpViewShell->ShowUIControls (true);
		}
	}

	if( mpTimeButton )
	{
		mpTimeButton->Hide();
		delete mpTimeButton;
		mpTimeButton = 0;
	}

	if( mpShowWindow )
		mpShowWindow->Hide();

	if ( mpViewShell )
	{
		if( meAnimationMode == ANIMATIONMODE_SHOW )
		{
			::sd::Window* pActWin = mpViewShell->GetActiveWindow();

			if (pActWin)
			{
				Size aVisSizePixel = pActWin->GetOutputSizePixel();
				Rectangle aVisAreaWin = pActWin->PixelToLogic( Rectangle( Point(0,0), aVisSizePixel) );
				mpViewShell->VisAreaChanged(aVisAreaWin);
				mpView->VisAreaChanged(pActWin);
				pActWin->GrabFocus();
			}
		}

		// restart the custom show dialog if he started us
		if( mpViewShell->IsStartShowWithDialog() && getDispatcher() )
		{
			mpViewShell->SetStartShowWithDialog( sal_False );
			getDispatcher()->Execute( SID_CUSTOMSHOW_DLG, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD );
		}

		mpViewShell->GetViewShellBase().UpdateBorder(true);
	}

	if( mpShowWindow )
	{
		delete mpShowWindow;
		mpShowWindow = 0;
	}

	setActiveXToolbarsVisible( sal_True );

	Application::EnableNoYieldMode(false);
	Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));

	mbDisposed = true;
}

bool SlideshowImpl::startPreview(
		const Reference< XDrawPage >& xDrawPage,
		const Reference< XAnimationNode >& xAnimationNode,
		::Window* pParent )
{
	bool bRet = false;

	try
	{
		const Reference<lang::XServiceInfo> xServiceInfo( xDrawPage, UNO_QUERY );
		if (xServiceInfo.is()) {
			const Sequence<OUString> supportedServices(
				xServiceInfo->getSupportedServiceNames() );
			for ( sal_Int32 pos = supportedServices.getLength(); pos--; ) {
				if (supportedServices[pos].equalsAsciiL(
						RTL_CONSTASCII_STRINGPARAM(
							"com.sun.star.drawing.MasterPage") )) {
					DBG_ERROR("sd::SlideshowImpl::startPreview() "
							  "not allowed on master page!");
					return false;
				}
			}
		}

		mxPreviewDrawPage = xDrawPage;
		mxPreviewAnimationNode = xAnimationNode;
		meAnimationMode = ANIMATIONMODE_PREVIEW;

		maPresSettings.mbAll = sal_False;
		maPresSettings.mbEndless = sal_False;
		maPresSettings.mbCustomShow = sal_False;
		maPresSettings.mbManual = sal_False;
		maPresSettings.mbMouseVisible = sal_False;
		maPresSettings.mbMouseAsPen = sal_False;
		maPresSettings.mbLockedPages = sal_False;
		maPresSettings.mbAlwaysOnTop = sal_False;
		maPresSettings.mbFullScreen = sal_False;
		maPresSettings.mbAnimationAllowed = sal_True;
		maPresSettings.mnPauseTimeout = 0;
		maPresSettings.mbShowPauseLogo = sal_False;
		maPresSettings.mbStartWithNavigator = sal_False;

		Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
		Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
		mpSlideController.reset( new AnimationSlideController( xSlides, AnimationSlideController::PREVIEW ) );

		sal_Int32 nSlideNumber = 0;
		Reference< XPropertySet > xSet( mxPreviewDrawPage, UNO_QUERY_THROW );
		xSet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Number" ) ) ) >>= nSlideNumber;
		mpSlideController->insertSlideNumber( nSlideNumber-1 );
		mpSlideController->setPreviewNode( xAnimationNode );

		mpShowWindow = new ShowWindow( this, ((pParent == 0) && mpViewShell) ?  mpParentWindow : pParent );
		if( mpViewShell )
		{
			mpViewShell->SetActiveWindow( mpShowWindow );
			mpShowWindow->SetViewShell (mpViewShell);
			mpViewShell->ShowUIControls (false);
		}

		if( mpView )
		{
			mpView->AddWindowToPaintView( mpShowWindow );
			mpView->SetAnimationPause( sal_True );
		}

		// call resize handler
		if( pParent )
		{
			maPresSize = pParent->GetSizePixel();
		}
		else if( mpViewShell )
		{
			Rectangle aContentRect (mpViewShell->GetViewShellBase().getClientRectangle());
			if (Application::GetSettings().GetLayoutRTL())
			{
				aContentRect.nLeft = aContentRect.nRight;
				aContentRect.nRight += aContentRect.nRight;
			}
			maPresSize = aContentRect.GetSize();
			mpShowWindow->SetPosPixel( aContentRect.TopLeft() );
		}
		else
		{
			DBG_ERROR("sd::SlideshowImpl::startPreview(), I need either a parent window or a viewshell!");
		}
		resize( maPresSize );

		sal_Int32 nPropertyCount = 1;
		if( mxPreviewAnimationNode.is() )
			nPropertyCount++;

		Sequence< beans::PropertyValue > aProperties(nPropertyCount);
		aProperties[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("AutomaticAdvancement") );
		aProperties[0].Value = uno::makeAny( (double)1.0 ); // one second timeout

		if( mxPreviewAnimationNode.is() )
		{
			aProperties[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("NoSlideTransitions") );
			aProperties[1].Value = uno::makeAny( sal_True );
		}

		bRet = startShowImpl( aProperties );

		if( mpShowWindow != 0 && meAnimationMode == ANIMATIONMODE_PREVIEW )
			mpShowWindow->SetPreviewMode();

	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::SlideshowImpl::startPreview(), "
					 "exception caught: ") +
			 rtl::OUStringToOString(
				 comphelper::anyToString( cppu::getCaughtException() ),
				 RTL_TEXTENCODING_UTF8 )).getStr() );
		bRet = false;
	}

	return bRet;
}

bool SlideshowImpl::startShow( PresentationSettingsEx* pPresSettings )
{
	const rtl::Reference<SlideshowImpl> this_(this);

	DBG_ASSERT( !mxShow.is(), "sd::SlideshowImpl::startShow(), called twice!" );
	if( mxShow.is() )
		return true;
	DBG_ASSERT( mpParentWindow!=NULL, "sd::SlideshowImpl::startShow() called without parent window" );
	if (mpParentWindow == NULL)
		return false;

	bool bRet = false;

	try
	{
		if( pPresSettings )
		{
			maPresSettings = *pPresSettings;
			mbRehearseTimings = pPresSettings->mbRehearseTimings;
		}

		// ---

		String	aPresSlide( maPresSettings.maPresPage );
		SdPage* pStartPage = mpViewShell ? mpViewShell->GetActualPage() : 0;
		bool	bStartWithActualSlide =  pStartPage &&
										( (meAnimationMode != ANIMATIONMODE_SHOW) ||
										   SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsStartWithActualPage() );

		// sollen Zeiten gestoppt werden?
		if( mbRehearseTimings )
		{
			maPresSettings.mbEndless = sal_False;
			maPresSettings.mbManual = sal_True;
			maPresSettings.mbMouseVisible = sal_True;
			maPresSettings.mbMouseAsPen = sal_False;
			maPresSettings.mnPauseTimeout = 0;
			maPresSettings.mbShowPauseLogo = sal_False;
			maPresSettings.mbStartWithNavigator = sal_False;
		}

		if( pStartPage )
		{
			if( pStartPage->GetPageKind() == PK_NOTES )
			{
				// we are in notes page mode, so get
				// the corresponding draw page
				const sal_uInt16 nPgNum = ( pStartPage->GetPageNum() - 2 ) >> 1;
				pStartPage = mpDoc->GetSdPage( nPgNum, PK_STANDARD );
			}
		}

		if( bStartWithActualSlide )
		{
			if( meAnimationMode != ANIMATIONMODE_SHOW )
			{
				if( pStartPage->GetPageKind() == PK_STANDARD )
				{
					aPresSlide = pStartPage->GetName();
					maPresSettings.mbAll = false;
				}
				else
				{
					bStartWithActualSlide = false;
				}
			}
		}
		else
		{
			if( pStartPage->GetPageKind() != PK_STANDARD )
			{
				bStartWithActualSlide = false;
			}
		}

		// build page list
		createSlideList( maPresSettings.mbAll, false, aPresSlide );

		if( bStartWithActualSlide )
		{
			sal_Int32 nSlideNum = ( pStartPage->GetPageNum() - 1 ) >> 1;

			if( !maPresSettings.mbAll && !maPresSettings.mbCustomShow )
			{
				// its start from dia, find out if it is located before our current Slide
				const sal_Int32 nSlideCount = mpDoc->GetSdPageCount( PK_STANDARD );
				sal_Int32 nSlide;
				for( nSlide = 0; (nSlide < nSlideCount); nSlide++ )
				{
					if( mpDoc->GetSdPage( (sal_uInt16) nSlide, PK_STANDARD )->GetName() == aPresSlide )
						break;
				}

				if( nSlide > nSlideNum )
					nSlideNum = -1;
			}

			if( nSlideNum != -1 )
				mpSlideController->setStartSlideNumber( nSlideNum );
		}

		// remember Slide number from where the show was started
		if( pStartPage )
			mnRestoreSlide = ( pStartPage->GetPageNum() - 1 ) / 2;

		if( mpSlideController->hasSlides() )
		{
			// hide child windows
			hideChildWindows();

			mpShowWindow = new ShowWindow( this, mpParentWindow );
			mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
			if( mpViewShell )
			{
				mpViewShell->SetActiveWindow( mpShowWindow );
				mpShowWindow->SetViewShell (mpViewShell);
				mpViewShell->GetViewShellBase().ShowUIControls (false);
				// Hide the side panes for in-place presentations.
				if ( ! maPresSettings.mbFullScreen)
					mpPaneHider.reset(new PaneHider(*mpViewShell,this));

				if( getViewFrame() )
					getViewFrame()->SetChildWindow( SID_NAVIGATOR, maPresSettings.mbStartWithNavigator );
			}

			// these Slots are forbidden in other views for this document
			if( mpDocSh )
			{
				mpDocSh->SetSlotFilter( sal_True, sizeof( pAllowed ) / sizeof( sal_uInt16 ), pAllowed );
				mpDocSh->ApplySlotFilter();
			}

			Help::DisableContextHelp();
			Help::DisableExtHelp();

		//	mpTimeButton = new PushButton( mpShowWindow, SdResId( RID_TIME_BUTTON ) );
		//	maPencil = Pointer( POINTER_PEN );
		//	mpTimeButton->Hide();

			if( maPresSettings.mbFullScreen )
			{
				// disable basic ide error handling
				maStarBASICGlobalErrorHdl = StarBASIC::GetGlobalErrorHdl();
				StarBASIC::SetGlobalErrorHdl( Link() );
			}

			// call resize handler
			maPresSize = mpParentWindow->GetSizePixel();
			if( !maPresSettings.mbFullScreen && mpViewShell )
			{
				const Rectangle& aClientRect = mpViewShell->GetViewShellBase().getClientRectangle();
				maPresSize = aClientRect.GetSize();
				mpShowWindow->SetPosPixel( aClientRect.TopLeft() );
				resize( maPresSize );
			}

			// #i41824#
			// Note: In FullScreen Mode the OS (window manager) sends a resize to
			// the WorkWindow once it actually resized it to full size.  The
			// WorkWindow propagates the resize to the DrawViewShell which calls
			// resize() at the SlideShow (this).  Calling resize here results in a
			// temporary display of a black window in the window's default size

/*
			if ( mbRehearseTimings )
			{
				Size  aButtonSizePixel( pTimeButton->GetSizePixel() );
				Point aButtonPosPixel( aButtonSizePixel.Width() >> 1, pShowWindow->GetSizePixel().Height() - aButtonSizePixel.Height() * 5 / 2);

				pTimeButton->SetPosPixel( aButtonPosPixel );
				aTimer.SetTimeoutHdl( LINK( this,FuSlideShow, TimeButtonTimeOutHdl ) );
				pTimeButton->SetClickHdl( LINK( this, FuSlideShow, TimeButtonHdl ) );
			}
*/

			if( mpView )
			{
				mpView->AddWindowToPaintView( mpShowWindow );
				mpView->SetAnimationPause( sal_True );
			}

			SfxBindings* pBindings = getBindings();
			if( pBindings )
			{
				pBindings->Invalidate( SID_PRESENTATION );
				pBindings->Invalidate( SID_REHEARSE_TIMINGS );
			}

			// Defer the sd::ShowWindow's GrabFocus to SlideShow::activate. so that the accessible event can be fired correctly.
			//mpShowWindow->GrabFocus();

			std::vector<beans::PropertyValue> aProperties;
			aProperties.reserve( 4 );

			aProperties.push_back(
				beans::PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("AdvanceOnClick") ),
					-1, Any( ! (maPresSettings.mbLockedPages != sal_False) ),
					beans::PropertyState_DIRECT_VALUE ) );

			aProperties.push_back(
				beans::PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("ImageAnimationsAllowed") ),
					-1, Any( maPresSettings.mbAnimationAllowed != sal_False ),
					beans::PropertyState_DIRECT_VALUE ) );

			const sal_Bool bZOrderEnabled(
				SD_MOD()->GetSdOptions( mpDoc->GetDocumentType() )->IsSlideshowRespectZOrder() );
			aProperties.push_back(
				beans::PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("DisableAnimationZOrder") ),
					-1, Any( bZOrderEnabled == sal_False ),
					beans::PropertyState_DIRECT_VALUE ) );

/*
			aProperties.push_back(
				beans::PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("MouseVisible") ),
					-1, Any( maPresSettings.mbMouseVisible != sal_False ),
					beans::PropertyState_DIRECT_VALUE ) );
*/
			aProperties.push_back(
				beans::PropertyValue(
					OUString( RTL_CONSTASCII_USTRINGPARAM("ForceManualAdvance") ),
					-1, Any( maPresSettings.mbManual != sal_False ),
					beans::PropertyState_DIRECT_VALUE ) );

			if( mbUsePen )
 			{
				aProperties.push_back(
					beans::PropertyValue(
						OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintColor") ),
						// User paint color is black by default.
						-1, Any( mnUserPaintColor ),
						beans::PropertyState_DIRECT_VALUE ) );

				aProperties.push_back(
					beans::PropertyValue(
						OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintStrokeWidth") ),
						// User paint color is black by default.
						-1, Any( mdUserPaintStrokeWidth ),
						beans::PropertyState_DIRECT_VALUE ) );
			}

			if (mbRehearseTimings) {
				aProperties.push_back(
					beans::PropertyValue(
						OUString( RTL_CONSTASCII_USTRINGPARAM("RehearseTimings") ),
						-1, Any(true), beans::PropertyState_DIRECT_VALUE ) );
			}

			bRet = startShowImpl( Sequence<beans::PropertyValue>(
									  &aProperties[0], aProperties.size() ) );

		}

		setActiveXToolbarsVisible( sal_False );
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::SlideshowImpl::startShow(), "
					 "exception caught: ") +
			 rtl::OUStringToOString(
				 comphelper::anyToString( cppu::getCaughtException() ),
				 RTL_TEXTENCODING_UTF8 )).getStr() );
		bRet = false;
	}

	return bRet;
}

bool SlideshowImpl::startShowImpl( const Sequence< beans::PropertyValue >& aProperties )
{
	try
	{
		mxShow = Reference< XSlideShow >( createSlideShow(), UNO_QUERY_THROW );
		mxView = mxView.createFromQuery( new SlideShowView(
											 *mpShowWindow,
											 mpDoc,
											 meAnimationMode,
											 this,
											 maPresSettings.mbFullScreen) );

		// try add wait symbol to properties:
		const Reference<rendering::XSpriteCanvas> xSpriteCanvas(
			mxView->getCanvas() );
		if (xSpriteCanvas.is())
		{
			BitmapEx waitSymbolBitmap( SdResId(BMP_WAIT_ICON) );
			const Reference<rendering::XBitmap> xBitmap(
				vcl::unotools::xBitmapFromBitmapEx(
					xSpriteCanvas->getDevice(), waitSymbolBitmap ) );
			if (xBitmap.is())
			{
				mxShow->setProperty(
					beans::PropertyValue(
						OUString( RTL_CONSTASCII_USTRINGPARAM("WaitSymbolBitmap") ),
						-1,
						makeAny( xBitmap ),
						beans::PropertyState_DIRECT_VALUE ) );
			}
		}

		const sal_Int32 nCount = aProperties.getLength();
		sal_Int32 nIndex;
		for( nIndex = 0; nIndex < nCount; nIndex++ )
			mxShow->setProperty( aProperties[nIndex] );

		mxShow->addView( mxView.getRef() );

		mxListenerProxy.set( new SlideShowListenerProxy( this, mxShow ) );
		mxListenerProxy->addAsSlideShowListener();


		NotifyDocumentEvent( mpDoc, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("OnStartPresentation") ) );
		displaySlideIndex( mpSlideController->getStartSlideIndex() );

		return true;
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::SlideshowImpl::startShowImpl(), "
					 "exception caught: ") +
			 rtl::OUStringToOString(
				 comphelper::anyToString( cppu::getCaughtException() ),
				 RTL_TEXTENCODING_UTF8 )).getStr() );
		return false;
	}
}

/** called only by the slideshow view when the first paint event occurs.
	This actually starts the slideshow. */
void SlideshowImpl::onFirstPaint()
{
	if( mpShowWindow )
	{
		/*
		mpShowWindow->SetBackground( Wallpaper( Color( COL_BLACK ) ) );
		mpShowWindow->Erase();
		mpShowWindow->SetBackground();
		*/
	}

	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	maUpdateTimer.SetTimeout( (sal_uLong)100 );
	maUpdateTimer.Start();
}

void SlideshowImpl::paint( const Rectangle& /* rRect */ )
{
	if( mxView.is() ) try
	{
		awt::PaintEvent aEvt;
		// aEvt.UpdateRect = TODO
		mxView->paint( aEvt );
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::paint(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::addSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException)
{
	if( mxListenerProxy.is() )
		mxListenerProxy->addSlideShowListener( xListener );
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::removeSlideShowListener( const Reference< XSlideShowListener >& xListener ) throw (RuntimeException)
{
	if( mxListenerProxy.is() )
		mxListenerProxy->removeSlideShowListener( xListener );
}

// ---------------------------------------------------------

void SlideshowImpl::slideEnded(const bool bReverse)
{
	if (bReverse)
		gotoPreviousSlide(true);
	else
		gotoNextSlide();
}

// ---------------------------------------------------------

void SlideshowImpl::removeShapeEvents()
{
	if( mxShow.is() && mxListenerProxy.is() ) try
	{
		WrappedShapeEventImplMap::iterator aIter;
		const WrappedShapeEventImplMap::iterator aEnd( maShapeEventMap.end() );

		for( aIter = maShapeEventMap.begin(); aIter != aEnd; aIter++ )
		{
			mxListenerProxy->removeShapeEventListener( (*aIter).first );
			mxShow->setShapeCursor( (*aIter).first, awt::SystemPointer::ARROW );
		}

		maShapeEventMap.clear();
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::SlideshowImpl::removeShapeEvents(), "
					 "exception caught: ") +
			 rtl::OUStringToOString(
				 comphelper::anyToString( cppu::getCaughtException() ),
				 RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// ---------------------------------------------------------

void SlideshowImpl::registerShapeEvents(sal_Int32 nSlideNumber)
{
	if( nSlideNumber >= 0 ) try
	{
		Reference< XDrawPagesSupplier > xDrawPages( mxModel, UNO_QUERY_THROW );
		Reference< XIndexAccess > xPages( xDrawPages->getDrawPages(), UNO_QUERY_THROW );

		Reference< XShapes > xDrawPage;
		xPages->getByIndex(nSlideNumber) >>= xDrawPage;

		if( xDrawPage.is() )
		{
			Reference< XMasterPageTarget > xMasterPageTarget( xDrawPage, UNO_QUERY );
			if( xMasterPageTarget.is() )
			{
				Reference< XShapes > xMasterPage( xMasterPageTarget->getMasterPage(), UNO_QUERY );
				if( xMasterPage.is() )
					registerShapeEvents( xMasterPage );
			}
			registerShapeEvents( xDrawPage );
		}
	}
	catch( Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::SlideshowImpl::registerShapeEvents(), "
					 "exception caught: ") +
			 rtl::OUStringToOString(
				 comphelper::anyToString( cppu::getCaughtException() ),
				 RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// ---------------------------------------------------------

void SlideshowImpl::registerShapeEvents( Reference< XShapes >& xShapes ) throw( Exception )
{
	try
	{
		const sal_Int32 nShapeCount = xShapes->getCount();
		sal_Int32 nShape;
		for( nShape = 0; nShape < nShapeCount; nShape++ )
		{
			Reference< XShape > xShape;
			xShapes->getByIndex( nShape ) >>= xShape;

			if( xShape.is() &&
				xShape->getShapeType().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.drawing.GroupShape") ) )
			{
				Reference< XShapes > xSubShapes( xShape, UNO_QUERY );
				if( xSubShapes.is() )
					registerShapeEvents( xSubShapes );
			}

			Reference< XPropertySet > xSet( xShape, UNO_QUERY );
			if( !xSet.is() )
				continue;

			Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
			if( !xSetInfo.is() || !xSetInfo->hasPropertyByName( msOnClick ) )
				continue;

			WrappedShapeEventImplPtr pEvent( new WrappedShapeEventImpl );
			xSet->getPropertyValue( msOnClick ) >>= pEvent->meClickAction;

			switch( pEvent->meClickAction )
			{
			case ClickAction_PREVPAGE:
			case ClickAction_NEXTPAGE:
			case ClickAction_FIRSTPAGE:
			case ClickAction_LASTPAGE:
			case ClickAction_STOPPRESENTATION:
				break;
			case ClickAction_BOOKMARK:
				if( xSetInfo->hasPropertyByName( msBookmark ) )
					xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
				if( getSlideNumberForBookmark( pEvent->maStrBookmark ) == -1 )
					continue;
				break;
			case ClickAction_DOCUMENT:
			case ClickAction_SOUND:
			case ClickAction_PROGRAM:
			case ClickAction_MACRO:
				if( xSetInfo->hasPropertyByName( msBookmark ) )
					xSet->getPropertyValue( msBookmark ) >>= pEvent->maStrBookmark;
				break;
			case ClickAction_VERB:
				if( xSetInfo->hasPropertyByName( msVerb ) )
					xSet->getPropertyValue( msVerb ) >>= pEvent->mnVerb;
				break;
			default:
				continue; // skip all others
			}

			maShapeEventMap[ xShape ] = pEvent;

			if( mxListenerProxy.is() )
				mxListenerProxy->addShapeEventListener( xShape );
			mxShow->setShapeCursor( xShape, awt::SystemPointer::REFHAND );
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::registerShapeEvents(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// ---------------------------------------------------------

void SlideshowImpl::displayCurrentSlide (const bool bSkipAllMainSequenceEffects)
{
	stopSound();
	removeShapeEvents();

	if( mpSlideController.get() && mxShow.is() )
	{
		Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(),
													UNO_QUERY_THROW );
		mpSlideController->displayCurrentSlide( mxShow, xDrawPages, bSkipAllMainSequenceEffects );
		registerShapeEvents(mpSlideController->getCurrentSlideNumber());
		update();

		SfxBindings* pBindings = getBindings();
		if( pBindings )
		{
			pBindings->Invalidate( SID_NAVIGATOR_STATE );
			pBindings->Invalidate( SID_NAVIGATOR_PAGENAME );
		}
	}
	// send out page change event and notify to update all acc info for current page
	if (mpViewShell)
	{
		sal_Int32 currentPageIndex = getCurrentSlideIndex();
		mpViewShell->fireSwitchCurrentPage(currentPageIndex);
		mpViewShell->NotifyAccUpdate();
	}
}

// ---------------------------------------------------------

void SlideshowImpl::endPresentation()
{
/*
	if( maPresSettings.mbMouseAsPen)
	{
		Reference< XMultiServiceFactory > xDocFactory(mpDoc->getUnoModel(), UNO_QUERY );
		if( xDocFactory.is() )
			mxShow->registerUserPaintPolygons(xDocFactory);
	}
*/
	if( !mnEndShowEvent )
		mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) );
}

// ---------------------------------------------------------

IMPL_LINK( SlideshowImpl, endPresentationHdl, void*, EMPTYARG )
{
	mnEndShowEvent = 0;

	if( mxPresentation.is() )
		mxPresentation->end();
	return 0;
}

// ---------------------------------------------------------

void SAL_CALL SlideshowImpl::pause() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( !mbIsPaused ) try
	{
		mbIsPaused = sal_True;
		if( mxShow.is() )
		{
			mxShow->pause(sal_True);

			if( mxListenerProxy.is() )
				mxListenerProxy->paused();
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::pause(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// ---------------------------------------------------------

void SAL_CALL SlideshowImpl::resume() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mbIsPaused ) try
	{
		if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
		{
			mpShowWindow->RestartShow();
		}
		else
		{
			mbIsPaused = sal_False;
			if( mxShow.is() )
			{
				mxShow->pause(sal_False);
				update();

				if( mxListenerProxy.is() )
					mxListenerProxy->resumed();
			}
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::resume(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// ---------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::isPaused() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return mbIsPaused;
}

// ---------------------------------------------------------

void SAL_CALL SlideshowImpl::blankScreen( sal_Int32 nColor ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mpShowWindow && mpSlideController )
	{
		if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), nColor ) )
		{
			pause();
		}
	}
}

// ---------------------------------------------------------
// XShapeEventListener
// ---------------------------------------------------------

void SlideshowImpl::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& /* aOriginalEvent */ )
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	WrappedShapeEventImplPtr pEvent = maShapeEventMap[xShape];
	if( !pEvent.get() )
		return;

	switch( pEvent->meClickAction )
	{
	case ClickAction_PREVPAGE:			gotoPreviousSlide(); 		break;
	case ClickAction_NEXTPAGE:			gotoNextSlide();			break;
	case ClickAction_FIRSTPAGE:			gotoFirstSlide();			break;
	case ClickAction_LASTPAGE:			gotoLastSlide();			break;
	case ClickAction_STOPPRESENTATION:	endPresentation();			break;
	case ClickAction_BOOKMARK:
	{
		gotoBookmark( pEvent->maStrBookmark );
	}
	break;
	case ClickAction_SOUND:
	{
		try
		{
			mxPlayer.set(avmedia::MediaWindow::createPlayer(pEvent->maStrBookmark), uno::UNO_QUERY_THROW );
			mxPlayer->start();
		}
		catch( uno::Exception& e )
		{
			(void)e;
			DBG_ERROR("sd::SlideshowImpl::click(), exception caught!" );
		}
	}
	break;

	case ClickAction_DOCUMENT:
	{
		OUString aBookmark( pEvent->maStrBookmark );

		sal_Int32 nPos = aBookmark.indexOf( sal_Unicode('#') );
		if( nPos >= 0 )
		{
			OUString aURL( aBookmark.copy( 0, nPos+1 ) );
			OUString aName( aBookmark.copy( nPos+1 ) );
			aURL += getUiNameFromPageApiNameImpl( aName );
			aBookmark = aURL;
		}

		mpDocSh->OpenBookmark( aBookmark );
	}
	break;

	case ClickAction_PROGRAM:
	{
		INetURLObject aURL(
			::URIHelper::SmartRel2Abs(
				INetURLObject(mpDocSh->GetMedium()->GetBaseURL()),
				pEvent->maStrBookmark, ::URIHelper::GetMaybeFileHdl(), true,
				false, INetURLObject::WAS_ENCODED,
				INetURLObject::DECODE_UNAMBIGUOUS ) );

		if( INET_PROT_FILE == aURL.GetProtocol() )
		{
			SfxStringItem aUrl( SID_FILE_NAME, aURL.GetMainURL( INetURLObject::NO_DECODE ) );
			SfxBoolItem aBrowsing( SID_BROWSE, sal_True );

			SfxViewFrame* pViewFrm = SfxViewFrame::Current();
			if (pViewFrm)
				pViewFrm->GetDispatcher()->Execute( SID_OPENDOC,
  											SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
											&aUrl,
											&aBrowsing,
											0L );
		}
	}
	break;

	case presentation::ClickAction_MACRO:
	{
		const String aMacro( pEvent->maStrBookmark );

		if ( SfxApplication::IsXScriptURL( aMacro ) )
		{
			Any aRet;
			Sequence< sal_Int16 > aOutArgsIndex;
			Sequence< Any > aOutArgs;
			Sequence< Any >* pInArgs = new Sequence< Any >(0);
			mpDocSh->CallXScript( aMacro, *pInArgs, aRet, aOutArgsIndex, aOutArgs);
		}
		else
		{
			// aMacro has the following syntax:
			// "Macroname.Modulname.Libname.Dokumentname" or
			// "Macroname.Modulname.Libname.Applikationsname"
			String aMacroName = aMacro.GetToken(0, sal_Unicode('.'));
			String aModulName = aMacro.GetToken(1, sal_Unicode('.'));
			String aLibName   = aMacro.GetToken(2, sal_Unicode('.'));
			String aDocName   = aMacro.GetToken(3, sal_Unicode('.'));

			// todo: is the limitation still given that only
			// Modulname+Macroname can be used here?
			String aExecMacro(aModulName);
			aExecMacro.Append( sal_Unicode('.') );
			aExecMacro.Append( aMacroName );
			mpDocSh->GetBasic()->Call(aExecMacro);
		}
	}
	break;

	case ClickAction_VERB:
	{
		// todo, better do it async?
		SdrObject* pObj = GetSdrObjectFromXShape( xShape );
		SdrOle2Obj* pOleObject = PTR_CAST(SdrOle2Obj, pObj);
		if (pOleObject && mpViewShell )
			mpViewShell->ActivateObject(pOleObject, pEvent->mnVerb);
	}
	break;
	default:
		break;
	}
}

// ---------------------------------------------------------

sal_Int32 SlideshowImpl::getSlideNumberForBookmark( const OUString& rStrBookmark )
{
	sal_Bool bIsMasterPage;
	OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark );
	sal_uInt16 nPgNum = mpDoc->GetPageByName( aBookmark, bIsMasterPage );

	if( nPgNum == SDRPAGE_NOTFOUND )
	{
		// Ist das Bookmark ein Objekt?
		SdrObject* pObj = mpDoc->GetObj( aBookmark );

		if( pObj )
		{
			nPgNum = pObj->GetPage()->GetPageNum();
			bIsMasterPage = (sal_Bool)pObj->GetPage()->IsMasterPage();
		}
	}

	if( (nPgNum == SDRPAGE_NOTFOUND) || bIsMasterPage || static_cast<SdPage*>(mpDoc->GetPage(nPgNum))->GetPageKind() != PK_STANDARD )
		return -1;

	return ( nPgNum - 1) >> 1;
}

// ---------------------------------------------------------

void SlideshowImpl::hyperLinkClicked( rtl::OUString const& aHyperLink ) throw (RuntimeException)
{
	OUString aBookmark( aHyperLink );

	sal_Int32 nPos = aBookmark.indexOf( sal_Unicode('#') );
	if( nPos >= 0 )
	{
		OUString aURL( aBookmark.copy( 0, nPos+1 ) );
		OUString aName( aBookmark.copy( nPos+1 ) );
		aURL += getUiNameFromPageApiNameImpl( aName );
		aBookmark = aURL;
	}

	mpDocSh->OpenBookmark( aBookmark );
}

// ---------------------------------------------------------

void SlideshowImpl::displaySlideNumber( sal_Int32 nSlideNumber )
{
	if( mpSlideController.get() )
	{
		if( mpSlideController->jumpToSlideNumber( nSlideNumber ) )
		{
			displayCurrentSlide();
		}
	}
}

// ---------------------------------------------------------

/** nSlideIndex == -1 displays current slide again */
void SlideshowImpl::displaySlideIndex( sal_Int32 nSlideIndex )
{
	if( mpSlideController.get() )
	{
		if( (nSlideIndex == -1) || mpSlideController->jumpToSlideIndex( nSlideIndex ) )
		{
			displayCurrentSlide();
		}
	}
}

// ---------------------------------------------------------

void SlideshowImpl::jumpToBookmark( const String& sBookmark )
{
	sal_Int32 nSlideNumber = getSlideNumberForBookmark( sBookmark );
	if( nSlideNumber != -1 )
		displaySlideNumber( nSlideNumber );
}

// ---------------------------------------------------------

sal_Int32 SlideshowImpl::getCurrentSlideNumber()
{
	return mpSlideController.get() ? mpSlideController->getCurrentSlideNumber() : -1;
}

// ---------------------------------------------------------

sal_Int32 SlideshowImpl::getFirstSlideNumber()
{
	sal_Int32 nRet = 0;
	if( mpSlideController.get() )
	{
		sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
		if( nSlideIndexCount >= 0 )
		{
			nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
			while( nSlideIndexCount-- )
			{
				sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
				if( nRet > nTemp )
					nRet = nTemp;
			}
		}
	}

	return nRet;
}

// ---------------------------------------------------------

sal_Int32 SlideshowImpl::getLastSlideNumber()
{
	sal_Int32 nRet = 0;
	if( mpSlideController.get() )
	{
		sal_Int32 nSlideIndexCount = mpSlideController->getSlideIndexCount() - 1;
		if( nSlideIndexCount >= 0 )
		{
			nRet = mpSlideController->getSlideNumber( nSlideIndexCount );
			while( nSlideIndexCount-- )
			{
				sal_Int32 nTemp = mpSlideController->getSlideNumber( nSlideIndexCount );
				if( nRet < nTemp )
					nRet = nTemp;
			}
		}
	}

	return nRet;
}

// ---------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::isEndless() throw( RuntimeException )
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return maPresSettings.mbEndless;
}

// ---------------------------------------------------------

double SlideshowImpl::update()
{
	startUpdateTimer();
	return -1;
}

// ---------------------------------------------------------

void SlideshowImpl::startUpdateTimer()
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	maUpdateTimer.SetTimeout( 0 );
	maUpdateTimer.Start();
}

// ---------------------------------------------------------

/** this timer is called 20ms after a new slide was displayed.
	This is used to unfreeze user input that was disabled after
	slide change to skip input that was buffered during slide
	transition preparation */
IMPL_LINK( SlideshowImpl, ReadyForNextInputHdl, Timer*, EMPTYARG )
{
	mbInputFreeze = false;
	return 0;
}

// ---------------------------------------------------------

/** if I catch someone someday who calls this method by hand
	and not by using the timer, I will personally punish this
	person seriously, even if this person is me.
*/
IMPL_LINK( SlideshowImpl, updateHdl, Timer*, EMPTYARG )
{
	mnUpdateEvent = 0;

	return updateSlideShow();
}




IMPL_LINK( SlideshowImpl, PostYieldListener, void*, EMPTYARG )
{
	Application::EnableNoYieldMode(false);
	Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));

	if (mbDisposed)
		return 0;

	// Call Reschedule() but make sure that we are not destroyed during its
	// execution (we still can be disposed, though.)
	const rtl::Reference<SlideshowImpl> pSelf (this);
	Application::Reschedule(true);

	// Update the slide show if we are still alive.
	if ( ! mbDisposed)
		return updateSlideShow();
	else
		return 0;
}




sal_Int32 SlideshowImpl::updateSlideShow (void)
{
	// doing some nMagic
	const rtl::Reference<SlideshowImpl> this_(this);

	Reference< XSlideShow > xShow( mxShow );
	if ( ! xShow.is())
		return 0;

	try
	{
		// TODO(Q3): Evaluate under various systems and setups,
		// whether this is really necessary. Under WinXP and Matrox
		// G550, the frame rates were much more steadier with this
		// tweak, although.

// currently no solution, because this kills sound (at least on Windows)
//		 // Boost our prio, as long as we're in the render loop
//		 ::canvas::tools::PriorityBooster aBooster(2);

		double fUpdate = 0.0;
		if( !xShow->update(fUpdate) )
			fUpdate = -1.0;

		if (mxShow.is() && (fUpdate >= 0.0))
		{
			if (::basegfx::fTools::equalZero(fUpdate))
			{
				// Use post yield listener for short update intervalls.
				Application::EnableNoYieldMode(true);
				Application::AddPostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
			}
			else
			{
				// Avoid busy loop when the previous call to update()
				// returns a small positive number but not 0 (which is
				// handled above). Also, make sure that calls to update()
				// have a minimum frequency.
				// => Allow up to 60 frames per second.  Call at least once
				// every 4 seconds.
				const static sal_Int32 mnMaximumFrameCount (60);
				const static double mnMinimumTimeout (1.0 / mnMaximumFrameCount);
				const static double mnMaximumTimeout (4.0);
				fUpdate = ::basegfx::clamp(fUpdate, mnMinimumTimeout, mnMaximumTimeout);

				// Make sure that the maximum frame count has not been set
				// too high (only then conversion to milliseconds and long
				// integer may lead to zero value.)
				OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0);

				Application::EnableNoYieldMode(false);
				Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));

				// Use a timer for the asynchronous callback.
				maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
				maUpdateTimer.Start();
			}
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::updateSlideShow(), exception caught: ")
				+ rtl::OUStringToOString(
					comphelper::anyToString( cppu::getCaughtException() ),
					RTL_TEXTENCODING_UTF8 )).getStr() );
	}
	return 0;
}

// ---------------------------------------------------------

bool SlideshowImpl::keyInput(const KeyEvent& rKEvt)
{
	if( !mxShow.is() || mbInputFreeze )
		return false;

	bool bRet = true;

	try
	{
		const int nKeyCode = rKEvt.GetKeyCode().GetCode();
		switch( nKeyCode )
		{
			case awt::Key::CONTEXTMENU:
				if( !mnContextMenuEvent )
				{
					if( mpShowWindow )
						maPopupMousePos = mpShowWindow->GetPointerState().maPos;
					mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
				}
				break;

			// cancel show
			case KEY_ESCAPE:
			case KEY_SUBTRACT:
				// in case the user cancels the presentation, switch to current slide
				// in edit mode
				if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
				{
					if( mpSlideController->getCurrentSlideNumber() != -1 )
						mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
				}
				endPresentation();
				break;

			// advance show
			case KEY_PAGEDOWN:
				if(rKEvt.GetKeyCode().IsMod2())
				{
					gotoNextSlide();
					break;
				}
				// warning, fall through!
			case KEY_SPACE:
			case KEY_RIGHT:
			case KEY_DOWN:
			case KEY_N:
				gotoNextEffect();
				break;

			case KEY_RETURN:
			{
				if( maCharBuffer.Len() )
				{
					if( mpSlideController.get() )
					{
						if( mpSlideController->jumpToSlideNumber( maCharBuffer.ToInt32() - 1 ) )
							displayCurrentSlide();
					}
					maCharBuffer.Erase();
				}
				else
				{
					gotoNextEffect();
				}
			}
			break;

			// numeric: add to buffer
			case KEY_0:
			case KEY_1:
			case KEY_2:
			case KEY_3:
			case KEY_4:
			case KEY_5:
			case KEY_6:
			case KEY_7:
			case KEY_8:
			case KEY_9:
				maCharBuffer.Append( rKEvt.GetCharCode() );
				break;

			case KEY_PAGEUP:
				if(rKEvt.GetKeyCode().IsMod2())
				{
					gotoPreviousSlide();
					break;
				}
				// warning, fall through!
			case KEY_LEFT:
			case KEY_UP:
			case KEY_P:
			case KEY_BACKSPACE:
				gotoPreviousEffect();
				break;

			case KEY_HOME:
				gotoFirstSlide();
				break;

			case KEY_END:
				gotoLastSlide();
				break;

			case KEY_B:
			case KEY_W:
			case KEY_POINT:
			case KEY_COMMA:
			{
				blankScreen( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? 0x00ffffff : 0x00000000 );
			}
			break;

			default:
				bRet = false;
			break;
		}
	}
	catch( Exception& e )
	{
		bRet = false;
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::keyInput(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}

	return bRet;
}

IMPL_LINK( SlideshowImpl, EventListenerHdl, VclSimpleEvent*, pEvent )
{
	if( !mxShow.is() || mbInputFreeze )
		return 0;

	if( pEvent && (pEvent->GetId() == VCLEVENT_WINDOW_COMMAND) && static_cast<VclWindowEvent*>(pEvent)->GetData() )
	{
		const CommandEvent& rEvent = *(const CommandEvent*)static_cast<VclWindowEvent*>(pEvent)->GetData();

		if( rEvent.GetCommand() == COMMAND_MEDIA )
		{
			switch( rEvent.GetMediaCommand() )
			{
#if defined( QUARTZ )
			case MEDIA_COMMAND_MENU:
				if( !mnContextMenuEvent )
				{
				if( mpShowWindow )
					maPopupMousePos = mpShowWindow->GetPointerState().maPos;
				mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
				}
				break;
			case MEDIA_COMMAND_VOLUME_DOWN:
				gotoPreviousSlide();
				break;
			case MEDIA_COMMAND_VOLUME_UP:
				gotoNextEffect();
				break;
#endif
			case MEDIA_COMMAND_NEXTTRACK:
				gotoNextEffect();
				break;
			case MEDIA_COMMAND_PAUSE:
				if( !mbIsPaused )
					blankScreen(0);
				break;
			case MEDIA_COMMAND_PLAY:
				if( mbIsPaused )
					resume();
				break;

			case MEDIA_COMMAND_PLAY_PAUSE:
				if( mbIsPaused )
					resume();
				else
					blankScreen(0);
				break;
			case MEDIA_COMMAND_PREVIOUSTRACK:
				gotoPreviousSlide();
				break;
			case MEDIA_COMMAND_NEXTTRACK_HOLD:
				gotoLastSlide();
				break;

			case MEDIA_COMMAND_REWIND:
				gotoFirstSlide();
				break;
			case MEDIA_COMMAND_STOP:
				// in case the user cancels the presentation, switch to current slide
				// in edit mode
				if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
				{
					if( mpSlideController->getCurrentSlideNumber() != -1 )
						mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
				}
				endPresentation();
				break;
			}
		}
	}

	return 0;
}

// ---------------------------------------------------------

void SlideshowImpl::mouseButtonUp(const MouseEvent& rMEvt)
{
	if( rMEvt.IsRight() && !mnContextMenuEvent )
	{
		maPopupMousePos = rMEvt.GetPosPixel();
		mnContextMenuEvent = Application::PostUserEvent( LINK( this, SlideshowImpl, ContextMenuHdl ) );
	}
}

// ---------------------------------------------------------

IMPL_LINK( SlideshowImpl, ContextMenuHdl, void*, EMPTYARG )
{
	mnContextMenuEvent = 0;

	if( mpSlideController.get() == 0 )
		return 0;

	mbWasPaused = mbIsPaused;
	if( !mbWasPaused )
		pause();

	PopupMenu* pMenu = new PopupMenu( SdResId( RID_SLIDESHOW_CONTEXTMENU ) );

	// Adding button to display if in Pen  mode
	pMenu->CheckItem( CM_PEN_MODE, mbUsePen);

	const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
	pMenu->EnableItem( CM_NEXT_SLIDE, ( mpSlideController->getNextSlideIndex() != -1 ) );
	pMenu->EnableItem( CM_PREV_SLIDE, ( mpSlideController->getPreviousSlideIndex() != -1 ) || (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) );

	PopupMenu* pPageMenu = pMenu->GetPopupMenu( CM_GOTO );

	SfxViewFrame* pViewFrame = getViewFrame();
	if( pViewFrame )
	{
		Reference< ::com::sun::star::frame::XFrame > xFrame( pViewFrame->GetFrame().GetFrameInterface() );
		if( xFrame.is() )
		{
			pMenu->SetItemImage( CM_NEXT_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10617") ), sal_False, sal_False ) );
			pMenu->SetItemImage( CM_PREV_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10618") ), sal_False, sal_False ) );

			if( pPageMenu )
			{
				pPageMenu->SetItemImage( CM_FIRST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10616") ), sal_False, sal_False ) );
				pPageMenu->SetItemImage( CM_LAST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10619") ), sal_False, sal_False ) );
			}
		}
	}

	// populate slide goto list
	if( pPageMenu )
	{
		const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount();
		if( nPageNumberCount <= 1 )
		{
			pMenu->EnableItem( CM_GOTO, sal_False );
		}
		else
		{
			sal_Int32 nCurrentSlideNumber = mpSlideController->getCurrentSlideNumber();
			if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
				nCurrentSlideNumber = -1;

			pPageMenu->EnableItem( CM_FIRST_SLIDE, ( mpSlideController->getSlideNumber(0) != nCurrentSlideNumber ) );
			pPageMenu->EnableItem( CM_LAST_SLIDE, ( mpSlideController->getSlideNumber( mpSlideController->getSlideIndexCount() - 1) != nCurrentSlideNumber ) );

			sal_Int32 nPageNumber;

			for( nPageNumber = 0; nPageNumber < nPageNumberCount; nPageNumber++ )
			{
				if( mpSlideController->isVisibleSlideNumber( nPageNumber ) )
				{
					SdPage* pPage = mpDoc->GetSdPage((sal_uInt16)nPageNumber, PK_STANDARD);
					if (pPage)
					{
						pPageMenu->InsertItem( (sal_uInt16)(CM_SLIDES + nPageNumber), pPage->GetName() );
						if( nPageNumber == nCurrentSlideNumber )
							pPageMenu->CheckItem( (sal_uInt16)(CM_SLIDES + nPageNumber) );
					}
				}
			}
		}
	}

	if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
	{
		PopupMenu* pBlankMenu = pMenu->GetPopupMenu( CM_SCREEN );
		if( pBlankMenu )
		{
			pBlankMenu->CheckItem( ( mpShowWindow->GetBlankColor() == Color( COL_WHITE ) ) ? CM_SCREEN_WHITE : CM_SCREEN_BLACK  );
		}
	}

	PopupMenu* pWidthMenu = pMenu->GetPopupMenu( CM_WIDTH_PEN);

	// populate color width list
	if( pWidthMenu )
	{
		sal_Int32 nIterator;
		double nWidth;

		nWidth = 4.0;
		for( nIterator = 1; nIterator < 6; nIterator++)
		{
			switch(nIterator)
			{
				case 1:
					nWidth = 4.0;
					break;
				case 2:
					nWidth = 100.0;
					break;
				case 3:
					nWidth = 150.0;
					break;
				case 4:
					nWidth = 200.0;
					break;
				case 5:
					nWidth = 400.0;
					break;
				default:
					break;
			}

			pWidthMenu->EnableItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator), sal_True);
			if( nWidth ==  mdUserPaintStrokeWidth)
				pWidthMenu->CheckItem( (sal_uInt16)(CM_WIDTH_PEN + nIterator) );
		}
	}

	pMenu->SetSelectHdl( LINK( this, SlideshowImpl, ContextMenuSelectHdl ) );
	pMenu->Execute( mpShowWindow, maPopupMousePos );
	delete pMenu;

	if( mxView.is() )
		mxView->ignoreNextMouseReleased();

	if( !mbWasPaused )
		resume();
	return 0;
}

// ---------------------------------------------------------

IMPL_LINK( SlideshowImpl, ContextMenuSelectHdl, Menu *, pMenu )
{
	if( pMenu )
	{
		sal_uInt16 nMenuId = pMenu->GetCurItemId();

		switch( nMenuId )
		{
		case CM_PREV_SLIDE:
			gotoPreviousSlide();
			mbWasPaused = false;
			break;
		case CM_NEXT_SLIDE:
			gotoNextSlide();
			mbWasPaused = false;
			break;
		case CM_FIRST_SLIDE:
			gotoFirstSlide();
			mbWasPaused = false;
			break;
		case CM_LAST_SLIDE:
			gotoLastSlide();
			mbWasPaused = false;
			break;
		case CM_SCREEN_BLACK:
		case CM_SCREEN_WHITE:
		{
			const Color aBlankColor( (nMenuId == CM_SCREEN_WHITE) ? COL_WHITE : COL_BLACK );
			if( mbWasPaused )
			{
				if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_BLANK )
				{
					if( mpShowWindow->GetBlankColor() == aBlankColor )
					{
						mbWasPaused = false;
						mpShowWindow->RestartShow();
						break;
					}
				}
				mpShowWindow->RestartShow();
			}
			if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) )
			{
				pause();
				mbWasPaused = true;
			}
		}
		break;
		case CM_COLOR_PEN:
			{
				// Open a color picker based on SvColorDialog
				::Color aColor( mnUserPaintColor );
				SvColorDialog aColorDlg( mpShowWindow);
				aColorDlg.SetColor( aColor );

				if (aColorDlg.Execute() )
				{
					aColor = aColorDlg.GetColor();
					setPenColor(aColor.GetColor());
				}
				mbWasPaused = false;
			}
			break;

		case CM_WIDTH_PEN_VERY_THIN:
			{
				setPenWidth(4.0);
				mbWasPaused = false;
			}
			break;

		case CM_WIDTH_PEN_THIN:
			{
				setPenWidth(100.0);
				mbWasPaused = false;
			}
			break;

		case CM_WIDTH_PEN_NORMAL:
			{
				setPenWidth(150.0);
				mbWasPaused = false;
			}
			break;

		case CM_WIDTH_PEN_THICK:
			{
				setPenWidth(200.0);
				mbWasPaused = false;
			}
			break;

		case CM_WIDTH_PEN_VERY_THICK:
			{
				setPenWidth(400.0);
				mbWasPaused = false;
			}
			break;
		case CM_ERASE_ALLINK:
			{
				setEraseAllInk(true);
				mbWasPaused = false;
			}
			break;
		case CM_PEN_MODE:
			{
				setUsePen(!mbUsePen);
				mbWasPaused = false;
			}
			break;
		case CM_ENDSHOW:
			// in case the user cancels the presentation, switch to current slide
			// in edit mode
			if( mpSlideController.get() && (ANIMATIONMODE_SHOW == meAnimationMode) )
			{
				if( mpSlideController->getCurrentSlideNumber() != -1 )
				{
					mnRestoreSlide = mpSlideController->getCurrentSlideNumber();
				}
			}
			endPresentation();
			break;
		default:
			sal_Int32 nPageNumber = nMenuId - CM_SLIDES;
			const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
			if( (eMode == SHOWWINDOWMODE_END) || (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
			{
				mpShowWindow->RestartShow( nPageNumber );
			}
			else if( nPageNumber != mpSlideController->getCurrentSlideNumber() )
			{
				displaySlideNumber( nPageNumber );
			}
			mbWasPaused = false;
			break;
		}
	}

	return 0;
}

// ---------------------------------------------------------

Reference< XSlideShow > SlideshowImpl::createSlideShow() const
{
	Reference< XSlideShow > xShow;

	try
	{
		Reference< lang::XMultiServiceFactory > xFactory(
			::comphelper::getProcessServiceFactory(),
			UNO_QUERY_THROW );

		Reference< XInterface > xInt( xFactory->createInstance(
				OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.SlideShow")) ) );

		xShow.set( xInt, UNO_QUERY_THROW );
	}
	catch( uno::Exception& e )
	{
		(void)e;
		DBG_ERROR(
			(OString("sd::SlideshowImpl::createSlideShow(), "
					 "exception caught: ") +
			 rtl::OUStringToOString(
				 comphelper::anyToString( cppu::getCaughtException() ),
				 RTL_TEXTENCODING_UTF8 )).getStr() );
	}

	return xShow;
}

// ---------------------------------------------------------

void SlideshowImpl::createSlideList( bool bAll, bool bStartWithActualSlide, const String& rPresSlide )
{
	const long nSlideCount = mpDoc->GetSdPageCount( PK_STANDARD );

	if( nSlideCount )
	{
		SdCustomShow*	pCustomShow;

		if( !bStartWithActualSlide && mpDoc->GetCustomShowList() && maPresSettings.mbCustomShow )
			pCustomShow = (SdCustomShow*) mpDoc->GetCustomShowList()->GetCurObject();
		else
			pCustomShow = NULL;

		// create animation slide controller
		AnimationSlideController::Mode eMode =
			( pCustomShow && pCustomShow->Count() ) ? AnimationSlideController::CUSTOM :
				(bAll ? AnimationSlideController::ALL : AnimationSlideController::FROM);

		Reference< XDrawPagesSupplier > xDrawPages( mpDoc->getUnoModel(), UNO_QUERY_THROW );
		Reference< XIndexAccess > xSlides( xDrawPages->getDrawPages(), UNO_QUERY_THROW );
		mpSlideController.reset( new AnimationSlideController( xSlides, eMode ) );

		if( eMode != AnimationSlideController::CUSTOM )
		{
			sal_Int32 nFirstSlide = 0;

			// normal presentation
			if( eMode == AnimationSlideController::FROM )
			{
				if( rPresSlide.Len() )
				{
					sal_Int32 nSlide;
					sal_Bool bTakeNextAvailable = sal_False;

					for( nSlide = 0, nFirstSlide = -1; ( nSlide < nSlideCount ) && ( -1 == nFirstSlide ); nSlide++ )
					{
						SdPage* pTestSlide = mpDoc->GetSdPage( (sal_uInt16)nSlide, PK_STANDARD );

						if( pTestSlide->GetName() == rPresSlide )
						{
							if( pTestSlide->IsExcluded() )
								bTakeNextAvailable = sal_True;
							else
								nFirstSlide = nSlide;
						}
						else if( bTakeNextAvailable && !pTestSlide->IsExcluded() )
							nFirstSlide = nSlide;
					}

					if( -1 == nFirstSlide )
						nFirstSlide = 0;
				}
			}

			for( sal_Int32 i = 0; i < nSlideCount; i++ )
			{
				bool bVisible = ( mpDoc->GetSdPage( (sal_uInt16)i, PK_STANDARD ) )->IsExcluded() ? false : true;
				if( bVisible || (eMode == AnimationSlideController::ALL) )
					mpSlideController->insertSlideNumber( i, bVisible );
			}

			mpSlideController->setStartSlideNumber( nFirstSlide );
		}
		else
		{
			if( meAnimationMode != ANIMATIONMODE_SHOW && rPresSlide.Len() )
			{
				sal_Int32 nSlide;
				for( nSlide = 0; nSlide < nSlideCount; nSlide++ )
					if( rPresSlide == mpDoc->GetSdPage( (sal_uInt16) nSlide, PK_STANDARD )->GetName() )
						break;

				if( nSlide < nSlideCount )
					mpSlideController->insertSlideNumber( (sal_uInt16) nSlide );
			}

			void* pCustomSlide;
			sal_Int32 nSlideIndex;
			for( pCustomSlide = pCustomShow->First(),nSlideIndex=0; pCustomSlide; pCustomSlide = pCustomShow->Next(), nSlideIndex++ )
			{
				const sal_uInt16 nSdSlide = ( ( (SdPage*) pCustomSlide )->GetPageNum() - 1 ) / 2;

				if( !( mpDoc->GetSdPage( nSdSlide, PK_STANDARD ) )->IsExcluded())
					mpSlideController->insertSlideNumber( nSdSlide );
			}
		}
	}
}

// ---------------------------------------------------------

typedef sal_uInt16 (*FncGetChildWindowId)();

FncGetChildWindowId aShowChilds[] =
{
	&AnimationChildWindow::GetChildWindowId,
	&Svx3DChildWindow::GetChildWindowId,
	&SvxFontWorkChildWindow::GetChildWindowId,
	&SvxColorChildWindow::GetChildWindowId,
	&SvxSearchDialogWrapper::GetChildWindowId,
	&SvxBmpMaskChildWindow::GetChildWindowId,
	&SvxIMapDlgChildWindow::GetChildWindowId,
	&SvxHyperlinkDlgWrapper::GetChildWindowId,
	&SvxHlinkDlgWrapper::GetChildWindowId,
	&SfxTemplateDialogWrapper::GetChildWindowId,
	&GalleryChildWindow::GetChildWindowId
};

#define NAVIGATOR_CHILD_MASK		0x80000000UL

void SlideshowImpl::hideChildWindows()
{
	mnChildMask = 0UL;

	if( ANIMATIONMODE_SHOW == meAnimationMode )
	{
		SfxViewFrame* pViewFrame = getViewFrame();

		if( pViewFrame )
		{
			if( pViewFrame->GetChildWindow( SID_NAVIGATOR ) != NULL )
				mnChildMask |= NAVIGATOR_CHILD_MASK;

			for( sal_uLong i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
			{
				const sal_uInt16 nId = ( *aShowChilds[ i ] )();

				if( pViewFrame->GetChildWindow( nId ) )
				{
					pViewFrame->SetChildWindow( nId, sal_False );
					mnChildMask |= 1 << i;
				}
			}
		}
	}
}

// ---------------------------------------------------------

void SlideshowImpl::showChildWindows()
{
	if( ANIMATIONMODE_SHOW == meAnimationMode )
	{
		SfxViewFrame* pViewFrame = getViewFrame();
		if( pViewFrame )
		{
			pViewFrame->SetChildWindow( SID_NAVIGATOR, ( mnChildMask & NAVIGATOR_CHILD_MASK ) != 0 );

			for( sal_uLong i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ )
			{
				if( mnChildMask & ( 1 << i ) )
					pViewFrame->SetChildWindow( ( *aShowChilds[ i ] )(), sal_True );
			}
		}
	}
}

// ---------------------------------------------------------

SfxViewFrame* SlideshowImpl::getViewFrame() const
{
	return mpViewShell ? mpViewShell->GetViewFrame() : 0;
}

// ---------------------------------------------------------

SfxDispatcher* SlideshowImpl::getDispatcher() const
{
	return (mpViewShell && mpViewShell->GetViewFrame()) ? mpViewShell->GetViewFrame()->GetDispatcher() : 0;
}

// ---------------------------------------------------------

SfxBindings* SlideshowImpl::getBindings() const
{
	return (mpViewShell && mpViewShell->GetViewFrame()) ? &mpViewShell->GetViewFrame()->GetBindings() : 0;
}

// ---------------------------------------------------------

void SlideshowImpl::resize( const Size& rSize )
{
	maPresSize = rSize;

	if( mpShowWindow && (ANIMATIONMODE_VIEW != meAnimationMode) )
	{
		mpShowWindow->SetSizePixel( maPresSize );
		mpShowWindow->Show();

		// Call ToTop() to bring the window to top if
		// a) the old size is not degenerate (then the window will be closed
		// soon) and
		// b) the animation mode is not that of a preview (on the one hand
		// this leaves the old behavior for the slide show mode unmodified
		// and on the other hand does not move the focus from the document
		// to the (preview) window; the ToTop() seems not to be necessary at
		// least for the preview).
//		if( !aOldSize.Width() && !aOldSize.Height() )
//			mpShowWindow->ToTop();
	}

	if( mxView.is() ) try
	{
		awt::WindowEvent aEvt;
		mxView->windowResized(aEvt);
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::resize(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// -----------------------------------------------------------------------------

void SlideshowImpl::setActiveXToolbarsVisible( sal_Bool bVisible )
{
	// in case of ActiveX control the toolbars should not be visible if slide show runs in window mode
	// actually it runs always in window mode in case of ActiveX control
	if ( !maPresSettings.mbFullScreen && mpDocSh && mpDocSh->GetMedium() )
	{
		SFX_ITEMSET_ARG( mpDocSh->GetMedium()->GetItemSet(), pItem, SfxBoolItem, SID_VIEWONLY, sal_False );
		if ( pItem && pItem->GetValue() )
		{
			// this is a plugin/activex mode, no toolbars should be visible during slide show
			// after the end of slide show they should be visible again
			SfxViewFrame* pViewFrame = getViewFrame();
			if( pViewFrame )
			{
				try
				{
					Reference< frame::XLayoutManager > xLayoutManager;
					Reference< beans::XPropertySet > xFrameProps( pViewFrame->GetFrame().GetTopFrame().GetFrameInterface(), UNO_QUERY_THROW );
					if ( ( xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) )
								>>= xLayoutManager )
					  && xLayoutManager.is() )
					{
						xLayoutManager->setVisible( bVisible );
					}
				}
				catch( uno::Exception& )
				{}
			}
		}
	}
}

// -----------------------------------------------------------------------------

void SAL_CALL SlideshowImpl::activate() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	maDeactivateTimer.Stop();

	if( !mbActive && mxShow.is() )
	{
		mbActive = sal_True;

		if( ANIMATIONMODE_SHOW == meAnimationMode )
		{
			if( mbAutoSaveWasOn )
				setAutoSaveState( false );

			if( mpShowWindow )
			{
				SfxViewFrame* pViewFrame = getViewFrame();
				SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : 0;

				hideChildWindows();

				if( pDispatcher )
				{
					// filter all forbidden slots
					pDispatcher->SetSlotFilter( sal_True, sizeof(pAllowed) / sizeof(sal_uInt16), pAllowed );
				}

				if( getBindings() )
					getBindings()->InvalidateAll(sal_True);

				mpShowWindow->GrabFocus();
			}
		}

		resume();
	}
}

// -----------------------------------------------------------------------------

void SAL_CALL SlideshowImpl::deactivate() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mbActive && mxShow.is() )
	{
		maDeactivateTimer.Start();
	}
}

// -----------------------------------------------------------------------------

IMPL_LINK( SlideshowImpl, deactivateHdl, Timer*, EMPTYARG )
{
	if( mbActive && mxShow.is() )
	{
		mbActive = sal_False;

		pause();

		if( ANIMATIONMODE_SHOW == meAnimationMode )
		{
			if( mbAutoSaveWasOn )
				setAutoSaveState( true );

			if( mpShowWindow )
			{
				showChildWindows();
			}
		}
	}
	return 0;
}

// ---------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::isActive() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return mbActive;
}

// -----------------------------------------------------------------------------

void SlideshowImpl::receiveRequest(SfxRequest& rReq)
{
	const SfxItemSet* pArgs 	 = rReq.GetArgs();

	switch ( rReq.GetSlot() )
	{
		case SID_NAVIGATOR_PEN:
			setUsePen(!mbUsePen);
		break;

		case SID_NAVIGATOR_PAGE:
		{
			PageJump	eJump = (PageJump)((SfxAllEnumItem&) pArgs->Get(SID_NAVIGATOR_PAGE)).GetValue();
			switch( eJump )
			{
				case PAGE_FIRST:		gotoFirstSlide(); break;
				case PAGE_LAST:			gotoLastSlide(); break;
				case PAGE_NEXT:			gotoNextSlide(); break;
				case PAGE_PREVIOUS:		gotoPreviousSlide(); break;
				case PAGE_NONE:			break;
			}
		}
		break;

		case SID_NAVIGATOR_OBJECT:
		{
			const String aTarget( ((SfxStringItem&) pArgs->Get(SID_NAVIGATOR_OBJECT)).GetValue() );

			// is the bookmark a Slide?
			sal_Bool		bIsMasterPage;
			sal_uInt16		nPgNum = mpDoc->GetPageByName( aTarget, bIsMasterPage );
			SdrObject*  pObj   = NULL;

			if( nPgNum == SDRPAGE_NOTFOUND )
			{
				// is the bookmark an object?
				pObj = mpDoc->GetObj( aTarget );

				if( pObj )
					nPgNum = pObj->GetPage()->GetPageNum();
			}

			if( nPgNum != SDRPAGE_NOTFOUND )
			{
				nPgNum = ( nPgNum - 1 ) >> 1;
				displaySlideNumber( nPgNum );
			}
		}
		break;
	}
}

// ---------------------------------------------------------

void SlideshowImpl::setAutoSaveState( bool bOn)
{
	try
	{
		uno::Reference<lang::XMultiServiceFactory> xFac( ::comphelper::getProcessServiceFactory() );

		uno::Reference< util::XURLTransformer > xParser(
			xFac->createInstance( OUString::createFromAscii("com.sun.star.util.URLTransformer" ) ),
				uno::UNO_QUERY_THROW);
		util::URL aURL;
		aURL.Complete = OUString::createFromAscii("vnd.sun.star.autorecovery:/setAutoSaveState");
		xParser->parseStrict(aURL);

		Sequence< beans::PropertyValue > aArgs(1);
		aArgs[0].Name = OUString::createFromAscii("AutoSaveState");
		aArgs[0].Value <<= bOn ? sal_True : sal_False;

		uno::Reference< frame::XDispatch > xAutoSave(
			xFac->createInstance(OUString::createFromAscii("com.sun.star.frame.AutoRecovery")),
			uno::UNO_QUERY_THROW);
		xAutoSave->dispatch(aURL, aArgs);
	}
	catch( Exception& )
	{
		DBG_ERROR("sd::SlideshowImpl::setAutoSaveState(), exception caught!");
	}
}

// ---------------------------------------------------------

Reference< XDrawPage > SAL_CALL SlideshowImpl::getCurrentSlide() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	Reference< XDrawPage > xSlide;
	if( mxShow.is() && mpSlideController.get() )
	{
		sal_Int32 nSlide = getCurrentSlideNumber();
		if( (nSlide >= 0) && (nSlide < mpSlideController->getSlideNumberCount() ) )
			xSlide = mpSlideController->getSlideByNumber( nSlide );
	}

	return xSlide;
}

// ---------------------------------------------------------

sal_Int32 SAL_CALL SlideshowImpl::getNextSlideIndex() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mxShow.is() )
	{
		return mpSlideController->getNextSlideIndex();
	}
	else
	{
		return -1;
	}
}

// ---------------------------------------------------------

sal_Int32 SAL_CALL SlideshowImpl::getCurrentSlideIndex() throw (RuntimeException)
{
	return mpSlideController.get() ? mpSlideController->getCurrentSlideIndex() : -1;
}

// --------------------------------------------------------------------
// ::com::sun::star::presentation::XSlideShowController:
// --------------------------------------------------------------------

::sal_Int32 SAL_CALL SlideshowImpl::getSlideCount() throw (RuntimeException)
{
	return mpSlideController.get() ? mpSlideController->getSlideIndexCount() : 0;
}

// --------------------------------------------------------------------

Reference< XDrawPage > SAL_CALL SlideshowImpl::getSlideByIndex(::sal_Int32 Index) throw (RuntimeException, css::lang::IndexOutOfBoundsException)
{
	if( (mpSlideController.get() == 0 ) || (Index < 0) || (Index >= mpSlideController->getSlideIndexCount() ) )
		throw IndexOutOfBoundsException();

	return mpSlideController->getSlideByNumber( mpSlideController->getSlideNumber( Index ) );
}

sal_Bool SAL_CALL SlideshowImpl::getAlwaysOnTop() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return maPresSettings.mbAlwaysOnTop;
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setAlwaysOnTop( sal_Bool bAlways ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	if( maPresSettings.mbAlwaysOnTop != bAlways )
	{
		maPresSettings.mbAlwaysOnTop = bAlways;
		// todo, can this be changed while running?
	}
}

// --------------------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::isFullScreen() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return maPresSettings.mbFullScreen;
}

// --------------------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::getMouseVisible() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return maPresSettings.mbMouseVisible;
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setMouseVisible( sal_Bool bVisible ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	if( maPresSettings.mbMouseVisible != bVisible )
	{
		maPresSettings.mbMouseVisible = bVisible;
		if( mpShowWindow )
			mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible );
	}
}

// --------------------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::getUsePen() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return mbUsePen;
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setUsePen( sal_Bool bMouseAsPen ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	mbUsePen = bMouseAsPen;
	if( mxShow.is() ) try
	{
		// For Pencolor;
		Any aValue;
		if( mbUsePen )
			aValue <<= mnUserPaintColor;
		beans::PropertyValue aPenProp;
		aPenProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintColor" ));
		aPenProp.Value = aValue;
		mxShow->setProperty( aPenProp );

		//for StrokeWidth :
		if( mbUsePen )
		{
			beans::PropertyValue aPenPropWidth;
			aPenPropWidth.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintStrokeWidth" ));
			aPenPropWidth.Value <<= mdUserPaintStrokeWidth;
			mxShow->setProperty( aPenPropWidth );

			// for Pen Mode
			beans::PropertyValue aPenPropSwitchPenMode;
			aPenPropSwitchPenMode.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SwitchPenMode" ));
			aPenPropSwitchPenMode.Value <<= sal_True;
			mxShow->setProperty( aPenPropSwitchPenMode );
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::setUsePen(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// --------------------------------------------------------------------

double SAL_CALL SlideshowImpl::getPenWidth() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return mdUserPaintStrokeWidth;
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setPenWidth( double dStrokeWidth ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	mdUserPaintStrokeWidth = dStrokeWidth;
	setUsePen( true ); // enable pen mode, update color and width
}

// --------------------------------------------------------------------

sal_Int32 SAL_CALL SlideshowImpl::getPenColor() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return mnUserPaintColor;
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setPenColor( sal_Int32 nColor ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	mnUserPaintColor = nColor;
	setUsePen( true ); // enable pen mode, update color
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setUseEraser( ::sal_Bool /*_usepen*/ ) throw (css::uno::RuntimeException)
{
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setPenMode( bool bSwitchPenMode ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	setUsePen( bSwitchPenMode ); // SwitchPen Mode

}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::setEraseAllInk(bool bEraseAllInk) throw (RuntimeException)
{
	if( bEraseAllInk )
	{
 		::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
		if( mxShow.is() ) try
		{
			beans::PropertyValue aPenPropEraseAllInk;
			aPenPropEraseAllInk.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "EraseAllInk" ));
			aPenPropEraseAllInk.Value <<= bEraseAllInk;
			mxShow->setProperty( aPenPropEraseAllInk );
		}
		catch( Exception& e )
		{
			static_cast<void>(e);
			DBG_ERROR(
				(OString("sd::SlideshowImpl::setEraseAllInk(), "
						"exception caught: ") +
				rtl::OUStringToOString(
					comphelper::anyToString( cppu::getCaughtException() ),
					RTL_TEXTENCODING_UTF8 )).getStr() );
		}
	}
}

void SAL_CALL SlideshowImpl::setEraseInk( sal_Int32 /*nEraseInkSize*/ ) throw (css::uno::RuntimeException)
{
}

void SAL_CALL SlideshowImpl::setEraserMode( bool /*bSwitchEraserMode*/ ) throw (css::uno::RuntimeException)
{
}

// --------------------------------------------------------------------
// XSlideShowController Methods
// --------------------------------------------------------------------

sal_Bool SAL_CALL SlideshowImpl::isRunning(  ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	return mxShow.is();
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoNextEffect(  ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mxShow.is() && mpSlideController.get() && mpShowWindow )
	{
		if( mbIsPaused )
			resume();

		const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
		if( eMode == SHOWWINDOWMODE_END )
		{
			endPresentation();
		}
		else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
		{
			mpShowWindow->RestartShow();
		}
		else
		{
			mxShow->nextEffect();
			update();
		}
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoPreviousEffect(  ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mxShow.is() && mpSlideController.get() && mpShowWindow )
	{
		if( mbIsPaused )
			resume();

		const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
		if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
		{
			mpShowWindow->RestartShow();
		}
		else
		{
			mxShow->previousEffect();
			update();
		}
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoFirstSlide(  ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mpShowWindow && mpSlideController.get() )
	{
		if( mbIsPaused )
			resume();

		if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
		{
			if( mpSlideController->getSlideIndexCount() )
				mpShowWindow->RestartShow( 0);
		}
		else
		{
			displaySlideIndex( 0 );
		}
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoNextSlide(  ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mbIsPaused )
		resume();

	const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
	if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
	{
		mpShowWindow->RestartShow();
	}
	else
	{
		// if this is a show, ignore user inputs and
		// start 20ms timer to reenable inputs to fiter
		// buffered inputs during slide transition
		if( meAnimationMode == ANIMATIONMODE_SHOW )
		{
			mbInputFreeze = true;
			maInputFreezeTimer.Start();
		}

		if( mpSlideController.get() )
		{
			if( mpSlideController->nextSlide() )
			{
				displayCurrentSlide();
			}
			else
			{
				stopSound();

				if( meAnimationMode == ANIMATIONMODE_PREVIEW )
				{
					endPresentation();
				}
				else if( maPresSettings.mbEndless )
				{
					if( maPresSettings.mnPauseTimeout )
					{
						if( mpShowWindow )
						{
							if ( maPresSettings.mbShowPauseLogo )
							{
								Graphic aGraphic;
								Image aImage;
								bool bLoad = vcl::ImageRepository::loadBrandingImage(
									rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "logo" ) ),
									aImage );
								OSL_ENSURE( bLoad, "Can't load logo image");
								if ( bLoad )
									aGraphic = Graphic(aImage.GetBitmapEx());
								mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout, &aGraphic );
							}
							else
								mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout );
						}
					}
					else
					{
						displaySlideIndex( 0 );
					}
				}
				else
				{
					if( mpShowWindow )
					{
						mpShowWindow->SetEndMode();
						pause();
					}
				}
			}
		}
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoPreviousSlide(  ) throw (RuntimeException)
{
	gotoPreviousSlide(false);
}

void SlideshowImpl::gotoPreviousSlide (const bool bSkipAllMainSequenceEffects)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mxShow.is() && mpSlideController.get() ) try
	{
		if( mbIsPaused )
			resume();

		const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode();
		if( eMode == SHOWWINDOWMODE_END )
		{
			const sal_Int32 nLastSlideIndex = mpSlideController->getCurrentSlideIndex();
			if( nLastSlideIndex >= 0 )
				mpShowWindow->RestartShow( nLastSlideIndex );
		}
		else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) )
		{
			mpShowWindow->RestartShow();
		}
		else
		{
			if( mpSlideController->previousSlide())
				displayCurrentSlide(bSkipAllMainSequenceEffects);
			else if (bSkipAllMainSequenceEffects)
			{
				// We could not go to the previous slide (probably because
				// the current slide is already the first one).  We still
				// have to call displayCurrentSlide because the calling
				// slideshow can not determine whether there is a previous
				// slide or not and has already prepared for a slide change.
				// This slide change has to be completed now, even when
				// changing to the same slide.
				// Note that in this special case we do NOT pass
				// bSkipAllMainSequenceEffects because we display the same
				// slide as before and do not want to show all its effects.
				displayCurrentSlide(false);
			}
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::gotoPreviousSlide(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoLastSlide() throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mpSlideController.get() )
	{
		if( mbIsPaused )
			resume();

		const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1;
		if( nLastSlideIndex >= 0 )
		{
			if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END )
			{
				mpShowWindow->RestartShow( nLastSlideIndex );
			}
			else
			{
				displaySlideIndex( nLastSlideIndex );
			}
		}
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoBookmark( const OUString& rBookmark ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mbIsPaused )
		resume();

	sal_Int32 nSlideNumber = getSlideNumberForBookmark( rBookmark );
	if( nSlideNumber != -1 )
		displaySlideNumber( nSlideNumber );
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoSlide( const Reference< XDrawPage >& xSlide )
	throw(IllegalArgumentException, RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mpSlideController.get() && xSlide.is() )
	{
		if( mbIsPaused )
			resume();

		const sal_Int32 nSlideCount = mpSlideController->getSlideNumberCount();
		for( sal_Int32 nSlide = 0; nSlide < nSlideCount; nSlide++ )
		{
			if( mpSlideController->getSlideByNumber( nSlide ) == xSlide )
			{
				displaySlideNumber( nSlide );
			}
		}
	}
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::gotoSlideIndex( sal_Int32 nIndex ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	if( mbIsPaused )
		resume();

	displaySlideIndex( nIndex );
}

// --------------------------------------------------------------------

void SAL_CALL SlideshowImpl::stopSound(  ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	try
	{
		if( mxPlayer.is() )
		{
			mxPlayer->stop();
			mxPlayer.clear();
		}
	}
	catch( Exception& e )
	{
		static_cast<void>(e);
		DBG_ERROR(
			(OString("sd::SlideshowImpl::stopSound(), "
					"exception caught: ") +
			rtl::OUStringToOString(
				comphelper::anyToString( cppu::getCaughtException() ),
				RTL_TEXTENCODING_UTF8 )).getStr() );
	}
}

// --------------------------------------------------------------------
// XIndexAccess
// --------------------------------------------------------------------

::sal_Int32 SAL_CALL SlideshowImpl::getCount(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return getSlideCount();
}

// --------------------------------------------------------------------

::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)
{
	return Any( getSlideByIndex( Index ) );
}

// --------------------------------------------------------------------

::com::sun::star::uno::Type SAL_CALL SlideshowImpl::getElementType(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return XDrawPage::static_type();
}

// --------------------------------------------------------------------

::sal_Bool SAL_CALL SlideshowImpl::hasElements(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return getSlideCount() != 0;
}

// --------------------------------------------------------------------

Reference< XSlideShow > SAL_CALL SlideshowImpl::getSlideShow() throw (RuntimeException)
{
	return mxShow;
}

// --------------------------------------------------------------------


PresentationSettingsEx::PresentationSettingsEx( const PresentationSettingsEx& r )
: PresentationSettings( r )
, mbRehearseTimings(r.mbRehearseTimings)
, mbPreview(r.mbPreview)
, mpParentWindow( 0 )
{
}

PresentationSettingsEx::PresentationSettingsEx( PresentationSettings& r )
: PresentationSettings( r )
, mbRehearseTimings(sal_False)
, mbPreview(sal_False)
, mpParentWindow(0)
{
}

void PresentationSettingsEx::SetArguments( const Sequence< PropertyValue >& rArguments ) throw (IllegalArgumentException)
{
	sal_Int32 nArguments = rArguments.getLength();
	const PropertyValue* pValue = rArguments.getConstArray();

	while( nArguments-- )
	{
		SetPropertyValue( pValue->Name, pValue->Value );
		pValue++;
	}
}

void PresentationSettingsEx::SetPropertyValue( const OUString& rProperty, const Any& rValue ) throw (IllegalArgumentException)
{
	if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("RehearseTimings") ) )
	{
		if( rValue >>= mbRehearseTimings )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Preview") ) )
	{
		if( rValue >>= mbPreview )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AnimationNode") ) )
	{
		if( rValue >>= mxAnimationNode )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ) )
	{
		Reference< XWindow > xWindow;
		if( rValue >>= xWindow )
		{
			mpParentWindow = xWindow.is() ? VCLUnoHelper::GetWindow( xWindow ) : 0;
			return;
		}
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AllowAnimations") ) )
	{
		if( rValue >>= mbAnimationAllowed )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("AllowAnimations") ) )
	{
		if( rValue >>= mbAnimationAllowed )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("FirstPage") ) )
	{
		OUString aPresPage;
		if( rValue >>= aPresPage )
		{
			maPresPage = getUiNameFromPageApiNameImpl(aPresPage);
			mbCustomShow = sal_False;
			mbAll = sal_False;
			return;
		}
		else
		{
			if( rValue >>= mxStartPage )
				return;
		}
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsAlwaysOnTop") ) )
	{
		if( rValue >>= mbAlwaysOnTop )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsAutomatic") ) )
	{
		if( rValue >>= mbManual )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsEndless") ) )
	{
		if( rValue >>= mbEndless )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsFullScreen") ) )
	{
		if( rValue >>= mbFullScreen )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("IsMouseVisible") ) )
	{
		if( rValue >>= mbMouseVisible )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Pause") ) )
	{
		sal_Int32 nPause = -1;
		if( (rValue >>= nPause) && (nPause >= 0) )
		{
			mnPauseTimeout = nPause;
			return;
		}
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("StartWithNavigator") ) )
	{
		if( rValue >>= mbStartWithNavigator )
			return;
	}
	else if( rProperty.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UsePen") ) )
	{
		if( rValue >>= mbMouseAsPen )
			return;
	}
	throw IllegalArgumentException();
}

// ---------------------------------------------------------
// XAnimationListener
// ---------------------------------------------------------

SlideShowListenerProxy::SlideShowListenerProxy( const rtl::Reference< SlideshowImpl >& xController, const css::uno::Reference< css::presentation::XSlideShow >& xSlideShow )
: maListeners( m_aMutex )
, mxController( xController )
, mxSlideShow( xSlideShow )
{
}

// ---------------------------------------------------------

SlideShowListenerProxy::~SlideShowListenerProxy()
{
}

// ---------------------------------------------------------

void SlideShowListenerProxy::addAsSlideShowListener()
{
	if( mxSlideShow.is() )
	{
		Reference< XSlideShowListener > xSlideShowListener( this );
		mxSlideShow->addSlideShowListener( xSlideShowListener );
	}
}

// ---------------------------------------------------------

void SlideShowListenerProxy::removeAsSlideShowListener()
{
	if( mxSlideShow.is() )
	{
		Reference< XSlideShowListener > xSlideShowListener( this );
		mxSlideShow->removeSlideShowListener( xSlideShowListener );
	}
}

// ---------------------------------------------------------

void SlideShowListenerProxy::addShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
{
	if( mxSlideShow.is() )
	{
		Reference< XShapeEventListener > xListener( this );
		mxSlideShow->addShapeEventListener( xListener, xShape );
	}
}

// ---------------------------------------------------------

void SlideShowListenerProxy::removeShapeEventListener( const css::uno::Reference< css::drawing::XShape >& xShape )
{
	if( mxSlideShow.is() )
	{
		Reference< XShapeEventListener > xListener( this );
		mxSlideShow->removeShapeEventListener( xListener, xShape );
	}
}

// ---------------------------------------------------------

void SlideShowListenerProxy::addSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
{
	maListeners.addInterface(xListener);
}

// ---------------------------------------------------------

void SlideShowListenerProxy::removeSlideShowListener( const css::uno::Reference< css::presentation::XSlideShowListener >& xListener )
{
	maListeners.removeInterface(xListener);
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::beginEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::beginEvent, _1,  boost::cref(xNode) ));
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::endEvent( const Reference< XAnimationNode >& xNode ) throw (RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::endEvent, _1, boost::cref(xNode) ));
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::repeat( const Reference< XAnimationNode >& xNode, ::sal_Int32 nRepeat ) throw (RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::bind( &XAnimationListener::repeat, _1,  boost::cref(xNode), boost::cref(nRepeat) ));
}

// ---------------------------------------------------------
// ::com::sun::star::presentation::XSlideShowListener:
// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::paused(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::paused ) );
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::resumed(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::resumed ) );
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::slideTransitionStarted( ) throw (RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionStarted ) );
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::slideTransitionEnded( ) throw (::com::sun::star::uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideTransitionEnded ) );
}

// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::slideAnimationsEnded(  ) throw (::com::sun::star::uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if( maListeners.getLength() >= 0 )
		maListeners.forEach<XSlideShowListener>( boost::mem_fn( &XSlideShowListener::slideAnimationsEnded ) );
}

// ---------------------------------------------------------

void SlideShowListenerProxy::slideEnded(sal_Bool bReverse) throw (RuntimeException)
{
	{
		::osl::MutexGuard aGuard( m_aMutex );

		if( maListeners.getLength() >= 0 )
			maListeners.forEach<XSlideShowListener>(
				boost::bind( &XSlideShowListener::slideEnded, _1, bReverse) );
	}

	{
		::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
		if( mxController.is() )
			mxController->slideEnded(bReverse);
	}
}

// ---------------------------------------------------------

void SlideShowListenerProxy::hyperLinkClicked( rtl::OUString const& aHyperLink ) throw (RuntimeException)
{
	{
		::osl::MutexGuard aGuard( m_aMutex );

		if( maListeners.getLength() >= 0 )
			maListeners.forEach<XSlideShowListener>( boost::bind( &XSlideShowListener::hyperLinkClicked, _1, boost::cref(aHyperLink) ));
	}

	{
		::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
		if( mxController.is() )
			mxController->hyperLinkClicked(aHyperLink);
	}
}

// ---------------------------------------------------------
// XEventListener
// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::disposing( const ::com::sun::star::lang::EventObject& aDisposeEvent ) throw (RuntimeException)
{
	maListeners.disposeAndClear( aDisposeEvent );
	mxController.clear();
	mxSlideShow.clear();
}

// ---------------------------------------------------------
// XShapeEventListener
// ---------------------------------------------------------

void SAL_CALL SlideShowListenerProxy::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& aOriginalEvent ) throw (RuntimeException)
{
	::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	if( mxController.is() )
		mxController->click(xShape, aOriginalEvent );
}

} // namespace ::sd

/* vim: set noet sw=4 ts=4: */
