1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/awt/Key.hpp>
22 #include "showwindow.hxx"
24 #include <unotools/syslocale.hxx>
25 #include <sfx2/viewfrm.hxx>
28 #include <slideshow.hxx>
29 #include <ViewShellBase.hxx>
30 #include <sdresid.hxx>
32 #include <strings.hrc>
34 #include <vcl/settings.hxx>
35 #include <vcl/virdev.hxx>
37 using namespace ::com::sun::star
;
41 static const sal_uInt64 HIDE_MOUSE_TIMEOUT
= 10000;
42 static const sal_uInt64 SHOW_MOUSE_TIMEOUT
= 1000;
44 ShowWindow::ShowWindow( const ::rtl::Reference
< SlideshowImpl
>& xController
, vcl::Window
* pParent
)
45 : ::sd::Window( pParent
)
46 , mnPauseTimeout( SLIDE_NO_TIMEOUT
)
47 , mnRestartPageIndex( PAGE_NO_END
)
48 , meShowWindowMode(SHOWWINDOWMODE_NORMAL
)
49 , mbShowNavigatorAfterSpecialMode( false )
50 , mbMouseAutoHide(true)
51 , mbMouseCursorHidden(false)
53 , mxController( xController
)
55 SetOutDevViewType( OutDevViewType::SlideShow
);
57 // Do never mirror the preview window. This explicitly includes right
58 // to left writing environments.
61 MapMode
aMap(GetMapMode());
62 aMap
.SetMapUnit(MapUnit::Map100thMM
);
66 SetHelpId( HID_SD_WIN_PRESENTATION
);
68 maPauseTimer
.SetInvokeHandler( LINK( this, ShowWindow
, PauseTimeoutHdl
) );
69 maPauseTimer
.SetTimeout( 1000 );
70 maMouseTimer
.SetInvokeHandler( LINK( this, ShowWindow
, MouseTimeoutHdl
) );
71 maMouseTimer
.SetTimeout( HIDE_MOUSE_TIMEOUT
);
73 maShowBackground
= Wallpaper( COL_BLACK
);
74 SetBackground(); // avoids that VCL paints any background!
76 AddEventListener( LINK( this, ShowWindow
, EventHdl
) );
79 ShowWindow::~ShowWindow()
84 void ShowWindow::dispose()
88 ::sd::Window::dispose();
91 void ShowWindow::KeyInput(const KeyEvent
& rKEvt
)
95 if( SHOWWINDOWMODE_PREVIEW
== meShowWindowMode
)
100 else if( SHOWWINDOWMODE_END
== meShowWindowMode
)
102 const int nKeyCode
= rKEvt
.GetKeyCode().GetCode();
111 case awt::Key::CONTEXTMENU
:
112 // these keys will be handled by the slide show even
120 else if( SHOWWINDOWMODE_BLANK
== meShowWindowMode
)
125 else if( SHOWWINDOWMODE_PAUSE
== meShowWindowMode
)
127 const int nKeyCode
= rKEvt
.GetKeyCode().GetCode();
140 case awt::Key::CONTEXTMENU
:
141 // these keys will be handled by the slide show even
153 if( mxController
.is() )
154 bReturn
= mxController
->keyInput(rKEvt
);
160 mpViewShell
->KeyInput(rKEvt
,this);
164 Window::KeyInput(rKEvt
);
170 mpViewShell
->SetActiveWindow( this );
173 void ShowWindow::MouseButtonDown(const MouseEvent
& /*rMEvt*/)
175 if( SHOWWINDOWMODE_PREVIEW
== meShowWindowMode
)
179 else if( mpViewShell
)
181 mpViewShell
->SetActiveWindow( this );
185 void ShowWindow::MouseMove(const MouseEvent
& /*rMEvt*/)
187 if( mbMouseAutoHide
)
189 if( mbMouseCursorHidden
)
191 if( mnFirstMouseMove
)
193 // if this is not the first mouse move while hidden, see if
194 // enough time has pasted to show mouse pointer again
195 sal_uInt64 nTime
= ::tools::Time::GetSystemTicks();
196 if( (nTime
- mnFirstMouseMove
) >= SHOW_MOUSE_TIMEOUT
)
199 mnFirstMouseMove
= 0;
200 mbMouseCursorHidden
= false;
201 maMouseTimer
.SetTimeout( HIDE_MOUSE_TIMEOUT
);
202 maMouseTimer
.Start();
207 // if this is the first mouse move, note current
208 // time and start idle timer to cancel show mouse pointer
209 // again if not enough mouse movement is measured
210 mnFirstMouseMove
= ::tools::Time::GetSystemTicks();
211 maMouseTimer
.SetTimeout( 2*SHOW_MOUSE_TIMEOUT
);
212 maMouseTimer
.Start();
217 // current mousemove restarts the idle timer to hide the mouse
218 maMouseTimer
.Start();
223 mpViewShell
->SetActiveWindow( this );
226 void ShowWindow::MouseButtonUp(const MouseEvent
& rMEvt
)
228 if( SHOWWINDOWMODE_PREVIEW
== meShowWindowMode
)
232 else if( (SHOWWINDOWMODE_END
== meShowWindowMode
) && !rMEvt
.IsRight() )
236 else if( (( SHOWWINDOWMODE_BLANK
== meShowWindowMode
) || ( SHOWWINDOWMODE_PAUSE
== meShowWindowMode
))
237 && !rMEvt
.IsRight() )
243 if( mxController
.is() )
244 mxController
->mouseButtonUp( rMEvt
);
249 * if FuSlideShow is still available, forward it
251 void ShowWindow::Paint(vcl::RenderContext
& /*rRenderContext*/, const ::tools::Rectangle
& rRect
)
253 if( (meShowWindowMode
== SHOWWINDOWMODE_NORMAL
) || (meShowWindowMode
== SHOWWINDOWMODE_PREVIEW
) )
255 if( mxController
.is() )
257 mxController
->paint();
259 else if(mpViewShell
)
261 mpViewShell
->Paint(rRect
, this);
266 DrawWallpaper( rRect
, maShowBackground
);
268 if( SHOWWINDOWMODE_END
== meShowWindowMode
)
272 else if( SHOWWINDOWMODE_PAUSE
== meShowWindowMode
)
274 DrawPauseScene( false );
276 else if( SHOWWINDOWMODE_BLANK
== meShowWindowMode
)
278 // just blank through background color => nothing to be done here
283 void ShowWindow::LoseFocus()
287 if( SHOWWINDOWMODE_PREVIEW
== meShowWindowMode
)
291 void ShowWindow::SetEndMode()
293 if( ( SHOWWINDOWMODE_NORMAL
== meShowWindowMode
) && mpViewShell
&& mpViewShell
->GetView() )
295 DeleteWindowFromPaintView();
296 meShowWindowMode
= SHOWWINDOWMODE_END
;
297 maShowBackground
= Wallpaper( COL_BLACK
);
299 // hide navigator if it is visible
300 if( mpViewShell
->GetViewFrame()->GetChildWindow( SID_NAVIGATOR
) )
302 mpViewShell
->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR
, false );
303 mbShowNavigatorAfterSpecialMode
= true;
310 bool ShowWindow::SetPauseMode( sal_Int32 nTimeout
, Graphic
const * pLogo
)
312 rtl::Reference
< SlideShow
> xSlideShow
;
315 xSlideShow
= SlideShow::GetSlideShow( mpViewShell
->GetViewShellBase() );
317 if( xSlideShow
.is() && !nTimeout
)
319 xSlideShow
->jumpToPageIndex( 0 );
321 else if( ( SHOWWINDOWMODE_NORMAL
== meShowWindowMode
) && mpViewShell
&& mpViewShell
->GetView() )
323 DeleteWindowFromPaintView();
324 mnPauseTimeout
= nTimeout
;
325 mnRestartPageIndex
= 0;
326 meShowWindowMode
= SHOWWINDOWMODE_PAUSE
;
327 maShowBackground
= Wallpaper( COL_BLACK
);
329 // hide navigator if it is visible
330 if( mpViewShell
->GetViewFrame()->GetChildWindow( SID_NAVIGATOR
) )
332 mpViewShell
->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR
, false );
333 mbShowNavigatorAfterSpecialMode
= true;
341 if( SLIDE_NO_TIMEOUT
!= mnPauseTimeout
)
342 maPauseTimer
.Start();
345 return( SHOWWINDOWMODE_PAUSE
== meShowWindowMode
);
348 bool ShowWindow::SetBlankMode( sal_Int32 nPageIndexToRestart
, const Color
& rBlankColor
)
350 if( ( SHOWWINDOWMODE_NORMAL
== meShowWindowMode
) && mpViewShell
&& mpViewShell
->GetView() )
352 DeleteWindowFromPaintView();
353 mnRestartPageIndex
= nPageIndexToRestart
;
354 meShowWindowMode
= SHOWWINDOWMODE_BLANK
;
355 maShowBackground
= Wallpaper( rBlankColor
);
357 // hide navigator if it is visible
358 if( mpViewShell
->GetViewFrame()->GetChildWindow( SID_NAVIGATOR
) )
360 mpViewShell
->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR
, false );
361 mbShowNavigatorAfterSpecialMode
= true;
367 return( SHOWWINDOWMODE_BLANK
== meShowWindowMode
);
370 void ShowWindow::SetPreviewMode()
372 meShowWindowMode
= SHOWWINDOWMODE_PREVIEW
;
375 void ShowWindow::TerminateShow()
381 maShowBackground
= Wallpaper( COL_BLACK
);
382 meShowWindowMode
= SHOWWINDOWMODE_NORMAL
;
383 mnPauseTimeout
= SLIDE_NO_TIMEOUT
;
388 if( mbShowNavigatorAfterSpecialMode
)
390 mpViewShell
->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR
);
391 mbShowNavigatorAfterSpecialMode
= false;
395 if( mxController
.is() )
396 mxController
->endPresentation();
398 mnRestartPageIndex
= PAGE_NO_END
;
401 void ShowWindow::RestartShow()
403 RestartShow( mnRestartPageIndex
);
406 void ShowWindow::RestartShow( sal_Int32 nPageIndexToRestart
)
409 ShowWindowMode eOldShowWindowMode
= meShowWindowMode
;
414 maShowBackground
= Wallpaper( COL_BLACK
);
415 meShowWindowMode
= SHOWWINDOWMODE_NORMAL
;
416 mnPauseTimeout
= SLIDE_NO_TIMEOUT
;
420 rtl::Reference
< SlideShow
> xSlideShow( SlideShow::GetSlideShow( mpViewShell
->GetViewShellBase() ) );
422 if( xSlideShow
.is() )
424 AddWindowToPaintView();
426 if( SHOWWINDOWMODE_BLANK
== eOldShowWindowMode
)
428 xSlideShow
->pause(false);
433 xSlideShow
->jumpToPageIndex( nPageIndexToRestart
);
438 mnRestartPageIndex
= PAGE_NO_END
;
441 if( mbShowNavigatorAfterSpecialMode
)
444 mpViewShell
->GetViewFrame()->ShowChildWindow( SID_NAVIGATOR
);
445 mbShowNavigatorAfterSpecialMode
= false;
449 void ShowWindow::DrawPauseScene( bool bTimeoutOnly
)
451 const MapMode
& rMap
= GetMapMode();
452 const Point
aOutOrg( PixelToLogic( Point() ) );
453 const Size
aOutSize( GetOutputSize() );
454 const Size
aTextSize(LogicToLogic(Size(0, 14), MapMode(MapUnit::MapPoint
), rMap
));
455 const Size
aOffset(LogicToLogic(Size(1000, 1000), MapMode(MapUnit::Map100thMM
), rMap
));
456 OUString
aText( SdResId( STR_PRES_PAUSE
) );
459 vcl::Font
aFont( GetSettings().GetStyleSettings().GetMenuFont() );
460 const vcl::Font
aOldFont( GetFont() );
462 aFont
.SetFontSize( aTextSize
);
463 aFont
.SetColor( COL_WHITE
);
464 aFont
.SetCharSet( aOldFont
.GetCharSet() );
465 aFont
.SetLanguage( aOldFont
.GetLanguage() );
467 if( !bTimeoutOnly
&& ( maLogo
.GetType() != GraphicType::NONE
) )
471 if (maLogo
.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel
)
472 aGrfSize
= PixelToLogic( maLogo
.GetPrefSize() );
474 aGrfSize
= LogicToLogic( maLogo
.GetPrefSize(), maLogo
.GetPrefMapMode(), rMap
);
476 const Point
aGrfPos( std::max( aOutOrg
.X() + aOutSize
.Width() - aGrfSize
.Width() - aOffset
.Width(), aOutOrg
.X() ),
477 std::max( aOutOrg
.Y() + aOutSize
.Height() - aGrfSize
.Height() - aOffset
.Height(), aOutOrg
.Y() ) );
479 if( maLogo
.IsAnimated() )
480 maLogo
.StartAnimation( this, aGrfPos
, aGrfSize
, reinterpret_cast<sal_IntPtr
>(this) );
482 maLogo
.Draw( this, aGrfPos
, aGrfSize
);
485 if( SLIDE_NO_TIMEOUT
!= mnPauseTimeout
)
487 MapMode
aVMap( rMap
);
488 ScopedVclPtrInstance
< VirtualDevice
> pVDev( *this );
490 aVMap
.SetOrigin( Point() );
491 pVDev
->SetMapMode( aVMap
);
492 pVDev
->SetBackground( Wallpaper( COL_BLACK
) );
494 // set font first, to determine real output height
495 pVDev
->SetFont( aFont
);
497 const Size
aVDevSize( aOutSize
.Width(), pVDev
->GetTextHeight() );
499 if( pVDev
->SetOutputSize( aVDevSize
) )
501 // Note: if performance gets an issue here, we can use NumberFormatter directly
502 SvtSysLocale aSysLocale
;
503 const LocaleDataWrapper
& aLocaleData
= aSysLocale
.GetLocaleData();
506 aText
+= aLocaleData
.getDuration( ::tools::Time( 0, 0, mnPauseTimeout
) );
508 pVDev
->DrawText( Point( aOffset
.Width(), 0 ), aText
);
509 DrawOutDev( Point( aOutOrg
.X(), aOffset
.Height() ), aVDevSize
, Point(), aVDevSize
, *pVDev
.get() );
517 DrawText( Point( aOutOrg
.X() + aOffset
.Width(), aOutOrg
.Y() + aOffset
.Height() ), aText
);
522 void ShowWindow::DrawEndScene()
524 const vcl::Font
aOldFont( GetFont() );
525 vcl::Font
aFont( GetSettings().GetStyleSettings().GetMenuFont() );
527 const Point
aOutOrg( PixelToLogic( Point() ) );
528 const Size
aTextSize(LogicToLogic(Size(0, 14), MapMode(MapUnit::MapPoint
), GetMapMode()));
529 const OUString
aText( SdResId( STR_PRES_SOFTEND
) );
531 aFont
.SetFontSize( aTextSize
);
532 aFont
.SetColor( COL_WHITE
);
533 aFont
.SetCharSet( aOldFont
.GetCharSet() );
534 aFont
.SetLanguage( aOldFont
.GetLanguage() );
536 DrawText( Point( aOutOrg
.X() + aTextSize
.Height(), aOutOrg
.Y() + aTextSize
.Height() ), aText
);
540 IMPL_LINK( ShowWindow
, PauseTimeoutHdl
, Timer
*, pTimer
, void )
542 if( !( --mnPauseTimeout
) )
546 DrawPauseScene( true );
551 IMPL_LINK_NOARG(ShowWindow
, MouseTimeoutHdl
, Timer
*, void)
553 if( mbMouseCursorHidden
)
555 // not enough mouse movements since first recording so
556 // cancel show mouse pointer for now
557 mnFirstMouseMove
= 0;
561 // mouse has been idle to long, hide pointer
562 ShowPointer( false );
563 mbMouseCursorHidden
= true;
567 IMPL_LINK( ShowWindow
, EventHdl
, VclWindowEvent
&, rEvent
, void )
569 if( mbMouseAutoHide
)
571 if (rEvent
.GetId() == VclEventId::WindowShow
)
573 maMouseTimer
.SetTimeout( HIDE_MOUSE_TIMEOUT
);
574 maMouseTimer
.Start();
579 void ShowWindow::SetPresentationArea( const ::tools::Rectangle
& rPresArea
)
581 maPresArea
= rPresArea
;
584 void ShowWindow::DeleteWindowFromPaintView()
586 if( mpViewShell
->GetView() )
587 mpViewShell
->GetView()->DeleteWindowFromPaintView( this );
589 sal_uInt16 nChild
= GetChildCount();
591 GetChild( nChild
)->Show( false );
594 void ShowWindow::AddWindowToPaintView()
596 if( mpViewShell
->GetView() )
597 mpViewShell
->GetView()->AddWindowToPaintView( this, nullptr );
599 sal_uInt16 nChild
= GetChildCount();
601 GetChild( nChild
)->Show();
604 // Override the sd::Window's CreateAccessible to create a different accessible object
605 css::uno::Reference
<css::accessibility::XAccessible
>
606 ShowWindow::CreateAccessible()
608 css::uno::Reference
< css::accessibility::XAccessible
> xAcc
= GetAccessible(false);
613 if (mpViewShell
!= nullptr)
615 xAcc
= mpViewShell
->CreateAccessibleDocumentView (this);
621 SAL_WARN("sd", "::sd::Window::CreateAccessible: no view shell");
622 return vcl::Window::CreateAccessible ();
625 } // end of namespace sd
627 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */