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

Quelle  vclxwindow.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 <stdarg.h>
#include <memory>
#include <com/sun/star/awt/WindowEvent.hpp>
#include <com/sun/star/awt/KeyEvent.hpp>
#include <com/sun/star/awt/MouseEvent.hpp>
#include <com/sun/star/awt/MouseWheelBehavior.hpp>
#include <com/sun/star/awt/Style.hpp>
#include <com/sun/star/awt/DockingEvent.hpp>
#include <com/sun/star/awt/EndDockingEvent.hpp>
#include <com/sun/star/awt/EndPopupModeEvent.hpp>
#include <com/sun/star/awt/XWindowListener2.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
#include <toolkit/awt/vclxwindow.hxx>
#include <awt/vclxpointer.hxx>
#include <toolkit/awt/vclxwindows.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <helper/property.hxx>
#include <rtl/math.hxx>
#include <sal/log.hxx>
#include <utility>
#include <vcl/toolkit/floatwin.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <tools/color.hxx>
#include <tools/fract.hxx>
#include <tools/debug.hxx>
#include <vcl/accessiblefactory.hxx>
#include <vcl/event.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/pdfextoutdevdata.hxx>
#include <vcl/tabpage.hxx>
#include <vcl/ctrl.hxx>
#include <vcl/settings.hxx>
#include <vcl/unohelp.hxx>
#include <vcl/commandevent.hxx>
#include <comphelper/flagguard.hxx>
#include <comphelper/interfacecontainer3.hxx>
#include <comphelper/profilezone.hxx>
#include "stylesettings.hxx"
#include <tools/urlobj.hxx>

#include <helper/unopropertyarrayhelper.hxx>
#include <atomic>

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::lang::EventObject;
using ::com::sun::star::awt::XWindowListener2;
using ::com::sun::star::awt::XDockableWindowListener;
using ::com::sun::star::awt::XDevice;
using ::com::sun::star::awt::XStyleSettings;
using ::com::sun::star::lang::DisposedException;
using ::com::sun::star::style::VerticalAlignment;
using ::com::sun::star::style::VerticalAlignment_TOP;
using ::com::sun::star::style::VerticalAlignment_MIDDLE;
using ::com::sun::star::style::VerticalAlignment_BOTTOM;

namespace WritingMode2 = ::com::sun::star::text::WritingMode2;


//= VCLXWindowImpl

class VCLXWindowImpl
{
private:
    typedef ::std::vector< VCLXWindow::Callback >                       CallbackArray;

private:
    VCLXWindow&                         mrAntiImpl;
    bool                                mbDisposed;
    bool                                mbDrawingOntoParent;    // no bit mask, is passed around  by reference
    bool                            mbEnableVisible;
    bool                            mbDirectVisible;

    ::osl::Mutex                        maListenerContainerMutex;
    ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>  maWindow2Listeners;
    ::comphelper::OInterfaceContainerHelper3<XDockableWindowListener> maDockableWindowListeners;
    EventListenerMultiplexer            maEventListeners;
    FocusListenerMultiplexer            maFocusListeners;
    WindowListenerMultiplexer           maWindowListeners;
    KeyListenerMultiplexer              maKeyListeners;
    MouseListenerMultiplexer            maMouseListeners;
    MouseMotionListenerMultiplexer      maMouseMotionListeners;
    PaintListenerMultiplexer            maPaintListeners;
    VclContainerListenerMultiplexer     maContainerListeners;
    TopWindowListenerMultiplexer        maTopWindowListeners;

    CallbackArray                       maCallbackEvents;
    ImplSVEvent *                       mnCallbackEventId;

public:
    bool                                mbDisposing             : 1;
    bool                                mbDesignMode            : 1;
    bool                                mbSynthesizingVCLEvent  : 1;
    bool                                mbWithDefaultProps      : 1;

    std::atomic<int>                    mnListenerLockLevel;
    sal_Int16                           mnWritingMode;
    sal_Int16                           mnContextWritingMode;

    std::unique_ptr<UnoPropertyArrayHelper>
                                        mpPropHelper;

    css::uno::Reference< css::accessibility::XAccessibleContext >
                                        mxAccessibleContext;
    css::uno::Reference< css::awt::XGraphics >
                                        mxViewGraphics;
    rtl::Reference< toolkit::WindowStyleSettings >
                                        mxWindowStyleSettings;

public:
    bool&   getDrawingOntoParent_ref()  { return mbDrawingOntoParent; }

public:
    /** ctor
    @param _pAntiImpl
        the <type>VCLXWindow</type> instance which the object belongs to. Must
        live longer then the object just being constructed.
    */

    VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps );

    VCLXWindowImpl( const VCLXWindowImpl& ) = delete;
    const VCLXWindowImpl& operator=(const VCLXWindowImpl&) = delete;

    /** synchronously mbEnableVisible
    */

    void    setEnableVisible( bool bEnableVisible ) { mbEnableVisible = bEnableVisible; }
    bool    isEnableVisible() const { return mbEnableVisible; }
    /** synchronously mbDirectVisible;
    */

    void    setDirectVisible( bool bDirectVisible ) { mbDirectVisible = bDirectVisible; }
    bool    isDirectVisible() const { return mbDirectVisible; }

    /** impl-version of VCLXWindow::ImplExecuteAsyncWithoutSolarLock
    */

    void    callBackAsync( const VCLXWindow::Callback& i_callback );

    /** notifies the object that its VCLXWindow is being disposed
    */

    void    disposing();

    Reference< XStyleSettings > getStyleSettings();

    /** returns the container of registered XWindowListener2 listeners
    */

    ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& getWindow2Listeners() { return maWindow2Listeners; }
    ::comphelper::OInterfaceContainerHelper3<XDockableWindowListener>& getDockableWindowListeners() { return maDockableWindowListeners; }
    EventListenerMultiplexer&            getEventListeners()         { return maEventListeners; }
    FocusListenerMultiplexer&            getFocusListeners()         { return maFocusListeners; }
    WindowListenerMultiplexer&           getWindowListeners()        { return maWindowListeners; }
    KeyListenerMultiplexer&              getKeyListeners()           { return maKeyListeners; }
    MouseListenerMultiplexer&            getMouseListeners()         { return maMouseListeners; }
    MouseMotionListenerMultiplexer&      getMouseMotionListeners()   { return maMouseMotionListeners; }
    PaintListenerMultiplexer&            getPaintListeners()         { return maPaintListeners; }
    VclContainerListenerMultiplexer&     getContainerListeners()     { return maContainerListeners; }
    TopWindowListenerMultiplexer&        getTopWindowListeners()     { return maTopWindowListeners; }

private:
    DECL_LINK( OnProcessCallbacks, void*, void );
};


VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps )
    :mrAntiImpl( _rAntiImpl )
    ,mbDisposed( false )
    ,mbDrawingOntoParent( false )
    ,mbEnableVisible(true)
    ,mbDirectVisible(true)
    ,maWindow2Listeners( maListenerContainerMutex )
    ,maDockableWindowListeners( maListenerContainerMutex )
    ,maEventListeners( _rAntiImpl )
    ,maFocusListeners( _rAntiImpl )
    ,maWindowListeners( _rAntiImpl )
    ,maKeyListeners( _rAntiImpl )
    ,maMouseListeners( _rAntiImpl )
    ,maMouseMotionListeners( _rAntiImpl )
    ,maPaintListeners( _rAntiImpl )
    ,maContainerListeners( _rAntiImpl )
    ,maTopWindowListeners( _rAntiImpl )
    ,mnCallbackEventId( nullptr )
    ,mbDisposing( false )
    ,mbDesignMode( false )
    ,mbSynthesizingVCLEvent( false )
    ,mbWithDefaultProps( _bWithDefaultProps )
    ,mnListenerLockLevel( 0 )
    ,mnWritingMode( WritingMode2::CONTEXT )
    ,mnContextWritingMode( WritingMode2::CONTEXT )
{
}

void VCLXWindowImpl::disposing()
{
    SolarMutexGuard aGuard;

    assert(!mbDisposed);

    mbDisposed = true;

    if ( mnCallbackEventId )
    {
        Application::RemoveUserEvent( mnCallbackEventId );
        mnCallbackEventId = nullptr;
        // we acquired our VCLXWindow once before posting the event, release this one ref now
        mrAntiImpl.release();
    }
    maCallbackEvents.clear();

    css::lang::EventObject aEvent;
    aEvent.Source = mrAntiImpl;

    maDockableWindowListeners.disposeAndClear( aEvent );
    maEventListeners.disposeAndClear( aEvent );
    maFocusListeners.disposeAndClear( aEvent );
    maWindowListeners.disposeAndClear( aEvent );
    maKeyListeners.disposeAndClear( aEvent );
    maMouseListeners.disposeAndClear( aEvent );
    maMouseMotionListeners.disposeAndClear( aEvent );
    maPaintListeners.disposeAndClear( aEvent );
    maContainerListeners.disposeAndClear( aEvent );
    maTopWindowListeners.disposeAndClear( aEvent );
    maWindow2Listeners.disposeAndClear( aEvent );

    if ( mxWindowStyleSettings )
        mxWindowStyleSettings->dispose();
    mxWindowStyleSettings.clear();
}


void VCLXWindowImpl::callBackAsync( const VCLXWindow::Callback& i_callback )
{
    DBG_TESTSOLARMUTEX();
    maCallbackEvents.push_back( i_callback );
    if ( !mnCallbackEventId )
    {
        // ensure our VCLXWindow is not destroyed while the event is underway
        mrAntiImpl.acquire();
        mnCallbackEventId = Application::PostUserEvent( LINK( this, VCLXWindowImpl, OnProcessCallbacks ) );
    }
}


IMPL_LINK_NOARG(VCLXWindowImpl, OnProcessCallbacks, void*, void)
{
    const Reference< uno::XInterface > xKeepAlive( mrAntiImpl );

    SAL_INFO("toolkit.controls""OnProcessCallbacks grabbing solarmutex");

    // work on a copy of the callback array
    CallbackArray aCallbacksCopy;
    {
        SolarMutexGuard aGuard;
        aCallbacksCopy.swap(maCallbackEvents);

        // we acquired our VCLXWindow once before posting the event, release this one ref now
        mrAntiImpl.release();

        assert( mnCallbackEventId && "should not be possible to call us if the event was removed");

        mnCallbackEventId = nullptr;
    }

    {
        SAL_INFO("toolkit.controls""OnProcessCallbacks relinquished solarmutex");
        SolarMutexReleaser aReleaseSolar;
        for (const auto& rCallback : aCallbacksCopy)
        {
            rCallback();
        }
    }
}

Reference< XStyleSettings > VCLXWindowImpl::getStyleSettings()
{
    SolarMutexGuard aGuard;
    if ( mbDisposed )
        throw DisposedException( OUString(), mrAntiImpl );
    if ( !mxWindowStyleSettings.is() )
        mxWindowStyleSettings = new ::toolkit::WindowStyleSettings( maListenerContainerMutex, mrAntiImpl );
    return mxWindowStyleSettings;
}


// Uses an out-parameter instead of return value, due to the object reference

static void ImplInitWindowEvent( css::awt::WindowEvent& rEvent, vcl::Window const * pWindow )
{
    Point aPos = pWindow->GetPosPixel();
    Size aSz = pWindow->GetSizePixel();

    rEvent.X = aPos.X();
    rEvent.Y = aPos.Y();

    rEvent.Width = aSz.Width();
    rEvent.Height = aSz.Height();

    pWindow->GetBorder( rEvent.LeftInset, rEvent.TopInset, rEvent.RightInset, rEvent.BottomInset );
}

VCLXWindow::VCLXWindow( bool _bWithDefaultProps )
{
    mpImpl.reset( new VCLXWindowImpl( *this, _bWithDefaultProps ) );
}

VCLXWindow::~VCLXWindow()
{
    assert(mpImpl->mbDisposing && "forgot to call dispose()");
}


void VCLXWindow::ImplExecuteAsyncWithoutSolarLock( const Callback& i_callback )
{
    if (mpImpl->mbDisposing)
        return;
    mpImpl->callBackAsync( i_callback );
}

void VCLXWindow::SetWindow( const VclPtr<vcl::Window> &pWindow )
{
    assert(!mpImpl->mbDisposing || !pWindow);

    if ( GetWindow() )
    {
        GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
//        GetWindow()->DbgAssertNoEventListeners();
    }

    SetOutputDevice( pWindow ? pWindow->GetOutDev() : nullptr );

    if ( GetWindow() )
    {
        GetWindow()->AddEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
        bool bDirectVisible = pWindow && pWindow->IsVisible();
        mpImpl->setDirectVisible( bDirectVisible );
    }
}

void VCLXWindow::suspendVclEventListening( )
{
    ++mpImpl->mnListenerLockLevel;
}

void VCLXWindow::resumeVclEventListening( )
{
    DBG_ASSERT( mpImpl->mnListenerLockLevel, "VCLXWindow::resumeVclEventListening: not suspended!" );
    --mpImpl->mnListenerLockLevel;
}

void VCLXWindow::notifyWindowRemoved( vcl::Window const & _rWindow )
{
    if ( mpImpl->getContainerListeners().getLength() )
    {
        awt::VclContainerEvent aEvent;
        aEvent.Source = *this;
        aEvent.Child = static_cast< XWindow* >( _rWindow.GetWindowPeer() );
        mpImpl->getContainerListeners().windowRemoved( aEvent );
    }
}

IMPL_LINK( VCLXWindow, WindowEventListener, VclWindowEvent&, rEvent, void )
{
    if ( mpImpl->mbDisposing || mpImpl->mnListenerLockLevel )
        return;

    DBG_ASSERT( rEvent.GetWindow() && GetWindow(), "Window???" );
    ProcessWindowEvent( rEvent );
}

namespace
{
    struct CallWindow2Listener
    {
        CallWindow2Listener( ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& i_rWindow2Listeners, const bool i_bEnabled, EventObject i_Event )
            :m_rWindow2Listeners( i_rWindow2Listeners )
            ,m_bEnabled( i_bEnabled )
            ,m_aEvent(std::move( i_Event ))
        {
        }

        void operator()()
        {
            m_rWindow2Listeners.notifyEach( m_bEnabled ? &XWindowListener2::windowEnabled : &XWindowListener2::windowDisabled, m_aEvent );
        }

        ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>&  m_rWindow2Listeners;
        const bool                          m_bEnabled;
        const EventObject                   m_aEvent;
    };
}

void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
    if (mpImpl->mbDisposing)
        return;
    css::uno::Reference< css::uno::XInterface > xThis( getXWeak() );

    switch ( rVclWindowEvent.GetId() )
    {
        case VclEventId::WindowEnabled:
        case VclEventId::WindowDisabled:
        {
            Callback aCallback = CallWindow2Listener(
                mpImpl->getWindow2Listeners(),
                ( VclEventId::WindowEnabled == rVclWindowEvent.GetId() ),
                EventObject( *this )
            );
            ImplExecuteAsyncWithoutSolarLock( aCallback );
        }
        break;

        case VclEventId::WindowPaint:
        {
            if ( mpImpl->getPaintListeners().getLength() )
            {
                css::awt::PaintEvent aEvent;
                aEvent.Source = getXWeak();
                aEvent.UpdateRect = vcl::unohelper::ConvertToAWTRect(
                    *static_cast<tools::Rectangle*>(rVclWindowEvent.GetData()));
                aEvent.Count = 0;
                mpImpl->getPaintListeners().windowPaint( aEvent );
            }
        }
        break;
        case VclEventId::WindowMove:
        {
            if ( mpImpl->getWindowListeners().getLength() )
            {
                css::awt::WindowEvent aEvent;
                aEvent.Source = getXWeak();
                ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
                mpImpl->getWindowListeners().windowMoved( aEvent );
            }
        }
        break;
        case VclEventId::WindowResize:
        {
            if ( mpImpl->getWindowListeners().getLength() )
            {
                css::awt::WindowEvent aEvent;
                aEvent.Source = getXWeak();
                ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
                mpImpl->getWindowListeners().windowResized( aEvent );
            }
        }
        break;
        case VclEventId::WindowShow:
        {
            if ( mpImpl->getWindowListeners().getLength() )
            {
                css::awt::WindowEvent aEvent;
                aEvent.Source = getXWeak();
                ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
                mpImpl->getWindowListeners().windowShown( aEvent );
            }

            // For TopWindows this means opened...
            if ( mpImpl->getTopWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getTopWindowListeners().windowOpened( aEvent );
            }
        }
        break;
        case VclEventId::WindowHide:
        {
            if ( mpImpl->getWindowListeners().getLength() )
            {
                css::awt::WindowEvent aEvent;
                aEvent.Source = getXWeak();
                ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
                mpImpl->getWindowListeners().windowHidden( aEvent );
            }

            // For TopWindows this means closed...
            if ( mpImpl->getTopWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getTopWindowListeners().windowClosed( aEvent );
            }
        }
        break;
        case VclEventId::WindowActivate:
        case VclEventId::WindowDeactivate:
        {
            if (!mpImpl->getTopWindowListeners().getLength())
                return;

            // Suppress events which are unlikely to be interesting to our listeners.
            vcl::Window* pWin = static_cast<vcl::Window*>(rVclWindowEvent.GetData());
            bool bSuppress = false;

            while (pWin)
            {
                // Either the event came from the same window, from its
                // child, or from a child of its border window (e.g.
                // menubar or notebookbar).
                if (pWin->GetWindow(GetWindowType::Client) == GetWindow())
                    return;

                if (pWin->IsMenuFloatingWindow())
                    bSuppress = true;

                if (pWin->GetType() == WindowType::FLOATINGWINDOW &&
                    static_cast<FloatingWindow*>(pWin)->IsInPopupMode())
                    bSuppress = true;

                // Otherwise, don't suppress if the event came from a different frame.
                if (!bSuppress && pWin->GetWindow(GetWindowType::Frame) == pWin)
                    break;

                pWin = pWin->GetWindow(GetWindowType::RealParent);
            }

            css::lang::EventObject aEvent;
            aEvent.Source = getXWeak();
            if (rVclWindowEvent.GetId() == VclEventId::WindowActivate)
                mpImpl->getTopWindowListeners().windowActivated( aEvent );
            else
                mpImpl->getTopWindowListeners().windowDeactivated( aEvent );
        }
        break;
        case VclEventId::WindowClose:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::closed, aEvent );
            }
            if ( mpImpl->getTopWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getTopWindowListeners().windowClosing( aEvent );
            }
        }
        break;
        case VclEventId::ControlGetFocus:
        case VclEventId::WindowGetFocus:
        {
            if  (   (   rVclWindowEvent.GetWindow()->IsCompoundControl()
                    &&  rVclWindowEvent.GetId() == VclEventId::ControlGetFocus
                    )
                ||  (   !rVclWindowEvent.GetWindow()->IsCompoundControl()
                    &&  rVclWindowEvent.GetId() == VclEventId::WindowGetFocus
                    )
                )
            {
                if ( mpImpl->getFocusListeners().getLength() )
                {
                    css::awt::FocusEvent aEvent;
                    aEvent.Source = getXWeak();
                    aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags());
                    aEvent.Temporary = false;
                    mpImpl->getFocusListeners().focusGained( aEvent );
                }
            }
        }
        break;
        case VclEventId::ControlLoseFocus:
        case VclEventId::WindowLoseFocus:
        {
            if  (   (   rVclWindowEvent.GetWindow()->IsCompoundControl()
                    &&  rVclWindowEvent.GetId() == VclEventId::ControlLoseFocus
                    )
                ||  (   !rVclWindowEvent.GetWindow()->IsCompoundControl()
                    &&  rVclWindowEvent.GetId() == VclEventId::WindowLoseFocus
                    )
                )
            {
                if ( mpImpl->getFocusListeners().getLength() )
                {
                    css::awt::FocusEvent aEvent;
                    aEvent.Source = getXWeak();
                    aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags());
                    aEvent.Temporary = false;

                    vcl::Window* pNext = Application::GetFocusWindow();
                    if ( pNext )
                    {
                        // Don't care about internals if this control is compound
                        vcl::Window* pNextC = pNext;
                        while ( pNextC && !pNextC->IsCompoundControl() )
                            pNextC = pNextC->GetParent();
                        if ( pNextC )
                            pNext = pNextC;

                        pNext->GetComponentInterface();
                        aEvent.NextFocus = cppu::getXWeak(pNext->GetWindowPeer());
                    }
                    mpImpl->getFocusListeners().focusLost( aEvent );
                }
            }
        }
        break;
        case VclEventId::WindowMinimize:
        {
            if ( mpImpl->getTopWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getTopWindowListeners().windowMinimized( aEvent );
            }
        }
        break;
        case VclEventId::WindowNormalize:
        {
            if ( mpImpl->getTopWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getTopWindowListeners().windowNormalized( aEvent );
            }
        }
        break;
        case VclEventId::WindowKeyInput:
        {
            if ( mpImpl->getKeyListeners().getLength() )
            {
                css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
                    *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
                ) );
                mpImpl->getKeyListeners().keyPressed( aEvent );
            }
        }
        break;
        case VclEventId::WindowKeyUp:
        {
            if ( mpImpl->getKeyListeners().getLength() )
            {
                css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
                    *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
                ) );
                mpImpl->getKeyListeners().keyReleased( aEvent );
            }
        }
        break;
        case VclEventId::WindowCommand:
        {
            CommandEvent* pCmdEvt = static_cast<CommandEvent*>(rVclWindowEvent.GetData());
            if ( mpImpl->getMouseListeners().getLength() && ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu ) )
            {
                // CommandEventId::ContextMenu: send as mousePressed with PopupTrigger = true ...
                Point aWhere = static_cast< CommandEvent* >( rVclWindowEvent.GetData() )->GetMousePosPixel();
                if ( !pCmdEvt->IsMouseEvent() )
                {   // for keyboard events, we set the coordinates to -1,-1. This is a slight HACK, but the current API
                    // handles a context menu command as special case of a mouse event, which is simply wrong.
                    // Without extending the API, we would not have another chance to notify listeners of a
                    // keyboard-triggered context menu request
                    aWhere = Point( -1, -1 );
                }

                MouseEvent aMEvt( aWhere, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, 0 );
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( aMEvt, *this ) );
                aEvent.PopupTrigger = true;

                Callback aCallback = [ this, aEvent=std::move(aEvent) ]()
                                     { this->mpImpl->getMouseListeners().mousePressed( aEvent ); };

                ImplExecuteAsyncWithoutSolarLock( aCallback );
            }
        }
        break;
        case VclEventId::WindowMouseMove:
        {
            MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData());
            if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
            {
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
                bool const isEnter(pMouseEvt->IsEnterWindow());
                Callback aCallback = [ this, isEnter, aEvent=std::move(aEvent) ]()
                     { MouseListenerMultiplexer& rMouseListeners = this->mpImpl->getMouseListeners();
                       isEnter
                           ? rMouseListeners.mouseEntered(aEvent)
                           : rMouseListeners.mouseExited(aEvent); };

                ImplExecuteAsyncWithoutSolarLock( aCallback );
            }

            if ( mpImpl->getMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
            {
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
                aEvent.ClickCount = 0;
                if ( pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE )
                    mpImpl->getMouseMotionListeners().mouseMoved( aEvent );
                else
                    mpImpl->getMouseMotionListeners().mouseDragged( aEvent );
            }
        }
        break;
        case VclEventId::WindowMouseButtonDown:
        {
            if ( mpImpl->getMouseListeners().getLength() )
            {
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
                Callback aCallback = [ this, aEvent=std::move(aEvent) ]()
                                     { this->mpImpl->getMouseListeners().mousePressed( aEvent ); };
                ImplExecuteAsyncWithoutSolarLock( aCallback );
            }
        }
        break;
        case VclEventId::WindowMouseButtonUp:
        {
            if ( mpImpl->getMouseListeners().getLength() )
            {
                awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );

                Callback aCallback = [ this, aEvent=std::move(aEvent) ]()
                                     { this->mpImpl->getMouseListeners().mouseReleased( aEvent ); };
                ImplExecuteAsyncWithoutSolarLock( aCallback );
            }
        }
        break;
        case VclEventId::WindowStartDocking:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData());

                if( pData )
                {
                    css::awt::DockingEvent aEvent;
                    aEvent.Source = getXWeak();
                    aEvent.TrackingRectangle = vcl::unohelper::ConvertToAWTRect(pData->maTrackRect);
                    aEvent.MousePos.X = pData->maMousePos.X();
                    aEvent.MousePos.Y = pData->maMousePos.Y();
                    aEvent.bLiveMode = false;
                    aEvent.bInteractive = true;

                    mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::startDocking, aEvent );
                }
            }
        }
        break;
        case VclEventId::WindowDocking:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData());

                if( pData )
                {
                    css::awt::DockingEvent aEvent;
                    aEvent.Source = getXWeak();
                    aEvent.TrackingRectangle = vcl::unohelper::ConvertToAWTRect(pData->maTrackRect);
                    aEvent.MousePos.X = pData->maMousePos.X();
                    aEvent.MousePos.Y = pData->maMousePos.Y();
                    aEvent.bLiveMode = false;
                    aEvent.bInteractive = true;

                    Reference< XDockableWindowListener > xFirstListener;
                    ::comphelper::OInterfaceIteratorHelper3 aIter( mpImpl->getDockableWindowListeners() );
                    while ( aIter.hasMoreElements() && !xFirstListener.is() )
                    {
                        xFirstListener = aIter.next();
                    }

                    css::awt::DockingData aDockingData =
                        xFirstListener->docking( aEvent );
                    pData->maTrackRect
                        = vcl::unohelper::ConvertToVCLRect(aDockingData.TrackingRectangle);
                    pData->mbFloating = aDockingData.bFloating;
                }
            }
        }
        break;
        case VclEventId::WindowEndDocking:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                EndDockingData *pData = static_cast<EndDockingData*>(rVclWindowEvent.GetData());

                if( pData )
                {
                    css::awt::EndDockingEvent aEvent;
                    aEvent.Source = getXWeak();
                    aEvent.WindowRectangle = vcl::unohelper::ConvertToAWTRect(pData->maWindowRect);
                    aEvent.bFloating = pData->mbFloating;
                    aEvent.bCancelled = pData->mbCancelled;
                    mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endDocking, aEvent );
                }
            }
        }
        break;
        case VclEventId::WindowPrepareToggleFloating:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                sal_Bool *p_bFloating = static_cast<sal_Bool*>(rVclWindowEvent.GetData());

                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();

                Reference< XDockableWindowListener > xFirstListener;
                ::comphelper::OInterfaceIteratorHelper3 aIter( mpImpl->getDockableWindowListeners() );
                while ( aIter.hasMoreElements() && !xFirstListener.is() )
                {
                    xFirstListener = aIter.next();
                }

                *p_bFloating = xFirstListener->prepareToggleFloatingMode( aEvent );
            }
        }
        break;
        case VclEventId::WindowToggleFloating:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                css::lang::EventObject aEvent;
                aEvent.Source = getXWeak();
                mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::toggleFloatingMode, aEvent );
            }
        }
        break;
        case VclEventId::WindowEndPopupMode:
        {
            if ( mpImpl->getDockableWindowListeners().getLength() )
            {
                EndPopupModeData *pData = static_cast<EndPopupModeData*>(rVclWindowEvent.GetData());

                if( pData )
                {
                    css::awt::EndPopupModeEvent aEvent;
                    aEvent.Source = getXWeak();
                    aEvent.FloatingPosition.X = pData->maFloatingPos.X();
                    aEvent.FloatingPosition.Y = pData->maFloatingPos.Y();
                    aEvent.bTearoff = pData->mbTearoff;
                    mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endPopupMode, aEvent );
                }
            }
        }
        break;
        defaultbreak;
    }
}

uno::Reference< accessibility::XAccessibleContext > VCLXWindow::CreateAccessibleContext()
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return nullptr;

    VclPtr<vcl::Window> pWindow = GetWindow();
    return AccessibleFactory::createAccessibleContext(pWindow);
}

void VCLXWindow::SetSynthesizingVCLEvent( bool _b )
{
    mpImpl->mbSynthesizingVCLEvent = _b;
}

bool VCLXWindow::IsSynthesizingVCLEvent() const
{
    return mpImpl->mbSynthesizingVCLEvent;
}

Size VCLXWindow::ImplCalcWindowSize( const Size& rOutSz ) const
{
    Size aSz = rOutSz;

    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        sal_Int32 nLeft, nTop, nRight, nBottom;
        pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
        aSz.AdjustWidth(nLeft+nRight );
        aSz.AdjustHeight(nTop+nBottom );
    }
    return aSz;
}


// css::lang::Component
void VCLXWindow::dispose(  )
{
    SolarMutexGuard aGuard;

    if ( mpImpl->mbDisposing )
        return;

    mpImpl->mbDisposing = true;

    mpImpl->mxViewGraphics = nullptr;

    mpImpl->disposing();

    if ( VclPtr<vcl::Window> pWindow = GetWindow() )
    {
        pWindow->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
        pWindow->SetWindowPeer( nullptr, nullptr );

        SetOutputDevice( nullptr );
        pWindow.disposeAndClear();
    }

    // #i14103# dispose the accessible context after the window has been destroyed,
    // otherwise the old value in the child event fired in VCLXAccessibleComponent::ProcessWindowEvent()
    // for VclEventId::WindowChildDestroyed contains a reference to an already disposed accessible object
    try
    {
        css::uno::Reference< css::lang::XComponent > xComponent( mpImpl->mxAccessibleContext, css::uno::UNO_QUERY );
        if ( xComponent.is() )
            xComponent->dispose();
    }
    catch ( const css::uno::Exception& )
    {
        OSL_FAIL( "VCLXWindow::dispose: could not dispose the accessible context!" );
    }
    mpImpl->mxAccessibleContext.clear();
}

void VCLXWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing) // called during dispose by accessibility stuff
        return;
    mpImpl->getEventListeners().addInterface( rxListener );
}

void VCLXWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getEventListeners().removeInterface( rxListener );
}


// css::awt::XWindow
void VCLXWindow::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
{
    SolarMutexGuard aGuard;
    comphelper::ProfileZone aZone("setPosSize");

    if ( GetWindow() )
    {
        if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) )
            vcl::Window::GetDockingManager()->SetPosSizePixel( GetWindow() , X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
        else
            GetWindow()->setPosSizePixel( X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
    }
}

css::awt::Rectangle VCLXWindow::getPosSize(  )
{
    SolarMutexGuard aGuard;

    css::awt::Rectangle aBounds;
    if ( GetWindow() )
    {
        if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) )
            aBounds = vcl::unohelper::ConvertToAWTRect(
                vcl::Window::GetDockingManager()->GetPosSizePixel(GetWindow()));
        else
            aBounds = vcl::unohelper::ConvertToAWTRect(
                tools::Rectangle(GetWindow()->GetPosPixel(), GetWindow()->GetSizePixel()));
    }

    return aBounds;
}

void VCLXWindow::setVisible( sal_Bool bVisible )
{
    SolarMutexGuard aGuard;

    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        mpImpl->setDirectVisible( bVisible );
        pWindow->Show( bVisible &&  mpImpl->isEnableVisible() );
    }
}

void VCLXWindow::setEnable( sal_Bool bEnable )
{
    SolarMutexGuard aGuard;

    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        pWindow->Enable( bEnable, false ); // #95824# without children!
        pWindow->EnableInput( bEnable );
    }
}

void VCLXWindow::setFocus(  )
{
    SolarMutexGuard aGuard;

    if ( GetWindow() )
        GetWindow()->GrabFocus();
}

void VCLXWindow::addWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;

    mpImpl->getWindowListeners().addInterface( rxListener );

    Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
    if ( xListener2.is() )
        mpImpl->getWindow2Listeners().addInterface( xListener2 );

    // #100119# Get all resize events, even if height or width 0, or invisible
    if ( GetWindow() )
        GetWindow()->EnableAllResize();
}

void VCLXWindow::removeWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener )
{
    SolarMutexGuard aGuard;

    if (mpImpl->mbDisposing)
        return;

    Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
    if ( xListener2.is() )
        mpImpl->getWindow2Listeners().removeInterface( xListener2 );

    mpImpl->getWindowListeners().removeInterface( rxListener );
}

void VCLXWindow::addFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getFocusListeners().addInterface( rxListener );
}

void VCLXWindow::removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getFocusListeners().removeInterface( rxListener );
}

void VCLXWindow::addKeyListener( const css::uno::Reference< css::awt::XKeyListener >&&nbsp;rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getKeyListeners().addInterface( rxListener );
}

void VCLXWindow::removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >&&nbsp;rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getKeyListeners().removeInterface( rxListener );
}

void VCLXWindow::addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getMouseListeners().addInterface( rxListener );
}

void VCLXWindow::removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getMouseListeners().removeInterface( rxListener );
}

void VCLXWindow::addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getMouseMotionListeners().addInterface( rxListener );
}

void VCLXWindow::removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getMouseMotionListeners().removeInterface( rxListener );
}

void VCLXWindow::addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getPaintListeners().addInterface( rxListener );
}

void VCLXWindow::removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
{
    SolarMutexGuard aGuard;
    if (mpImpl->mbDisposing)
        return;
    mpImpl->getPaintListeners().removeInterface( rxListener );
}

// css::awt::XWindowPeer
css::uno::Reference< css::awt::XToolkit > VCLXWindow::getToolkit(  )
{
    // no guard. nothing to guard here.
    // 82463 - 12/21/00 - fs
    return Application::GetVCLToolkit();
}

void VCLXWindow::setPointer( const css::uno::Reference< css::awt::XPointer >& rxPointer )
{
    SolarMutexGuard aGuard;

    VCLXPointer* pPointer = dynamic_cast<VCLXPointer*>( rxPointer.get() );
    if ( pPointer && GetWindow() )
        GetWindow()->SetPointer( pPointer->GetPointer() );
}

void VCLXWindow::setBackground( sal_Int32 nColor )
{
    SolarMutexGuard aGuard;

    if ( !GetWindow() )
        return;

    Color aColor(ColorTransparency, nColor);
    GetWindow()->SetBackground( aColor );
    GetWindow()->SetControlBackground( aColor );

    WindowType eWinType = GetWindow()->GetType();
    if ( ( eWinType == WindowType::WINDOW ) ||
         ( eWinType == WindowType::WORKWINDOW ) ||
         ( eWinType == WindowType::FLOATINGWINDOW ) )
    {
        GetWindow()->Invalidate();
    }
}

void VCLXWindow::invalidate( sal_Int16 nInvalidateFlags )
{
    SolarMutexGuard aGuard;

    if ( GetWindow() )
        GetWindow()->Invalidate( static_cast<InvalidateFlags>(nInvalidateFlags) );
}

void VCLXWindow::invalidateRect( const css::awt::Rectangle& rRect, sal_Int16 nInvalidateFlags )
{
    SolarMutexGuard aGuard;

    if ( GetWindow() )
        GetWindow()->Invalidate(vcl::unohelper::ConvertToVCLRect(rRect),
                                static_cast<InvalidateFlags>(nInvalidateFlags));
}


// css::awt::XVclWindowPeer
sal_Bool VCLXWindow::isChild( const css::uno::Reference< css::awt::XWindowPeer >& rxPeer )
{
    SolarMutexGuard aGuard;

    bool bIsChild = false;
    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( pWindow )
    {
        VclPtr<vcl::Window> pPeerWindow = VCLUnoHelper::GetWindow( rxPeer );
        bIsChild = pPeerWindow && pWindow->IsChild( pPeerWindow );
    }

    return bIsChild;
}

void VCLXWindow::setDesignMode( sal_Bool bOn )
{
    SolarMutexGuard aGuard;

    mpImpl->mbDesignMode = bOn;
}

sal_Bool VCLXWindow::isDesignMode(  )
{
    SolarMutexGuard aGuard;
    return mpImpl->mbDesignMode;
}

void VCLXWindow::enableClipSiblings( sal_Bool bClip )
{
    SolarMutexGuard aGuard;

    if ( GetWindow() )
        GetWindow()->EnableClipSiblings( bClip );
}

void VCLXWindow::setForeground( sal_Int32 nColor )
{
    SolarMutexGuard aGuard;

    if ( GetWindow() )
    {
        GetWindow()->SetControlForeground( Color(ColorTransparency, nColor) );
    }
}

void VCLXWindow::setControlFont( const css::awt::FontDescriptor& rFont )
{
    SolarMutexGuard aGuard;

    if ( GetWindow() )
        GetWindow()->SetControlFont( VCLUnoHelper::CreateFont( rFont, GetWindow()->GetControlFont() ) );
}

void VCLXWindow::getStyles( sal_Int16 nType, css::awt::FontDescriptor& Font, sal_Int32& ForegroundColor, sal_Int32& BackgroundColor )
{
    SolarMutexGuard aGuard;

    if ( !GetWindow() )
        return;

    const StyleSettings& rStyleSettings = GetWindow()->GetSettings().GetStyleSettings();

    switch ( nType )
    {
        case css::awt::Style::FRAME:
        {
            Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
            ForegroundColor = sal_Int32(rStyleSettings.GetWindowTextColor());
            BackgroundColor = sal_Int32(rStyleSettings.GetWindowColor());
        }
        break;
        case css::awt::Style::DIALOG:
        {
            Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
            ForegroundColor = sal_Int32(rStyleSettings.GetDialogTextColor());
            BackgroundColor = sal_Int32(rStyleSettings.GetDialogColor());
        }
        break;
        default: OSL_FAIL( "VCLWindow::getStyles() - unknown Type" );
    }
}

namespace toolkit
{
    static void setColorSettings( vcl::Window* _pWindow, const css::uno::Any& _rValue,
        void (StyleSettings::*pSetter)( const Color& ), const Color& (StyleSettings::*pGetter)( ) const )
    {
        sal_Int32 nColor = 0;
        if ( !( _rValue >>= nColor ) )
            nColor = sal_Int32((Application::GetSettings().GetStyleSettings().*pGetter)());

        AllSettings aSettings = _pWindow->GetSettings();
        StyleSettings aStyleSettings = aSettings.GetStyleSettings();

        (aStyleSettings.*pSetter)( Color( ColorTransparency, nColor ) );

        aSettings.SetStyleSettings( aStyleSettings );
        _pWindow->SetSettings( aSettings, true );
    }
}

// Terminated by BASEPROPERTY_NOTFOUND (or 0)
void VCLXWindow::PushPropertyIds( std::vector< sal_uInt16 > &rIds,
                                  int nFirstId, ...)
{
    va_list pVarArgs;
    va_start( pVarArgs, nFirstId );

    for ( int nId = nFirstId; nId != BASEPROPERTY_NOTFOUND;
          nId = va_arg( pVarArgs, int ) )
        rIds.push_back( static_cast<sal_uInt16>(nId) );

    va_end( pVarArgs );
}

void VCLXWindow::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds, bool bWithDefaults )
{
    // These are common across ~all VCLXWindow derived classes
    if( bWithDefaults )
        PushPropertyIds( rIds,
                         BASEPROPERTY_ALIGN,
                         BASEPROPERTY_BACKGROUNDCOLOR,
                         BASEPROPERTY_BORDER,
                         BASEPROPERTY_BORDERCOLOR,
                         BASEPROPERTY_DEFAULTCONTROL,
                         BASEPROPERTY_ENABLED,
                         BASEPROPERTY_FONTDESCRIPTOR,
                         BASEPROPERTY_HELPTEXT,
                         BASEPROPERTY_HELPURL,
                         BASEPROPERTY_TEXT,
                         BASEPROPERTY_PRINTABLE,
                         BASEPROPERTY_ENABLEVISIBLE, // for visibility
                         BASEPROPERTY_TABSTOP,
                         0);

    // lovely hack from:
    // void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
    if( std::find(rIds.begin(), rIds.end(), BASEPROPERTY_FONTDESCRIPTOR) != rIds.end() )
    {
        // some properties are not included in the FontDescriptor, but every time
        // when we have a FontDescriptor we want to have these properties too.
        // => Easier to register the here, instead everywhere where I register the FontDescriptor...

        rIds.push_back( BASEPROPERTY_TEXTCOLOR );
        rIds.push_back( BASEPROPERTY_TEXTLINECOLOR );
        rIds.push_back( BASEPROPERTY_FONTRELIEF );
        rIds.push_back( BASEPROPERTY_FONTEMPHASISMARK );
    }
}

void VCLXWindow::GetPropertyIds( std::vector< sal_uInt16 >& _out_rIds )
{
    return ImplGetPropertyIds( _out_rIds, mpImpl->mbWithDefaultProps );
}

ListenerMultiplexerBase<css::awt::XVclContainerListener>& VCLXWindow::GetContainerListeners()
{
    return mpImpl->getContainerListeners();
}

ListenerMultiplexerBase<css::awt::XTopWindowListener>& VCLXWindow::GetTopWindowListeners()
{
    return mpImpl->getTopWindowListeners();
}

namespace
{
    void    lcl_updateWritingMode( vcl::Window& _rWindow, const sal_Int16 _nWritingMode, const sal_Int16 _nContextWritingMode )
    {
        bool bEnableRTL = false;
        switch ( _nWritingMode )
        {
        case WritingMode2::LR_TB:   bEnableRTL = falsebreak;
        case WritingMode2::RL_TB:   bEnableRTL = truebreak;
        case WritingMode2::CONTEXT:
        {
            // consult our ContextWritingMode. If it has an explicit RTL/LTR value, then use
            // it. If it doesn't (but is CONTEXT itself), then just ask the parent window of our
            // own window for its RTL mode
            switch ( _nContextWritingMode )
            {
                case WritingMode2::LR_TB:   bEnableRTL = falsebreak;
                case WritingMode2::RL_TB:   bEnableRTL = truebreak;
                case WritingMode2::CONTEXT:
                {
                    const vcl::Window* pParent = _rWindow.GetParent();
                    OSL_ENSURE( pParent, "lcl_updateWritingMode: cannot determine context's writing mode!" );
                    if ( pParent )
                        bEnableRTL = pParent->IsRTLEnabled();
                }
                break;
            }
        }
        break;
        default:
            OSL_FAIL( "lcl_updateWritingMode: unsupported WritingMode!" );
        }   // switch ( nWritingMode )

        _rWindow.EnableRTL( bEnableRTL );
    }
}

void VCLXWindow::setProperty( const OUString& PropertyName, const css::uno::Any&&nbsp;Value )
{
    SolarMutexGuard aGuard;

    VclPtr<vcl::Window> pWindow = GetWindow();
    if ( !pWindow )
        return;

    bool bVoid = Value.getValueTypeClass() == css::uno::TypeClass_VOID;

    WindowType eWinType = pWindow->GetType();
    sal_uInt16 nPropType = GetPropertyId( PropertyName );
    switch ( nPropType )
    {
        case BASEPROPERTY_REFERENCE_DEVICE:
        {
            Control* pControl = dynamic_cast< Control* >( pWindow.get() );
            OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
            if ( !pControl )
                break;
            Reference< XDevice > xDevice( Value, UNO_QUERY );
            OutputDevice* pDevice = VCLUnoHelper::GetOutputDevice( xDevice );
            pControl->SetReferenceDevice( pDevice );
        }
        break;

        case BASEPROPERTY_CONTEXT_WRITING_MODE:
        {
            OSL_VERIFY( Value >>= mpImpl->mnContextWritingMode );
            if ( mpImpl->mnWritingMode == WritingMode2::CONTEXT )
                lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
        }
        break;

        case BASEPROPERTY_WRITING_MODE:
        {
            bool bProperType = ( Value >>= mpImpl->mnWritingMode );
            OSL_ENSURE( bProperType, "VCLXWindow::setProperty( 'WritingMode' ): illegal value type!" );
            if ( bProperType )
                lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
        }
        break;

        case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
        {
            sal_uInt16 nWheelBehavior( css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY );
            OSL_VERIFY( Value >>= nWheelBehavior );

            AllSettings aSettings = pWindow->GetSettings();
            MouseSettings aMouseSettings = aSettings.GetMouseSettings();

            MouseWheelBehaviour nVclBehavior( MouseWheelBehaviour::FocusOnly );
            switch ( nWheelBehavior )
            {
            case css::awt::MouseWheelBehavior::SCROLL_DISABLED:   nVclBehavior = MouseWheelBehaviour::Disable;     break;
            case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclBehavior = MouseWheelBehaviour::FocusOnly;  break;
            case css::awt::MouseWheelBehavior::SCROLL_ALWAYS:     nVclBehavior = MouseWheelBehaviour::ALWAYS;      break;
            default:
                OSL_FAIL( "VCLXWindow::setProperty( 'MouseWheelBehavior' ): illegal property value!" );
            }

            aMouseSettings.SetWheelBehavior( nVclBehavior );
            aSettings.SetMouseSettings( aMouseSettings );
            pWindow->SetSettings( aSettings, true );
        }
        break;

        case BASEPROPERTY_NATIVE_WIDGET_LOOK:
        {
            bool bEnable( true );
            OSL_VERIFY( Value >>= bEnable );
            pWindow->EnableNativeWidget( bEnable );
        }
        break;

        case BASEPROPERTY_PLUGINPARENT:
        {
            // set parent handle
            SetSystemParent_Impl( Value );
        }
        break;

        case BASEPROPERTY_ENABLED:
        {
            bool b = bool();
            if ( Value >>= b )
                setEnable( b );
        }
        break;
        case BASEPROPERTY_ENABLEVISIBLE:
        {
            bool b = false;
            if ( Value >>= b )
            {
                if( b != mpImpl->isEnableVisible() )
                {
                    mpImpl->setEnableVisible( b );
                    pWindow->Show( b && mpImpl->isDirectVisible() );
                }
            }
        }
        break;
        case BASEPROPERTY_TEXT:
        case BASEPROPERTY_LABEL:
        case BASEPROPERTY_TITLE:
        {
            OUString aText;
            if ( Value >>= aText )
            {
                switch (eWinType)
                {
                    case WindowType::OKBUTTON:
                    case WindowType::CANCELBUTTON:
                    case WindowType::HELPBUTTON:
                        // Standard Button: overwrite only if not empty.
                        if (!aText.isEmpty())
                            pWindow->SetText( aText );
                        break;

                    default:
                        pWindow->SetText( aText );
                        break;
                }
            }
        }
        break;
        case BASEPROPERTY_ACCESSIBLENAME:
        {
            OUString aText;
            if ( Value >>= aText )
                pWindow->SetAccessibleName( aText );
        }
        break;
        case BASEPROPERTY_HELPURL:
        {
            OUString aURL;
            if ( Value >>= aURL )
            {
                INetURLObject aHelpURL( aURL );
                if ( aHelpURL.GetProtocol() == INetProtocol::Hid )
                    pWindow->SetHelpId( aHelpURL.GetURLPath() );
                else
                    pWindow->SetHelpId( aURL );
            }
        }
        break;
        case BASEPROPERTY_HELPTEXT:
        {
            OUString aHelpText;
            if ( Value >>= aHelpText )
            {
                pWindow->SetQuickHelpText( aHelpText );
            }
        }
        break;
        case BASEPROPERTY_FONTDESCRIPTOR:
        {
            if ( bVoid )
                pWindow->SetControlFont( vcl::Font() );
            else
            {
                css::awt::FontDescriptor aFont;
                if ( Value >>= aFont )
                    pWindow->SetControlFont( VCLUnoHelper::CreateFont( aFont, pWindow->GetControlFont() ) );
            }
        }
        break;
        case BASEPROPERTY_FONTRELIEF:
        {
            sal_Int16 n = sal_Int16();
            if ( Value >>= n )
            {
                vcl::Font aFont = pWindow->GetControlFont();
                aFont.SetRelief( static_cast<FontRelief>(n) );
                pWindow->SetControlFont( aFont );
            }
        }
        break;
        case BASEPROPERTY_FONTEMPHASISMARK:
        {
            sal_Int16 n = sal_Int16();
            if ( Value >>= n )
            {
                vcl::Font aFont = pWindow->GetControlFont();
                aFont.SetEmphasisMark( static_cast<FontEmphasisMark>(n) );
                pWindow->SetControlFont( aFont );
            }
        }
        break;
        case BASEPROPERTY_BACKGROUNDCOLOR:
            if ( bVoid )
            {
                switch ( eWinType )
                {
                    // set dialog color for default
                    case WindowType::DIALOG:
                    case WindowType::MESSBOX:
                    case WindowType::INFOBOX:
                    case WindowType::WARNINGBOX:
                    case WindowType::ERRORBOX:
                    case WindowType::QUERYBOX:
                    case WindowType::TABPAGE:
                    {
                        Color aColor = pWindow->GetSettings().GetStyleSettings().GetDialogColor();
                        pWindow->SetBackground( aColor );
                        pWindow->SetControlBackground( aColor );
                        break;
                    }

                    case WindowType::FIXEDTEXT:
                    case WindowType::CHECKBOX:
                    case WindowType::RADIOBUTTON:
                    case WindowType::GROUPBOX:
                    case WindowType::FIXEDLINE:
                    {
                        // support transparency only for special controls
                        pWindow->SetBackground();
                        pWindow->SetControlBackground();
                        pWindow->SetPaintTransparent( true );
                        break;
                    }

                    default:
                    {
                        // default code which enables transparency for
                        // compound controls. It's not real transparency
                        // as most of these controls repaint their client
                        // area completely new.
                        if ( pWindow->IsCompoundControl() )
                            pWindow->SetBackground();
                        pWindow->SetControlBackground();
                        break;
                    }
                }
            }
            else
            {
                Color aColor;
                if ( Value >>= aColor )
                {
                    pWindow->SetControlBackground( aColor );
                    pWindow->SetBackground( aColor );
                    switch ( eWinType )
                    {
                        // reset paint transparent mode
                        case WindowType::FIXEDTEXT:
                        case WindowType::CHECKBOX:
                        case WindowType::RADIOBUTTON:
                        case WindowType::GROUPBOX:
                        case WindowType::FIXEDLINE:
                            pWindow->SetPaintTransparent( false );
                            break;
                        default:
                            break;
                    }
                    pWindow->Invalidate();  // Invalidate if control does not respond to it
                }
            }
        break;
        case BASEPROPERTY_TEXTCOLOR:
            if ( bVoid )
            {
                pWindow->SetControlForeground();
            }
            else
            {
                Color nColor ;
                if ( Value >>= nColor )
                {
                    pWindow->SetTextColor( nColor );
                    pWindow->SetControlForeground( nColor );
                }
            }
        break;
        case BASEPROPERTY_TEXTLINECOLOR:
            if ( bVoid )
            {
                pWindow->SetTextLineColor();
            }
            else
            {
                Color nColor;
                if ( Value >>= nColor )
                    pWindow->SetTextLineColor( nColor );
            }
        break;
        case BASEPROPERTY_FILLCOLOR:
            if ( bVoid )
                pWindow->GetOutDev()->SetFillColor();
            else
            {
                Color nColor;
                if ( Value >>= nColor )
                    pWindow->GetOutDev()->SetFillColor( nColor );
            }
        break;
        case BASEPROPERTY_LINECOLOR:
            if ( bVoid )
                pWindow->GetOutDev()->SetLineColor();
            else
            {
                Color nColor;
                if ( Value >>= nColor )
                    pWindow->GetOutDev()->SetLineColor( nColor );
            }
        break;
        case BASEPROPERTY_HIGHLIGHT_COLOR:
        {
            Color nColor = 0;
            if ( bVoid )
            {
                nColor = Application::GetSettings().GetStyleSettings().GetHighlightColor();
            }
            else
            {
                if (!(Value >>= nColor))
                    break;
            }

            AllSettings aSettings(pWindow->GetSettings());
            StyleSettings aStyle(aSettings.GetStyleSettings());
            aStyle.SetHighlightColor(nColor);
            aSettings.SetStyleSettings(aStyle);
            pWindow->SetSettings(aSettings);
        }
        break;
        case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR:
        {
            Color nColor = 0;
            if (bVoid)
            {
                nColor = Application::GetSettings().GetStyleSettings().GetHighlightTextColor();
            }
            else
            {
                if (!(Value >>= nColor))
                    break;
            }

            AllSettings aSettings(pWindow->GetSettings());
            StyleSettings aStyle(aSettings.GetStyleSettings());
            aStyle.SetHighlightTextColor(nColor);
            aSettings.SetStyleSettings(aStyle);
            pWindow->SetSettings(aSettings);
        }
        break;
        case BASEPROPERTY_BORDER:
        {
            WinBits nStyle = pWindow->GetStyle();
            sal_uInt16 nTmp = 0;
            Value >>= nTmp;
            // clear any dodgy bits passed in, can come from dodgy extensions
            nTmp &= o3tl::typed_flags<WindowBorderStyle>::mask;
            WindowBorderStyle nBorder = static_cast<WindowBorderStyle>(nTmp);
            if ( !bool(nBorder) )
            {
                pWindow->SetStyle( nStyle & ~WB_BORDER );
            }
            else
            {
                pWindow->SetStyle( nStyle | WB_BORDER );
                pWindow->SetBorderStyle( nBorder );
            }
        }
        break;
        case BASEPROPERTY_TABSTOP:
        {
            WinBits nStyle = pWindow->GetStyle() & ~WB_TABSTOP;
            if ( !bVoid )
            {
                bool bTab = false;
                Value >>= bTab;
                if ( bTab )
                    nStyle |= WB_TABSTOP;
                else
                    nStyle |= WB_NOTABSTOP;
            }
            pWindow->SetStyle( nStyle );
        }
        break;
        case BASEPROPERTY_VERTICALALIGN:
        {
            VerticalAlignment eAlign = css::style::VerticalAlignment::VerticalAlignment_MAKE_FIXED_SIZE;
            WinBits nStyle = pWindow->GetStyle();
            nStyle &= ~(WB_TOP|WB_VCENTER|WB_BOTTOM);
            if ( !bVoid )
                Value >>= eAlign;
            switch ( eAlign )
            {
            case VerticalAlignment_TOP:
                nStyle |= WB_TOP;
                break;
            case VerticalAlignment_MIDDLE:
                nStyle |= WB_VCENTER;
                break;
            case VerticalAlignment_BOTTOM:
                nStyle |= WB_BOTTOM;
                break;
            default: ; // for warning free code, MAKE_FIXED_SIZE
            }
            pWindow->SetStyle( nStyle );
        }
        break;
        case BASEPROPERTY_ALIGN:
        {
            sal_Int16 nAlign = PROPERTY_ALIGN_LEFT;
            switch ( eWinType )
            {
                case WindowType::COMBOBOX:
                case WindowType::PUSHBUTTON:
                case WindowType::OKBUTTON:
                case WindowType::CANCELBUTTON:
                case WindowType::HELPBUTTON:
                    nAlign = PROPERTY_ALIGN_CENTER;
                    [[fallthrough]];
                case WindowType::FIXEDTEXT:
                case WindowType::EDIT:
                case WindowType::MULTILINEEDIT:
                case WindowType::CHECKBOX:
                case WindowType::RADIOBUTTON:
                case WindowType::LISTBOX:
                {
                    WinBits nStyle = pWindow->GetStyle();
                    nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT);
                    if ( !bVoid )
                        Value >>= nAlign;
                    if ( nAlign == PROPERTY_ALIGN_LEFT )
                        nStyle |= WB_LEFT;
                    else if ( nAlign == PROPERTY_ALIGN_CENTER )
                        nStyle |= WB_CENTER;
                    else
                        nStyle |= WB_RIGHT;
                    pWindow->SetStyle( nStyle );
                }
                break;
                defaultbreak;
            }
        }
        break;
        case BASEPROPERTY_MULTILINE:
        {
            if  (  ( eWinType == WindowType::FIXEDTEXT )
                || ( eWinType == WindowType::CHECKBOX )
                || ( eWinType == WindowType::RADIOBUTTON )
                || ( eWinType == WindowType::PUSHBUTTON )
                || ( eWinType == WindowType::OKBUTTON )
                || ( eWinType == WindowType::CANCELBUTTON )
                || ( eWinType == WindowType::HELPBUTTON )
                )
            {
                WinBits nStyle = pWindow->GetStyle();
                bool bMulti = false;
                Value >>= bMulti;
                if ( bMulti )
                    nStyle |= WB_WORDBREAK;
                else
                    nStyle &= ~WB_WORDBREAK;
                pWindow->SetStyle( nStyle );
            }
        }
        break;
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=96 H=98 G=96

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