Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sd/source/ui/slideshow/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 39 kB image not shown  

Quelle  slideshow.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */


#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/drawing/framework/XControllerManager.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/util/URL.hpp>

#include <comphelper/propertyvalue.hxx>
#include <cppuhelper/supportsservice.hxx>

#include <sal/log.hxx>
#include <vcl/svapp.hxx>
#include <vcl/wrkwin.hxx>
#include <svx/svdpool.hxx>
#include <svx/svdlayer.hxx>
#include <svl/itemprop.hxx>

#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/sfxsids.hrc>

#include <framework/FrameworkHelper.hxx>
#include <comphelper/extract.hxx>

#include <FrameView.hxx>
#include <createpresentation.hxx>
#include <unomodel.hxx>
#include <slideshow.hxx>
#include "slideshowimpl.hxx"
#include <sdattr.hrc>
#include <sdmod.hxx>
#include <FactoryIds.hxx>
#include <DrawDocShell.hxx>
#include <ViewShell.hxx>
#include <ViewShellBase.hxx>
#include "SlideShowRestarter.hxx"
#include <DrawController.hxx>
#include <PresentationViewShell.hxx>
#include <customshowlist.hxx>
#include <unopage.hxx>
#include <sdpage.hxx>
#include <cusshow.hxx>
#include <optsitem.hxx>
#include <strings.hrc>
#include <sdresid.hxx>

using ::com::sun::star::presentation::XSlideShowController;
using ::sd::framework::FrameworkHelper;
using ::com::sun::star::awt::XWindow;
using namespace ::sd;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::animations;

namespace {
    /** This local version of the work window overrides DataChanged() so that it
        can restart the slide show when a display is added or removed.
    */

    class FullScreenWorkWindow : public WorkWindow
    {
    public:
        FullScreenWorkWindow (
            const ::rtl::Reference<SlideShow>& rpSlideShow,
            ViewShellBase* pViewShellBase)
            : WorkWindow(nullptr, WB_HIDE | WB_CLIPCHILDREN),
              mpRestarter(std::make_shared<SlideShowRestarter>(rpSlideShow, pViewShellBase))
        {}

        void Restart(bool bForce)
        {
            mpRestarter->Restart(bForce);
        }

        virtual void DataChanged (const DataChangedEvent& rEvent) override
        {
            if (rEvent.GetType() == DataChangedEventType::DISPLAY)
                Restart(false);
        }

    private:
        ::std::shared_ptr<SlideShowRestarter> mpRestarter;
    };
}

static std::span<const SfxItemPropertyMapEntry> ImplGetPresentationPropertyMap()
{
    // NOTE: First member must be sorted
    static const SfxItemPropertyMapEntry aPresentationPropertyMap_Impl[] =
    {
        { u"AllowAnimations"_ustr,          ATTR_PRESENT_ANIMATION_ALLOWED,       cppu::UnoType<bool>::get(),                0, 0 },
        { u"CustomShow"_ustr,               ATTR_PRESENT_CUSTOMSHOW,              ::cppu::UnoType<OUString>::get(),     0, 0 },
        { u"Display"_ustr,                  ATTR_PRESENT_DISPLAY,                 ::cppu::UnoType<sal_Int32>::get(),    0, 0 },
        { u"FirstPage"_ustr,                ATTR_PRESENT_DIANAME,                 ::cppu::UnoType<OUString>::get(),     0, 0 },
        { u"IsAlwaysOnTop"_ustr,            ATTR_PRESENT_ALWAYS_ON_TOP,           cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsAutomatic"_ustr,              ATTR_PRESENT_MANUEL,                  cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsEndless"_ustr,                ATTR_PRESENT_ENDLESS,                 cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsFullScreen"_ustr,             ATTR_PRESENT_FULLSCREEN,              cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsShowAll"_ustr,                ATTR_PRESENT_ALL,                     cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsMouseVisible"_ustr,           ATTR_PRESENT_MOUSE,                   cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsShowLogo"_ustr,               ATTR_PRESENT_SHOW_PAUSELOGO,          cppu::UnoType<bool>::get(),                0, 0 },
        { u"IsTransitionOnClick"_ustr,      ATTR_PRESENT_CHANGE_PAGE,             cppu::UnoType<bool>::get(),                0, 0 },
        { u"Pause"_ustr,                    ATTR_PRESENT_PAUSE_TIMEOUT,           ::cppu::UnoType<sal_Int32>::get(),    0, 0 },
        { u"StartWithNavigator"_ustr,       ATTR_PRESENT_NAVIGATOR,               cppu::UnoType<bool>::get(),                0, 0 },
        { u"UsePen"_ustr,                   ATTR_PRESENT_PEN,                     cppu::UnoType<bool>::get(),                0, 0 },
    };

    return aPresentationPropertyMap_Impl;
}


SlideShow::SlideShow( SdDrawDocument* pDoc )
: maPropSet(ImplGetPresentationPropertyMap(), SdrObject::GetGlobalDrawObjectItemPool())
, mbIsInStartup(false)
, mpDoc( pDoc )
, mpCurrentViewShellBase( nullptr )
, mpFullScreenViewShellBase( nullptr )
, mpFullScreenFrameView( nullptr )
, mnInPlaceConfigEvent( nullptr )
{
}

void SlideShow::ThrowIfDisposed() const
{
    if( mpDoc == nullptr )
        throw DisposedException();
}

/// used by the model to create a slideshow for it
rtl::Reference< SlideShow > SlideShow::Create( SdDrawDocument* pDoc )
{
    return new SlideShow( pDoc );
}

rtl::Reference< SlideShow > SlideShow::GetSlideShow( SdDrawDocument const * pDocument )
{
    rtl::Reference< SlideShow > xRet;

    if( pDocument )
        xRet = GetSlideShow( *pDocument );

    return xRet;
}

rtl::Reference< SlideShow > SlideShow::GetSlideShow( SdDrawDocument const & rDocument )
{
    return rtl::Reference< SlideShow >(
        dynamic_cast< SlideShow* >( rDocument.getPresentation().get() ) );
}

rtl::Reference< SlideShow > SlideShow::GetSlideShow( ViewShellBase const & rBase )
{
    return GetSlideShow( rBase.GetDocument() );
}

css::uno::Reference< css::presentation::XSlideShowController > SlideShow::GetSlideShowController(ViewShellBase const & rBase )
{
    rtl::Reference< SlideShow > xSlideShow( GetSlideShow( rBase ) );

    Reference< XSlideShowController > xRet;
    if( xSlideShow.is() )
        xRet = xSlideShow->getController();

    return xRet;
}

bool SlideShow::StartPreview( ViewShellBase const & rBase,
    const css::uno::Reference< css::drawing::XDrawPage >& xDrawPage,
    const css::uno::Reference< css::animations::XAnimationNode >& xAnimationNode )
{
    rtl::Reference< SlideShow > xSlideShow( GetSlideShow( rBase ) );
    if( !xSlideShow.is() )
        return false;

    // end an already running IASS Preview (when someone is fast)
    if (xSlideShow->IsInteractiveSlideshow() && xSlideShow->isInteractiveSetup())
        xSlideShow->endInteractivePreview();

    // check if IASS re-use of running Slideshow can/should be done
    // and do it
    if (xSlideShow->IsInteractiveSlideshow() && xSlideShow->isFullScreen()) // IASS
        return xSlideShow->startInteractivePreview( xDrawPage, xAnimationNode );

    // fallback to usual mode
    xSlideShow->startPreview( xDrawPage, xAnimationNode );
    return true;
}

void SlideShow::Stop( ViewShellBase const & rBase )
{
    rtl::Reference< SlideShow > xSlideShow( GetSlideShow( rBase ) );
    if( xSlideShow.is() )
        xSlideShow->end();
}

bool SlideShow::IsRunning( ViewShellBase const & rBase )
{
    rtl::Reference< SlideShow > xSlideShow( GetSlideShow( rBase ) );
    return xSlideShow.is() && xSlideShow->isRunning();
}

bool SlideShow::IsRunning( const ViewShell& rViewShell )
{
    rtl::Reference< SlideShow > xSlideShow( GetSlideShow( rViewShell.GetViewShellBase() ) );
    return xSlideShow.is() && xSlideShow->isRunning() && (xSlideShow->mxController->getViewShell() == &rViewShell);
}

/// returns true if the interactive slideshow mode is activated
bool SlideShow::IsInteractiveSlideshow(const ViewShellBase* pViewShellBase)
{
    if (nullptr == pViewShellBase)
        return false;
    rtl::Reference< SlideShow > xSlideShow(GetSlideShow(*pViewShellBase));
    if (!xSlideShow.is())
        return false;
    return xSlideShow->IsInteractiveSlideshow();
}

bool SlideShow::IsInteractiveSlideshow() const
{
    return mpDoc->getPresentationSettings().mbInteractive;
}

void SlideShow::CreateController(  ViewShell* pViewSh, ::sd::View* pView, vcl::Window* pParentWindow )
{
    SAL_INFO_IF( !mxController.is(), "sd.slideshow""sd::SlideShow::CreateController(), clean up old controller first!" );

    Reference< XPresentation2 > xThis( this );

    // Reset mbIsInStartup.  From here mxController.is() is used to prevent
    // multiple slide show instances for one document.
    mxController.set(new SlideshowImpl(xThis, pViewSh, pView, mpDoc, pParentWindow));

    mbIsInStartup = false;

}

// XServiceInfo
OUString SAL_CALL SlideShow::getImplementationName(  )
{
    return u"com.sun.star.comp.sd.SlideShow"_ustr;
}

sal_Bool SAL_CALL SlideShow::supportsService( const OUString& ServiceName )
{
    return cppu::supportsService( this, ServiceName );
}

Sequence< OUString > SAL_CALL SlideShow::getSupportedServiceNames(  )
{
    return { u"com.sun.star.presentation.Presentation"_ustr };
}

// XPropertySet
Reference< XPropertySetInfo > SAL_CALL SlideShow::getPropertySetInfo()
{
    SolarMutexGuard aGuard;
    static Reference< XPropertySetInfo > xInfo = maPropSet.getPropertySetInfo();
    return xInfo;
 }

void SAL_CALL SlideShow::setPropertyValue( const OUString& aPropertyName, const Any&&nbsp;aValue )
{
    SolarMutexGuard aGuard;
    ThrowIfDisposed();

    sd::PresentationSettings& rPresSettings = mpDoc->getPresentationSettings();

    const SfxItemPropertyMapEntry* pEntry = maPropSet.getPropertyMapEntry(aPropertyName);

    if( pEntry && ((pEntry->nFlags & PropertyAttribute::READONLY) != 0) )
        throw PropertyVetoException();

    bool bValuesChanged = false;
    bool bIllegalArgument = true;

    switch( pEntry ? pEntry->nWID : -1 )
    {
    case ATTR_PRESENT_ALL:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if( rPresSettings.mbAll != bVal )
            {
                rPresSettings.mbAll = bVal;
                bValuesChanged = true;
                if( bVal )
                    rPresSettings.mbCustomShow = false;
            }
        }
        break;
    }
    case ATTR_PRESENT_CHANGE_PAGE:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if( bVal == rPresSettings.mbLockedPages )
            {
                bValuesChanged = true;
                rPresSettings.mbLockedPages = !bVal;
            }
        }
        break;
    }

    case ATTR_PRESENT_ANIMATION_ALLOWED:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if(rPresSettings.mbAnimationAllowed != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbAnimationAllowed = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_CUSTOMSHOW:
    {
        OUString aShowName;
        if( aValue >>= aShowName )
        {
            bIllegalArgument = false;

            SdCustomShowList* pCustomShowList = mpDoc->GetCustomShowList();
            if(pCustomShowList)
            {
                SdCustomShow* pCustomShow;
                for( pCustomShow = pCustomShowList->First(); pCustomShow != nullptr; pCustomShow = pCustomShowList->Next() )
                {
                    if( pCustomShow->GetName() == aShowName )
                        break;
                }

                rPresSettings.mbCustomShow = true;
                bValuesChanged = true;
            }
        }
        break;
    }
    case ATTR_PRESENT_ENDLESS:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if( rPresSettings.mbEndless != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbEndless = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_FULLSCREEN:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;
            if( rPresSettings.mbFullScreen != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbFullScreen = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_DIANAME:
    {
        OUString aPresPage;
        aValue >>= aPresPage;
        bIllegalArgument = false;
        if( (rPresSettings.maPresPage != aPresPage) || !rPresSettings.mbCustomShow || !rPresSettings.mbAll )
        {
            bValuesChanged = true;
            rPresSettings.maPresPage = getUiNameFromPageApiNameImpl(aPresPage);
            rPresSettings.mbCustomShow = false;
            rPresSettings.mbAll = false;
        }
        break;
    }
    case ATTR_PRESENT_MANUEL:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if( rPresSettings.mbManual != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbManual = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_MOUSE:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;
            if( rPresSettings.mbMouseVisible != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbMouseVisible = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_ALWAYS_ON_TOP:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if( rPresSettings.mbAlwaysOnTop != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbAlwaysOnTop = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_NAVIGATOR:
        bIllegalArgument = false;
        //ignored, but exists in some older documents
        break;
    case ATTR_PRESENT_PEN:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if(rPresSettings.mbMouseAsPen != bVal)
            {
                bValuesChanged = true;
                rPresSettings.mbMouseAsPen = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_PAUSE_TIMEOUT:
    {
        sal_Int32 nValue = 0;
        if( (aValue >>= nValue) && (nValue >= 0) )
        {
            bIllegalArgument = false;
            if( rPresSettings.mnPauseTimeout != nValue )
            {
                bValuesChanged = true;
                rPresSettings.mnPauseTimeout = nValue;
            }
        }
        break;
    }
    case ATTR_PRESENT_SHOW_PAUSELOGO:
    {
        bool bVal = false;

        if( aValue >>= bVal )
        {
            bIllegalArgument = false;

            if( rPresSettings.mbShowPauseLogo != bVal )
            {
                bValuesChanged = true;
                rPresSettings.mbShowPauseLogo = bVal;
            }
        }
        break;
    }
    case ATTR_PRESENT_DISPLAY:
    {
        sal_Int32 nDisplay = 0;
        if( aValue >>= nDisplay )
        {
            bIllegalArgument = false;

            SdOptions* pOptions = SdModule::get()->GetSdOptions(DocumentType::Impress);
            pOptions->SetDisplay( nDisplay );

            FullScreenWorkWindow *pWin = dynamic_cast<FullScreenWorkWindow *>(GetWorkWindow());
            if( !pWin )
                return;
            pWin->Restart(true);
        }
        break;
    }

    default:
        throw UnknownPropertyException( OUString::number(pEntry ? pEntry->nWID : -1), static_cast<cppu::OWeakObject*>(this));
    }

    if( bIllegalArgument )
        throw IllegalArgumentException();

    if( bValuesChanged )
        mpDoc->SetChanged();
}

Any SAL_CALL SlideShow::getPropertyValue( const OUString& PropertyName )
{
    SolarMutexGuard aGuard;
    ThrowIfDisposed();

    const sd::PresentationSettings& rPresSettings = mpDoc->getPresentationSettings();

    const SfxItemPropertyMapEntry* pEntry = maPropSet.getPropertyMapEntry(PropertyName);

    switch( pEntry ? pEntry->nWID : -1 )
    {
    case ATTR_PRESENT_ALL:
        return Any( !rPresSettings.mbCustomShow && rPresSettings.mbAll );
    case ATTR_PRESENT_CHANGE_PAGE:
        return Any( !rPresSettings.mbLockedPages );
    case ATTR_PRESENT_ANIMATION_ALLOWED:
        return Any( rPresSettings.mbAnimationAllowed );
    case ATTR_PRESENT_CUSTOMSHOW:
        {
            SdCustomShowList* pList = mpDoc->GetCustomShowList();
            SdCustomShow* pShow = (pList && rPresSettings.mbCustomShow) ? pList->GetCurObject() : nullptr;
            OUString aShowName;

            if(pShow)
                aShowName = pShow->GetName();

            return Any( aShowName );
        }
    case ATTR_PRESENT_ENDLESS:
        return Any( rPresSettings.mbEndless );
    case ATTR_PRESENT_FULLSCREEN:
        return Any( rPresSettings.mbFullScreen );
    case ATTR_PRESENT_DIANAME:
        {
            OUString aSlideName;

            if( !rPresSettings.mbCustomShow && !rPresSettings.mbAll )
                aSlideName = getPageApiNameFromUiName( rPresSettings.maPresPage );

            return Any( aSlideName );
        }
    case ATTR_PRESENT_MANUEL:
        return Any( rPresSettings.mbManual );
    case ATTR_PRESENT_MOUSE:
        return Any( rPresSettings.mbMouseVisible );
    case ATTR_PRESENT_ALWAYS_ON_TOP:
        return Any( rPresSettings.mbAlwaysOnTop );
    case ATTR_PRESENT_NAVIGATOR:
        return Any( false );
    case ATTR_PRESENT_PEN:
        return Any( rPresSettings.mbMouseAsPen );
    case ATTR_PRESENT_PAUSE_TIMEOUT:
        return Any( rPresSettings.mnPauseTimeout );
    case ATTR_PRESENT_SHOW_PAUSELOGO:
        return Any( rPresSettings.mbShowPauseLogo );
    case ATTR_PRESENT_DISPLAY:
    {
        SdOptions* pOptions = SdModule::get()->GetSdOptions(DocumentType::Impress);
        return Any(pOptions->GetDisplay());
    }

    default:
        throw UnknownPropertyException( OUString::number(pEntry ? pEntry->nWID : -1), static_cast<cppu::OWeakObject*>(this));
    }
}

void SAL_CALL SlideShow::addPropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >&  )
{
}

void SAL_CALL SlideShow::removePropertyChangeListener( const OUString& , const Reference< XPropertyChangeListener >&  )
{
}

void SAL_CALL SlideShow::addVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >&  )
{
}

void SAL_CALL SlideShow::removeVetoableChangeListener( const OUString& , const Reference< XVetoableChangeListener >&  )
{
}

// XPresentation

void SAL_CALL SlideShow::start()
{
    const Sequence< PropertyValue > aArguments;
    startWithArguments( aArguments );
}

WorkWindow *SlideShow::GetWorkWindow()
{
    if( !mpFullScreenViewShellBase )
        return nullptr;

    PresentationViewShell* pShell = dynamic_cast<PresentationViewShell*>(mpFullScreenViewShellBase->GetMainViewShell().get());

    if( !pShell)
        return nullptr;

    SfxViewFrame* pFrame = pShell->GetViewFrame();
    if (!pFrame)
        return nullptr;

    return dynamic_cast<WorkWindow*>(pFrame->GetFrame().GetWindow().GetParent());
}

bool SlideShow::IsExitAfterPresenting() const
{
    SolarMutexGuard aGuard;
    ThrowIfDisposed();
    return mpDoc->IsExitAfterPresenting();
}

void SlideShow::SetExitAfterPresenting(bool bExit)
{
    SolarMutexGuard aGuard;
    ThrowIfDisposed();
    mpDoc->SetExitAfterPresenting(bExit);
}

void SAL_CALL SlideShow::end()
{
    SolarMutexGuard aGuard;

    if (IsInteractiveSlideshow() && isInteractiveSetup())
    {
        // If IASS was active clean that up, but do not end SlideShow
        endInteractivePreview();
        return;
    }

    // The mbIsInStartup flag should have been reset during the start of the
    // slide show.  Reset it here just in case that something has horribly
    // gone wrong.
    assert(!mbIsInStartup);

    rtl::Reference< SlideshowImpl > xController( mxController );
    if( !xController.is() )
        return;

    mxController.clear();

    if( mpFullScreenFrameView )
    {
        delete mpFullScreenFrameView;
        mpFullScreenFrameView = nullptr;
    }

    ViewShellBase* pFullScreenViewShellBase = mpFullScreenViewShellBase;
    mpFullScreenViewShellBase = nullptr;

    // dispose before fullscreen window changes screens
    // (potentially). If this needs to be moved behind
    // pWorkWindow->StartPresentationMode() again, read issue
    // pWorkWindow->i94007 & implement the solution outlined
    // there.
    xController->dispose();

    if( pFullScreenViewShellBase )
    {
        PresentationViewShell* pShell = dynamic_cast<PresentationViewShell*>(pFullScreenViewShellBase->GetMainViewShell().get());

        if( pShell && pShell->GetViewFrame() )
        {
            WorkWindow* pWorkWindow = dynamic_cast<WorkWindow*>(pShell->GetViewFrame()->GetFrame().GetWindow().GetParent());
            if( pWorkWindow )
            {
                pWorkWindow->StartPresentationMode(   (mxController.is() && mxController->maPresSettings.mbAlwaysOnTop)
                                                    ? PresentationFlags::HideAllApps : PresentationFlags::NONE );
            }
        }
    }

    if( pFullScreenViewShellBase )
    {
        PresentationViewShell* pShell = nullptr;
        {
            // Get the shell pointer in its own scope to be sure that
            // the shared_ptr to the shell is released before DoClose()
            // is called.
            ::std::shared_ptr<ViewShell> pSharedView (pFullScreenViewShellBase->GetMainViewShell());
            pShell = dynamic_cast<PresentationViewShell*>(pSharedView.get());
        }
        if( pShell && pShell->GetViewFrame() )
            pShell->GetViewFrame()->DoClose();
    }
    else if( mpCurrentViewShellBase )
    {
        ViewShell* pViewShell = mpCurrentViewShellBase->GetMainViewShell().get();

        if( pViewShell )
        {
            FrameView* pFrameView = pViewShell->GetFrameView();

            if( pFrameView && (pFrameView->GetPresentationViewShellId() != SID_VIEWSHELL0) )
            {
                ViewShell::ShellType ePreviousType (pFrameView->GetPreviousViewShellType());
                pFrameView->SetPreviousViewShellType(ViewShell::ST_NONE);

                pFrameView->SetPresentationViewShellId(SID_VIEWSHELL0);
                pFrameView->SetPreviousViewShellType(pViewShell->GetShellType());

                framework::FrameworkHelper::Instance(*mpCurrentViewShellBase)->RequestView(
                    framework::FrameworkHelper::GetViewURL(ePreviousType),
                    framework::FrameworkHelper::msCenterPaneURL);

                pViewShell->GetViewFrame()->GetBindings().InvalidateAll( true );
            }
        }
    }

    if( mpCurrentViewShellBase )
    {
        if (ViewShell* const pViewShell = mpCurrentViewShellBase->GetMainViewShell().get())
        {
            // invalidate the view shell so the presentation slot will be re-enabled
            // and the rehearsing will be updated
            pViewShell->Invalidate();

            if( xController->meAnimationMode ==ANIMATIONMODE_SHOW )
            {
                // switch to the previously visible Slide
                DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>( pViewShell );
                if( pDrawViewShell )
                    pDrawViewShell->SwitchPage( static_cast<sal_uInt16>(xController->getRestoreSlide()) );
                else
                {
                    DrawController& rDrawController =
                        *mpCurrentViewShellBase->GetDrawController();
                    rDrawController.setCurrentPage(
                        Reference<XDrawPage>(
                            mpDoc->GetSdPage(xController->getRestoreSlide(), PageKind::Standard)->getUnoPage(),
                            UNO_QUERY));
                }
            }

            if( pViewShell->GetDoc()->IsExitAfterPresenting() )
            {
                pViewShell->GetDoc()->SetExitAfterPresenting( false );

                Reference<frame::XDispatchProvider> xProvider(pViewShell->GetViewShellBase().GetController()->getFrame(),
                                                              UNO_QUERY);
                if( xProvider.is() )
                {
                    util::URL aURL;
                    aURL.Complete = ".uno:CloseFrame";

                    uno::Reference< frame::XDispatch > xDispatch(
                        xProvider->queryDispatch(
                            aURL, OUString(), 0));
                    if( xDispatch.is() )
                    {
                        xDispatch->dispatch(aURL,
                                            uno::Sequence< beans::PropertyValue >());
                    }
                }
            }

            // In case mbMouseAsPen was set, a new layer DrawnInSlideshow might have been generated
            // during slideshow, which is not known to FrameView yet.
            if (any2bool(getPropertyValue(u"UsePen"_ustr))
                && pViewShell->GetDoc()->GetLayerAdmin().GetLayer(u"DrawnInSlideshow"_ustr))
            {
                SdrLayerIDSet aDocLayerIDSet;
                pViewShell->GetDoc()->GetLayerAdmin().getVisibleLayersODF(aDocLayerIDSet);
                if (pViewShell->GetFrameView()->GetVisibleLayers() != aDocLayerIDSet)
                {
                    pViewShell->GetFrameView()->SetVisibleLayers(aDocLayerIDSet);
                }
                pViewShell->GetDoc()->GetLayerAdmin().getPrintableLayersODF(aDocLayerIDSet);
                if (pViewShell->GetFrameView()->GetPrintableLayers() != aDocLayerIDSet)
                {
                    pViewShell->GetFrameView()->SetPrintableLayers(aDocLayerIDSet);
                }
                pViewShell->GetDoc()->GetLayerAdmin().getLockedLayersODF(aDocLayerIDSet);
                if (pViewShell->GetFrameView()->GetLockedLayers() != aDocLayerIDSet)
                {
                    pViewShell->GetFrameView()->SetLockedLayers(aDocLayerIDSet);
                }
                pViewShell->InvalidateWindows();
            }

            // Fire the acc focus event when focus is switched back. The above method
            // mpCurrentViewShellBase->GetWindow()->GrabFocus() will set focus to WorkWindow
            // instead of the sd::window, so here call Shell's method to fire the focus event
            pViewShell->SwitchActiveViewFireFocus();
        }
    }
    mpCurrentViewShellBase = nullptr;
}

void SAL_CALL SlideShow::rehearseTimings()
{
    Sequence< PropertyValue > aArguments{ comphelper::makePropertyValue(u"RehearseTimings"_ustr, true) };
    startWithArguments( aArguments );
}

// XPresentation2

void SAL_CALL SlideShow::startWithArguments(const Sequence< PropertyValue >& rArguments)
{
    SolarMutexGuard aGuard;
    ThrowIfDisposed();

    // Stop a running show before starting a new one.
    if( mxController.is() )
    {
        assert(!mbIsInStartup);
        end();
    }
    else if (mbIsInStartup)
    {
        // We are already somewhere in process of starting a slide show but
        // have not yet got to the point where mxController is set.  There
        // is not yet a slide show to end so return silently.
        return;
    }

    // Prevent multiple instance of the SlideShow class for one document.
    mbIsInStartup = true;

    mxCurrentSettings = std::make_shared<PresentationSettingsEx>( mpDoc->getPresentationSettings() );
    mxCurrentSettings->SetArguments( rArguments );

    // if there is no view shell base set, use the current one or the first using this document
    if( mpCurrentViewShellBase == nullptr )
    {
        // first check current
        ::sd::ViewShellBase* pBase = ::sd::ViewShellBase::GetViewShellBase( SfxViewFrame::Current() );
        if( pBase && pBase->GetDocument() == mpDoc )
        {
            mpCurrentViewShellBase = pBase;
        }
        else
        {
            // current is not ours, so get first from ours
            mpCurrentViewShellBase = ::sd::ViewShellBase::GetViewShellBase( SfxViewFrame::GetFirst( mpDoc->GetDocSh() ) );
        }
    }

    // #i118456# make sure TextEdit changes get pushed to model.
    // mpDrawView is tested against NULL above already.
    if(mpCurrentViewShellBase)
    {
        ViewShell* pViewShell = mpCurrentViewShellBase->GetMainViewShell().get();

        if(pViewShell && pViewShell->GetView())
        {
            pViewShell->GetView()->SdrEndTextEdit();
        }
    }

    // Start either a full-screen or an in-place show.
    if(mxCurrentSettings->mbFullScreen && !mxCurrentSettings->mbPreview)
        StartFullscreenPresentation();
    else
        StartInPlacePresentation();

}

sal_Bool SAL_CALL SlideShow::isRunning(  )
{
    SolarMutexGuard aGuard;
    return mxController.is() && mxController->isRunning();
}

Reference< XSlideShowController > SAL_CALL SlideShow::getController(  )
{
    ThrowIfDisposed();

    return mxController;
}

// XComponent

void SlideShow::disposing(std::unique_lock<std::mutex>&)
{
    SolarMutexGuard aGuard;

    if( mnInPlaceConfigEvent )
    {
        Application::RemoveUserEvent( mnInPlaceConfigEvent );
        mnInPlaceConfigEvent = nullptr;
    }

    if( mxController.is() )
    {
        mxController->dispose();
        mxController.clear();
    }

    mpCurrentViewShellBase = nullptr;
    mpFullScreenViewShellBase = nullptr;
    mpDoc = nullptr;
}

bool SlideShow::startInteractivePreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode )
{
    if (!mxController.is())
        return false;

    mxController->startInteractivePreview(xDrawPage, xAnimationNode);
    return mxController->isInteractiveSetup();
}

bool SlideShow::isInteractiveSetup() const
{
    if (!mxController.is())
        return false;

    return mxController->isInteractiveSetup();
}

void SlideShow::endInteractivePreview()
{
    mxController->endInteractivePreview();
}

void SlideShow::startPreview( const Reference< XDrawPage >& xDrawPage, const Reference< XAnimationNode >& xAnimationNode )
{
    Sequence< PropertyValue > aArguments{
        comphelper::makePropertyValue(u"Preview"_ustr, true),
        comphelper::makePropertyValue(u"FirstPage"_ustr, xDrawPage),
        comphelper::makePropertyValue(u"AnimationNode"_ustr, xAnimationNode),
        comphelper::makePropertyValue(u"ParentWindow"_ustr, Reference< XWindow >()),
    };

    startWithArguments( aArguments );
}

OutputDevice* SlideShow::getShowWindow()
{
    return mxController.is() ? mxController->mpShowWindow->GetOutDev() : nullptr;
}

int SlideShow::getAnimationMode() const
{
    return mxController.is() ? mxController->meAnimationMode : ANIMATIONMODE_SHOW;
}

void SlideShow::jumpToPageIndex( sal_Int32 nPageIndex )
{
    if( mxController.is() )
        mxController->displaySlideIndex( nPageIndex );
}

void SlideShow::jumpToPageNumber( sal_Int32 nPageNumber )
{
    if( mxController.is() )
        mxController->displaySlideNumber( nPageNumber );
}

sal_Int32 SlideShow::getCurrentPageNumber() const
{
    return mxController.is() ? mxController->getCurrentSlideNumber() : 0;
}

void SlideShow::jumpToBookmark( const OUString& sBookmark )
{
    if( mxController.is() )
        mxController->jumpToBookmark( sBookmark );
}

bool SlideShow::isFullScreen() const
{
    return mxController.is() && mxController->maPresSettings.mbFullScreen;
}

void SlideShow::resize( const Size &rSize )
{
    if( mxController.is() )
        mxController->resize( rSize );
}

bool SlideShow::activate( ViewShellBase& rBase )
{
    if( (mpFullScreenViewShellBase == &rBase) && !mxController.is() )
    {
        ::std::shared_ptr<PresentationViewShell> pShell = std::dynamic_pointer_cast<PresentationViewShell>(rBase.GetMainViewShell());
        if (pShell != nullptr)
        {
            pShell->FinishInitialization( mpFullScreenFrameView );
            mpFullScreenFrameView = nullptr;

            CreateController( pShell.get(), pShell->GetView(), rBase.GetViewWindow() );

            if (!mxController->startShow(mxCurrentSettings.get()))
                return false;

            pShell->Resize();
            // Defer the sd::ShowWindow's GrabFocus to here. so that the accessible event can be fired correctly.
            pShell->GetActiveWindow()->GrabFocus();
        }
    }

    if( mxController.is() )
        mxController->activate();

    return true;
}

void SlideShow::deactivate()
{
    mxController->deactivate();
}

bool SlideShow::keyInput(const KeyEvent& rKEvt)
{
    return mxController.is() && mxController->keyInput(rKEvt);
}

void SlideShow::paint()
{
    if( mxController.is() )
        mxController->paint();
}

void SlideShow::pause( bool bPause )
{
    if( mxController.is() )
    {
        if( bPause )
            mxController->pause();
        else
            mxController->resume();
    }
}

bool SlideShow::swipe(const CommandGestureSwipeData& rSwipeData)
{
    return mxController.is() && mxController->swipe(rSwipeData);
}

bool SlideShow::longpress(const CommandGestureLongPressData& rLongPressData)
{
    return mxController.is() && mxController->longpress(rLongPressData);
}

void SlideShow::StartInPlacePresentationConfigurationCallback()
{
    if( mnInPlaceConfigEvent != nullptr )
        Application::RemoveUserEvent( mnInPlaceConfigEvent );

    mnInPlaceConfigEvent = Application::PostUserEvent( LINK( this, SlideShow, StartInPlacePresentationConfigurationHdl ) );
}

IMPL_LINK_NOARG(SlideShow, StartInPlacePresentationConfigurationHdl, void*, void)
{
    mnInPlaceConfigEvent = nullptr;
    StartInPlacePresentation();
}

void SlideShow::StartInPlacePresentation()
{
    if( mpCurrentViewShellBase )
    {
        // Save the current view shell type so that it can be restored after the
        // show has ended.  If there already is a saved shell type then that is
        // not overwritten.

        ViewShell::ShellType eShell = ViewShell::ST_NONE;

        ::std::shared_ptr<FrameworkHelper> pHelper(FrameworkHelper::Instance(*mpCurrentViewShellBase));
        ::std::shared_ptr<ViewShell> pMainViewShell(pHelper->GetViewShell(FrameworkHelper::msCenterPaneURL));

        if( pMainViewShell )
            eShell = pMainViewShell->GetShellType();

        if( eShell != ViewShell::ST_IMPRESS )
        {
            // Switch temporary to a DrawViewShell which supports the in-place presentation.

            if( pMainViewShell )
            {
                FrameView* pFrameView = pMainViewShell->GetFrameView();
                pFrameView->SetPresentationViewShellId(SID_VIEWSHELL1);
                pFrameView->SetPreviousViewShellType (pMainViewShell->GetShellType());
                pFrameView->SetPageKind (PageKind::Standard);
            }

            pHelper->RequestView( FrameworkHelper::msImpressViewURL, FrameworkHelper::msCenterPaneURL );
            pHelper->RunOnConfigurationEvent(
                FrameworkHelper::msConfigurationUpdateEndEvent,
                [this] (bool const) { return this->StartInPlacePresentationConfigurationCallback(); } );
            return;
        }
        else
        {
            vcl::Window* pParentWindow = mxCurrentSettings->mpParentWindow;
            if( pParentWindow == nullptr )
                pParentWindow = mpCurrentViewShellBase->GetViewWindow();

            CreateController( pMainViewShell.get(), pMainViewShell->GetView(), pParentWindow );
        }
    }
    else if( mxCurrentSettings->mpParentWindow )
    {
        // no current view shell, but parent window
        CreateController( nullptr, nullptr, mxCurrentSettings->mpParentWindow );
    }

    if( !mxController.is() )
        return;

    bool bSuccess = false;
    if( mxCurrentSettings && mxCurrentSettings->mbPreview )
    {
        bSuccess = mxController->startPreview(mxCurrentSettings->mxStartPage, mxCurrentSettings->mxAnimationNode, mxCurrentSettings->mpParentWindow );
    }
    else
    {
        bSuccess = mxController->startShow(mxCurrentSettings.get());
    }

    if( !bSuccess )
        end();
    else
    {
        if( mpCurrentViewShellBase && ( !mxCurrentSettings || ( mxCurrentSettings && !mxCurrentSettings->mbPreview ) ) )
            mpCurrentViewShellBase->GetWindow()->GrabFocus();
    }
}

void SlideShow::StartFullscreenPresentation( )
{
    // Create the top level window in which the PresentationViewShell(Base)
    // will be created.  This is done here explicitly so that we can make it
    // fullscreen.
    const sal_Int32 nDisplay (GetDisplay());
    VclPtr<WorkWindow> pWorkWindow = VclPtr<FullScreenWorkWindow>::Create(this, mpCurrentViewShellBase);
    pWorkWindow->SetBackground(Wallpaper(COL_BLACK));
    OUString Title(SdResId(STR_FULLSCREEN_SLIDESHOW));
    Title = Title.replaceFirst("%s",
                               mpCurrentViewShellBase->GetDocShell()->GetTitle(SFX_TITLE_DETECT));
    pWorkWindow->SetText(Title);
    pWorkWindow->StartPresentationMode( true, mpDoc->getPresentationSettings().mbAlwaysOnTop ? PresentationFlags::HideAllApps : PresentationFlags::NONE, nDisplay);
    //    pWorkWindow->ShowFullScreenMode(sal_False, nDisplay);

    if (!pWorkWindow->IsVisible())
        return;

    // Initialize the new presentation view shell with a copy of the
    // frame view of the current view shell.  This avoids that
    // changes made by the presentation have an effect on the other
    // view shells.
    FrameView* pOriginalFrameView = nullptr;
    ::std::shared_ptr<ViewShell> xShell(mpCurrentViewShellBase->GetMainViewShell());
    if (xShell)
        pOriginalFrameView = xShell->GetFrameView();

    delete mpFullScreenFrameView;
    mpFullScreenFrameView = new FrameView(mpDoc, pOriginalFrameView);

    // The new frame is created hidden.  To make it visible and activate the
    // new view shell--a prerequisite to process slot calls and initialize
    // its panes--a GrabFocus() has to be called later on.
    SfxFrame* pNewFrame = SfxFrame::CreateHidden( *mpDoc->GetDocSh(), *pWorkWindow, PRESENTATION_FACTORY_ID );
    pNewFrame->SetPresentationMode(true);

    mpFullScreenViewShellBase = static_cast<ViewShellBase*>(pNewFrame->GetCurrentViewFrame()->GetViewShell());
    if(mpFullScreenViewShellBase != nullptr)
    {
        // The following GrabFocus() is responsible for activating the
        // new view shell.  Without it the screen remains blank (under
        // Windows and some Linux variants.)
        mpFullScreenViewShellBase->GetWindow()->GrabFocus();
    }
}

/// convert configuration setting display concept to real screens
sal_Int32 SlideShow::GetDisplay()
{
    sal_Int32 nDisplay = 0;

    SdOptions* pOptions = SdModule::get()->GetSdOptions(DocumentType::Impress);
    if( pOptions )
        nDisplay = pOptions->GetDisplay();

    if( nDisplay < 0 )
        nDisplay = -1;
    else if( nDisplay == 0)
        nDisplay = static_cast<sal_Int32>(Application::GetDisplayExternalScreen());
    else
        nDisplay--;

    SAL_INFO("sd""Presenting on real screen " << nDisplay);

    return nDisplay;
}

bool SlideShow::dependsOn( ViewShellBase const * pViewShellBase )
{
    return mxController.is() && (pViewShellBase == mpCurrentViewShellBase) && mpFullScreenViewShellBase;
}

Reference< presentation::XPresentation2 > CreatePresentation( const SdDrawDocument& rDocument )
{
    return Reference< presentation::XPresentation2 >( SlideShow::Create( const_cast< SdDrawDocument* >( &rDocument ) ) );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=95 H=100 G=97

¤ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.