The changes caused several issues in the presenter console (mouse events delivered to wrong widgets). Also it turned up that parent windows got the notification about mouse events from their children, but the position was always relative to the top widget, so very unhelpful for the parent widgets. Also I found out that there are XKeyHandler and XMouseClickHandler interfaces which already do what I tried to do with the below commits (events get passed down to parent widgets, and they even can be marked as consumed). So the original issue reported can be fixed by using XKeyHandler/XMouseClickHandler instead. This reverts the following two commits: * "Related tdf#122920 Treat UNO key events the same as mouse events"9e0e97b716
* "tdf#122920 Send UNO mouse events to parent window listeners as well"6f43902b12
Change-Id: I005d22770a7a4db9588c5bc22197dc0ae526627e Reviewed-on: https://gerrit.libreoffice.org/82423 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt@cib.de>
2547 lines
87 KiB
C++
2547 lines
87 KiB
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 <toolkit/awt/vclxpointer.hxx>
|
|
#include <toolkit/awt/vclxwindows.hxx>
|
|
#include <toolkit/helper/vclunohelper.hxx>
|
|
#include <toolkit/helper/convert.hxx>
|
|
#include <toolkit/helper/property.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/window.hxx>
|
|
#include <tools/color.hxx>
|
|
#include <tools/fract.hxx>
|
|
#include <tools/debug.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/commandevent.hxx>
|
|
#include <comphelper/flagguard.hxx>
|
|
#include <comphelper/interfacecontainer2.hxx>
|
|
#include <comphelper/profilezone.hxx>
|
|
#include "stylesettings.hxx"
|
|
#include <tools/urlobj.hxx>
|
|
|
|
#include <helper/accessibilityclient.hxx>
|
|
#include <helper/unopropertyarrayhelper.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
using ::com::sun::star::uno::Reference;
|
|
using ::com::sun::star::uno::UNO_QUERY;
|
|
using ::com::sun::star::uno::RuntimeException;
|
|
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;
|
|
::toolkit::AccessibilityClient maAccFactory;
|
|
bool mbDisposed;
|
|
bool mbDrawingOntoParent; // no bit mask, is passed around by reference
|
|
bool mbEnableVisible;
|
|
bool mbDirectVisible;
|
|
|
|
::osl::Mutex maListenerContainerMutex;
|
|
::comphelper::OInterfaceContainerHelper2 maWindow2Listeners;
|
|
::comphelper::OInterfaceContainerHelper2 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 const mbWithDefaultProps : 1;
|
|
|
|
sal_uLong 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;
|
|
css::uno::Reference< css::awt::XStyleSettings >
|
|
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();
|
|
|
|
::toolkit::AccessibilityClient& getAccessibleFactory()
|
|
{
|
|
return maAccFactory;
|
|
}
|
|
|
|
Reference< XStyleSettings > getStyleSettings();
|
|
|
|
/** returns the container of registered XWindowListener2 listeners
|
|
*/
|
|
::comphelper::OInterfaceContainerHelper2& getWindow2Listeners() { return maWindow2Listeners; }
|
|
::comphelper::OInterfaceContainerHelper2& 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)
|
|
,maListenerContainerMutex( )
|
|
,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;
|
|
if ( mnCallbackEventId )
|
|
Application::RemoveUserEvent( mnCallbackEventId );
|
|
mnCallbackEventId = nullptr;
|
|
|
|
mbDisposed= true;
|
|
|
|
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 );
|
|
|
|
::toolkit::WindowStyleSettings* pStyleSettings = static_cast< ::toolkit::WindowStyleSettings* >( mxWindowStyleSettings.get() );
|
|
if ( pStyleSettings != nullptr )
|
|
pStyleSettings->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 = maCallbackEvents;
|
|
maCallbackEvents.clear();
|
|
|
|
// we acquired our VCLXWindow once before posting the event, release this one ref now
|
|
mrAntiImpl.release();
|
|
|
|
if ( !mnCallbackEventId )
|
|
// we were disposed while waiting for the mutex to lock
|
|
return;
|
|
|
|
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()
|
|
{
|
|
mpImpl.reset();
|
|
|
|
if ( GetWindow() )
|
|
{
|
|
GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
|
|
GetWindow()->SetWindowPeer( nullptr, nullptr );
|
|
GetWindow()->SetAccessible( nullptr );
|
|
}
|
|
}
|
|
|
|
|
|
void VCLXWindow::ImplExecuteAsyncWithoutSolarLock( const Callback& i_callback )
|
|
{
|
|
mpImpl->callBackAsync( i_callback );
|
|
}
|
|
|
|
|
|
::toolkit::IAccessibleFactory& VCLXWindow::getAccessibleFactory()
|
|
{
|
|
return mpImpl->getAccessibleFactory().getFactory();
|
|
}
|
|
|
|
void VCLXWindow::SetWindow( const VclPtr<vcl::Window> &pWindow )
|
|
{
|
|
if ( GetWindow() )
|
|
{
|
|
GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
|
|
// GetWindow()->DbgAssertNoEventListeners();
|
|
}
|
|
|
|
SetOutputDevice( pWindow );
|
|
|
|
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->mnListenerLockLevel )
|
|
return;
|
|
|
|
DBG_ASSERT( rEvent.GetWindow() && GetWindow(), "Window???" );
|
|
ProcessWindowEvent( rEvent );
|
|
}
|
|
|
|
namespace
|
|
{
|
|
struct CallWindow2Listener
|
|
{
|
|
CallWindow2Listener( ::comphelper::OInterfaceContainerHelper2& i_rWindow2Listeners, const bool i_bEnabled, const EventObject& i_rEvent )
|
|
:m_rWindow2Listeners( i_rWindow2Listeners )
|
|
,m_bEnabled( i_bEnabled )
|
|
,m_aEvent( i_rEvent )
|
|
{
|
|
}
|
|
|
|
void operator()()
|
|
{
|
|
m_rWindow2Listeners.notifyEach( m_bEnabled ? &XWindowListener2::windowEnabled : &XWindowListener2::windowDisabled, m_aEvent );
|
|
}
|
|
|
|
::comphelper::OInterfaceContainerHelper2& m_rWindow2Listeners;
|
|
const bool m_bEnabled;
|
|
const EventObject m_aEvent;
|
|
};
|
|
}
|
|
|
|
void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
|
|
{
|
|
css::uno::Reference< css::uno::XInterface > xThis( static_cast<cppu::OWeakObject*>(this) );
|
|
|
|
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 = static_cast<cppu::OWeakObject*>(this);
|
|
aEvent.UpdateRect = AWTRectangle( *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 = static_cast<cppu::OWeakObject*>(this);
|
|
ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
|
|
mpImpl->getWindowListeners().windowMoved( aEvent );
|
|
}
|
|
}
|
|
break;
|
|
case VclEventId::WindowResize:
|
|
{
|
|
if ( mpImpl->getWindowListeners().getLength() )
|
|
{
|
|
css::awt::WindowEvent aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
|
|
mpImpl->getWindowListeners().windowResized( aEvent );
|
|
}
|
|
}
|
|
break;
|
|
case VclEventId::WindowShow:
|
|
{
|
|
if ( mpImpl->getWindowListeners().getLength() )
|
|
{
|
|
css::awt::WindowEvent aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
|
|
mpImpl->getWindowListeners().windowShown( aEvent );
|
|
}
|
|
|
|
// For TopWindows this means opened...
|
|
if ( mpImpl->getTopWindowListeners().getLength() )
|
|
{
|
|
css::lang::EventObject aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
mpImpl->getTopWindowListeners().windowOpened( aEvent );
|
|
}
|
|
}
|
|
break;
|
|
case VclEventId::WindowHide:
|
|
{
|
|
if ( mpImpl->getWindowListeners().getLength() )
|
|
{
|
|
css::awt::WindowEvent aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
|
|
mpImpl->getWindowListeners().windowHidden( aEvent );
|
|
}
|
|
|
|
// For TopWindows this means closed...
|
|
if ( mpImpl->getTopWindowListeners().getLength() )
|
|
{
|
|
css::lang::EventObject aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
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 = static_cast<cppu::OWeakObject*>(this);
|
|
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 = static_cast<cppu::OWeakObject*>(this);
|
|
mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::closed, aEvent );
|
|
}
|
|
if ( mpImpl->getTopWindowListeners().getLength() )
|
|
{
|
|
css::lang::EventObject aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
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 = static_cast<cppu::OWeakObject*>(this);
|
|
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 = static_cast<cppu::OWeakObject*>(this);
|
|
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 = static_cast<cppu::OWeakObject*>(pNext->GetWindowPeer());
|
|
}
|
|
mpImpl->getFocusListeners().focusLost( aEvent );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case VclEventId::WindowMinimize:
|
|
{
|
|
if ( mpImpl->getTopWindowListeners().getLength() )
|
|
{
|
|
css::lang::EventObject aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
mpImpl->getTopWindowListeners().windowMinimized( aEvent );
|
|
}
|
|
}
|
|
break;
|
|
case VclEventId::WindowNormalize:
|
|
{
|
|
if ( mpImpl->getTopWindowListeners().getLength() )
|
|
{
|
|
css::lang::EventObject aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
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 ]()
|
|
{ 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 ]()
|
|
{ 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 ]()
|
|
{ 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 ]()
|
|
{ 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 = static_cast<cppu::OWeakObject*>(this);
|
|
aEvent.TrackingRectangle = AWTRectangle( 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 = static_cast<cppu::OWeakObject*>(this);
|
|
aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
|
|
aEvent.MousePos.X = pData->maMousePos.X();
|
|
aEvent.MousePos.Y = pData->maMousePos.Y();
|
|
aEvent.bLiveMode = false;
|
|
aEvent.bInteractive = true;
|
|
|
|
Reference< XDockableWindowListener > xFirstListener;
|
|
::comphelper::OInterfaceIteratorHelper2 aIter( mpImpl->getDockableWindowListeners() );
|
|
while ( aIter.hasMoreElements() && !xFirstListener.is() )
|
|
{
|
|
xFirstListener.set( aIter.next(), UNO_QUERY );
|
|
}
|
|
|
|
css::awt::DockingData aDockingData =
|
|
xFirstListener->docking( aEvent );
|
|
pData->maTrackRect = VCLRectangle( 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 = static_cast<cppu::OWeakObject*>(this);
|
|
aEvent.WindowRectangle = AWTRectangle( 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 = static_cast<cppu::OWeakObject*>(this);
|
|
|
|
Reference< XDockableWindowListener > xFirstListener;
|
|
::comphelper::OInterfaceIteratorHelper2 aIter( mpImpl->getDockableWindowListeners() );
|
|
while ( aIter.hasMoreElements() && !xFirstListener.is() )
|
|
{
|
|
xFirstListener.set( aIter.next(), UNO_QUERY );
|
|
}
|
|
|
|
*p_bFloating = xFirstListener->prepareToggleFloatingMode( aEvent );
|
|
}
|
|
}
|
|
break;
|
|
case VclEventId::WindowToggleFloating:
|
|
{
|
|
if ( mpImpl->getDockableWindowListeners().getLength() )
|
|
{
|
|
css::lang::EventObject aEvent;
|
|
aEvent.Source = static_cast<cppu::OWeakObject*>(this);
|
|
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 = static_cast<cppu::OWeakObject*>(this);
|
|
aEvent.FloatingPosition.X = pData->maFloatingPos.X();
|
|
aEvent.FloatingPosition.Y = pData->maFloatingPos.Y();
|
|
aEvent.bTearoff = pData->mbTearoff;
|
|
mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endPopupMode, aEvent );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
uno::Reference< accessibility::XAccessibleContext > VCLXWindow::CreateAccessibleContext()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
return getAccessibleFactory().createAccessibleContext( this );
|
|
}
|
|
|
|
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::XUnoTunnel
|
|
UNO3_GETIMPLEMENTATION2_IMPL(VCLXWindow, VCLXDevice);
|
|
|
|
|
|
// css::lang::Component
|
|
void VCLXWindow::dispose( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
mpImpl->mxViewGraphics = nullptr;
|
|
|
|
if ( !mpImpl->mbDisposing )
|
|
{
|
|
mpImpl->mbDisposing = true;
|
|
|
|
mpImpl->disposing();
|
|
|
|
if ( GetWindow() )
|
|
{
|
|
VclPtr<OutputDevice> pOutDev = GetOutputDevice();
|
|
SetWindow( nullptr ); // so that handlers are logged off, if necessary (virtual)
|
|
SetOutputDevice( nullptr );
|
|
pOutDev.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();
|
|
|
|
mpImpl->mbDisposing = false;
|
|
}
|
|
}
|
|
|
|
void VCLXWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
mpImpl->getEventListeners().addInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
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 = AWTRectangle( vcl::Window::GetDockingManager()->GetPosSizePixel( GetWindow() ) );
|
|
else
|
|
aBounds = AWTRectangle( 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;
|
|
|
|
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;
|
|
|
|
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;
|
|
mpImpl->getFocusListeners().addInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getFocusListeners().removeInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::addKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getKeyListeners().addInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getKeyListeners().removeInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getMouseListeners().addInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getMouseListeners().removeInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getMouseMotionListeners().addInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getMouseMotionListeners().removeInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
mpImpl->getPaintListeners().addInterface( rxListener );
|
|
}
|
|
|
|
void VCLXWindow::removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
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 = comphelper::getUnoTunnelImplementation<VCLXPointer>( rxPointer );
|
|
if ( pPointer && GetWindow() )
|
|
GetWindow()->SetPointer( pPointer->GetPointer() );
|
|
}
|
|
|
|
void VCLXWindow::setBackground( sal_Int32 nColor )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
if ( GetWindow() )
|
|
{
|
|
Color aColor(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( VCLRectangle(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(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() )
|
|
{
|
|
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( 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 );
|
|
}
|
|
|
|
::comphelper::OInterfaceContainerHelper2& VCLXWindow::GetContainerListeners()
|
|
{
|
|
return mpImpl->getContainerListeners();
|
|
}
|
|
|
|
::comphelper::OInterfaceContainerHelper2& 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 = false; break;
|
|
case WritingMode2::RL_TB: bEnableRTL = true; break;
|
|
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 = false; break;
|
|
case WritingMode2::RL_TB: bEnableRTL = true; break;
|
|
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& Value )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if ( !pWindow )
|
|
return;
|
|
|
|
bool bVoid = Value.getValueType().getTypeClass() == 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( OUStringToOString( aHelpURL.GetURLPath(), RTL_TEXTENCODING_UTF8 ) );
|
|
else
|
|
pWindow->SetHelpId( OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ) );
|
|
}
|
|
}
|
|
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
|
|
{
|
|
sal_Int32 nColor = 0;
|
|
if ( Value >>= nColor )
|
|
{
|
|
Color aColor( nColor );
|
|
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
|
|
{
|
|
sal_Int32 nColor = 0;
|
|
if ( Value >>= nColor )
|
|
{
|
|
Color aColor( nColor );
|
|
pWindow->SetTextColor( aColor );
|
|
pWindow->SetControlForeground( aColor );
|
|
}
|
|
}
|
|
break;
|
|
case BASEPROPERTY_TEXTLINECOLOR:
|
|
if ( bVoid )
|
|
{
|
|
pWindow->SetTextLineColor();
|
|
}
|
|
else
|
|
{
|
|
sal_Int32 nColor = 0;
|
|
if ( Value >>= nColor )
|
|
{
|
|
Color aColor( nColor );
|
|
pWindow->SetTextLineColor( aColor );
|
|
}
|
|
}
|
|
break;
|
|
case BASEPROPERTY_FILLCOLOR:
|
|
if ( bVoid )
|
|
pWindow->SetFillColor();
|
|
else
|
|
{
|
|
sal_Int32 nColor = 0;
|
|
if ( Value >>= nColor )
|
|
{
|
|
Color aColor( nColor );
|
|
pWindow->SetFillColor( aColor );
|
|
}
|
|
}
|
|
break;
|
|
case BASEPROPERTY_LINECOLOR:
|
|
if ( bVoid )
|
|
pWindow->SetLineColor();
|
|
else
|
|
{
|
|
sal_Int32 nColor = 0;
|
|
if ( Value >>= nColor )
|
|
{
|
|
Color aColor( nColor );
|
|
pWindow->SetLineColor( aColor );
|
|
}
|
|
}
|
|
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;
|
|
default: break;
|
|
}
|
|
}
|
|
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;
|
|
case BASEPROPERTY_ORIENTATION:
|
|
{
|
|
if ( eWinType == WindowType::FIXEDLINE)
|
|
{
|
|
sal_Int32 nOrientation = 0;
|
|
if ( Value >>= nOrientation )
|
|
{
|
|
WinBits nStyle = pWindow->GetStyle();
|
|
nStyle &= ~(WB_HORZ|WB_VERT);
|
|
if ( nOrientation == 0 )
|
|
nStyle |= WB_HORZ;
|
|
else
|
|
nStyle |= WB_VERT;
|
|
|
|
pWindow->SetStyle( nStyle );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case BASEPROPERTY_AUTOMNEMONICS:
|
|
{
|
|
bool bAutoMnemonics = false;
|
|
Value >>= bAutoMnemonics;
|
|
AllSettings aSettings = pWindow->GetSettings();
|
|
StyleSettings aStyleSettings = aSettings.GetStyleSettings();
|
|
if ( aStyleSettings.GetAutoMnemonic() != bAutoMnemonics )
|
|
{
|
|
aStyleSettings.SetAutoMnemonic( bAutoMnemonics );
|
|
aSettings.SetStyleSettings( aStyleSettings );
|
|
pWindow->SetSettings( aSettings );
|
|
}
|
|
}
|
|
break;
|
|
case BASEPROPERTY_MOUSETRANSPARENT:
|
|
{
|
|
bool bMouseTransparent = false;
|
|
Value >>= bMouseTransparent;
|
|
pWindow->SetMouseTransparent( bMouseTransparent );
|
|
}
|
|
break;
|
|
case BASEPROPERTY_PAINTTRANSPARENT:
|
|
{
|
|
bool bPaintTransparent = false;
|
|
Value >>= bPaintTransparent;
|
|
pWindow->SetPaintTransparent( bPaintTransparent );
|
|
// pWindow->SetBackground();
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_REPEAT:
|
|
{
|
|
bool bRepeat( false );
|
|
Value >>= bRepeat;
|
|
|
|
WinBits nStyle = pWindow->GetStyle();
|
|
if ( bRepeat )
|
|
nStyle |= WB_REPEAT;
|
|
else
|
|
nStyle &= ~WB_REPEAT;
|
|
pWindow->SetStyle( nStyle );
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_REPEAT_DELAY:
|
|
{
|
|
sal_Int32 nRepeatDelay = 0;
|
|
if ( Value >>= nRepeatDelay )
|
|
{
|
|
AllSettings aSettings = pWindow->GetSettings();
|
|
MouseSettings aMouseSettings = aSettings.GetMouseSettings();
|
|
|
|
aMouseSettings.SetButtonRepeat( nRepeatDelay );
|
|
aSettings.SetMouseSettings( aMouseSettings );
|
|
|
|
pWindow->SetSettings( aSettings, true );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_SYMBOL_COLOR:
|
|
::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetButtonTextColor, &StyleSettings::GetButtonTextColor );
|
|
break;
|
|
|
|
case BASEPROPERTY_BORDERCOLOR:
|
|
::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetMonoColor, &StyleSettings::GetMonoColor);
|
|
break;
|
|
}
|
|
}
|
|
|
|
css::uno::Any VCLXWindow::getProperty( const OUString& PropertyName )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
css::uno::Any aProp;
|
|
if ( GetWindow() )
|
|
{
|
|
WindowType eWinType = GetWindow()->GetType();
|
|
sal_uInt16 nPropType = GetPropertyId( PropertyName );
|
|
switch ( nPropType )
|
|
{
|
|
case BASEPROPERTY_REFERENCE_DEVICE:
|
|
{
|
|
VclPtr<Control> pControl = GetAsDynamic<Control >();
|
|
OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
|
|
if ( !pControl )
|
|
break;
|
|
|
|
VCLXDevice* pDevice = new VCLXDevice;
|
|
pDevice->SetOutputDevice( pControl->GetReferenceDevice() );
|
|
aProp <<= Reference< XDevice >( pDevice );
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_CONTEXT_WRITING_MODE:
|
|
aProp <<= mpImpl->mnContextWritingMode;
|
|
break;
|
|
|
|
case BASEPROPERTY_WRITING_MODE:
|
|
aProp <<= mpImpl->mnWritingMode;
|
|
break;
|
|
|
|
case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
|
|
{
|
|
MouseWheelBehaviour nVclBehavior = GetWindow()->GetSettings().GetMouseSettings().GetWheelBehavior();
|
|
sal_uInt16 nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
|
|
switch ( nVclBehavior )
|
|
{
|
|
case MouseWheelBehaviour::Disable: nBehavior = css::awt::MouseWheelBehavior::SCROLL_DISABLED; break;
|
|
case MouseWheelBehaviour::FocusOnly: nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break;
|
|
case MouseWheelBehaviour::ALWAYS: nBehavior = css::awt::MouseWheelBehavior::SCROLL_ALWAYS; break;
|
|
default:
|
|
OSL_FAIL( "VCLXWindow::getProperty( 'MouseWheelBehavior' ): illegal VCL value!" );
|
|
}
|
|
aProp <<= nBehavior;
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_NATIVE_WIDGET_LOOK:
|
|
aProp <<= GetWindow()->IsNativeWidgetEnabled();
|
|
break;
|
|
|
|
case BASEPROPERTY_ENABLED:
|
|
aProp <<= GetWindow()->IsEnabled();
|
|
break;
|
|
|
|
case BASEPROPERTY_ENABLEVISIBLE:
|
|
aProp <<= mpImpl->isEnableVisible();
|
|
break;
|
|
|
|
case BASEPROPERTY_HIGHCONTRASTMODE:
|
|
aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetHighContrastMode();
|
|
break;
|
|
|
|
case BASEPROPERTY_TEXT:
|
|
case BASEPROPERTY_LABEL:
|
|
case BASEPROPERTY_TITLE:
|
|
{
|
|
OUString aText = GetWindow()->GetText();
|
|
aProp <<= aText;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_ACCESSIBLENAME:
|
|
{
|
|
OUString aText = GetWindow()->GetAccessibleName();
|
|
aProp <<= aText;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_HELPTEXT:
|
|
{
|
|
OUString aText = GetWindow()->GetQuickHelpText();
|
|
aProp <<= aText;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_HELPURL:
|
|
{
|
|
OUString aHelpId( OStringToOUString( GetWindow()->GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
|
|
aProp <<= aHelpId;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_FONTDESCRIPTOR:
|
|
{
|
|
vcl::Font aFont = GetWindow()->GetControlFont();
|
|
css::awt::FontDescriptor aFD = VCLUnoHelper::CreateFontDescriptor( aFont );
|
|
aProp <<= aFD;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_BACKGROUNDCOLOR:
|
|
aProp <<= GetWindow()->GetControlBackground();
|
|
break;
|
|
case BASEPROPERTY_DISPLAYBACKGROUNDCOLOR:
|
|
aProp <<= GetWindow()->GetBackgroundColor();
|
|
break;
|
|
case BASEPROPERTY_FONTRELIEF:
|
|
aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetRelief());
|
|
break;
|
|
case BASEPROPERTY_FONTEMPHASISMARK:
|
|
aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetEmphasisMark());
|
|
break;
|
|
case BASEPROPERTY_TEXTCOLOR:
|
|
aProp <<= GetWindow()->GetControlForeground();
|
|
break;
|
|
case BASEPROPERTY_TEXTLINECOLOR:
|
|
aProp <<= GetWindow()->GetTextLineColor();
|
|
break;
|
|
case BASEPROPERTY_FILLCOLOR:
|
|
aProp <<= GetWindow()->GetFillColor();
|
|
break;
|
|
case BASEPROPERTY_LINECOLOR:
|
|
aProp <<= GetWindow()->GetLineColor();
|
|
break;
|
|
case BASEPROPERTY_BORDER:
|
|
{
|
|
WindowBorderStyle nBorder = WindowBorderStyle::NONE;
|
|
if ( GetWindow()->GetStyle() & WB_BORDER )
|
|
nBorder = GetWindow()->GetBorderStyle();
|
|
aProp <<= static_cast<sal_uInt16>(nBorder);
|
|
}
|
|
break;
|
|
case BASEPROPERTY_TABSTOP:
|
|
aProp <<= ( GetWindow()->GetStyle() & WB_TABSTOP ) != 0;
|
|
break;
|
|
case BASEPROPERTY_VERTICALALIGN:
|
|
{
|
|
WinBits nStyle = GetWindow()->GetStyle();
|
|
if ( nStyle & WB_TOP )
|
|
aProp <<= VerticalAlignment_TOP;
|
|
else if ( nStyle & WB_VCENTER )
|
|
aProp <<= VerticalAlignment_MIDDLE;
|
|
else if ( nStyle & WB_BOTTOM )
|
|
aProp <<= VerticalAlignment_BOTTOM;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_ALIGN:
|
|
{
|
|
switch ( eWinType )
|
|
{
|
|
case WindowType::FIXEDTEXT:
|
|
case WindowType::EDIT:
|
|
case WindowType::MULTILINEEDIT:
|
|
case WindowType::CHECKBOX:
|
|
case WindowType::RADIOBUTTON:
|
|
case WindowType::LISTBOX:
|
|
case WindowType::COMBOBOX:
|
|
case WindowType::PUSHBUTTON:
|
|
case WindowType::OKBUTTON:
|
|
case WindowType::CANCELBUTTON:
|
|
case WindowType::HELPBUTTON:
|
|
{
|
|
WinBits nStyle = GetWindow()->GetStyle();
|
|
if ( nStyle & WB_LEFT )
|
|
aProp <<= sal_Int16(PROPERTY_ALIGN_LEFT);
|
|
else if ( nStyle & WB_CENTER )
|
|
aProp <<= sal_Int16(PROPERTY_ALIGN_CENTER);
|
|
else if ( nStyle & WB_RIGHT )
|
|
aProp <<= sal_Int16(PROPERTY_ALIGN_RIGHT);
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
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 )
|
|
)
|
|
aProp <<= ( GetWindow()->GetStyle() & WB_WORDBREAK ) != 0;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_AUTOMNEMONICS:
|
|
{
|
|
bool bAutoMnemonics = GetWindow()->GetSettings().GetStyleSettings().GetAutoMnemonic();
|
|
aProp <<= bAutoMnemonics;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_MOUSETRANSPARENT:
|
|
{
|
|
bool bMouseTransparent = GetWindow()->IsMouseTransparent();
|
|
aProp <<= bMouseTransparent;
|
|
}
|
|
break;
|
|
case BASEPROPERTY_PAINTTRANSPARENT:
|
|
{
|
|
bool bPaintTransparent = GetWindow()->IsPaintTransparent();
|
|
aProp <<= bPaintTransparent;
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_REPEAT:
|
|
aProp <<= ( 0 != ( GetWindow()->GetStyle() & WB_REPEAT ) );
|
|
break;
|
|
|
|
case BASEPROPERTY_REPEAT_DELAY:
|
|
{
|
|
sal_Int32 nButtonRepeat = GetWindow()->GetSettings().GetMouseSettings().GetButtonRepeat();
|
|
aProp <<= nButtonRepeat;
|
|
}
|
|
break;
|
|
|
|
case BASEPROPERTY_SYMBOL_COLOR:
|
|
aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetButtonTextColor();
|
|
break;
|
|
|
|
case BASEPROPERTY_BORDERCOLOR:
|
|
aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetMonoColor();
|
|
break;
|
|
}
|
|
}
|
|
return aProp;
|
|
}
|
|
|
|
|
|
// css::awt::XLayoutConstrains
|
|
css::awt::Size VCLXWindow::getMinimumSize( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
// Use this method only for those components which can be created through
|
|
// css::awt::Toolkit , but do not have an interface
|
|
|
|
Size aSz;
|
|
if ( GetWindow() )
|
|
{
|
|
WindowType nWinType = GetWindow()->GetType();
|
|
switch ( nWinType )
|
|
{
|
|
case WindowType::CONTROL:
|
|
aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*12 );
|
|
aSz.setHeight( GetWindow()->GetTextHeight()+2*6 );
|
|
break;
|
|
|
|
case WindowType::PATTERNBOX:
|
|
case WindowType::NUMERICBOX:
|
|
case WindowType::METRICBOX:
|
|
case WindowType::CURRENCYBOX:
|
|
case WindowType::DATEBOX:
|
|
case WindowType::TIMEBOX:
|
|
case WindowType::LONGCURRENCYBOX:
|
|
aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*2 );
|
|
aSz.setHeight( GetWindow()->GetTextHeight()+2*2 );
|
|
break;
|
|
case WindowType::SCROLLBARBOX:
|
|
return VCLXScrollBar::implGetMinimumSize( GetWindow() );
|
|
default:
|
|
aSz = GetWindow()->get_preferred_size();
|
|
}
|
|
}
|
|
|
|
return css::awt::Size( aSz.Width(), aSz.Height() );
|
|
}
|
|
|
|
css::awt::Size VCLXWindow::getPreferredSize( )
|
|
{
|
|
return getMinimumSize();
|
|
}
|
|
|
|
css::awt::Size VCLXWindow::calcAdjustedSize( const css::awt::Size& rNewSize )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
css::awt::Size aNewSize( rNewSize );
|
|
css::awt::Size aMinSize = getMinimumSize();
|
|
|
|
if ( aNewSize.Width < aMinSize.Width )
|
|
aNewSize.Width = aMinSize.Width;
|
|
if ( aNewSize.Height < aMinSize.Height )
|
|
aNewSize.Height = aMinSize.Height;
|
|
|
|
return aNewSize;
|
|
}
|
|
|
|
|
|
// css::awt::XView
|
|
sal_Bool VCLXWindow::setGraphics( const css::uno::Reference< css::awt::XGraphics >& rxDevice )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
if ( VCLUnoHelper::GetOutputDevice( rxDevice ) )
|
|
mpImpl->mxViewGraphics = rxDevice;
|
|
else
|
|
mpImpl->mxViewGraphics = nullptr;
|
|
|
|
return mpImpl->mxViewGraphics.is();
|
|
}
|
|
|
|
css::uno::Reference< css::awt::XGraphics > VCLXWindow::getGraphics( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
return mpImpl->mxViewGraphics;
|
|
}
|
|
|
|
css::awt::Size VCLXWindow::getSize( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
Size aSz;
|
|
if ( GetWindow() )
|
|
aSz = GetWindow()->GetSizePixel();
|
|
return css::awt::Size( aSz.Width(), aSz.Height() );
|
|
}
|
|
|
|
void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if ( !pWindow )
|
|
return;
|
|
|
|
if ( isDesignMode() || mpImpl->isEnableVisible() )
|
|
{
|
|
OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( mpImpl->mxViewGraphics );
|
|
if (!pDev)
|
|
pDev = pWindow->GetParent();
|
|
TabPage* pTabPage = dynamic_cast< TabPage* >( pWindow.get() );
|
|
if ( pTabPage )
|
|
{
|
|
Point aPos( nX, nY );
|
|
Size aSize = pWindow->GetSizePixel();
|
|
|
|
aPos = pDev->PixelToLogic( aPos );
|
|
aSize = pDev->PixelToLogic( aSize );
|
|
|
|
pTabPage->Draw( pDev, aPos, aSize, DrawFlags::NONE );
|
|
return;
|
|
}
|
|
|
|
Point aPos( nX, nY );
|
|
|
|
if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent() == pDev ) )
|
|
{
|
|
// #i40647# don't draw here if this is a recursive call
|
|
// sometimes this is called recursively, because the Update call on the parent
|
|
// (strangely) triggers another paint. Prevent a stack overflow here
|
|
// Yes, this is only fixing symptoms for the moment...
|
|
// #i40647# / 2005-01-18 / frank.schoenheit@sun.com
|
|
if ( !mpImpl->getDrawingOntoParent_ref() )
|
|
{
|
|
::comphelper::FlagGuard aDrawingflagGuard( mpImpl->getDrawingOntoParent_ref() );
|
|
|
|
bool bWasVisible = pWindow->IsVisible();
|
|
Point aOldPos( pWindow->GetPosPixel() );
|
|
|
|
if ( bWasVisible && aOldPos == aPos )
|
|
{
|
|
pWindow->Update();
|
|
return;
|
|
}
|
|
|
|
pWindow->SetPosPixel( aPos );
|
|
|
|
// Update parent first to avoid painting the parent upon the update
|
|
// of this window, as it may otherwise cause the parent
|
|
// to hide this window again
|
|
if( pWindow->GetParent() )
|
|
pWindow->GetParent()->Update();
|
|
|
|
pWindow->Show();
|
|
pWindow->Update();
|
|
pWindow->SetParentUpdateMode( false );
|
|
pWindow->Hide();
|
|
pWindow->SetParentUpdateMode( true );
|
|
|
|
pWindow->SetPosPixel( aOldPos );
|
|
if ( bWasVisible )
|
|
pWindow->Show();
|
|
}
|
|
}
|
|
else if ( pDev )
|
|
{
|
|
Size aSz = pWindow->GetSizePixel();
|
|
aSz = pDev->PixelToLogic( aSz );
|
|
Point aP = pDev->PixelToLogic( aPos );
|
|
|
|
vcl::PDFExtOutDevData* pPDFExport = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
|
|
bool bDrawSimple = ( pDev->GetOutDevType() == OUTDEV_PRINTER )
|
|
|| ( pDev->GetOutDevViewType() == OutDevViewType::PrintPreview )
|
|
|| ( pPDFExport != nullptr );
|
|
if ( bDrawSimple )
|
|
{
|
|
pWindow->Draw( pDev, aP, aSz, DrawFlags::NoControls );
|
|
}
|
|
else
|
|
{
|
|
bool bOldNW =pWindow->IsNativeWidgetEnabled();
|
|
if( bOldNW )
|
|
pWindow->EnableNativeWidget(false);
|
|
pWindow->PaintToDevice( pDev, aP, aSz );
|
|
if( bOldNW )
|
|
pWindow->EnableNativeWidget();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void VCLXWindow::setZoom( float fZoomX, float /*fZoomY*/ )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
if ( GetWindow() )
|
|
{
|
|
// Fraction::Fraction takes a double, but we have a float only.
|
|
// The implicit conversion from float to double can result in a precision loss, i.e. 1.2 is converted to
|
|
// 1.200000000047something. To prevent this, we convert explicitly to double, and round it.
|
|
double nZoom( fZoomX );
|
|
Fraction aZoom(::rtl::math::round(nZoom, 4));
|
|
aZoom.ReduceInaccurate(10); // to avoid runovers and BigInt mapping
|
|
GetWindow()->SetZoom(aZoom);
|
|
}
|
|
}
|
|
|
|
// css::lang::XEventListener
|
|
void SAL_CALL VCLXWindow::disposing( const css::lang::EventObject& _rSource )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
// check if it comes from our AccessibleContext
|
|
uno::Reference< uno::XInterface > aAC( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
|
|
uno::Reference< uno::XInterface > xSource( _rSource.Source, uno::UNO_QUERY );
|
|
|
|
if ( aAC.get() == xSource.get() )
|
|
{ // yep, it does
|
|
mpImpl->mxAccessibleContext.clear();
|
|
}
|
|
}
|
|
|
|
// css::accessibility::XAccessible
|
|
css::uno::Reference< css::accessibility::XAccessibleContext > VCLXWindow::getAccessibleContext( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
// already disposed
|
|
if( ! mpImpl )
|
|
return uno::Reference< accessibility::XAccessibleContext >();
|
|
|
|
if ( !mpImpl->mxAccessibleContext.is() && GetWindow() )
|
|
{
|
|
mpImpl->mxAccessibleContext = CreateAccessibleContext();
|
|
|
|
// add as event listener to this component
|
|
// in case somebody disposes it, we do not want to have a (though weak) reference to a dead
|
|
// object
|
|
uno::Reference< lang::XComponent > xComp( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
|
|
if ( xComp.is() )
|
|
xComp->addEventListener( this );
|
|
}
|
|
|
|
return mpImpl->mxAccessibleContext;
|
|
}
|
|
|
|
// css::awt::XDockable
|
|
void SAL_CALL VCLXWindow::addDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
if ( xListener.is() )
|
|
mpImpl->getDockableWindowListeners().addInterface( xListener );
|
|
|
|
}
|
|
|
|
void SAL_CALL VCLXWindow::removeDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
mpImpl->getDockableWindowListeners().removeInterface( xListener );
|
|
}
|
|
|
|
void SAL_CALL VCLXWindow::enableDocking( sal_Bool bEnable )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if ( pWindow )
|
|
pWindow->EnableDocking( bEnable );
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::isFloating( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if( pWindow )
|
|
return vcl::Window::GetDockingManager()->IsFloating( pWindow );
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void SAL_CALL VCLXWindow::setFloatingMode( sal_Bool bFloating )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if( pWindow )
|
|
vcl::Window::GetDockingManager()->SetFloatingMode( pWindow, bFloating );
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::isLocked( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if( pWindow )
|
|
return vcl::Window::GetDockingManager()->IsLocked( pWindow );
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void SAL_CALL VCLXWindow::lock( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) )
|
|
vcl::Window::GetDockingManager()->Lock( pWindow );
|
|
}
|
|
|
|
void SAL_CALL VCLXWindow::unlock( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
|
|
VclPtr<vcl::Window> pWindow = GetWindow();
|
|
if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) )
|
|
vcl::Window::GetDockingManager()->Unlock( pWindow );
|
|
}
|
|
|
|
void SAL_CALL VCLXWindow::startPopupMode( const css::awt::Rectangle& )
|
|
{
|
|
// TODO: remove interface in the next incompatible build
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::isInPopupMode( )
|
|
{
|
|
// TODO: remove interface in the next incompatible build
|
|
return false;
|
|
}
|
|
|
|
|
|
// css::awt::XWindow2
|
|
|
|
void SAL_CALL VCLXWindow::setOutputSize( const css::awt::Size& aSize )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
VclPtr<vcl::Window> pWindow;
|
|
if( (pWindow = GetWindow()) != nullptr )
|
|
{
|
|
DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >(pWindow.get());
|
|
if( pDockingWindow )
|
|
pDockingWindow->SetOutputSizePixel( VCLSize( aSize ) );
|
|
else
|
|
pWindow->SetOutputSizePixel( VCLSize( aSize ) );
|
|
}
|
|
}
|
|
|
|
css::awt::Size SAL_CALL VCLXWindow::getOutputSize( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
VclPtr<vcl::Window> pWindow;
|
|
if( (pWindow = GetWindow()) != nullptr )
|
|
{
|
|
DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >(pWindow.get());
|
|
if( pDockingWindow )
|
|
return AWTSize( pDockingWindow->GetOutputSizePixel() );
|
|
else
|
|
return AWTSize( pWindow->GetOutputSizePixel() );
|
|
}
|
|
else
|
|
return css::awt::Size();
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::isVisible( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( GetWindow() )
|
|
return GetWindow()->IsVisible();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::isActive( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( GetWindow() )
|
|
return GetWindow()->IsActive();
|
|
else
|
|
return false;
|
|
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::isEnabled( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( GetWindow() )
|
|
return GetWindow()->IsEnabled();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
sal_Bool SAL_CALL VCLXWindow::hasFocus( )
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if( GetWindow() )
|
|
return GetWindow()->HasFocus();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// css::beans::XPropertySetInfo
|
|
|
|
UnoPropertyArrayHelper *
|
|
VCLXWindow::GetPropHelper()
|
|
{
|
|
SolarMutexGuard aGuard;
|
|
if ( mpImpl->mpPropHelper == nullptr )
|
|
{
|
|
std::vector< sal_uInt16 > aIDs;
|
|
GetPropertyIds( aIDs );
|
|
mpImpl->mpPropHelper.reset( new UnoPropertyArrayHelper( aIDs ) );
|
|
}
|
|
return mpImpl->mpPropHelper.get();
|
|
}
|
|
|
|
css::uno::Sequence< css::beans::Property > SAL_CALL
|
|
VCLXWindow::getProperties()
|
|
{
|
|
return GetPropHelper()->getProperties();
|
|
}
|
|
css::beans::Property SAL_CALL
|
|
VCLXWindow::getPropertyByName( const OUString& rName )
|
|
{
|
|
return GetPropHelper()->getPropertyByName( rName );
|
|
}
|
|
|
|
sal_Bool SAL_CALL
|
|
VCLXWindow::hasPropertyByName( const OUString& rName )
|
|
{
|
|
return GetPropHelper()->hasPropertyByName( rName );
|
|
}
|
|
|
|
Reference< XStyleSettings > SAL_CALL VCLXWindow::getStyleSettings()
|
|
{
|
|
return mpImpl->getStyleSettings();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|