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 18 kB image not shown  

Quelle  showwin.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/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)
    {
        --nChild;
        GetChild(nChild)->Show( false );
    }
}

void ShowWindow::AddWindowToPaintView()
{
    if( mpViewShell->GetView() )
        mpViewShell->GetView()->AddDeviceToPaintView( *GetOutDev(), nullptr );

    sal_uInt16 nChild = GetChildCount();
    while (nChild)
    {
        --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: */

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.2 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.