Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / toolkit / source / awt / vclxwindow.cxx
blob930d8fe4eaee9f3966170558b7ad39d2a05a3106
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <stdarg.h>
22 #include <memory>
23 #include <com/sun/star/awt/WindowEvent.hpp>
24 #include <com/sun/star/awt/KeyEvent.hpp>
25 #include <com/sun/star/awt/MouseEvent.hpp>
26 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
27 #include <com/sun/star/awt/Style.hpp>
28 #include <com/sun/star/awt/DockingEvent.hpp>
29 #include <com/sun/star/awt/EndDockingEvent.hpp>
30 #include <com/sun/star/awt/EndPopupModeEvent.hpp>
31 #include <com/sun/star/awt/XWindowListener2.hpp>
32 #include <com/sun/star/style/VerticalAlignment.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/text/WritingMode2.hpp>
35 #include <toolkit/awt/vclxwindow.hxx>
36 #include <awt/vclxpointer.hxx>
37 #include <toolkit/awt/vclxwindows.hxx>
38 #include <toolkit/helper/vclunohelper.hxx>
39 #include <toolkit/helper/convert.hxx>
40 #include <helper/property.hxx>
41 #include <rtl/math.hxx>
42 #include <sal/log.hxx>
43 #include <utility>
44 #include <vcl/toolkit/floatwin.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/window.hxx>
47 #include <tools/color.hxx>
48 #include <tools/fract.hxx>
49 #include <tools/debug.hxx>
50 #include <vcl/event.hxx>
51 #include <vcl/dockwin.hxx>
52 #include <vcl/pdfextoutdevdata.hxx>
53 #include <vcl/tabpage.hxx>
54 #include <vcl/ctrl.hxx>
55 #include <vcl/settings.hxx>
56 #include <vcl/commandevent.hxx>
57 #include <comphelper/flagguard.hxx>
58 #include <comphelper/interfacecontainer3.hxx>
59 #include <comphelper/profilezone.hxx>
60 #include "stylesettings.hxx"
61 #include <tools/urlobj.hxx>
63 #include <helper/accessibilityclient.hxx>
64 #include <helper/unopropertyarrayhelper.hxx>
66 using namespace ::com::sun::star;
68 using ::com::sun::star::uno::Reference;
69 using ::com::sun::star::uno::UNO_QUERY;
70 using ::com::sun::star::lang::EventObject;
71 using ::com::sun::star::awt::XWindowListener2;
72 using ::com::sun::star::awt::XDockableWindowListener;
73 using ::com::sun::star::awt::XDevice;
74 using ::com::sun::star::awt::XStyleSettings;
75 using ::com::sun::star::lang::DisposedException;
76 using ::com::sun::star::style::VerticalAlignment;
77 using ::com::sun::star::style::VerticalAlignment_TOP;
78 using ::com::sun::star::style::VerticalAlignment_MIDDLE;
79 using ::com::sun::star::style::VerticalAlignment_BOTTOM;
81 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
84 //= VCLXWindowImpl
86 class VCLXWindowImpl
88 private:
89 typedef ::std::vector< VCLXWindow::Callback > CallbackArray;
91 private:
92 VCLXWindow& mrAntiImpl;
93 ::toolkit::AccessibilityClient maAccFactory;
94 bool mbDisposed;
95 bool mbDrawingOntoParent; // no bit mask, is passed around by reference
96 bool mbEnableVisible;
97 bool mbDirectVisible;
99 ::osl::Mutex maListenerContainerMutex;
100 ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2> maWindow2Listeners;
101 ::comphelper::OInterfaceContainerHelper3<XDockableWindowListener> maDockableWindowListeners;
102 EventListenerMultiplexer maEventListeners;
103 FocusListenerMultiplexer maFocusListeners;
104 WindowListenerMultiplexer maWindowListeners;
105 KeyListenerMultiplexer maKeyListeners;
106 MouseListenerMultiplexer maMouseListeners;
107 MouseMotionListenerMultiplexer maMouseMotionListeners;
108 PaintListenerMultiplexer maPaintListeners;
109 VclContainerListenerMultiplexer maContainerListeners;
110 TopWindowListenerMultiplexer maTopWindowListeners;
112 CallbackArray maCallbackEvents;
113 ImplSVEvent * mnCallbackEventId;
115 public:
116 bool mbDisposing : 1;
117 bool mbDesignMode : 1;
118 bool mbSynthesizingVCLEvent : 1;
119 bool mbWithDefaultProps : 1;
121 sal_uLong mnListenerLockLevel;
122 sal_Int16 mnWritingMode;
123 sal_Int16 mnContextWritingMode;
125 std::unique_ptr<UnoPropertyArrayHelper>
126 mpPropHelper;
128 css::uno::Reference< css::accessibility::XAccessibleContext >
129 mxAccessibleContext;
130 css::uno::Reference< css::awt::XGraphics >
131 mxViewGraphics;
132 css::uno::Reference< css::awt::XStyleSettings >
133 mxWindowStyleSettings;
135 public:
136 bool& getDrawingOntoParent_ref() { return mbDrawingOntoParent; }
138 public:
139 /** ctor
140 @param _pAntiImpl
141 the <type>VCLXWindow</type> instance which the object belongs to. Must
142 live longer then the object just being constructed.
144 VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps );
146 VCLXWindowImpl( const VCLXWindowImpl& ) = delete;
147 const VCLXWindowImpl& operator=(const VCLXWindowImpl&) = delete;
149 /** synchronously mbEnableVisible
151 void setEnableVisible( bool bEnableVisible ) { mbEnableVisible = bEnableVisible; }
152 bool isEnableVisible() const { return mbEnableVisible; }
153 /** synchronously mbDirectVisible;
155 void setDirectVisible( bool bDirectVisible ) { mbDirectVisible = bDirectVisible; }
156 bool isDirectVisible() const { return mbDirectVisible; }
158 /** impl-version of VCLXWindow::ImplExecuteAsyncWithoutSolarLock
160 void callBackAsync( const VCLXWindow::Callback& i_callback );
162 /** notifies the object that its VCLXWindow is being disposed
164 void disposing();
166 ::toolkit::AccessibilityClient& getAccessibleFactory()
168 return maAccFactory;
171 Reference< XStyleSettings > getStyleSettings();
173 /** returns the container of registered XWindowListener2 listeners
175 ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& getWindow2Listeners() { return maWindow2Listeners; }
176 ::comphelper::OInterfaceContainerHelper3<XDockableWindowListener>& getDockableWindowListeners() { return maDockableWindowListeners; }
177 EventListenerMultiplexer& getEventListeners() { return maEventListeners; }
178 FocusListenerMultiplexer& getFocusListeners() { return maFocusListeners; }
179 WindowListenerMultiplexer& getWindowListeners() { return maWindowListeners; }
180 KeyListenerMultiplexer& getKeyListeners() { return maKeyListeners; }
181 MouseListenerMultiplexer& getMouseListeners() { return maMouseListeners; }
182 MouseMotionListenerMultiplexer& getMouseMotionListeners() { return maMouseMotionListeners; }
183 PaintListenerMultiplexer& getPaintListeners() { return maPaintListeners; }
184 VclContainerListenerMultiplexer& getContainerListeners() { return maContainerListeners; }
185 TopWindowListenerMultiplexer& getTopWindowListeners() { return maTopWindowListeners; }
187 private:
188 DECL_LINK( OnProcessCallbacks, void*, void );
192 VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps )
193 :mrAntiImpl( _rAntiImpl )
194 ,mbDisposed( false )
195 ,mbDrawingOntoParent( false )
196 ,mbEnableVisible(true)
197 ,mbDirectVisible(true)
198 ,maWindow2Listeners( maListenerContainerMutex )
199 ,maDockableWindowListeners( maListenerContainerMutex )
200 ,maEventListeners( _rAntiImpl )
201 ,maFocusListeners( _rAntiImpl )
202 ,maWindowListeners( _rAntiImpl )
203 ,maKeyListeners( _rAntiImpl )
204 ,maMouseListeners( _rAntiImpl )
205 ,maMouseMotionListeners( _rAntiImpl )
206 ,maPaintListeners( _rAntiImpl )
207 ,maContainerListeners( _rAntiImpl )
208 ,maTopWindowListeners( _rAntiImpl )
209 ,mnCallbackEventId( nullptr )
210 ,mbDisposing( false )
211 ,mbDesignMode( false )
212 ,mbSynthesizingVCLEvent( false )
213 ,mbWithDefaultProps( _bWithDefaultProps )
214 ,mnListenerLockLevel( 0 )
215 ,mnWritingMode( WritingMode2::CONTEXT )
216 ,mnContextWritingMode( WritingMode2::CONTEXT )
220 void VCLXWindowImpl::disposing()
222 SolarMutexGuard aGuard;
224 assert(!mbDisposed);
226 mbDisposed = true;
228 if ( mnCallbackEventId )
230 Application::RemoveUserEvent( mnCallbackEventId );
231 mnCallbackEventId = nullptr;
232 // we acquired our VCLXWindow once before posting the event, release this one ref now
233 mrAntiImpl.release();
235 maCallbackEvents.clear();
237 css::lang::EventObject aEvent;
238 aEvent.Source = mrAntiImpl;
240 maDockableWindowListeners.disposeAndClear( aEvent );
241 maEventListeners.disposeAndClear( aEvent );
242 maFocusListeners.disposeAndClear( aEvent );
243 maWindowListeners.disposeAndClear( aEvent );
244 maKeyListeners.disposeAndClear( aEvent );
245 maMouseListeners.disposeAndClear( aEvent );
246 maMouseMotionListeners.disposeAndClear( aEvent );
247 maPaintListeners.disposeAndClear( aEvent );
248 maContainerListeners.disposeAndClear( aEvent );
249 maTopWindowListeners.disposeAndClear( aEvent );
250 maWindow2Listeners.disposeAndClear( aEvent );
252 ::toolkit::WindowStyleSettings* pStyleSettings = static_cast< ::toolkit::WindowStyleSettings* >( mxWindowStyleSettings.get() );
253 if ( pStyleSettings != nullptr )
254 pStyleSettings->dispose();
255 mxWindowStyleSettings.clear();
259 void VCLXWindowImpl::callBackAsync( const VCLXWindow::Callback& i_callback )
261 DBG_TESTSOLARMUTEX();
262 maCallbackEvents.push_back( i_callback );
263 if ( !mnCallbackEventId )
265 // ensure our VCLXWindow is not destroyed while the event is underway
266 mrAntiImpl.acquire();
267 mnCallbackEventId = Application::PostUserEvent( LINK( this, VCLXWindowImpl, OnProcessCallbacks ) );
272 IMPL_LINK_NOARG(VCLXWindowImpl, OnProcessCallbacks, void*, void)
274 const Reference< uno::XInterface > xKeepAlive( mrAntiImpl );
276 SAL_INFO("toolkit.controls", "OnProcessCallbacks grabbing solarmutex");
278 // work on a copy of the callback array
279 CallbackArray aCallbacksCopy;
281 SolarMutexGuard aGuard;
282 aCallbacksCopy.swap(maCallbackEvents);
284 // we acquired our VCLXWindow once before posting the event, release this one ref now
285 mrAntiImpl.release();
287 assert( mnCallbackEventId && "should not be possible to call us if the event was removed");
289 mnCallbackEventId = nullptr;
293 SAL_INFO("toolkit.controls", "OnProcessCallbacks relinquished solarmutex");
294 SolarMutexReleaser aReleaseSolar;
295 for (const auto& rCallback : aCallbacksCopy)
297 rCallback();
302 Reference< XStyleSettings > VCLXWindowImpl::getStyleSettings()
304 SolarMutexGuard aGuard;
305 if ( mbDisposed )
306 throw DisposedException( OUString(), mrAntiImpl );
307 if ( !mxWindowStyleSettings.is() )
308 mxWindowStyleSettings = new ::toolkit::WindowStyleSettings( maListenerContainerMutex, mrAntiImpl );
309 return mxWindowStyleSettings;
313 // Uses an out-parameter instead of return value, due to the object reference
315 static void ImplInitWindowEvent( css::awt::WindowEvent& rEvent, vcl::Window const * pWindow )
317 Point aPos = pWindow->GetPosPixel();
318 Size aSz = pWindow->GetSizePixel();
320 rEvent.X = aPos.X();
321 rEvent.Y = aPos.Y();
323 rEvent.Width = aSz.Width();
324 rEvent.Height = aSz.Height();
326 pWindow->GetBorder( rEvent.LeftInset, rEvent.TopInset, rEvent.RightInset, rEvent.BottomInset );
329 VCLXWindow::VCLXWindow( bool _bWithDefaultProps )
331 mpImpl.reset( new VCLXWindowImpl( *this, _bWithDefaultProps ) );
334 VCLXWindow::~VCLXWindow()
336 assert(mpImpl->mbDisposing && "forgot to call dispose()");
340 void VCLXWindow::ImplExecuteAsyncWithoutSolarLock( const Callback& i_callback )
342 if (mpImpl->mbDisposing)
343 return;
344 mpImpl->callBackAsync( i_callback );
348 ::toolkit::IAccessibleFactory& VCLXWindow::getAccessibleFactory()
350 return mpImpl->getAccessibleFactory().getFactory();
353 void VCLXWindow::SetWindow( const VclPtr<vcl::Window> &pWindow )
355 assert(!mpImpl->mbDisposing || !pWindow);
357 if ( GetWindow() )
359 GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
360 // GetWindow()->DbgAssertNoEventListeners();
363 SetOutputDevice( pWindow ? pWindow->GetOutDev() : nullptr );
365 if ( GetWindow() )
367 GetWindow()->AddEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
368 bool bDirectVisible = pWindow && pWindow->IsVisible();
369 mpImpl->setDirectVisible( bDirectVisible );
373 void VCLXWindow::suspendVclEventListening( )
375 ++mpImpl->mnListenerLockLevel;
378 void VCLXWindow::resumeVclEventListening( )
380 DBG_ASSERT( mpImpl->mnListenerLockLevel, "VCLXWindow::resumeVclEventListening: not suspended!" );
381 --mpImpl->mnListenerLockLevel;
384 void VCLXWindow::notifyWindowRemoved( vcl::Window const & _rWindow )
386 if ( mpImpl->getContainerListeners().getLength() )
388 awt::VclContainerEvent aEvent;
389 aEvent.Source = *this;
390 aEvent.Child = static_cast< XWindow* >( _rWindow.GetWindowPeer() );
391 mpImpl->getContainerListeners().windowRemoved( aEvent );
395 IMPL_LINK( VCLXWindow, WindowEventListener, VclWindowEvent&, rEvent, void )
397 if ( mpImpl->mbDisposing || mpImpl->mnListenerLockLevel )
398 return;
400 DBG_ASSERT( rEvent.GetWindow() && GetWindow(), "Window???" );
401 ProcessWindowEvent( rEvent );
404 namespace
406 struct CallWindow2Listener
408 CallWindow2Listener( ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& i_rWindow2Listeners, const bool i_bEnabled, EventObject i_Event )
409 :m_rWindow2Listeners( i_rWindow2Listeners )
410 ,m_bEnabled( i_bEnabled )
411 ,m_aEvent(std::move( i_Event ))
415 void operator()()
417 m_rWindow2Listeners.notifyEach( m_bEnabled ? &XWindowListener2::windowEnabled : &XWindowListener2::windowDisabled, m_aEvent );
420 ::comphelper::OInterfaceContainerHelper3<css::awt::XWindowListener2>& m_rWindow2Listeners;
421 const bool m_bEnabled;
422 const EventObject m_aEvent;
426 void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
428 if (mpImpl->mbDisposing)
429 return;
430 css::uno::Reference< css::uno::XInterface > xThis( static_cast<cppu::OWeakObject*>(this) );
432 switch ( rVclWindowEvent.GetId() )
434 case VclEventId::WindowEnabled:
435 case VclEventId::WindowDisabled:
437 Callback aCallback = CallWindow2Listener(
438 mpImpl->getWindow2Listeners(),
439 ( VclEventId::WindowEnabled == rVclWindowEvent.GetId() ),
440 EventObject( *this )
442 ImplExecuteAsyncWithoutSolarLock( aCallback );
444 break;
446 case VclEventId::WindowPaint:
448 if ( mpImpl->getPaintListeners().getLength() )
450 css::awt::PaintEvent aEvent;
451 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
452 aEvent.UpdateRect = AWTRectangle( *static_cast<tools::Rectangle*>(rVclWindowEvent.GetData()) );
453 aEvent.Count = 0;
454 mpImpl->getPaintListeners().windowPaint( aEvent );
457 break;
458 case VclEventId::WindowMove:
460 if ( mpImpl->getWindowListeners().getLength() )
462 css::awt::WindowEvent aEvent;
463 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
464 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
465 mpImpl->getWindowListeners().windowMoved( aEvent );
468 break;
469 case VclEventId::WindowResize:
471 if ( mpImpl->getWindowListeners().getLength() )
473 css::awt::WindowEvent aEvent;
474 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
475 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
476 mpImpl->getWindowListeners().windowResized( aEvent );
479 break;
480 case VclEventId::WindowShow:
482 if ( mpImpl->getWindowListeners().getLength() )
484 css::awt::WindowEvent aEvent;
485 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
486 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
487 mpImpl->getWindowListeners().windowShown( aEvent );
490 // For TopWindows this means opened...
491 if ( mpImpl->getTopWindowListeners().getLength() )
493 css::lang::EventObject aEvent;
494 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
495 mpImpl->getTopWindowListeners().windowOpened( aEvent );
498 break;
499 case VclEventId::WindowHide:
501 if ( mpImpl->getWindowListeners().getLength() )
503 css::awt::WindowEvent aEvent;
504 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
505 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
506 mpImpl->getWindowListeners().windowHidden( aEvent );
509 // For TopWindows this means closed...
510 if ( mpImpl->getTopWindowListeners().getLength() )
512 css::lang::EventObject aEvent;
513 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
514 mpImpl->getTopWindowListeners().windowClosed( aEvent );
517 break;
518 case VclEventId::WindowActivate:
519 case VclEventId::WindowDeactivate:
521 if (!mpImpl->getTopWindowListeners().getLength())
522 return;
524 // Suppress events which are unlikely to be interesting to our listeners.
525 vcl::Window* pWin = static_cast<vcl::Window*>(rVclWindowEvent.GetData());
526 bool bSuppress = false;
528 while (pWin)
530 // Either the event came from the same window, from its
531 // child, or from a child of its border window (e.g.
532 // menubar or notebookbar).
533 if (pWin->GetWindow(GetWindowType::Client) == GetWindow())
534 return;
536 if (pWin->IsMenuFloatingWindow())
537 bSuppress = true;
539 if (pWin->GetType() == WindowType::FLOATINGWINDOW &&
540 static_cast<FloatingWindow*>(pWin)->IsInPopupMode())
541 bSuppress = true;
543 // Otherwise, don't suppress if the event came from a different frame.
544 if (!bSuppress && pWin->GetWindow(GetWindowType::Frame) == pWin)
545 break;
547 pWin = pWin->GetWindow(GetWindowType::RealParent);
550 css::lang::EventObject aEvent;
551 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
552 if (rVclWindowEvent.GetId() == VclEventId::WindowActivate)
553 mpImpl->getTopWindowListeners().windowActivated( aEvent );
554 else
555 mpImpl->getTopWindowListeners().windowDeactivated( aEvent );
557 break;
558 case VclEventId::WindowClose:
560 if ( mpImpl->getDockableWindowListeners().getLength() )
562 css::lang::EventObject aEvent;
563 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
564 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::closed, aEvent );
566 if ( mpImpl->getTopWindowListeners().getLength() )
568 css::lang::EventObject aEvent;
569 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
570 mpImpl->getTopWindowListeners().windowClosing( aEvent );
573 break;
574 case VclEventId::ControlGetFocus:
575 case VclEventId::WindowGetFocus:
577 if ( ( rVclWindowEvent.GetWindow()->IsCompoundControl()
578 && rVclWindowEvent.GetId() == VclEventId::ControlGetFocus
580 || ( !rVclWindowEvent.GetWindow()->IsCompoundControl()
581 && rVclWindowEvent.GetId() == VclEventId::WindowGetFocus
585 if ( mpImpl->getFocusListeners().getLength() )
587 css::awt::FocusEvent aEvent;
588 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
589 aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags());
590 aEvent.Temporary = false;
591 mpImpl->getFocusListeners().focusGained( aEvent );
595 break;
596 case VclEventId::ControlLoseFocus:
597 case VclEventId::WindowLoseFocus:
599 if ( ( rVclWindowEvent.GetWindow()->IsCompoundControl()
600 && rVclWindowEvent.GetId() == VclEventId::ControlLoseFocus
602 || ( !rVclWindowEvent.GetWindow()->IsCompoundControl()
603 && rVclWindowEvent.GetId() == VclEventId::WindowLoseFocus
607 if ( mpImpl->getFocusListeners().getLength() )
609 css::awt::FocusEvent aEvent;
610 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
611 aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags());
612 aEvent.Temporary = false;
614 vcl::Window* pNext = Application::GetFocusWindow();
615 if ( pNext )
617 // Don't care about internals if this control is compound
618 vcl::Window* pNextC = pNext;
619 while ( pNextC && !pNextC->IsCompoundControl() )
620 pNextC = pNextC->GetParent();
621 if ( pNextC )
622 pNext = pNextC;
624 pNext->GetComponentInterface();
625 aEvent.NextFocus = static_cast<cppu::OWeakObject*>(pNext->GetWindowPeer());
627 mpImpl->getFocusListeners().focusLost( aEvent );
631 break;
632 case VclEventId::WindowMinimize:
634 if ( mpImpl->getTopWindowListeners().getLength() )
636 css::lang::EventObject aEvent;
637 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
638 mpImpl->getTopWindowListeners().windowMinimized( aEvent );
641 break;
642 case VclEventId::WindowNormalize:
644 if ( mpImpl->getTopWindowListeners().getLength() )
646 css::lang::EventObject aEvent;
647 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
648 mpImpl->getTopWindowListeners().windowNormalized( aEvent );
651 break;
652 case VclEventId::WindowKeyInput:
654 if ( mpImpl->getKeyListeners().getLength() )
656 css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
657 *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
658 ) );
659 mpImpl->getKeyListeners().keyPressed( aEvent );
662 break;
663 case VclEventId::WindowKeyUp:
665 if ( mpImpl->getKeyListeners().getLength() )
667 css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
668 *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
669 ) );
670 mpImpl->getKeyListeners().keyReleased( aEvent );
673 break;
674 case VclEventId::WindowCommand:
676 CommandEvent* pCmdEvt = static_cast<CommandEvent*>(rVclWindowEvent.GetData());
677 if ( mpImpl->getMouseListeners().getLength() && ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu ) )
679 // CommandEventId::ContextMenu: send as mousePressed with PopupTrigger = true ...
680 Point aWhere = static_cast< CommandEvent* >( rVclWindowEvent.GetData() )->GetMousePosPixel();
681 if ( !pCmdEvt->IsMouseEvent() )
682 { // for keyboard events, we set the coordinates to -1,-1. This is a slight HACK, but the current API
683 // handles a context menu command as special case of a mouse event, which is simply wrong.
684 // Without extending the API, we would not have another chance to notify listeners of a
685 // keyboard-triggered context menu request
686 aWhere = Point( -1, -1 );
689 MouseEvent aMEvt( aWhere, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, 0 );
690 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( aMEvt, *this ) );
691 aEvent.PopupTrigger = true;
693 Callback aCallback = [ this, aEvent ]()
694 { this->mpImpl->getMouseListeners().mousePressed( aEvent ); };
696 ImplExecuteAsyncWithoutSolarLock( aCallback );
699 break;
700 case VclEventId::WindowMouseMove:
702 MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData());
703 if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
705 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
706 bool const isEnter(pMouseEvt->IsEnterWindow());
707 Callback aCallback = [ this, isEnter, aEvent ]()
708 { MouseListenerMultiplexer& rMouseListeners = this->mpImpl->getMouseListeners();
709 isEnter
710 ? rMouseListeners.mouseEntered(aEvent)
711 : rMouseListeners.mouseExited(aEvent); };
713 ImplExecuteAsyncWithoutSolarLock( aCallback );
716 if ( mpImpl->getMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
718 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
719 aEvent.ClickCount = 0;
720 if ( pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE )
721 mpImpl->getMouseMotionListeners().mouseMoved( aEvent );
722 else
723 mpImpl->getMouseMotionListeners().mouseDragged( aEvent );
726 break;
727 case VclEventId::WindowMouseButtonDown:
729 if ( mpImpl->getMouseListeners().getLength() )
731 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
732 Callback aCallback = [ this, aEvent ]()
733 { this->mpImpl->getMouseListeners().mousePressed( aEvent ); };
734 ImplExecuteAsyncWithoutSolarLock( aCallback );
737 break;
738 case VclEventId::WindowMouseButtonUp:
740 if ( mpImpl->getMouseListeners().getLength() )
742 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
744 Callback aCallback = [ this, aEvent ]()
745 { this->mpImpl->getMouseListeners().mouseReleased( aEvent ); };
746 ImplExecuteAsyncWithoutSolarLock( aCallback );
749 break;
750 case VclEventId::WindowStartDocking:
752 if ( mpImpl->getDockableWindowListeners().getLength() )
754 DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData());
756 if( pData )
758 css::awt::DockingEvent aEvent;
759 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
760 aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
761 aEvent.MousePos.X = pData->maMousePos.X();
762 aEvent.MousePos.Y = pData->maMousePos.Y();
763 aEvent.bLiveMode = false;
764 aEvent.bInteractive = true;
766 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::startDocking, aEvent );
770 break;
771 case VclEventId::WindowDocking:
773 if ( mpImpl->getDockableWindowListeners().getLength() )
775 DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData());
777 if( pData )
779 css::awt::DockingEvent aEvent;
780 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
781 aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
782 aEvent.MousePos.X = pData->maMousePos.X();
783 aEvent.MousePos.Y = pData->maMousePos.Y();
784 aEvent.bLiveMode = false;
785 aEvent.bInteractive = true;
787 Reference< XDockableWindowListener > xFirstListener;
788 ::comphelper::OInterfaceIteratorHelper3 aIter( mpImpl->getDockableWindowListeners() );
789 while ( aIter.hasMoreElements() && !xFirstListener.is() )
791 xFirstListener = aIter.next();
794 css::awt::DockingData aDockingData =
795 xFirstListener->docking( aEvent );
796 pData->maTrackRect = VCLRectangle( aDockingData.TrackingRectangle );
797 pData->mbFloating = aDockingData.bFloating;
801 break;
802 case VclEventId::WindowEndDocking:
804 if ( mpImpl->getDockableWindowListeners().getLength() )
806 EndDockingData *pData = static_cast<EndDockingData*>(rVclWindowEvent.GetData());
808 if( pData )
810 css::awt::EndDockingEvent aEvent;
811 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
812 aEvent.WindowRectangle = AWTRectangle( pData->maWindowRect );
813 aEvent.bFloating = pData->mbFloating;
814 aEvent.bCancelled = pData->mbCancelled;
815 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endDocking, aEvent );
819 break;
820 case VclEventId::WindowPrepareToggleFloating:
822 if ( mpImpl->getDockableWindowListeners().getLength() )
824 sal_Bool *p_bFloating = static_cast<sal_Bool*>(rVclWindowEvent.GetData());
826 css::lang::EventObject aEvent;
827 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
829 Reference< XDockableWindowListener > xFirstListener;
830 ::comphelper::OInterfaceIteratorHelper3 aIter( mpImpl->getDockableWindowListeners() );
831 while ( aIter.hasMoreElements() && !xFirstListener.is() )
833 xFirstListener = aIter.next();
836 *p_bFloating = xFirstListener->prepareToggleFloatingMode( aEvent );
839 break;
840 case VclEventId::WindowToggleFloating:
842 if ( mpImpl->getDockableWindowListeners().getLength() )
844 css::lang::EventObject aEvent;
845 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
846 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::toggleFloatingMode, aEvent );
849 break;
850 case VclEventId::WindowEndPopupMode:
852 if ( mpImpl->getDockableWindowListeners().getLength() )
854 EndPopupModeData *pData = static_cast<EndPopupModeData*>(rVclWindowEvent.GetData());
856 if( pData )
858 css::awt::EndPopupModeEvent aEvent;
859 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
860 aEvent.FloatingPosition.X = pData->maFloatingPos.X();
861 aEvent.FloatingPosition.Y = pData->maFloatingPos.Y();
862 aEvent.bTearoff = pData->mbTearoff;
863 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endPopupMode, aEvent );
867 break;
868 default: break;
872 uno::Reference< accessibility::XAccessibleContext > VCLXWindow::CreateAccessibleContext()
874 SolarMutexGuard aGuard;
875 if (mpImpl->mbDisposing)
876 return nullptr;
877 return getAccessibleFactory().createAccessibleContext( this );
880 void VCLXWindow::SetSynthesizingVCLEvent( bool _b )
882 mpImpl->mbSynthesizingVCLEvent = _b;
885 bool VCLXWindow::IsSynthesizingVCLEvent() const
887 return mpImpl->mbSynthesizingVCLEvent;
890 Size VCLXWindow::ImplCalcWindowSize( const Size& rOutSz ) const
892 Size aSz = rOutSz;
894 VclPtr<vcl::Window> pWindow = GetWindow();
895 if ( pWindow )
897 sal_Int32 nLeft, nTop, nRight, nBottom;
898 pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
899 aSz.AdjustWidth(nLeft+nRight );
900 aSz.AdjustHeight(nTop+nBottom );
902 return aSz;
906 // css::lang::Component
907 void VCLXWindow::dispose( )
909 SolarMutexGuard aGuard;
911 if ( mpImpl->mbDisposing )
912 return;
914 mpImpl->mbDisposing = true;
916 mpImpl->mxViewGraphics = nullptr;
918 mpImpl->disposing();
920 if ( VclPtr<vcl::Window> pWindow = GetWindow() )
922 pWindow->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
923 pWindow->SetWindowPeer( nullptr, nullptr );
924 pWindow->SetAccessible( nullptr );
926 SetOutputDevice( nullptr );
927 pWindow.disposeAndClear();
930 // #i14103# dispose the accessible context after the window has been destroyed,
931 // otherwise the old value in the child event fired in VCLXAccessibleComponent::ProcessWindowEvent()
932 // for VclEventId::WindowChildDestroyed contains a reference to an already disposed accessible object
935 css::uno::Reference< css::lang::XComponent > xComponent( mpImpl->mxAccessibleContext, css::uno::UNO_QUERY );
936 if ( xComponent.is() )
937 xComponent->dispose();
939 catch ( const css::uno::Exception& )
941 OSL_FAIL( "VCLXWindow::dispose: could not dispose the accessible context!" );
943 mpImpl->mxAccessibleContext.clear();
946 void VCLXWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
948 SolarMutexGuard aGuard;
949 if (mpImpl->mbDisposing) // called during dispose by accessibility stuff
950 return;
951 mpImpl->getEventListeners().addInterface( rxListener );
954 void VCLXWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
956 SolarMutexGuard aGuard;
957 if (mpImpl->mbDisposing)
958 return;
959 mpImpl->getEventListeners().removeInterface( rxListener );
963 // css::awt::XWindow
964 void VCLXWindow::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
966 SolarMutexGuard aGuard;
967 comphelper::ProfileZone aZone("setPosSize");
969 if ( GetWindow() )
971 if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) )
972 vcl::Window::GetDockingManager()->SetPosSizePixel( GetWindow() , X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
973 else
974 GetWindow()->setPosSizePixel( X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
978 css::awt::Rectangle VCLXWindow::getPosSize( )
980 SolarMutexGuard aGuard;
982 css::awt::Rectangle aBounds;
983 if ( GetWindow() )
985 if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) )
986 aBounds = AWTRectangle( vcl::Window::GetDockingManager()->GetPosSizePixel( GetWindow() ) );
987 else
988 aBounds = AWTRectangle( tools::Rectangle( GetWindow()->GetPosPixel(), GetWindow()->GetSizePixel() ) );
991 return aBounds;
994 void VCLXWindow::setVisible( sal_Bool bVisible )
996 SolarMutexGuard aGuard;
998 VclPtr<vcl::Window> pWindow = GetWindow();
999 if ( pWindow )
1001 mpImpl->setDirectVisible( bVisible );
1002 pWindow->Show( bVisible && mpImpl->isEnableVisible() );
1006 void VCLXWindow::setEnable( sal_Bool bEnable )
1008 SolarMutexGuard aGuard;
1010 VclPtr<vcl::Window> pWindow = GetWindow();
1011 if ( pWindow )
1013 pWindow->Enable( bEnable, false ); // #95824# without children!
1014 pWindow->EnableInput( bEnable );
1018 void VCLXWindow::setFocus( )
1020 SolarMutexGuard aGuard;
1022 if ( GetWindow() )
1023 GetWindow()->GrabFocus();
1026 void VCLXWindow::addWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener )
1028 SolarMutexGuard aGuard;
1029 if (mpImpl->mbDisposing)
1030 return;
1032 mpImpl->getWindowListeners().addInterface( rxListener );
1034 Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
1035 if ( xListener2.is() )
1036 mpImpl->getWindow2Listeners().addInterface( xListener2 );
1038 // #100119# Get all resize events, even if height or width 0, or invisible
1039 if ( GetWindow() )
1040 GetWindow()->EnableAllResize();
1043 void VCLXWindow::removeWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener )
1045 SolarMutexGuard aGuard;
1047 if (mpImpl->mbDisposing)
1048 return;
1050 Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
1051 if ( xListener2.is() )
1052 mpImpl->getWindow2Listeners().removeInterface( xListener2 );
1054 mpImpl->getWindowListeners().removeInterface( rxListener );
1057 void VCLXWindow::addFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
1059 SolarMutexGuard aGuard;
1060 if (mpImpl->mbDisposing)
1061 return;
1062 mpImpl->getFocusListeners().addInterface( rxListener );
1065 void VCLXWindow::removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
1067 SolarMutexGuard aGuard;
1068 if (mpImpl->mbDisposing)
1069 return;
1070 mpImpl->getFocusListeners().removeInterface( rxListener );
1073 void VCLXWindow::addKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener )
1075 SolarMutexGuard aGuard;
1076 if (mpImpl->mbDisposing)
1077 return;
1078 mpImpl->getKeyListeners().addInterface( rxListener );
1081 void VCLXWindow::removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener )
1083 SolarMutexGuard aGuard;
1084 if (mpImpl->mbDisposing)
1085 return;
1086 mpImpl->getKeyListeners().removeInterface( rxListener );
1089 void VCLXWindow::addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
1091 SolarMutexGuard aGuard;
1092 if (mpImpl->mbDisposing)
1093 return;
1094 mpImpl->getMouseListeners().addInterface( rxListener );
1097 void VCLXWindow::removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
1099 SolarMutexGuard aGuard;
1100 if (mpImpl->mbDisposing)
1101 return;
1102 mpImpl->getMouseListeners().removeInterface( rxListener );
1105 void VCLXWindow::addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
1107 SolarMutexGuard aGuard;
1108 if (mpImpl->mbDisposing)
1109 return;
1110 mpImpl->getMouseMotionListeners().addInterface( rxListener );
1113 void VCLXWindow::removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
1115 SolarMutexGuard aGuard;
1116 if (mpImpl->mbDisposing)
1117 return;
1118 mpImpl->getMouseMotionListeners().removeInterface( rxListener );
1121 void VCLXWindow::addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
1123 SolarMutexGuard aGuard;
1124 if (mpImpl->mbDisposing)
1125 return;
1126 mpImpl->getPaintListeners().addInterface( rxListener );
1129 void VCLXWindow::removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
1131 SolarMutexGuard aGuard;
1132 if (mpImpl->mbDisposing)
1133 return;
1134 mpImpl->getPaintListeners().removeInterface( rxListener );
1137 // css::awt::XWindowPeer
1138 css::uno::Reference< css::awt::XToolkit > VCLXWindow::getToolkit( )
1140 // no guard. nothing to guard here.
1141 // 82463 - 12/21/00 - fs
1142 return Application::GetVCLToolkit();
1145 void VCLXWindow::setPointer( const css::uno::Reference< css::awt::XPointer >& rxPointer )
1147 SolarMutexGuard aGuard;
1149 VCLXPointer* pPointer = dynamic_cast<VCLXPointer*>( rxPointer.get() );
1150 if ( pPointer && GetWindow() )
1151 GetWindow()->SetPointer( pPointer->GetPointer() );
1154 void VCLXWindow::setBackground( sal_Int32 nColor )
1156 SolarMutexGuard aGuard;
1158 if ( !GetWindow() )
1159 return;
1161 Color aColor(ColorTransparency, nColor);
1162 GetWindow()->SetBackground( aColor );
1163 GetWindow()->SetControlBackground( aColor );
1165 WindowType eWinType = GetWindow()->GetType();
1166 if ( ( eWinType == WindowType::WINDOW ) ||
1167 ( eWinType == WindowType::WORKWINDOW ) ||
1168 ( eWinType == WindowType::FLOATINGWINDOW ) )
1170 GetWindow()->Invalidate();
1174 void VCLXWindow::invalidate( sal_Int16 nInvalidateFlags )
1176 SolarMutexGuard aGuard;
1178 if ( GetWindow() )
1179 GetWindow()->Invalidate( static_cast<InvalidateFlags>(nInvalidateFlags) );
1182 void VCLXWindow::invalidateRect( const css::awt::Rectangle& rRect, sal_Int16 nInvalidateFlags )
1184 SolarMutexGuard aGuard;
1186 if ( GetWindow() )
1187 GetWindow()->Invalidate( VCLRectangle(rRect), static_cast<InvalidateFlags>(nInvalidateFlags) );
1191 // css::awt::XVclWindowPeer
1192 sal_Bool VCLXWindow::isChild( const css::uno::Reference< css::awt::XWindowPeer >& rxPeer )
1194 SolarMutexGuard aGuard;
1196 bool bIsChild = false;
1197 VclPtr<vcl::Window> pWindow = GetWindow();
1198 if ( pWindow )
1200 VclPtr<vcl::Window> pPeerWindow = VCLUnoHelper::GetWindow( rxPeer );
1201 bIsChild = pPeerWindow && pWindow->IsChild( pPeerWindow );
1204 return bIsChild;
1207 void VCLXWindow::setDesignMode( sal_Bool bOn )
1209 SolarMutexGuard aGuard;
1211 mpImpl->mbDesignMode = bOn;
1214 sal_Bool VCLXWindow::isDesignMode( )
1216 SolarMutexGuard aGuard;
1217 return mpImpl->mbDesignMode;
1220 void VCLXWindow::enableClipSiblings( sal_Bool bClip )
1222 SolarMutexGuard aGuard;
1224 if ( GetWindow() )
1225 GetWindow()->EnableClipSiblings( bClip );
1228 void VCLXWindow::setForeground( sal_Int32 nColor )
1230 SolarMutexGuard aGuard;
1232 if ( GetWindow() )
1234 GetWindow()->SetControlForeground( Color(ColorTransparency, nColor) );
1238 void VCLXWindow::setControlFont( const css::awt::FontDescriptor& rFont )
1240 SolarMutexGuard aGuard;
1242 if ( GetWindow() )
1243 GetWindow()->SetControlFont( VCLUnoHelper::CreateFont( rFont, GetWindow()->GetControlFont() ) );
1246 void VCLXWindow::getStyles( sal_Int16 nType, css::awt::FontDescriptor& Font, sal_Int32& ForegroundColor, sal_Int32& BackgroundColor )
1248 SolarMutexGuard aGuard;
1250 if ( !GetWindow() )
1251 return;
1253 const StyleSettings& rStyleSettings = GetWindow()->GetSettings().GetStyleSettings();
1255 switch ( nType )
1257 case css::awt::Style::FRAME:
1259 Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
1260 ForegroundColor = sal_Int32(rStyleSettings.GetWindowTextColor());
1261 BackgroundColor = sal_Int32(rStyleSettings.GetWindowColor());
1263 break;
1264 case css::awt::Style::DIALOG:
1266 Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
1267 ForegroundColor = sal_Int32(rStyleSettings.GetDialogTextColor());
1268 BackgroundColor = sal_Int32(rStyleSettings.GetDialogColor());
1270 break;
1271 default: OSL_FAIL( "VCLWindow::getStyles() - unknown Type" );
1275 namespace toolkit
1277 static void setColorSettings( vcl::Window* _pWindow, const css::uno::Any& _rValue,
1278 void (StyleSettings::*pSetter)( const Color& ), const Color& (StyleSettings::*pGetter)( ) const )
1280 sal_Int32 nColor = 0;
1281 if ( !( _rValue >>= nColor ) )
1282 nColor = sal_Int32((Application::GetSettings().GetStyleSettings().*pGetter)());
1284 AllSettings aSettings = _pWindow->GetSettings();
1285 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1287 (aStyleSettings.*pSetter)( Color( ColorTransparency, nColor ) );
1289 aSettings.SetStyleSettings( aStyleSettings );
1290 _pWindow->SetSettings( aSettings, true );
1294 // Terminated by BASEPROPERTY_NOTFOUND (or 0)
1295 void VCLXWindow::PushPropertyIds( std::vector< sal_uInt16 > &rIds,
1296 int nFirstId, ...)
1298 va_list pVarArgs;
1299 va_start( pVarArgs, nFirstId );
1301 for ( int nId = nFirstId; nId != BASEPROPERTY_NOTFOUND;
1302 nId = va_arg( pVarArgs, int ) )
1303 rIds.push_back( static_cast<sal_uInt16>(nId) );
1305 va_end( pVarArgs );
1308 void VCLXWindow::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds, bool bWithDefaults )
1310 // These are common across ~all VCLXWindow derived classes
1311 if( bWithDefaults )
1312 PushPropertyIds( rIds,
1313 BASEPROPERTY_ALIGN,
1314 BASEPROPERTY_BACKGROUNDCOLOR,
1315 BASEPROPERTY_BORDER,
1316 BASEPROPERTY_BORDERCOLOR,
1317 BASEPROPERTY_DEFAULTCONTROL,
1318 BASEPROPERTY_ENABLED,
1319 BASEPROPERTY_FONTDESCRIPTOR,
1320 BASEPROPERTY_HELPTEXT,
1321 BASEPROPERTY_HELPURL,
1322 BASEPROPERTY_TEXT,
1323 BASEPROPERTY_PRINTABLE,
1324 BASEPROPERTY_ENABLEVISIBLE, // for visibility
1325 BASEPROPERTY_TABSTOP,
1328 // lovely hack from:
1329 // void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
1330 if( std::find(rIds.begin(), rIds.end(), BASEPROPERTY_FONTDESCRIPTOR) != rIds.end() )
1332 // some properties are not included in the FontDescriptor, but every time
1333 // when we have a FontDescriptor we want to have these properties too.
1334 // => Easier to register the here, instead everywhere where I register the FontDescriptor...
1336 rIds.push_back( BASEPROPERTY_TEXTCOLOR );
1337 rIds.push_back( BASEPROPERTY_TEXTLINECOLOR );
1338 rIds.push_back( BASEPROPERTY_FONTRELIEF );
1339 rIds.push_back( BASEPROPERTY_FONTEMPHASISMARK );
1343 void VCLXWindow::GetPropertyIds( std::vector< sal_uInt16 >& _out_rIds )
1345 return ImplGetPropertyIds( _out_rIds, mpImpl->mbWithDefaultProps );
1348 ListenerMultiplexerBase<css::awt::XVclContainerListener>& VCLXWindow::GetContainerListeners()
1350 return mpImpl->getContainerListeners();
1353 ListenerMultiplexerBase<css::awt::XTopWindowListener>& VCLXWindow::GetTopWindowListeners()
1355 return mpImpl->getTopWindowListeners();
1358 namespace
1360 void lcl_updateWritingMode( vcl::Window& _rWindow, const sal_Int16 _nWritingMode, const sal_Int16 _nContextWritingMode )
1362 bool bEnableRTL = false;
1363 switch ( _nWritingMode )
1365 case WritingMode2::LR_TB: bEnableRTL = false; break;
1366 case WritingMode2::RL_TB: bEnableRTL = true; break;
1367 case WritingMode2::CONTEXT:
1369 // consult our ContextWritingMode. If it has an explicit RTL/LTR value, then use
1370 // it. If it doesn't (but is CONTEXT itself), then just ask the parent window of our
1371 // own window for its RTL mode
1372 switch ( _nContextWritingMode )
1374 case WritingMode2::LR_TB: bEnableRTL = false; break;
1375 case WritingMode2::RL_TB: bEnableRTL = true; break;
1376 case WritingMode2::CONTEXT:
1378 const vcl::Window* pParent = _rWindow.GetParent();
1379 OSL_ENSURE( pParent, "lcl_updateWritingMode: cannot determine context's writing mode!" );
1380 if ( pParent )
1381 bEnableRTL = pParent->IsRTLEnabled();
1383 break;
1386 break;
1387 default:
1388 OSL_FAIL( "lcl_updateWritingMode: unsupported WritingMode!" );
1389 } // switch ( nWritingMode )
1391 _rWindow.EnableRTL( bEnableRTL );
1395 void VCLXWindow::setProperty( const OUString& PropertyName, const css::uno::Any& Value )
1397 SolarMutexGuard aGuard;
1399 VclPtr<vcl::Window> pWindow = GetWindow();
1400 if ( !pWindow )
1401 return;
1403 bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID;
1405 WindowType eWinType = pWindow->GetType();
1406 sal_uInt16 nPropType = GetPropertyId( PropertyName );
1407 switch ( nPropType )
1409 case BASEPROPERTY_REFERENCE_DEVICE:
1411 Control* pControl = dynamic_cast< Control* >( pWindow.get() );
1412 OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
1413 if ( !pControl )
1414 break;
1415 Reference< XDevice > xDevice( Value, UNO_QUERY );
1416 OutputDevice* pDevice = VCLUnoHelper::GetOutputDevice( xDevice );
1417 pControl->SetReferenceDevice( pDevice );
1419 break;
1421 case BASEPROPERTY_CONTEXT_WRITING_MODE:
1423 OSL_VERIFY( Value >>= mpImpl->mnContextWritingMode );
1424 if ( mpImpl->mnWritingMode == WritingMode2::CONTEXT )
1425 lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
1427 break;
1429 case BASEPROPERTY_WRITING_MODE:
1431 bool bProperType = ( Value >>= mpImpl->mnWritingMode );
1432 OSL_ENSURE( bProperType, "VCLXWindow::setProperty( 'WritingMode' ): illegal value type!" );
1433 if ( bProperType )
1434 lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
1436 break;
1438 case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
1440 sal_uInt16 nWheelBehavior( css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY );
1441 OSL_VERIFY( Value >>= nWheelBehavior );
1443 AllSettings aSettings = pWindow->GetSettings();
1444 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
1446 MouseWheelBehaviour nVclBehavior( MouseWheelBehaviour::FocusOnly );
1447 switch ( nWheelBehavior )
1449 case css::awt::MouseWheelBehavior::SCROLL_DISABLED: nVclBehavior = MouseWheelBehaviour::Disable; break;
1450 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclBehavior = MouseWheelBehaviour::FocusOnly; break;
1451 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS: nVclBehavior = MouseWheelBehaviour::ALWAYS; break;
1452 default:
1453 OSL_FAIL( "VCLXWindow::setProperty( 'MouseWheelBehavior' ): illegal property value!" );
1456 aMouseSettings.SetWheelBehavior( nVclBehavior );
1457 aSettings.SetMouseSettings( aMouseSettings );
1458 pWindow->SetSettings( aSettings, true );
1460 break;
1462 case BASEPROPERTY_NATIVE_WIDGET_LOOK:
1464 bool bEnable( true );
1465 OSL_VERIFY( Value >>= bEnable );
1466 pWindow->EnableNativeWidget( bEnable );
1468 break;
1470 case BASEPROPERTY_PLUGINPARENT:
1472 // set parent handle
1473 SetSystemParent_Impl( Value );
1475 break;
1477 case BASEPROPERTY_ENABLED:
1479 bool b = bool();
1480 if ( Value >>= b )
1481 setEnable( b );
1483 break;
1484 case BASEPROPERTY_ENABLEVISIBLE:
1486 bool b = false;
1487 if ( Value >>= b )
1489 if( b != mpImpl->isEnableVisible() )
1491 mpImpl->setEnableVisible( b );
1492 pWindow->Show( b && mpImpl->isDirectVisible() );
1496 break;
1497 case BASEPROPERTY_TEXT:
1498 case BASEPROPERTY_LABEL:
1499 case BASEPROPERTY_TITLE:
1501 OUString aText;
1502 if ( Value >>= aText )
1504 switch (eWinType)
1506 case WindowType::OKBUTTON:
1507 case WindowType::CANCELBUTTON:
1508 case WindowType::HELPBUTTON:
1509 // Standard Button: overwrite only if not empty.
1510 if (!aText.isEmpty())
1511 pWindow->SetText( aText );
1512 break;
1514 default:
1515 pWindow->SetText( aText );
1516 break;
1520 break;
1521 case BASEPROPERTY_ACCESSIBLENAME:
1523 OUString aText;
1524 if ( Value >>= aText )
1525 pWindow->SetAccessibleName( aText );
1527 break;
1528 case BASEPROPERTY_HELPURL:
1530 OUString aURL;
1531 if ( Value >>= aURL )
1533 INetURLObject aHelpURL( aURL );
1534 if ( aHelpURL.GetProtocol() == INetProtocol::Hid )
1535 pWindow->SetHelpId( aHelpURL.GetURLPath() );
1536 else
1537 pWindow->SetHelpId( aURL );
1540 break;
1541 case BASEPROPERTY_HELPTEXT:
1543 OUString aHelpText;
1544 if ( Value >>= aHelpText )
1546 pWindow->SetQuickHelpText( aHelpText );
1549 break;
1550 case BASEPROPERTY_FONTDESCRIPTOR:
1552 if ( bVoid )
1553 pWindow->SetControlFont( vcl::Font() );
1554 else
1556 css::awt::FontDescriptor aFont;
1557 if ( Value >>= aFont )
1558 pWindow->SetControlFont( VCLUnoHelper::CreateFont( aFont, pWindow->GetControlFont() ) );
1561 break;
1562 case BASEPROPERTY_FONTRELIEF:
1564 sal_Int16 n = sal_Int16();
1565 if ( Value >>= n )
1567 vcl::Font aFont = pWindow->GetControlFont();
1568 aFont.SetRelief( static_cast<FontRelief>(n) );
1569 pWindow->SetControlFont( aFont );
1572 break;
1573 case BASEPROPERTY_FONTEMPHASISMARK:
1575 sal_Int16 n = sal_Int16();
1576 if ( Value >>= n )
1578 vcl::Font aFont = pWindow->GetControlFont();
1579 aFont.SetEmphasisMark( static_cast<FontEmphasisMark>(n) );
1580 pWindow->SetControlFont( aFont );
1583 break;
1584 case BASEPROPERTY_BACKGROUNDCOLOR:
1585 if ( bVoid )
1587 switch ( eWinType )
1589 // set dialog color for default
1590 case WindowType::DIALOG:
1591 case WindowType::MESSBOX:
1592 case WindowType::INFOBOX:
1593 case WindowType::WARNINGBOX:
1594 case WindowType::ERRORBOX:
1595 case WindowType::QUERYBOX:
1596 case WindowType::TABPAGE:
1598 Color aColor = pWindow->GetSettings().GetStyleSettings().GetDialogColor();
1599 pWindow->SetBackground( aColor );
1600 pWindow->SetControlBackground( aColor );
1601 break;
1604 case WindowType::FIXEDTEXT:
1605 case WindowType::CHECKBOX:
1606 case WindowType::RADIOBUTTON:
1607 case WindowType::GROUPBOX:
1608 case WindowType::FIXEDLINE:
1610 // support transparency only for special controls
1611 pWindow->SetBackground();
1612 pWindow->SetControlBackground();
1613 pWindow->SetPaintTransparent( true );
1614 break;
1617 default:
1619 // default code which enables transparency for
1620 // compound controls. It's not real transparency
1621 // as most of these controls repaint their client
1622 // area completely new.
1623 if ( pWindow->IsCompoundControl() )
1624 pWindow->SetBackground();
1625 pWindow->SetControlBackground();
1626 break;
1630 else
1632 Color aColor;
1633 if ( Value >>= aColor )
1635 pWindow->SetControlBackground( aColor );
1636 pWindow->SetBackground( aColor );
1637 switch ( eWinType )
1639 // reset paint transparent mode
1640 case WindowType::FIXEDTEXT:
1641 case WindowType::CHECKBOX:
1642 case WindowType::RADIOBUTTON:
1643 case WindowType::GROUPBOX:
1644 case WindowType::FIXEDLINE:
1645 pWindow->SetPaintTransparent( false );
1646 break;
1647 default:
1648 break;
1650 pWindow->Invalidate(); // Invalidate if control does not respond to it
1653 break;
1654 case BASEPROPERTY_TEXTCOLOR:
1655 if ( bVoid )
1657 pWindow->SetControlForeground();
1659 else
1661 Color nColor ;
1662 if ( Value >>= nColor )
1664 pWindow->SetTextColor( nColor );
1665 pWindow->SetControlForeground( nColor );
1668 break;
1669 case BASEPROPERTY_TEXTLINECOLOR:
1670 if ( bVoid )
1672 pWindow->SetTextLineColor();
1674 else
1676 Color nColor;
1677 if ( Value >>= nColor )
1678 pWindow->SetTextLineColor( nColor );
1680 break;
1681 case BASEPROPERTY_FILLCOLOR:
1682 if ( bVoid )
1683 pWindow->GetOutDev()->SetFillColor();
1684 else
1686 Color nColor;
1687 if ( Value >>= nColor )
1688 pWindow->GetOutDev()->SetFillColor( nColor );
1690 break;
1691 case BASEPROPERTY_LINECOLOR:
1692 if ( bVoid )
1693 pWindow->GetOutDev()->SetLineColor();
1694 else
1696 Color nColor;
1697 if ( Value >>= nColor )
1698 pWindow->GetOutDev()->SetLineColor( nColor );
1700 break;
1701 case BASEPROPERTY_HIGHLIGHT_COLOR:
1703 Color nColor = 0;
1704 if ( bVoid )
1706 nColor = Application::GetSettings().GetStyleSettings().GetHighlightColor();
1708 else
1710 if (!(Value >>= nColor))
1711 break;
1714 AllSettings aSettings(pWindow->GetSettings());
1715 StyleSettings aStyle(aSettings.GetStyleSettings());
1716 aStyle.SetHighlightColor(nColor);
1717 aSettings.SetStyleSettings(aStyle);
1718 pWindow->SetSettings(aSettings);
1720 break;
1721 case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR:
1723 Color nColor = 0;
1724 if (bVoid)
1726 nColor = Application::GetSettings().GetStyleSettings().GetHighlightTextColor();
1728 else
1730 if (!(Value >>= nColor))
1731 break;
1734 AllSettings aSettings(pWindow->GetSettings());
1735 StyleSettings aStyle(aSettings.GetStyleSettings());
1736 aStyle.SetHighlightTextColor(nColor);
1737 aSettings.SetStyleSettings(aStyle);
1738 pWindow->SetSettings(aSettings);
1740 break;
1741 case BASEPROPERTY_BORDER:
1743 WinBits nStyle = pWindow->GetStyle();
1744 sal_uInt16 nTmp = 0;
1745 Value >>= nTmp;
1746 // clear any dodgy bits passed in, can come from dodgy extensions
1747 nTmp &= o3tl::typed_flags<WindowBorderStyle>::mask;
1748 WindowBorderStyle nBorder = static_cast<WindowBorderStyle>(nTmp);
1749 if ( !bool(nBorder) )
1751 pWindow->SetStyle( nStyle & ~WB_BORDER );
1753 else
1755 pWindow->SetStyle( nStyle | WB_BORDER );
1756 pWindow->SetBorderStyle( nBorder );
1759 break;
1760 case BASEPROPERTY_TABSTOP:
1762 WinBits nStyle = pWindow->GetStyle() & ~WB_TABSTOP;
1763 if ( !bVoid )
1765 bool bTab = false;
1766 Value >>= bTab;
1767 if ( bTab )
1768 nStyle |= WB_TABSTOP;
1769 else
1770 nStyle |= WB_NOTABSTOP;
1772 pWindow->SetStyle( nStyle );
1774 break;
1775 case BASEPROPERTY_VERTICALALIGN:
1777 VerticalAlignment eAlign = css::style::VerticalAlignment::VerticalAlignment_MAKE_FIXED_SIZE;
1778 WinBits nStyle = pWindow->GetStyle();
1779 nStyle &= ~(WB_TOP|WB_VCENTER|WB_BOTTOM);
1780 if ( !bVoid )
1781 Value >>= eAlign;
1782 switch ( eAlign )
1784 case VerticalAlignment_TOP:
1785 nStyle |= WB_TOP;
1786 break;
1787 case VerticalAlignment_MIDDLE:
1788 nStyle |= WB_VCENTER;
1789 break;
1790 case VerticalAlignment_BOTTOM:
1791 nStyle |= WB_BOTTOM;
1792 break;
1793 default: ; // for warning free code, MAKE_FIXED_SIZE
1795 pWindow->SetStyle( nStyle );
1797 break;
1798 case BASEPROPERTY_ALIGN:
1800 sal_Int16 nAlign = PROPERTY_ALIGN_LEFT;
1801 switch ( eWinType )
1803 case WindowType::COMBOBOX:
1804 case WindowType::PUSHBUTTON:
1805 case WindowType::OKBUTTON:
1806 case WindowType::CANCELBUTTON:
1807 case WindowType::HELPBUTTON:
1808 nAlign = PROPERTY_ALIGN_CENTER;
1809 [[fallthrough]];
1810 case WindowType::FIXEDTEXT:
1811 case WindowType::EDIT:
1812 case WindowType::MULTILINEEDIT:
1813 case WindowType::CHECKBOX:
1814 case WindowType::RADIOBUTTON:
1815 case WindowType::LISTBOX:
1817 WinBits nStyle = pWindow->GetStyle();
1818 nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT);
1819 if ( !bVoid )
1820 Value >>= nAlign;
1821 if ( nAlign == PROPERTY_ALIGN_LEFT )
1822 nStyle |= WB_LEFT;
1823 else if ( nAlign == PROPERTY_ALIGN_CENTER )
1824 nStyle |= WB_CENTER;
1825 else
1826 nStyle |= WB_RIGHT;
1827 pWindow->SetStyle( nStyle );
1829 break;
1830 default: break;
1833 break;
1834 case BASEPROPERTY_MULTILINE:
1836 if ( ( eWinType == WindowType::FIXEDTEXT )
1837 || ( eWinType == WindowType::CHECKBOX )
1838 || ( eWinType == WindowType::RADIOBUTTON )
1839 || ( eWinType == WindowType::PUSHBUTTON )
1840 || ( eWinType == WindowType::OKBUTTON )
1841 || ( eWinType == WindowType::CANCELBUTTON )
1842 || ( eWinType == WindowType::HELPBUTTON )
1845 WinBits nStyle = pWindow->GetStyle();
1846 bool bMulti = false;
1847 Value >>= bMulti;
1848 if ( bMulti )
1849 nStyle |= WB_WORDBREAK;
1850 else
1851 nStyle &= ~WB_WORDBREAK;
1852 pWindow->SetStyle( nStyle );
1855 break;
1856 case BASEPROPERTY_ORIENTATION:
1858 if ( eWinType == WindowType::FIXEDLINE)
1860 sal_Int32 nOrientation = 0;
1861 if ( Value >>= nOrientation )
1863 WinBits nStyle = pWindow->GetStyle();
1864 nStyle &= ~(WB_HORZ|WB_VERT);
1865 if ( nOrientation == 0 )
1866 nStyle |= WB_HORZ;
1867 else
1868 nStyle |= WB_VERT;
1870 pWindow->SetStyle( nStyle );
1874 break;
1875 case BASEPROPERTY_AUTOMNEMONICS:
1877 bool bAutoMnemonics = false;
1878 Value >>= bAutoMnemonics;
1879 AllSettings aSettings = pWindow->GetSettings();
1880 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1881 if ( aStyleSettings.GetAutoMnemonic() != bAutoMnemonics )
1883 aStyleSettings.SetAutoMnemonic( bAutoMnemonics );
1884 aSettings.SetStyleSettings( aStyleSettings );
1885 pWindow->SetSettings( aSettings );
1888 break;
1889 case BASEPROPERTY_MOUSETRANSPARENT:
1891 bool bMouseTransparent = false;
1892 Value >>= bMouseTransparent;
1893 pWindow->SetMouseTransparent( bMouseTransparent );
1895 break;
1896 case BASEPROPERTY_PAINTTRANSPARENT:
1898 bool bPaintTransparent = false;
1899 Value >>= bPaintTransparent;
1900 pWindow->SetPaintTransparent( bPaintTransparent );
1901 // pWindow->SetBackground();
1903 break;
1905 case BASEPROPERTY_REPEAT:
1907 bool bRepeat( false );
1908 Value >>= bRepeat;
1910 WinBits nStyle = pWindow->GetStyle();
1911 if ( bRepeat )
1912 nStyle |= WB_REPEAT;
1913 else
1914 nStyle &= ~WB_REPEAT;
1915 pWindow->SetStyle( nStyle );
1917 break;
1919 case BASEPROPERTY_REPEAT_DELAY:
1921 sal_Int32 nRepeatDelay = 0;
1922 if ( Value >>= nRepeatDelay )
1924 AllSettings aSettings = pWindow->GetSettings();
1925 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
1927 aMouseSettings.SetButtonRepeat( nRepeatDelay );
1928 aSettings.SetMouseSettings( aMouseSettings );
1930 pWindow->SetSettings( aSettings, true );
1933 break;
1935 case BASEPROPERTY_SYMBOL_COLOR:
1936 ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetButtonTextColor, &StyleSettings::GetButtonTextColor );
1937 break;
1939 case BASEPROPERTY_BORDERCOLOR:
1940 ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetMonoColor, &StyleSettings::GetMonoColor);
1941 break;
1945 css::uno::Any VCLXWindow::getProperty( const OUString& PropertyName )
1947 SolarMutexGuard aGuard;
1949 css::uno::Any aProp;
1950 if ( GetWindow() )
1952 if (PropertyName == "ParentIs100thmm")
1954 bool bParentIs100thmm = false;
1955 VclPtr<vcl::Window> pWindow = GetWindow();
1956 if (pWindow)
1958 pWindow = pWindow->GetParent();
1959 if(pWindow && MapUnit::Map100thMM == pWindow->GetMapMode().GetMapUnit())
1961 bParentIs100thmm = true;
1964 aProp <<= bParentIs100thmm;
1965 return aProp;
1967 WindowType eWinType = GetWindow()->GetType();
1968 sal_uInt16 nPropType = GetPropertyId( PropertyName );
1969 switch ( nPropType )
1971 case BASEPROPERTY_REFERENCE_DEVICE:
1973 VclPtr<Control> pControl = GetAsDynamic<Control >();
1974 OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
1975 if ( !pControl )
1976 break;
1978 rtl::Reference<VCLXDevice> pDevice = new VCLXDevice;
1979 pDevice->SetOutputDevice( pControl->GetReferenceDevice() );
1980 aProp <<= Reference< XDevice >( pDevice );
1982 break;
1984 case BASEPROPERTY_CONTEXT_WRITING_MODE:
1985 aProp <<= mpImpl->mnContextWritingMode;
1986 break;
1988 case BASEPROPERTY_WRITING_MODE:
1989 aProp <<= mpImpl->mnWritingMode;
1990 break;
1992 case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
1994 MouseWheelBehaviour nVclBehavior = GetWindow()->GetSettings().GetMouseSettings().GetWheelBehavior();
1995 sal_uInt16 nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
1996 switch ( nVclBehavior )
1998 case MouseWheelBehaviour::Disable: nBehavior = css::awt::MouseWheelBehavior::SCROLL_DISABLED; break;
1999 case MouseWheelBehaviour::FocusOnly: nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break;
2000 case MouseWheelBehaviour::ALWAYS: nBehavior = css::awt::MouseWheelBehavior::SCROLL_ALWAYS; break;
2001 default:
2002 OSL_FAIL( "VCLXWindow::getProperty( 'MouseWheelBehavior' ): illegal VCL value!" );
2004 aProp <<= nBehavior;
2006 break;
2008 case BASEPROPERTY_NATIVE_WIDGET_LOOK:
2009 aProp <<= GetWindow()->IsNativeWidgetEnabled();
2010 break;
2012 case BASEPROPERTY_ENABLED:
2013 aProp <<= GetWindow()->IsEnabled();
2014 break;
2016 case BASEPROPERTY_ENABLEVISIBLE:
2017 aProp <<= mpImpl->isEnableVisible();
2018 break;
2020 case BASEPROPERTY_HIGHCONTRASTMODE:
2021 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetHighContrastMode();
2022 break;
2024 case BASEPROPERTY_TEXT:
2025 case BASEPROPERTY_LABEL:
2026 case BASEPROPERTY_TITLE:
2028 OUString aText = GetWindow()->GetText();
2029 aProp <<= aText;
2031 break;
2032 case BASEPROPERTY_ACCESSIBLENAME:
2034 OUString aText = GetWindow()->GetAccessibleName();
2035 aProp <<= aText;
2037 break;
2038 case BASEPROPERTY_HELPTEXT:
2040 OUString aText = GetWindow()->GetQuickHelpText();
2041 aProp <<= aText;
2043 break;
2044 case BASEPROPERTY_HELPURL:
2045 aProp <<= GetWindow()->GetHelpId();
2046 break;
2047 case BASEPROPERTY_FONTDESCRIPTOR:
2049 vcl::Font aFont = GetWindow()->GetControlFont();
2050 css::awt::FontDescriptor aFD = VCLUnoHelper::CreateFontDescriptor( aFont );
2051 aProp <<= aFD;
2053 break;
2054 case BASEPROPERTY_BACKGROUNDCOLOR:
2055 aProp <<= GetWindow()->GetControlBackground();
2056 break;
2057 case BASEPROPERTY_DISPLAYBACKGROUNDCOLOR:
2058 aProp <<= GetWindow()->GetBackgroundColor();
2059 break;
2060 case BASEPROPERTY_FONTRELIEF:
2061 aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetRelief());
2062 break;
2063 case BASEPROPERTY_FONTEMPHASISMARK:
2064 aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetEmphasisMark());
2065 break;
2066 case BASEPROPERTY_TEXTCOLOR:
2067 aProp <<= GetWindow()->GetControlForeground();
2068 break;
2069 case BASEPROPERTY_TEXTLINECOLOR:
2070 aProp <<= GetWindow()->GetTextLineColor();
2071 break;
2072 case BASEPROPERTY_FILLCOLOR:
2073 aProp <<= GetWindow()->GetOutDev()->GetFillColor();
2074 break;
2075 case BASEPROPERTY_LINECOLOR:
2076 aProp <<= GetWindow()->GetOutDev()->GetLineColor();
2077 break;
2078 case BASEPROPERTY_HIGHLIGHT_COLOR:
2079 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetHighlightColor();
2080 break;
2081 case BASEPROPERTY_HIGHLIGHT_TEXT_COLOR:
2082 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetHighlightTextColor();
2083 break;
2084 case BASEPROPERTY_BORDER:
2086 WindowBorderStyle nBorder = WindowBorderStyle::NONE;
2087 if ( GetWindow()->GetStyle() & WB_BORDER )
2088 nBorder = GetWindow()->GetBorderStyle();
2089 aProp <<= static_cast<sal_uInt16>(nBorder);
2091 break;
2092 case BASEPROPERTY_TABSTOP:
2093 aProp <<= ( GetWindow()->GetStyle() & WB_TABSTOP ) != 0;
2094 break;
2095 case BASEPROPERTY_VERTICALALIGN:
2097 WinBits nStyle = GetWindow()->GetStyle();
2098 if ( nStyle & WB_TOP )
2099 aProp <<= VerticalAlignment_TOP;
2100 else if ( nStyle & WB_VCENTER )
2101 aProp <<= VerticalAlignment_MIDDLE;
2102 else if ( nStyle & WB_BOTTOM )
2103 aProp <<= VerticalAlignment_BOTTOM;
2105 break;
2106 case BASEPROPERTY_ALIGN:
2108 switch ( eWinType )
2110 case WindowType::FIXEDTEXT:
2111 case WindowType::EDIT:
2112 case WindowType::MULTILINEEDIT:
2113 case WindowType::CHECKBOX:
2114 case WindowType::RADIOBUTTON:
2115 case WindowType::LISTBOX:
2116 case WindowType::COMBOBOX:
2117 case WindowType::PUSHBUTTON:
2118 case WindowType::OKBUTTON:
2119 case WindowType::CANCELBUTTON:
2120 case WindowType::HELPBUTTON:
2122 WinBits nStyle = GetWindow()->GetStyle();
2123 if ( nStyle & WB_LEFT )
2124 aProp <<= sal_Int16(PROPERTY_ALIGN_LEFT);
2125 else if ( nStyle & WB_CENTER )
2126 aProp <<= sal_Int16(PROPERTY_ALIGN_CENTER);
2127 else if ( nStyle & WB_RIGHT )
2128 aProp <<= sal_Int16(PROPERTY_ALIGN_RIGHT);
2130 break;
2131 default: break;
2134 break;
2135 case BASEPROPERTY_MULTILINE:
2137 if ( ( eWinType == WindowType::FIXEDTEXT )
2138 || ( eWinType == WindowType::CHECKBOX )
2139 || ( eWinType == WindowType::RADIOBUTTON )
2140 || ( eWinType == WindowType::PUSHBUTTON )
2141 || ( eWinType == WindowType::OKBUTTON )
2142 || ( eWinType == WindowType::CANCELBUTTON )
2143 || ( eWinType == WindowType::HELPBUTTON )
2145 aProp <<= ( GetWindow()->GetStyle() & WB_WORDBREAK ) != 0;
2147 break;
2148 case BASEPROPERTY_AUTOMNEMONICS:
2150 bool bAutoMnemonics = GetWindow()->GetSettings().GetStyleSettings().GetAutoMnemonic();
2151 aProp <<= bAutoMnemonics;
2153 break;
2154 case BASEPROPERTY_MOUSETRANSPARENT:
2156 bool bMouseTransparent = GetWindow()->IsMouseTransparent();
2157 aProp <<= bMouseTransparent;
2159 break;
2160 case BASEPROPERTY_PAINTTRANSPARENT:
2162 bool bPaintTransparent = GetWindow()->IsPaintTransparent();
2163 aProp <<= bPaintTransparent;
2165 break;
2167 case BASEPROPERTY_REPEAT:
2168 aProp <<= ( 0 != ( GetWindow()->GetStyle() & WB_REPEAT ) );
2169 break;
2171 case BASEPROPERTY_REPEAT_DELAY:
2173 sal_Int32 nButtonRepeat = GetWindow()->GetSettings().GetMouseSettings().GetButtonRepeat();
2174 aProp <<= nButtonRepeat;
2176 break;
2178 case BASEPROPERTY_SYMBOL_COLOR:
2179 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetButtonTextColor();
2180 break;
2182 case BASEPROPERTY_BORDERCOLOR:
2183 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetMonoColor();
2184 break;
2187 return aProp;
2191 // css::awt::XLayoutConstrains
2192 css::awt::Size VCLXWindow::getMinimumSize( )
2194 SolarMutexGuard aGuard;
2196 // Use this method only for those components which can be created through
2197 // css::awt::Toolkit , but do not have an interface
2199 Size aSz;
2200 if ( GetWindow() )
2202 WindowType nWinType = GetWindow()->GetType();
2203 switch ( nWinType )
2205 case WindowType::CONTROL:
2206 aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*12 );
2207 aSz.setHeight( GetWindow()->GetTextHeight()+2*6 );
2208 break;
2210 case WindowType::PATTERNBOX:
2211 case WindowType::NUMERICBOX:
2212 case WindowType::METRICBOX:
2213 case WindowType::CURRENCYBOX:
2214 case WindowType::DATEBOX:
2215 case WindowType::TIMEBOX:
2216 case WindowType::LONGCURRENCYBOX:
2217 aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*2 );
2218 aSz.setHeight( GetWindow()->GetTextHeight()+2*2 );
2219 break;
2220 case WindowType::SCROLLBARBOX:
2221 return VCLXScrollBar::implGetMinimumSize( GetWindow() );
2222 default:
2223 aSz = GetWindow()->get_preferred_size();
2227 return css::awt::Size( aSz.Width(), aSz.Height() );
2230 css::awt::Size VCLXWindow::getPreferredSize( )
2232 return getMinimumSize();
2235 css::awt::Size VCLXWindow::calcAdjustedSize( const css::awt::Size& rNewSize )
2237 SolarMutexGuard aGuard;
2239 css::awt::Size aNewSize( rNewSize );
2240 css::awt::Size aMinSize = getMinimumSize();
2242 if ( aNewSize.Width < aMinSize.Width )
2243 aNewSize.Width = aMinSize.Width;
2244 if ( aNewSize.Height < aMinSize.Height )
2245 aNewSize.Height = aMinSize.Height;
2247 return aNewSize;
2251 // css::awt::XView
2252 sal_Bool VCLXWindow::setGraphics( const css::uno::Reference< css::awt::XGraphics >& rxDevice )
2254 SolarMutexGuard aGuard;
2256 if ( VCLUnoHelper::GetOutputDevice( rxDevice ) )
2257 mpImpl->mxViewGraphics = rxDevice;
2258 else
2259 mpImpl->mxViewGraphics = nullptr;
2261 return mpImpl->mxViewGraphics.is();
2264 css::uno::Reference< css::awt::XGraphics > VCLXWindow::getGraphics( )
2266 SolarMutexGuard aGuard;
2268 return mpImpl->mxViewGraphics;
2271 css::awt::Size VCLXWindow::getSize( )
2273 SolarMutexGuard aGuard;
2275 Size aSz;
2276 if ( GetWindow() )
2277 aSz = GetWindow()->GetSizePixel();
2278 return css::awt::Size( aSz.Width(), aSz.Height() );
2281 void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY )
2283 SolarMutexGuard aGuard;
2285 VclPtr<vcl::Window> pWindow = GetWindow();
2286 if ( !pWindow )
2287 return;
2289 if ( !(isDesignMode() || mpImpl->isEnableVisible()) )
2290 return;
2292 OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( mpImpl->mxViewGraphics );
2293 if (!pDev)
2294 pDev = pWindow->GetParent()->GetOutDev();
2295 TabPage* pTabPage = dynamic_cast< TabPage* >( pWindow.get() );
2296 if ( pTabPage )
2298 Point aPos( nX, nY );
2299 aPos = pDev->PixelToLogic( aPos );
2300 pTabPage->Draw( pDev, aPos, SystemTextColorFlags::NONE );
2301 return;
2304 Point aPos( nX, nY );
2306 if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent()->GetOutDev() == pDev ) )
2308 // #i40647# don't draw here if this is a recursive call
2309 // sometimes this is called recursively, because the Update call on the parent
2310 // (strangely) triggers another paint. Prevent a stack overflow here
2311 // Yes, this is only fixing symptoms for the moment...
2312 // #i40647# / 2005-01-18 / frank.schoenheit@sun.com
2313 if ( !mpImpl->getDrawingOntoParent_ref() )
2315 ::comphelper::FlagGuard aDrawingflagGuard( mpImpl->getDrawingOntoParent_ref() );
2317 bool bWasVisible = pWindow->IsVisible();
2318 Point aOldPos( pWindow->GetPosPixel() );
2320 if ( bWasVisible && aOldPos == aPos )
2322 pWindow->PaintImmediately();
2323 return;
2326 pWindow->SetPosPixel( aPos );
2328 // Update parent first to avoid painting the parent upon the update
2329 // of this window, as it may otherwise cause the parent
2330 // to hide this window again
2331 if( pWindow->GetParent() )
2332 pWindow->GetParent()->PaintImmediately();
2334 pWindow->Show();
2335 pWindow->PaintImmediately();
2336 pWindow->SetParentUpdateMode( false );
2337 pWindow->Hide();
2338 pWindow->SetParentUpdateMode( true );
2340 pWindow->SetPosPixel( aOldPos );
2341 if ( bWasVisible )
2342 pWindow->Show();
2345 else if ( pDev )
2347 Point aP = pDev->PixelToLogic( aPos );
2349 vcl::PDFExtOutDevData* pPDFExport = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
2350 bool bDrawSimple = ( pDev->GetOutDevType() == OUTDEV_PRINTER )
2351 || ( pDev->GetOutDevViewType() == OutDevViewType::PrintPreview )
2352 || ( pPDFExport != nullptr );
2353 if ( bDrawSimple )
2355 pWindow->Draw( pDev, aP, SystemTextColorFlags::NoControls );
2357 else
2359 bool bOldNW =pWindow->IsNativeWidgetEnabled();
2360 if( bOldNW )
2361 pWindow->EnableNativeWidget(false);
2362 pWindow->PaintToDevice( pDev, aP );
2363 if( bOldNW )
2364 pWindow->EnableNativeWidget();
2369 void VCLXWindow::setZoom( float fZoomX, float /*fZoomY*/ )
2371 SolarMutexGuard aGuard;
2373 if ( GetWindow() )
2375 // Fraction::Fraction takes a double, but we have a float only.
2376 // The implicit conversion from float to double can result in a precision loss, i.e. 1.2 is converted to
2377 // 1.200000000047something. To prevent this, we convert explicitly to double, and round it.
2378 double nZoom( fZoomX );
2379 Fraction aZoom(::rtl::math::round(nZoom, 4));
2380 aZoom.ReduceInaccurate(10); // to avoid runovers and BigInt mapping
2381 GetWindow()->SetZoom(aZoom);
2385 // css::lang::XEventListener
2386 void SAL_CALL VCLXWindow::disposing( const css::lang::EventObject& _rSource )
2388 SolarMutexGuard aGuard;
2390 if (mpImpl->mbDisposing)
2391 return;
2393 // check if it comes from our AccessibleContext
2394 uno::Reference< uno::XInterface > aAC( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
2395 uno::Reference< uno::XInterface > xSource( _rSource.Source, uno::UNO_QUERY );
2397 if ( aAC.get() == xSource.get() )
2398 { // yep, it does
2399 mpImpl->mxAccessibleContext.clear();
2403 // css::accessibility::XAccessible
2404 css::uno::Reference< css::accessibility::XAccessibleContext > VCLXWindow::getAccessibleContext( )
2406 SolarMutexGuard aGuard;
2408 // already disposed
2409 if (mpImpl->mbDisposing)
2410 return uno::Reference< accessibility::XAccessibleContext >();
2412 if ( !mpImpl->mxAccessibleContext.is() && GetWindow() )
2414 mpImpl->mxAccessibleContext = CreateAccessibleContext();
2416 // add as event listener to this component
2417 // in case somebody disposes it, we do not want to have a (though weak) reference to a dead
2418 // object
2419 uno::Reference< lang::XComponent > xComp( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
2420 if ( xComp.is() )
2421 xComp->addEventListener( this );
2424 return mpImpl->mxAccessibleContext;
2427 // css::awt::XDockable
2428 void SAL_CALL VCLXWindow::addDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener )
2430 SolarMutexGuard aGuard;
2432 if (!mpImpl->mbDisposing && xListener.is() )
2433 mpImpl->getDockableWindowListeners().addInterface( xListener );
2437 void SAL_CALL VCLXWindow::removeDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener )
2439 SolarMutexGuard aGuard;
2441 if (!mpImpl->mbDisposing)
2442 mpImpl->getDockableWindowListeners().removeInterface( xListener );
2445 void SAL_CALL VCLXWindow::enableDocking( sal_Bool bEnable )
2447 SolarMutexGuard aGuard;
2449 VclPtr<vcl::Window> pWindow = GetWindow();
2450 if ( pWindow )
2451 pWindow->EnableDocking( bEnable );
2454 sal_Bool SAL_CALL VCLXWindow::isFloating( )
2456 SolarMutexGuard aGuard;
2458 VclPtr<vcl::Window> pWindow = GetWindow();
2459 if( pWindow )
2460 return vcl::Window::GetDockingManager()->IsFloating( pWindow );
2461 else
2462 return false;
2465 void SAL_CALL VCLXWindow::setFloatingMode( sal_Bool bFloating )
2467 SolarMutexGuard aGuard;
2469 VclPtr<vcl::Window> pWindow = GetWindow();
2470 if( pWindow )
2471 vcl::Window::GetDockingManager()->SetFloatingMode( pWindow, bFloating );
2474 sal_Bool SAL_CALL VCLXWindow::isLocked( )
2476 SolarMutexGuard aGuard;
2478 VclPtr<vcl::Window> pWindow = GetWindow();
2479 if( pWindow )
2480 return vcl::Window::GetDockingManager()->IsLocked( pWindow );
2481 else
2482 return false;
2485 void SAL_CALL VCLXWindow::lock( )
2487 SolarMutexGuard aGuard;
2489 VclPtr<vcl::Window> pWindow = GetWindow();
2490 if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) )
2491 vcl::Window::GetDockingManager()->Lock( pWindow );
2494 void SAL_CALL VCLXWindow::unlock( )
2496 SolarMutexGuard aGuard;
2498 VclPtr<vcl::Window> pWindow = GetWindow();
2499 if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) )
2500 vcl::Window::GetDockingManager()->Unlock( pWindow );
2503 void SAL_CALL VCLXWindow::startPopupMode( const css::awt::Rectangle& )
2505 // deprecated
2508 sal_Bool SAL_CALL VCLXWindow::isInPopupMode( )
2510 // deprecated
2511 return false;
2515 // css::awt::XWindow2
2517 void SAL_CALL VCLXWindow::setOutputSize( const css::awt::Size& aSize )
2519 SolarMutexGuard aGuard;
2520 if( VclPtr<vcl::Window> pWindow = GetWindow() )
2521 pWindow->SetOutputSizePixel( VCLSize( aSize ) );
2524 css::awt::Size SAL_CALL VCLXWindow::getOutputSize( )
2526 SolarMutexGuard aGuard;
2527 if( VclPtr<vcl::Window> pWindow = GetWindow() )
2528 return AWTSize( pWindow->GetOutputSizePixel() );
2529 else
2530 return css::awt::Size();
2533 sal_Bool SAL_CALL VCLXWindow::isVisible( )
2535 SolarMutexGuard aGuard;
2536 if( GetWindow() )
2537 return GetWindow()->IsVisible();
2538 else
2539 return false;
2542 sal_Bool SAL_CALL VCLXWindow::isActive( )
2544 SolarMutexGuard aGuard;
2545 if( GetWindow() )
2546 return GetWindow()->IsActive();
2547 else
2548 return false;
2552 sal_Bool SAL_CALL VCLXWindow::isEnabled( )
2554 SolarMutexGuard aGuard;
2555 if( GetWindow() )
2556 return GetWindow()->IsEnabled();
2557 else
2558 return false;
2561 sal_Bool SAL_CALL VCLXWindow::hasFocus( )
2563 SolarMutexGuard aGuard;
2564 if( GetWindow() )
2565 return GetWindow()->HasFocus();
2566 else
2567 return false;
2570 // css::beans::XPropertySetInfo
2572 UnoPropertyArrayHelper *
2573 VCLXWindow::GetPropHelper()
2575 SolarMutexGuard aGuard;
2576 if ( mpImpl->mpPropHelper == nullptr )
2578 std::vector< sal_uInt16 > aIDs;
2579 GetPropertyIds( aIDs );
2580 mpImpl->mpPropHelper.reset( new UnoPropertyArrayHelper( aIDs ) );
2582 return mpImpl->mpPropHelper.get();
2585 css::uno::Sequence< css::beans::Property > SAL_CALL
2586 VCLXWindow::getProperties()
2588 return GetPropHelper()->getProperties();
2590 css::beans::Property SAL_CALL
2591 VCLXWindow::getPropertyByName( const OUString& rName )
2593 return GetPropHelper()->getPropertyByName( rName );
2596 sal_Bool SAL_CALL
2597 VCLXWindow::hasPropertyByName( const OUString& rName )
2599 return GetPropHelper()->hasPropertyByName( rName );
2602 Reference< XStyleSettings > SAL_CALL VCLXWindow::getStyleSettings()
2604 return mpImpl->getStyleSettings();
2607 bool VCLXWindow::IsDisposed() const
2609 return mpImpl->mbDisposing;
2612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */