/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: slideshowimpl.cxx,v $ * * $Revision: 1.51 $ * * last change: $Author: obo $ $Date: 2008-02-25 15:51:01 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sd.hxx" #include <boost/scoped_ptr.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/XPropertySet.hpp> #include <com/sun/star/beans/XPropertySetInfo.hpp> #include <com/sun/star/awt/SystemPointer.hpp> #include <com/sun/star/util/XURLTransformer.hpp> #include <com/sun/star/frame/XDispatch.hpp> #ifndef _VOS_PROCESS_HXX_ #include <vos/process.hxx> #endif #ifndef _AEITEM_HXX #include <svtools/aeitem.hxx> #endif #ifndef SVTOOLS_URIHELPER_HXX #include <svtools/urihelper.hxx> #endif #include <sfx2/imagemgr.hxx> #ifndef _SFXREQUEST_HXX #include <sfx2/request.hxx> #endif #include "sfx2/docfile.hxx" #ifndef _SVX_UNOAPI_HXX_ #include <svx/unoapi.hxx> #endif #ifndef _SVDOOLE2_HXX #include <svx/svdoole2.hxx> #endif // for child window ids #include <sfx2/templdlg.hxx> #include <svx/f3dchild.hxx> #include <svx/imapdlg.hxx> #include <svx/fontwork.hxx> #include <svx/colrctrl.hxx> #include <svx/bmpmask.hxx> #include <svx/srchdlg.hxx> #include <svx/hyprlink.hxx> #include <svx/hyperdlg.hxx> #include <svx/galbrws.hxx> #ifndef SD_NAVIGATOR_CHILD_WINDOW_HXX #include "NavigatorChildWindow.hxx" #endif #ifndef SD_ANIMATION_CHILD_WINDOW_HXX #include "AnimationChildWindow.hxx" #endif #ifndef _SD_SLIDESHOWIMPL_HXX_ #include <slideshowimpl.hxx> #endif #ifndef _SD_SLIDESHOWVIEWIMPL_HXX_ #include <slideshowviewimpl.hxx> #endif #ifndef _SD_PGJUMP_HXX #include <pgjump.hxx> #endif #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" // TODO(Q3): This breaks encapsulation. Either export // these strings from avmedia, or provide an XManager // factory there #ifdef WNT # define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_DirectX" #elif defined QUARTZ # define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_QuickTime" #else # define AVMEDIA_MANAGER_SERVICE_NAME "com.sun.star.media.Manager_Java" #endif using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::XInterface; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::RuntimeException; using ::com::sun::star::lang::XComponent; using ::com::sun::star::lang::EventObject; using ::com::sun::star::lang::XInitialization; using ::com::sun::star::uno::Exception; using ::com::sun::star::document::XEventsSupplier; using ::com::sun::star::container::XNameReplace; using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::beans::XPropertySetInfo; using ::com::sun::star::animations::XAnimationNode; using ::rtl::OUString; using ::rtl::OString; using ::comphelper::ImplementationReference; using namespace ::com::sun::star; using namespace ::com::sun::star; using namespace ::com::sun::star::presentation; using namespace ::com::sun::star::drawing; extern String getUiNameFromPageApiNameImpl( const ::rtl::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 USHORT __READONLY_DATA pAllowed[] = { SID_OPENDOC , // 5501 // damit interne Spruenge klappen SID_JUMPTOMARK , // 5598 // SID_SHOWPOPUPS , // 5929 // SID_GALLERY , // 5960 // 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 ) { mnStartSlideNumber = 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 ); sal_Int32 getNextSlideIndex() const; sal_Int32 getPreviousSlideIndex() const; bool isVisibleSlideNumber( sal_Int32 nSlideNumber ) const; bool hasSlides() const { return !maSlideNumbers.empty(); } private: sal_Int32 getNextSlideNumber() const; 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; }; 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(); } 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 sal_Int32 nCurrentSlideNumber = getCurrentSlideNumber(); if( xShow.is() && (nCurrentSlideNumber != -1 ) ) { ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aProperties; Reference< XDrawPage > xSlide; Reference< XAnimationNode > xAnimNode; const sal_Int32 nNextSlideNumber = getNextSlideNumber(); if( getSlideAPI( nNextSlideNumber, xSlide, xAnimNode ) ) { Sequence< Any > aValue(2); aValue[0] <<= xSlide; aValue[1] <<= xAnimNode; aProperties.realloc(1); aProperties[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Prefetch" ) ); aProperties[0].Value <<= aValue; } if( getSlideAPI( nCurrentSlideNumber, xSlide, xAnimNode ) ) xShow->displaySlide( xSlide, xAnimNode, aProperties ); } } /////////////////////////////////////////////////////////////////////// // class SlideshowImpl /////////////////////////////////////////////////////////////////////// SlideshowImpl::SlideshowImpl( ViewShell* pViewSh, ::sd::View* pView, SdDrawDocument* pDoc, ::Window* pParentWindow ) : SlideshowImpl_base( 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), maPresSettings( pDoc->getPresentationSettings() ), 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) { if( mpViewShell ) mpOldActiveWindow = mpViewShell->GetActiveWindow(); maUpdateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, updateHdl)); maInputFreezeTimer.SetTimeoutHdl( LINK( this, SlideshowImpl, ReadyForNextInputHdl ) ); maInputFreezeTimer.SetTimeout( 20 ); SvtSaveOptions aOptions; // no autosave during show if( aOptions.IsAutoSave() ) mbAutoSaveWasOn = true; } SlideshowImpl::~SlideshowImpl() { if( mbAutoSaveWasOn ) setAutoSaveState( true ); if( mnEndShowEvent ) Application::RemoveUserEvent( mnEndShowEvent ); if( mnContextMenuEvent ) Application::RemoveUserEvent( mnContextMenuEvent ); maInputFreezeTimer.Stop(); stopShow(); } 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( ((pParent == 0) && mpViewShell) ? mpParentWindow : pParent ); if( mpViewShell ) { mpViewShell->SetActiveWindow( mpShowWindow ); mpShowWindow->SetViewShell (mpViewShell); mpViewShell->ShowUIControls (false); } if( mpView ) { mpView->AddWindowToPaintView( mpShowWindow ); mpView->SetAnimationPause( 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 = ::rtl::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( PresentationSettings* 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; // --- 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 USHORT 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( (USHORT) 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( mpParentWindow ); mpShowWindow->SetMouseAutoHide( !maPresSettings.mbMouseVisible ); if( mpViewShell ) { mpViewShell->SetActiveWindow( mpShowWindow ); mpShowWindow->SetViewShell (mpViewShell); mpViewShell->GetViewShellBase().ShowUIControls (false); mpPaneHider.reset(new PaneHider(*mpViewShell)); if( getViewFrame() ) getViewFrame()->SetChildWindow( SID_NAVIGATOR, maPresSettings.mbStartWithNavigator ); } // these Slots are forbiden in other views for this document if( mpDocSh ) { mpDocSh->SetSlotFilter( TRUE, sizeof( pAllowed ) / sizeof( USHORT ), 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( TRUE ); } SfxBindings* pBindings = getBindings(); if( pBindings ) { pBindings->Invalidate( SID_PRESENTATION ); pBindings->Invalidate( SID_REHEARSE_TIMINGS ); } 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( maPresSettings.mbMouseAsPen ) { aProperties.push_back( beans::PropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("UserPaintColor") ), -1, Any( static_cast<sal_Int32>(0x0000FF00L) ), 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() ) ); } } catch( Exception& e ) { (void)e; DBG_ERROR( (OString("sd::SlideshowImpl::startShow(), " "exception caught: ") + rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() ); stopShow(); 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() ); mxShow->addSlideShowListener( Reference< XSlideShowListener >( this ) ); 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() ); stopShow(); return false; } } void SlideshowImpl::stopShow() { if( !mxShow.is() ) return; maUpdateTimer.Stop(); if( mnUpdateEvent ) { Application::RemoveUserEvent( mnUpdateEvent ); mnUpdateEvent = 0; } removeShapeEvents(); try { mxShow->removeSlideShowListener( Reference< XSlideShowListener >(this) ); if( mxView.is() ) mxShow->removeView( mxView.getRef() ); Reference< XComponent > xComponent( mxShow, UNO_QUERY ); if( xComponent.is() ) { xComponent->dispose(); xComponent.clear(); } mxShow.clear(); if( mxView.is() ) { mxView->dispose(); mxView.reset(); } } catch( Exception& e ) { static_cast<void>(e); DBG_ERROR( (OString("sd::SlideshowImpl::stopShow(), " "exception caught: ") + rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() ); mxShow.clear(); mxView.reset(); } /* if( mpShowWindow ) { if(maPresSettings.mbMouseAsPen) mpShowWindow->SetPointer( maOldPointer ); mpShowWindow->ShowPointer( TRUE ); } */ mpSlideController.reset(); // der DrawView das Praesentationfenster wegnehmen und ihr dafuer ihre alten Fenster wiedergeben if( mpShowWindow && mpView ) mpView->DeleteWindowFromPaintView( mpShowWindow ); if( mpView ) mpView->SetAnimationPause( 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(); delete mpShowWindow; mpShowWindow = 0; } if ( mpViewShell ) { if( meAnimationMode == ANIMATIONMODE_SHOW ) { // switch to the previously visible Slide static_cast<DrawViewShell*>(mpViewShell)->SwitchPage( (USHORT)mnRestoreSlide ); // invalidate the view shell so the presentation slot will be re-enabled // and the rehersing will be updated mpViewShell->Invalidate(); ::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( FALSE ); getDispatcher()->Execute( SID_CUSTOMSHOW_DLG, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD ); } mpViewShell->GetViewShellBase().UpdateBorder(true); } } /** 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( (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 SlideshowImpl::slideEnded() throw (uno::RuntimeException) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); gotoNextSlide(); } void SlideshowImpl::removeShapeEvents() { try { Reference< XShapeEventListener > xListener( this ); WrappedShapeEventImplMap::iterator aIter; const WrappedShapeEventImplMap::iterator aEnd( maShapeEventMap.end() ); for( aIter = maShapeEventMap.begin(); aIter != aEnd; aIter++ ) { mxShow->removeShapeEventListener( xListener, (*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 { Reference< XShapeEventListener > xListener( this ); 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; mxShow->addShapeEventListener( xListener, 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::gotoNextEffect() { if( mxShow.is() && mpSlideController.get() && mpShowWindow ) { const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); if( eMode == SHOWWINDOWMODE_END ) { mpShowWindow->TerminateShow(); } else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) { mpShowWindow->RestartShow(); } else { mxShow->nextEffect(); update(); } } } void SlideshowImpl::gotoPreviousSlide() { if( mxShow.is() && mpSlideController.get() ) try { const ShowWindowMode eMode = mpShowWindow->GetShowWindowMode(); if( eMode == SHOWWINDOWMODE_END ) { const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1; if( nLastSlideIndex >= 0 ) mpShowWindow->RestartShow( nLastSlideIndex ); } else if( (eMode == SHOWWINDOWMODE_PAUSE) || (eMode == SHOWWINDOWMODE_BLANK) ) { mpShowWindow->RestartShow(); } else { if( mpSlideController->previousSlide() ) displayCurrentSlide(); } } 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 SlideshowImpl::stopSound() { 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() ); } } void SlideshowImpl::displayCurrentSlide() { stopSound(); removeShapeEvents(); if( mpSlideController.get() && mxShow.is() ) { mpSlideController->displayCurrentSlide( mxShow ); registerShapeEvents(mpSlideController->getCurrentSlideNumber()); update(); SfxBindings* pBindings = getBindings(); if( pBindings ) { pBindings->Invalidate( SID_NAVIGATOR_STATE ); pBindings->Invalidate( SID_NAVIGATOR_PAGENAME ); } } } void SlideshowImpl::gotoNextSlide() { 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 ) { boost::scoped_ptr< Graphic > pGraphic; if( maPresSettings.mbShowPauseLogo ) { // load about image from module path String aBmpFileName( RTL_CONSTASCII_USTRINGPARAM("about.bmp") ); INetURLObject aObj( SvtPathOptions().GetModulePath(), INET_PROT_FILE ); aObj.insertName( aBmpFileName ); SvFileStream aStrm( aObj.PathToFileName(), STREAM_STD_READ ); if ( !aStrm.GetError() ) { Bitmap aBmp; aStrm >> aBmp; pGraphic.reset( new Graphic(aBmp) ); pGraphic->SetPrefMapMode(MAP_PIXEL); } else { //if no image is located in the module path //use default logo from iso resource: String aMgrName( RTL_CONSTASCII_USTRINGPARAM( "iso" ) ); boost::scoped_ptr< ResMgr > pResMgr( ResMgr::CreateResMgr( U2S( aMgrName )) ); DBG_ASSERT(pResMgr,"No ResMgr found"); if(pResMgr.get()) { pGraphic.reset( new Graphic( Bitmap( ResId( RID_DEFAULT_ABOUT_BMP_LOGO, *pResMgr.get() ) ) ) ); pGraphic->SetPrefMapMode(MAP_PIXEL); } } } if( mpShowWindow ) mpShowWindow->SetPauseMode( 0, maPresSettings.mnPauseTimeout, pGraphic.get() ); } else { displaySlideIndex( 0 ); } } else { if( mpShowWindow ) mpShowWindow->SetEndMode(); } } } } } void SlideshowImpl::gotoFirstSlide() { if( mpShowWindow && mpSlideController.get() ) { if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END ) { if( mpSlideController->getSlideIndexCount() ) mpShowWindow->RestartShow( 0); } else { displaySlideIndex( 0 ); } } } void SlideshowImpl::gotoLastSlide() { if( mpSlideController.get() ) { const sal_Int32 nLastSlideIndex = mpSlideController->getSlideIndexCount() - 1; if( nLastSlideIndex >= 0 ) { if( mpShowWindow->GetShowWindowMode() == SHOWWINDOWMODE_END ) { mpShowWindow->RestartShow( nLastSlideIndex ); } else { displaySlideIndex( nLastSlideIndex ); } } } } void SlideshowImpl::endPresentation() { if( !mnEndShowEvent ) mnEndShowEvent = Application::PostUserEvent( LINK(this, SlideshowImpl, endPresentationHdl) ); } IMPL_LINK( SlideshowImpl, endPresentationHdl, void*, EMPTYARG ) { mnEndShowEvent = 0; if( mpViewShell ) mpViewShell->GetViewShellBase().StopPresentation(); else stopShow(); return 0; } void SlideshowImpl::enablePen() { if( mxShow.is()) try { uno::Any aValue; if( maPresSettings.mbMouseAsPen ) // todo: take color from configuration aValue <<= (sal_Int32)0x0000FF00L; beans::PropertyValue aPenProp; aPenProp.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "UserPaintColor" )); aPenProp.Value = aValue; mxShow->setProperty( aPenProp ); } catch( Exception& e ) { static_cast<void>(e); DBG_ERROR( (OString("sd::SlideshowImpl::enablePen(), " "exception caught: ") + rtl::OUStringToOString( comphelper::anyToString( cppu::getCaughtException() ), RTL_TEXTENCODING_UTF8 )).getStr() ); } } bool SlideshowImpl::pause( bool bPause ) { if( bPause != mbIsPaused ) try { mbIsPaused = bPause; if( mxShow.is() ) { bool bRet = mxShow->pause(bPause); if( !bPause ) update(); return bRet; } else { return false; } } 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() ); } return false; } // XShapeEventListener void SAL_CALL SlideshowImpl::click( const Reference< XShape >& xShape, const ::com::sun::star::awt::MouseEvent& /* aOriginalEvent */ ) throw (RuntimeException) { ::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: { sal_Int32 nSlideNumber = getSlideNumberForBookmark( pEvent->maStrBookmark ); if( nSlideNumber != -1 ) displaySlideNumber( nSlideNumber ); } 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, 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 ) { BOOL bIsMasterPage; OUString aBookmark = getUiNameFromPageApiNameImpl( rStrBookmark ); USHORT 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 = (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 SAL_CALL SlideshowImpl::disposing( const EventObject& /* Source */ ) throw (RuntimeException) { } 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::getCurrentSlideIndex() { return mpSlideController.get() ? mpSlideController->getCurrentSlideIndex() : -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; } bool SlideshowImpl::isEndless() { return maPresSettings.mbEndless; } bool SlideshowImpl::isDrawingPossible() { return maPresSettings.mbMouseAsPen; } 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 preperation */ 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 personaly punish this person seriously, even if this person is me. */ IMPL_LINK( SlideshowImpl, updateHdl, Timer*, EMPTYARG ) { mnUpdateEvent = 0; // doing some nMagic const rtl::Reference<SlideshowImpl> this_(this); 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); Reference< XSlideShow > xShow( mxShow ); double fUpdate = 0.0; if( !xShow->update(fUpdate) ) fUpdate = -1.0; if( mxShow.is() && ( fUpdate >= 0.0 ) ) { if( fUpdate < 0.5 ) { Application::Reschedule(TRUE); if( mxShow.is() ) mnUpdateEvent = Application::PostUserEvent(LINK(this,SlideshowImpl, updateHdl )); } else { const float MAX_UPDATE = 60.0; // do not wait longer than 60 seconds for next refresh if( fUpdate > MAX_UPDATE ) fUpdate = MAX_UPDATE; maUpdateTimer.SetTimeout( ::std::max( 1UL, static_cast<ULONG>(fUpdate * 1000.0) ) ); maUpdateTimer.Start(); } } } catch( Exception& e ) { static_cast<void>(e); DBG_ERROR( (OString("sd::SlideshowImpl::updateHdl(), " "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: case KEY_LEFT: case KEY_UP: case KEY_P: case KEY_BACKSPACE: gotoPreviousSlide(); break; case KEY_HOME: gotoFirstSlide(); break; case KEY_END: gotoLastSlide(); break; case KEY_B: case KEY_W: case KEY_POINT: case KEY_COMMA: { if( mpShowWindow ) { const Color aBlankColor( ((nKeyCode == KEY_W ) || (nKeyCode == KEY_COMMA)) ? COL_WHITE : COL_BLACK ); if( mpShowWindow->SetBlankMode( mpSlideController->getCurrentSlideIndex(), aBlankColor ) ) pause( true ); } } 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; } 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( true ); PopupMenu* pMenu = new PopupMenu( SdResId( RID_SLIDESHOW_CONTEXTMENU ) ); 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 && pViewFrame->GetFrame() ) { ::com::sun::star::uno::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") ), FALSE, FALSE ) ); pMenu->SetItemImage( CM_PREV_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10618") ), FALSE, FALSE ) ); if( pPageMenu ) { pPageMenu->SetItemImage( CM_FIRST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10616") ), FALSE, FALSE ) ); pPageMenu->SetItemImage( CM_LAST_SLIDE, GetImage( xFrame, OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:10619") ), FALSE, FALSE ) ); } } } // populate slide goto list if( pPageMenu ) { const sal_Int32 nPageNumberCount = mpSlideController->getSlideNumberCount(); if( nPageNumberCount <= 1 ) { pMenu->EnableItem( CM_GOTO, 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((USHORT)nPageNumber, PK_STANDARD); if (pPage) { pPageMenu->InsertItem( (USHORT)(CM_SLIDES + nPageNumber), pPage->GetName() ); if( nPageNumber == nCurrentSlideNumber ) pPageMenu->CheckItem( (USHORT)(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 ); } } pMenu->SetSelectHdl( LINK( this, SlideshowImpl, ContextMenuSelectHdl ) ); pMenu->Execute( mpShowWindow, maPopupMousePos ); delete pMenu; if( mxView.is() ) mxView->ignoreNextMouseReleased(); pause( mbWasPaused ); 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 ) ) { mbWasPaused = true; } } 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( ::rtl::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; // normale Praesentation if( eMode == AnimationSlideController::FROM ) { if( rPresSlide.Len() ) { sal_Int32 nSlide; BOOL bTakeNextAvailable = FALSE; for( nSlide = 0, nFirstSlide = -1; ( nSlide < nSlideCount ) && ( -1 == nFirstSlide ); nSlide++ ) { SdPage* pTestSlide = mpDoc->GetSdPage( (USHORT)nSlide, PK_STANDARD ); if( pTestSlide->GetName() == rPresSlide ) { if( pTestSlide->IsExcluded() ) bTakeNextAvailable = 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( (USHORT)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( (USHORT) nSlide, PK_STANDARD )->GetName() ) break; if( nSlide < nSlideCount ) mpSlideController->insertSlideNumber( (USHORT) nSlide ); } void* pCustomSlide; sal_Int32 nSlideIndex; for( pCustomSlide = pCustomShow->First(),nSlideIndex=0; pCustomSlide; pCustomSlide = pCustomShow->Next(), nSlideIndex++ ) { const USHORT nSdSlide = ( ( (SdPage*) pCustomSlide )->GetPageNum() - 1 ) / 2; if( !( mpDoc->GetSdPage( nSdSlide, PK_STANDARD ) )->IsExcluded()) mpSlideController->insertSlideNumber( nSdSlide ); } } } } typedef USHORT (*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( ULONG i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ ) { const USHORT nId = ( *aShowChilds[ i ] )(); if( pViewFrame->GetChildWindow( nId ) ) { pViewFrame->SetChildWindow( nId, 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( ULONG i = 0, nCount = sizeof( aShowChilds ) / sizeof( FncGetChildWindowId ); i < nCount; i++ ) { if( mnChildMask & ( 1 << i ) ) pViewFrame->SetChildWindow( ( *aShowChilds[ i ] )(), 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 behaviour 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::activate() { if(!mxShow.is()) return; if( ANIMATIONMODE_SHOW == meAnimationMode ) { if( mbAutoSaveWasOn ) setAutoSaveState( false ); if( mpShowWindow ) { SfxViewFrame* pViewFrame = getViewFrame(); SfxDispatcher* pDispatcher = pViewFrame ? pViewFrame->GetDispatcher() : 0; hideChildWindows(); if( pDispatcher ) { // filter all forbiden slots pDispatcher->SetSlotFilter( TRUE, sizeof(pAllowed) / sizeof(USHORT), pAllowed ); } if( getBindings() ) getBindings()->InvalidateAll(TRUE); mpShowWindow->GrabFocus(); } } pause( false ); } // ----------------------------------------------------------------------------- void SlideshowImpl::deactivate() { if( !mxShow.is() ) return; pause( true ); if( ANIMATIONMODE_SHOW == meAnimationMode ) { if( mbAutoSaveWasOn ) setAutoSaveState( true ); if( mpShowWindow ) { showChildWindows(); } } } // ----------------------------------------------------------------------------- void SlideshowImpl::receiveRequest(SfxRequest& rReq) { const SfxItemSet* pArgs = rReq.GetArgs(); switch ( rReq.GetSlot() ) { case SID_NAVIGATOR_PEN: maPresSettings.mbMouseAsPen = !maPresSettings.mbMouseAsPen; enablePen(); 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? BOOL bIsMasterPage; USHORT 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!"); } } SlideShowImplGuard::SlideShowImplGuard( SlideshowImpl* pImpl ) { mpImpl = pImpl; if( mpImpl ) mpImpl->acquire(); } SlideShowImplGuard::~SlideShowImplGuard() { if( mpImpl ) mpImpl->release(); } } // namespace ::sd