/* -*- 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 .
*/
using ::com::sun::star::presentation::XSlideShowController; using ::sd::framework::FrameworkHelper; using ::com::sun::star::awt::XWindow; usingnamespace ::sd; usingnamespace ::cppu; usingnamespace ::com::sun::star; usingnamespace ::com::sun::star::uno; usingnamespace ::com::sun::star::drawing; usingnamespace ::com::sun::star::beans; usingnamespace ::com::sun::star::lang; usingnamespace ::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))
{}
/// used by the model to create a slideshow for it
rtl::Reference< SlideShow > SlideShow::Create( SdDrawDocument* pDoc )
{ returnnew SlideShow( pDoc );
}
// 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 );
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));
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);
// 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 = 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();
} elseif( mpCurrentViewShellBase )
{
ViewShell* pViewShell = mpCurrentViewShellBase->GetMainViewShell().get();
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();
// 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;
}
// Stop a running show before starting a new one. if( mxController.is() )
{
assert(!mbIsInStartup);
end();
} elseif (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;
// 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();
// Start either a full-screen or an in-place show. if(mxCurrentSettings->mbFullScreen && !mxCurrentSettings->mbPreview)
StartFullscreenPresentation(); else
StartInPlacePresentation();
if (!mxController->startShow(mxCurrentSettings.get())) returnfalse;
pShell->Resize(); // Defer the sd::ShowWindow's GrabFocus to here. so that the accessible event can be fired correctly.
pShell->GetActiveWindow()->GrabFocus();
}
}
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.
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;
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.