summaryrefslogtreecommitdiffstats
path: root/sd/source/ui/slideshow/showwin.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slideshow/showwin.cxx')
-rw-r--r--sd/source/ui/slideshow/showwin.cxx633
1 files changed, 633 insertions, 0 deletions
diff --git a/sd/source/ui/slideshow/showwin.cxx b/sd/source/ui/slideshow/showwin.cxx
new file mode 100644
index 0000000000..d6ecc19a69
--- /dev/null
+++ b/sd/source/ui/slideshow/showwin.cxx
@@ -0,0 +1,633 @@
+/* -*- 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/awt/Key.hpp>
+
+#include "showwindow.hxx"
+#include "slideshowimpl.hxx"
+
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/sfxsids.hrc>
+
+
+#include <slideshow.hxx>
+#include <ViewShell.hxx>
+#include <sdresid.hxx>
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <sal/log.hxx>
+#include <utility>
+#include <vcl/settings.hxx>
+#include <vcl/virdev.hxx>
+#include <tools/duration.hxx>
+
+using namespace ::com::sun::star;
+
+namespace sd {
+
+const sal_uInt64 HIDE_MOUSE_TIMEOUT = 10000;
+const sal_uInt64 SHOW_MOUSE_TIMEOUT = 1000;
+
+ShowWindow::ShowWindow( ::rtl::Reference< SlideshowImpl > xController, vcl::Window* pParent )
+: ::sd::Window( pParent )
+, maPauseTimer("sd ShowWindow maPauseTimer")
+, maMouseTimer("sd ShowWindow maMouseTimer")
+, mnPauseTimeout( SLIDE_NO_TIMEOUT )
+, mnRestartPageIndex( PAGE_NO_END )
+, meShowWindowMode(SHOWWINDOWMODE_NORMAL)
+, mbShowNavigatorAfterSpecialMode( false )
+, mbMouseAutoHide(true)
+, mbMouseCursorHidden(false)
+, mnFirstMouseMove(0)
+, mxController(std::move( xController ))
+{
+ GetOutDev()->SetOutDevViewType( OutDevViewType::SlideShow );
+
+ // Do never mirror the preview window. This explicitly includes right
+ // to left writing environments.
+ EnableRTL (false);
+
+ MapMode aMap(GetMapMode());
+ aMap.SetMapUnit(MapUnit::Map100thMM);
+ SetMapMode(aMap);
+
+ // set HelpId
+ SetHelpId( HID_SD_WIN_PRESENTATION );
+
+ maPauseTimer.SetInvokeHandler( LINK( this, ShowWindow, PauseTimeoutHdl ) );
+ maPauseTimer.SetTimeout( 1000 );
+ maMouseTimer.SetInvokeHandler( LINK( this, ShowWindow, MouseTimeoutHdl ) );
+ maMouseTimer.SetTimeout( HIDE_MOUSE_TIMEOUT );
+
+ maShowBackground = Wallpaper( COL_BLACK );
+ SetBackground(); // avoids that VCL paints any background!
+ GetParent()->Show();
+ AddEventListener( LINK( this, ShowWindow, EventHdl ) );
+}
+
+ShowWindow::~ShowWindow()
+{
+ disposeOnce();
+}
+
+void ShowWindow::dispose()
+{
+ maPauseTimer.Stop();
+ maMouseTimer.Stop();
+ ::sd::Window::dispose();
+}
+
+void ShowWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ // Ignore workaround of https://gitlab.gnome.org/GNOME/gtk/issues/1785
+ // See calls to GtkSalFrame::makeFakeKeyPress (Fixed in GTK 3.24)
+ bool bFakeKeyPress = rKEvt.GetKeyCode().GetFullCode() == 0;
+ if (bFakeKeyPress)
+ return;
+
+ bool bReturn = false;
+
+ if( SHOWWINDOWMODE_PREVIEW == meShowWindowMode )
+ {
+ TerminateShow();
+ bReturn = true;
+ }
+ else if( SHOWWINDOWMODE_END == meShowWindowMode )
+ {
+ const int nKeyCode = rKEvt.GetKeyCode().GetCode();
+ switch( nKeyCode )
+ {
+ case KEY_PAGEUP:
+ case KEY_LEFT:
+ case KEY_UP:
+ case KEY_P:
+ case KEY_HOME:
+ case KEY_END:
+ case awt::Key::CONTEXTMENU:
+ // these keys will be handled by the slide show even
+ // while in end mode
+ break;
+ default:
+ TerminateShow();
+ bReturn = true;
+ }
+ }
+ else if( SHOWWINDOWMODE_BLANK == meShowWindowMode )
+ {
+ RestartShow();
+ bReturn = true;
+ }
+ else if( SHOWWINDOWMODE_PAUSE == meShowWindowMode )
+ {
+ const int nKeyCode = rKEvt.GetKeyCode().GetCode();
+ switch( nKeyCode )
+ {
+ case KEY_ESCAPE:
+ TerminateShow();
+ bReturn = true;
+ break;
+ case KEY_PAGEUP:
+ case KEY_RIGHT:
+ case KEY_UP:
+ case KEY_P:
+ case KEY_HOME:
+ case KEY_END:
+ case awt::Key::CONTEXTMENU:
+ // these keys will be handled by the slide show even
+ // while in end mode
+ break;
+ default:
+ RestartShow();
+ bReturn = true;
+ break;
+ }
+ }
+
+ if( !bReturn )
+ {
+ if( mxController.is() )
+ bReturn = mxController->keyInput(rKEvt);
+
+ if( !bReturn )
+ {
+ if( mpViewShell )
+ {
+ mpViewShell->KeyInput(rKEvt,this);
+ }
+ else
+ {
+ Window::KeyInput(rKEvt);
+ }
+ }
+ }
+
+ if( mpViewShell )
+ mpViewShell->SetActiveWindow( this );
+}
+
+void ShowWindow::MouseButtonDown(const MouseEvent& /*rMEvt*/)
+{
+ if( SHOWWINDOWMODE_PREVIEW == meShowWindowMode )
+ {
+ TerminateShow();
+ }
+ else if( mpViewShell )
+ {
+ mpViewShell->SetActiveWindow( this );
+ }
+}
+
+void ShowWindow::MouseMove(const MouseEvent& /*rMEvt*/)
+{
+ if( mbMouseAutoHide )
+ {
+ if( mbMouseCursorHidden )
+ {
+ if( mnFirstMouseMove )
+ {
+ // if this is not the first mouse move while hidden, see if
+ // enough time has pasted to show mouse pointer again
+ sal_uInt64 nTime = ::tools::Time::GetSystemTicks();
+ if( (nTime - mnFirstMouseMove) >= SHOW_MOUSE_TIMEOUT )
+ {
+ ShowPointer( true );
+ mnFirstMouseMove = 0;
+ mbMouseCursorHidden = false;
+ maMouseTimer.SetTimeout( HIDE_MOUSE_TIMEOUT );
+ maMouseTimer.Start();
+ }
+ }
+ else
+ {
+ // if this is the first mouse move, note current
+ // time and start idle timer to cancel show mouse pointer
+ // again if not enough mouse movement is measured
+ mnFirstMouseMove = ::tools::Time::GetSystemTicks();
+ maMouseTimer.SetTimeout( 2*SHOW_MOUSE_TIMEOUT );
+ maMouseTimer.Start();
+ }
+ }
+ else
+ {
+ // current mousemove restarts the idle timer to hide the mouse
+ maMouseTimer.Start();
+ }
+ }
+
+ if( mpViewShell )
+ mpViewShell->SetActiveWindow( this );
+}
+
+void ShowWindow::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ if( SHOWWINDOWMODE_PREVIEW == meShowWindowMode )
+ {
+ TerminateShow();
+ }
+ else if( (SHOWWINDOWMODE_END == meShowWindowMode) && !rMEvt.IsRight() )
+ {
+ TerminateShow();
+ }
+ else if( (( SHOWWINDOWMODE_BLANK == meShowWindowMode ) || ( SHOWWINDOWMODE_PAUSE == meShowWindowMode ))
+ && !rMEvt.IsRight() )
+ {
+ RestartShow();
+ }
+ else
+ {
+ if( mxController.is() )
+ mxController->mouseButtonUp( rMEvt );
+ }
+}
+
+/**
+ * if FuSlideShow is still available, forward it
+ */
+void ShowWindow::Paint(vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect)
+{
+ if( (meShowWindowMode == SHOWWINDOWMODE_NORMAL) || (meShowWindowMode == SHOWWINDOWMODE_PREVIEW) )
+ {
+ if( mxController.is() )
+ {
+ mxController->paint();
+ }
+ else if(mpViewShell )
+ {
+ mpViewShell->Paint(rRect, this);
+ }
+ }
+ else
+ {
+ GetOutDev()->DrawWallpaper( rRect, maShowBackground );
+
+ if( SHOWWINDOWMODE_END == meShowWindowMode )
+ {
+ DrawEndScene();
+ }
+ else if( SHOWWINDOWMODE_PAUSE == meShowWindowMode )
+ {
+ DrawPauseScene( false );
+ }
+ else if( SHOWWINDOWMODE_BLANK == meShowWindowMode )
+ {
+ // just blank through background color => nothing to be done here
+ }
+ }
+}
+
+void ShowWindow::LoseFocus()
+{
+ Window::LoseFocus();
+
+ if( SHOWWINDOWMODE_PREVIEW == meShowWindowMode)
+ TerminateShow();
+}
+
+void ShowWindow::SetEndMode()
+{
+ if( !(( SHOWWINDOWMODE_NORMAL == meShowWindowMode ) && mpViewShell && mpViewShell->GetView()) )
+ return;
+
+ DeleteWindowFromPaintView();
+ meShowWindowMode = SHOWWINDOWMODE_END;
+ maShowBackground = Wallpaper( COL_BLACK );
+
+ // hide navigator if it is visible
+ if( mpViewShell->GetViewFrame()->GetChildWindow( SID_NAVIGATOR ) )
+ {
+ mpViewShell->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR, false );
+ mbShowNavigatorAfterSpecialMode = true;
+ }
+
+ Invalidate();
+}
+
+bool ShowWindow::SetPauseMode( sal_Int32 nTimeout, Graphic const * pLogo )
+{
+ rtl::Reference< SlideShow > xSlideShow;
+
+ if( mpViewShell )
+ xSlideShow = SlideShow::GetSlideShow( mpViewShell->GetViewShellBase() );
+
+ if( xSlideShow.is() && !nTimeout )
+ {
+ xSlideShow->jumpToPageIndex( 0 );
+ }
+ else if( ( SHOWWINDOWMODE_NORMAL == meShowWindowMode ) && mpViewShell && mpViewShell->GetView() )
+ {
+ DeleteWindowFromPaintView();
+ mnPauseTimeout = nTimeout;
+ mnRestartPageIndex = 0;
+ meShowWindowMode = SHOWWINDOWMODE_PAUSE;
+ maShowBackground = Wallpaper( COL_BLACK );
+
+ // hide navigator if it is visible
+ if( mpViewShell->GetViewFrame()->GetChildWindow( SID_NAVIGATOR ) )
+ {
+ mpViewShell->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR, false );
+ mbShowNavigatorAfterSpecialMode = true;
+ }
+
+ if( pLogo )
+ maLogo = *pLogo;
+
+ Invalidate();
+
+ if( SLIDE_NO_TIMEOUT != mnPauseTimeout )
+ maPauseTimer.Start();
+ }
+
+ return( SHOWWINDOWMODE_PAUSE == meShowWindowMode );
+}
+
+bool ShowWindow::SetBlankMode( sal_Int32 nPageIndexToRestart, const Color& rBlankColor )
+{
+ if( ( SHOWWINDOWMODE_NORMAL == meShowWindowMode ) && mpViewShell && mpViewShell->GetView() )
+ {
+ DeleteWindowFromPaintView();
+ mnRestartPageIndex = nPageIndexToRestart;
+ meShowWindowMode = SHOWWINDOWMODE_BLANK;
+ maShowBackground = Wallpaper( rBlankColor );
+
+ // hide navigator if it is visible
+ if( mpViewShell->GetViewFrame()->GetChildWindow( SID_NAVIGATOR ) )
+ {
+ mpViewShell->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR, false );
+ mbShowNavigatorAfterSpecialMode = true;
+ }
+
+ Invalidate();
+ }
+
+ return( SHOWWINDOWMODE_BLANK == meShowWindowMode );
+}
+
+void ShowWindow::SetPreviewMode()
+{
+ meShowWindowMode = SHOWWINDOWMODE_PREVIEW;
+}
+
+void ShowWindow::TerminateShow()
+{
+ maLogo.Clear();
+ maPauseTimer.Stop();
+ maMouseTimer.Stop();
+ GetOutDev()->Erase();
+ maShowBackground = Wallpaper( COL_BLACK );
+ meShowWindowMode = SHOWWINDOWMODE_NORMAL;
+ mnPauseTimeout = SLIDE_NO_TIMEOUT;
+
+ if( mpViewShell )
+ {
+ // show navigator?
+ if( mbShowNavigatorAfterSpecialMode )
+ {
+ mpViewShell->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR );
+ mbShowNavigatorAfterSpecialMode = false;
+ }
+ }
+
+ if( mxController.is() )
+ mxController->endPresentation();
+
+ mnRestartPageIndex = PAGE_NO_END;
+}
+
+void ShowWindow::RestartShow()
+{
+ RestartShow( mnRestartPageIndex );
+}
+
+void ShowWindow::RestartShow( sal_Int32 nPageIndexToRestart )
+{
+ ShowWindowMode eOldShowWindowMode = meShowWindowMode;
+
+ maLogo.Clear();
+ maPauseTimer.Stop();
+ GetOutDev()->Erase();
+ maShowBackground = Wallpaper( COL_BLACK );
+ meShowWindowMode = SHOWWINDOWMODE_NORMAL;
+ mnPauseTimeout = SLIDE_NO_TIMEOUT;
+
+ if( mpViewShell )
+ {
+ rtl::Reference< SlideShow > xSlideShow( SlideShow::GetSlideShow( mpViewShell->GetViewShellBase() ) );
+
+ if( xSlideShow.is() )
+ {
+ AddWindowToPaintView();
+
+ if( SHOWWINDOWMODE_BLANK == eOldShowWindowMode || SHOWWINDOWMODE_END == eOldShowWindowMode )
+ {
+ xSlideShow->pause(false);
+ Invalidate();
+ }
+ else
+ {
+ xSlideShow->jumpToPageIndex( nPageIndexToRestart );
+ }
+ }
+ }
+
+ mnRestartPageIndex = PAGE_NO_END;
+
+ // show navigator?
+ if( mbShowNavigatorAfterSpecialMode )
+ {
+ if (mpViewShell)
+ mpViewShell->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR );
+ mbShowNavigatorAfterSpecialMode = false;
+ }
+}
+
+void ShowWindow::DrawPauseScene( bool bTimeoutOnly )
+{
+ const MapMode& rMap = GetMapMode();
+ const Point aOutOrg( PixelToLogic( Point() ) );
+ const Size aOutSize( GetOutDev()->GetOutputSize() );
+ const Size aTextSize(OutputDevice::LogicToLogic(Size(0, 14), MapMode(MapUnit::MapPoint), rMap));
+ const Size aOffset(OutputDevice::LogicToLogic(Size(1000, 1000), MapMode(MapUnit::Map100thMM), rMap));
+ OUString aText( SdResId( STR_PRES_PAUSE ) );
+ bool bDrawn = false;
+
+ vcl::Font aFont( GetSettings().GetStyleSettings().GetMenuFont() );
+ const vcl::Font aOldFont( GetFont() );
+
+ aFont.SetFontSize( aTextSize );
+ aFont.SetColor( COL_WHITE );
+ aFont.SetCharSet( aOldFont.GetCharSet() );
+ aFont.SetLanguage( aOldFont.GetLanguage() );
+
+ if( !bTimeoutOnly && ( maLogo.GetType() != GraphicType::NONE ) )
+ {
+ Size aGrfSize;
+
+ if (maLogo.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel)
+ aGrfSize = PixelToLogic( maLogo.GetPrefSize() );
+ else
+ aGrfSize = OutputDevice::LogicToLogic( maLogo.GetPrefSize(), maLogo.GetPrefMapMode(), rMap );
+
+ const Point aGrfPos( std::max( aOutOrg.X() + aOutSize.Width() - aGrfSize.Width() - aOffset.Width(), aOutOrg.X() ),
+ std::max( aOutOrg.Y() + aOutSize.Height() - aGrfSize.Height() - aOffset.Height(), aOutOrg.Y() ) );
+
+ if( maLogo.IsAnimated() )
+ maLogo.StartAnimation(*GetOutDev(), aGrfPos, aGrfSize, reinterpret_cast<sal_IntPtr>(this));
+ else
+ maLogo.Draw(*GetOutDev(), aGrfPos, aGrfSize);
+ }
+
+ if( SLIDE_NO_TIMEOUT != mnPauseTimeout )
+ {
+ MapMode aVMap( rMap );
+ ScopedVclPtrInstance< VirtualDevice > pVDev( *GetOutDev() );
+
+ aVMap.SetOrigin( Point() );
+ pVDev->SetMapMode( aVMap );
+ pVDev->SetBackground( Wallpaper( COL_BLACK ) );
+
+ // set font first, to determine real output height
+ pVDev->SetFont( aFont );
+
+ const Size aVDevSize( aOutSize.Width(), pVDev->GetTextHeight() );
+
+ if( pVDev->SetOutputSize( aVDevSize ) )
+ {
+ // Note: if performance gets an issue here, we can use NumberFormatter directly
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& aLocaleData = aSysLocale.GetLocaleData();
+
+ aText += " ( " + aLocaleData.getDuration( ::tools::Duration( 0, 0, 0, mnPauseTimeout, 0 )) + " )";
+ pVDev->DrawText( Point( aOffset.Width(), 0 ), aText );
+ GetOutDev()->DrawOutDev( Point( aOutOrg.X(), aOffset.Height() ), aVDevSize, Point(), aVDevSize, *pVDev );
+ bDrawn = true;
+ }
+ }
+
+ if( !bDrawn )
+ {
+ SetFont( aFont );
+ GetOutDev()->DrawText( Point( aOutOrg.X() + aOffset.Width(), aOutOrg.Y() + aOffset.Height() ), aText );
+ SetFont( aOldFont );
+ }
+}
+
+void ShowWindow::DrawEndScene()
+{
+ const vcl::Font aOldFont( GetFont() );
+ vcl::Font aFont( GetSettings().GetStyleSettings().GetMenuFont() );
+
+ const Point aOutOrg( PixelToLogic( Point() ) );
+ const Size aTextSize(OutputDevice::LogicToLogic(Size(0, 14), MapMode(MapUnit::MapPoint), GetMapMode()));
+ const OUString aText( SdResId( STR_PRES_SOFTEND ) );
+
+ aFont.SetFontSize( aTextSize );
+ aFont.SetColor( COL_WHITE );
+ aFont.SetCharSet( aOldFont.GetCharSet() );
+ aFont.SetLanguage( aOldFont.GetLanguage() );
+ SetFont( aFont );
+ GetOutDev()->DrawText( Point( aOutOrg.X() + aTextSize.Height(), aOutOrg.Y() + aTextSize.Height() ), aText );
+ SetFont( aOldFont );
+}
+
+IMPL_LINK( ShowWindow, PauseTimeoutHdl, Timer*, pTimer, void )
+{
+ if( !( --mnPauseTimeout ) )
+ RestartShow();
+ else
+ {
+ DrawPauseScene( true );
+ pTimer->Start();
+ }
+}
+
+IMPL_LINK_NOARG(ShowWindow, MouseTimeoutHdl, Timer *, void)
+{
+ if( mbMouseCursorHidden )
+ {
+ // not enough mouse movements since first recording so
+ // cancel show mouse pointer for now
+ mnFirstMouseMove = 0;
+ }
+ else
+ {
+ // mouse has been idle too long, hide pointer
+ ShowPointer( false );
+ mbMouseCursorHidden = true;
+ }
+}
+
+IMPL_LINK( ShowWindow, EventHdl, VclWindowEvent&, rEvent, void )
+{
+ if( mbMouseAutoHide )
+ {
+ if (rEvent.GetId() == VclEventId::WindowShow)
+ {
+ maMouseTimer.SetTimeout( HIDE_MOUSE_TIMEOUT );
+ maMouseTimer.Start();
+ }
+ }
+}
+
+void ShowWindow::DeleteWindowFromPaintView()
+{
+ if( mpViewShell->GetView() )
+ mpViewShell->GetView()->DeleteDeviceFromPaintView( *GetOutDev() );
+
+ sal_uInt16 nChild = GetChildCount();
+ while( nChild-- )
+ GetChild( nChild )->Show( false );
+}
+
+void ShowWindow::AddWindowToPaintView()
+{
+ if( mpViewShell->GetView() )
+ mpViewShell->GetView()->AddDeviceToPaintView( *GetOutDev(), nullptr );
+
+ sal_uInt16 nChild = GetChildCount();
+ while( nChild-- )
+ GetChild( nChild )->Show();
+}
+
+// Override the sd::Window's CreateAccessible to create a different accessible object
+css::uno::Reference<css::accessibility::XAccessible>
+ ShowWindow::CreateAccessible()
+{
+ css::uno::Reference< css::accessibility::XAccessible > xAcc = GetAccessible(false);
+ if (xAcc)
+ {
+ return xAcc;
+ }
+ if (mpViewShell != nullptr)
+ {
+ xAcc = mpViewShell->CreateAccessibleDocumentView (this);
+ SetAccessible(xAcc);
+ return xAcc;
+ }
+ else
+ {
+ SAL_WARN("sd", "::sd::Window::CreateAccessible: no view shell");
+ return vcl::Window::CreateAccessible ();
+ }
+}
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */