1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 
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 <toolkit/awt/vclxpointer.hxx>
37 #include <toolkit/awt/vclxwindows.hxx>
38 #include <toolkit/helper/vclunohelper.hxx>
39 #include <toolkit/helper/convert.hxx>
40 #include <toolkit/helper/property.hxx>
41 #include <sal/log.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/window.hxx>
44 #include <tools/color.hxx>
45 #include <tools/fract.hxx>
46 #include <tools/debug.hxx>
47 #include <vcl/event.hxx>
48 #include <vcl/dockwin.hxx>
49 #include <vcl/pdfextoutdevdata.hxx>
50 #include <vcl/tabpage.hxx>
51 #include <vcl/ctrl.hxx>
52 #include <vcl/settings.hxx>
53 #include <vcl/commandevent.hxx>
54 #include <comphelper/flagguard.hxx>
55 #include <comphelper/interfacecontainer2.hxx>
56 #include <comphelper/profilezone.hxx>
57 #include "stylesettings.hxx"
58 #include <tools/urlobj.hxx>
59 
60 #include <helper/accessibilityclient.hxx>
61 #include <helper/unopropertyarrayhelper.hxx>
62 
63 using namespace ::com::sun::star;
64 
65 using ::com::sun::star::uno::Reference;
66 using ::com::sun::star::uno::UNO_QUERY;
67 using ::com::sun::star::uno::RuntimeException;
68 using ::com::sun::star::lang::EventObject;
69 using ::com::sun::star::awt::XWindowListener2;
70 using ::com::sun::star::awt::XDockableWindowListener;
71 using ::com::sun::star::awt::XDevice;
72 using ::com::sun::star::awt::XStyleSettings;
73 using ::com::sun::star::lang::DisposedException;
74 using ::com::sun::star::style::VerticalAlignment;
75 using ::com::sun::star::style::VerticalAlignment_TOP;
76 using ::com::sun::star::style::VerticalAlignment_MIDDLE;
77 using ::com::sun::star::style::VerticalAlignment_BOTTOM;
78 
79 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
80 
81 
82 //= VCLXWindowImpl
83 
84 class VCLXWindowImpl
85 {
86 private:
87     typedef ::std::vector< VCLXWindow::Callback >                       CallbackArray;
88 
89 private:
90     VCLXWindow&                         mrAntiImpl;
91     ::toolkit::AccessibilityClient      maAccFactory;
92     bool                                mbDisposed;
93     bool                                mbDrawingOntoParent;    // no bit mask, is passed around  by reference
94     bool                            mbEnableVisible;
95     bool                            mbDirectVisible;
96 
97     ::osl::Mutex                        maListenerContainerMutex;
98     ::comphelper::OInterfaceContainerHelper2   maWindow2Listeners;
99     ::comphelper::OInterfaceContainerHelper2   maDockableWindowListeners;
100     EventListenerMultiplexer            maEventListeners;
101     FocusListenerMultiplexer            maFocusListeners;
102     WindowListenerMultiplexer           maWindowListeners;
103     KeyListenerMultiplexer              maKeyListeners;
104     MouseListenerMultiplexer            maMouseListeners;
105     MouseMotionListenerMultiplexer      maMouseMotionListeners;
106     PaintListenerMultiplexer            maPaintListeners;
107     VclContainerListenerMultiplexer     maContainerListeners;
108     TopWindowListenerMultiplexer        maTopWindowListeners;
109 
110     CallbackArray                       maCallbackEvents;
111     ImplSVEvent *                       mnCallbackEventId;
112 
113 public:
114     bool                                mbDisposing             : 1;
115     bool                                mbDesignMode            : 1;
116     bool                                mbSynthesizingVCLEvent  : 1;
117     bool const                          mbWithDefaultProps      : 1;
118 
119     sal_uLong                           mnListenerLockLevel;
120     sal_Int16                           mnWritingMode;
121     sal_Int16                           mnContextWritingMode;
122 
123     std::unique_ptr<UnoPropertyArrayHelper>
124                                         mpPropHelper;
125 
126     css::uno::Reference< css::accessibility::XAccessibleContext >
127                                         mxAccessibleContext;
128     css::uno::Reference< css::awt::XGraphics >
129                                         mxViewGraphics;
130     css::uno::Reference< css::awt::XStyleSettings >
131                                         mxWindowStyleSettings;
132 
133 public:
getDrawingOntoParent_ref()134     bool&   getDrawingOntoParent_ref()  { return mbDrawingOntoParent; }
135 
136 public:
137     /** ctor
138     @param _pAntiImpl
139         the <type>VCLXWindow</type> instance which the object belongs to. Must
140         live longer then the object just being constructed.
141     */
142     VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps );
143 
144     VCLXWindowImpl( const VCLXWindowImpl& ) = delete;
145     const VCLXWindowImpl& operator=(const VCLXWindowImpl&) = delete;
146 
147     /** synchronously mbEnableVisible
148     */
setEnableVisible(bool bEnableVisible)149     void    setEnableVisible( bool bEnableVisible ) { mbEnableVisible = bEnableVisible; }
isEnableVisible() const150     bool    isEnableVisible() const { return mbEnableVisible; }
151     /** synchronously mbDirectVisible;
152     */
setDirectVisible(bool bDirectVisible)153     void    setDirectVisible( bool bDirectVisible ) { mbDirectVisible = bDirectVisible; }
isDirectVisible() const154     bool    isDirectVisible() const { return mbDirectVisible; }
155 
156     /** impl-version of VCLXWindow::ImplExecuteAsyncWithoutSolarLock
157     */
158     void    callBackAsync( const VCLXWindow::Callback& i_callback );
159 
160     /** notifies the object that its VCLXWindow is being disposed
161     */
162     void    disposing();
163 
getAccessibleFactory()164     ::toolkit::AccessibilityClient& getAccessibleFactory()
165     {
166         return maAccFactory;
167     }
168 
169     Reference< XStyleSettings > getStyleSettings();
170 
171     /** returns the container of registered XWindowListener2 listeners
172     */
getWindow2Listeners()173     ::comphelper::OInterfaceContainerHelper2&   getWindow2Listeners()       { return maWindow2Listeners; }
getDockableWindowListeners()174     ::comphelper::OInterfaceContainerHelper2&   getDockableWindowListeners(){ return maDockableWindowListeners; }
getEventListeners()175     EventListenerMultiplexer&            getEventListeners()         { return maEventListeners; }
getFocusListeners()176     FocusListenerMultiplexer&            getFocusListeners()         { return maFocusListeners; }
getWindowListeners()177     WindowListenerMultiplexer&           getWindowListeners()        { return maWindowListeners; }
getKeyListeners()178     KeyListenerMultiplexer&              getKeyListeners()           { return maKeyListeners; }
getMouseListeners()179     MouseListenerMultiplexer&            getMouseListeners()         { return maMouseListeners; }
getMouseMotionListeners()180     MouseMotionListenerMultiplexer&      getMouseMotionListeners()   { return maMouseMotionListeners; }
getPaintListeners()181     PaintListenerMultiplexer&            getPaintListeners()         { return maPaintListeners; }
getContainerListeners()182     VclContainerListenerMultiplexer&     getContainerListeners()     { return maContainerListeners; }
getTopWindowListeners()183     TopWindowListenerMultiplexer&        getTopWindowListeners()     { return maTopWindowListeners; }
184 
185 private:
186     DECL_LINK( OnProcessCallbacks, void*, void );
187 };
188 
189 
VCLXWindowImpl(VCLXWindow & _rAntiImpl,bool _bWithDefaultProps)190 VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, bool _bWithDefaultProps )
191     :mrAntiImpl( _rAntiImpl )
192     ,mbDisposed( false )
193     ,mbDrawingOntoParent( false )
194     ,mbEnableVisible(true)
195     ,mbDirectVisible(true)
196     ,maListenerContainerMutex( )
197     ,maWindow2Listeners( maListenerContainerMutex )
198     ,maDockableWindowListeners( maListenerContainerMutex )
199     ,maEventListeners( _rAntiImpl )
200     ,maFocusListeners( _rAntiImpl )
201     ,maWindowListeners( _rAntiImpl )
202     ,maKeyListeners( _rAntiImpl )
203     ,maMouseListeners( _rAntiImpl )
204     ,maMouseMotionListeners( _rAntiImpl )
205     ,maPaintListeners( _rAntiImpl )
206     ,maContainerListeners( _rAntiImpl )
207     ,maTopWindowListeners( _rAntiImpl )
208     ,mnCallbackEventId( nullptr )
209     ,mbDisposing( false )
210     ,mbDesignMode( false )
211     ,mbSynthesizingVCLEvent( false )
212     ,mbWithDefaultProps( _bWithDefaultProps )
213     ,mnListenerLockLevel( 0 )
214     ,mnWritingMode( WritingMode2::CONTEXT )
215     ,mnContextWritingMode( WritingMode2::CONTEXT )
216 {
217 }
218 
disposing()219 void VCLXWindowImpl::disposing()
220 {
221     SolarMutexGuard aGuard;
222     if ( mnCallbackEventId )
223         Application::RemoveUserEvent( mnCallbackEventId );
224     mnCallbackEventId = nullptr;
225 
226     mbDisposed= true;
227 
228     css::lang::EventObject aEvent;
229     aEvent.Source = mrAntiImpl;
230 
231     maDockableWindowListeners.disposeAndClear( aEvent );
232     maEventListeners.disposeAndClear( aEvent );
233     maFocusListeners.disposeAndClear( aEvent );
234     maWindowListeners.disposeAndClear( aEvent );
235     maKeyListeners.disposeAndClear( aEvent );
236     maMouseListeners.disposeAndClear( aEvent );
237     maMouseMotionListeners.disposeAndClear( aEvent );
238     maPaintListeners.disposeAndClear( aEvent );
239     maContainerListeners.disposeAndClear( aEvent );
240     maTopWindowListeners.disposeAndClear( aEvent );
241 
242     ::toolkit::WindowStyleSettings* pStyleSettings = static_cast< ::toolkit::WindowStyleSettings* >( mxWindowStyleSettings.get() );
243     if ( pStyleSettings != nullptr )
244         pStyleSettings->dispose();
245     mxWindowStyleSettings.clear();
246 }
247 
248 
callBackAsync(const VCLXWindow::Callback & i_callback)249 void VCLXWindowImpl::callBackAsync( const VCLXWindow::Callback& i_callback )
250 {
251     DBG_TESTSOLARMUTEX();
252     maCallbackEvents.push_back( i_callback );
253     if ( !mnCallbackEventId )
254     {
255         // ensure our VCLXWindow is not destroyed while the event is underway
256         mrAntiImpl.acquire();
257         mnCallbackEventId = Application::PostUserEvent( LINK( this, VCLXWindowImpl, OnProcessCallbacks ) );
258     }
259 }
260 
261 
IMPL_LINK_NOARG(VCLXWindowImpl,OnProcessCallbacks,void *,void)262 IMPL_LINK_NOARG(VCLXWindowImpl, OnProcessCallbacks, void*, void)
263 {
264     const Reference< uno::XInterface > xKeepAlive( mrAntiImpl );
265 
266     SAL_INFO("toolkit.controls", "OnProcessCallbacks grabbing solarmutex");
267 
268     // work on a copy of the callback array
269     CallbackArray aCallbacksCopy;
270     {
271         SolarMutexGuard aGuard;
272         aCallbacksCopy = maCallbackEvents;
273         maCallbackEvents.clear();
274 
275         // we acquired our VCLXWindow once before posting the event, release this one ref now
276         mrAntiImpl.release();
277 
278         if ( !mnCallbackEventId )
279             // we were disposed while waiting for the mutex to lock
280             return;
281 
282         mnCallbackEventId = nullptr;
283     }
284 
285     {
286         SAL_INFO("toolkit.controls", "OnProcessCallbacks relinquished solarmutex");
287         SolarMutexReleaser aReleaseSolar;
288         for (const auto& rCallback : aCallbacksCopy)
289         {
290             rCallback();
291         }
292     }
293 }
294 
getStyleSettings()295 Reference< XStyleSettings > VCLXWindowImpl::getStyleSettings()
296 {
297     SolarMutexGuard aGuard;
298     if ( mbDisposed )
299         throw DisposedException( OUString(), mrAntiImpl );
300     if ( !mxWindowStyleSettings.is() )
301         mxWindowStyleSettings = new ::toolkit::WindowStyleSettings( maListenerContainerMutex, mrAntiImpl );
302     return mxWindowStyleSettings;
303 }
304 
305 
306 // Uses an out-parameter instead of return value, due to the object reference
307 
ImplInitWindowEvent(css::awt::WindowEvent & rEvent,vcl::Window const * pWindow)308 static void ImplInitWindowEvent( css::awt::WindowEvent& rEvent, vcl::Window const * pWindow )
309 {
310     Point aPos = pWindow->GetPosPixel();
311     Size aSz = pWindow->GetSizePixel();
312 
313     rEvent.X = aPos.X();
314     rEvent.Y = aPos.Y();
315 
316     rEvent.Width = aSz.Width();
317     rEvent.Height = aSz.Height();
318 
319     pWindow->GetBorder( rEvent.LeftInset, rEvent.TopInset, rEvent.RightInset, rEvent.BottomInset );
320 }
321 
VCLXWindow(bool _bWithDefaultProps)322 VCLXWindow::VCLXWindow( bool _bWithDefaultProps )
323 {
324     mpImpl.reset( new VCLXWindowImpl( *this, _bWithDefaultProps ) );
325 }
326 
~VCLXWindow()327 VCLXWindow::~VCLXWindow()
328 {
329     mpImpl.reset();
330 
331     if ( GetWindow() )
332     {
333         GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
334         GetWindow()->SetWindowPeer( nullptr, nullptr );
335         GetWindow()->SetAccessible( nullptr );
336     }
337 }
338 
339 
ImplExecuteAsyncWithoutSolarLock(const Callback & i_callback)340 void VCLXWindow::ImplExecuteAsyncWithoutSolarLock( const Callback& i_callback )
341 {
342     mpImpl->callBackAsync( i_callback );
343 }
344 
345 
getAccessibleFactory()346 ::toolkit::IAccessibleFactory& VCLXWindow::getAccessibleFactory()
347 {
348     return mpImpl->getAccessibleFactory().getFactory();
349 }
350 
SetWindow(const VclPtr<vcl::Window> & pWindow)351 void VCLXWindow::SetWindow( const VclPtr<vcl::Window> &pWindow )
352 {
353     if ( GetWindow() )
354     {
355         GetWindow()->RemoveEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
356 //        GetWindow()->DbgAssertNoEventListeners();
357     }
358 
359     SetOutputDevice( pWindow );
360 
361     if ( GetWindow() )
362     {
363         GetWindow()->AddEventListener( LINK( this, VCLXWindow, WindowEventListener ) );
364         bool bDirectVisible = pWindow && pWindow->IsVisible();
365         mpImpl->setDirectVisible( bDirectVisible );
366     }
367 }
368 
suspendVclEventListening()369 void VCLXWindow::suspendVclEventListening( )
370 {
371     ++mpImpl->mnListenerLockLevel;
372 }
373 
resumeVclEventListening()374 void VCLXWindow::resumeVclEventListening( )
375 {
376     DBG_ASSERT( mpImpl->mnListenerLockLevel, "VCLXWindow::resumeVclEventListening: not suspended!" );
377     --mpImpl->mnListenerLockLevel;
378 }
379 
notifyWindowRemoved(vcl::Window const & _rWindow)380 void VCLXWindow::notifyWindowRemoved( vcl::Window const & _rWindow )
381 {
382     if ( mpImpl->getContainerListeners().getLength() )
383     {
384         awt::VclContainerEvent aEvent;
385         aEvent.Source = *this;
386         aEvent.Child = static_cast< XWindow* >( _rWindow.GetWindowPeer() );
387         mpImpl->getContainerListeners().windowRemoved( aEvent );
388     }
389 }
390 
IMPL_LINK(VCLXWindow,WindowEventListener,VclWindowEvent &,rEvent,void)391 IMPL_LINK( VCLXWindow, WindowEventListener, VclWindowEvent&, rEvent, void )
392 {
393     if ( mpImpl->mnListenerLockLevel )
394         return;
395 
396     DBG_ASSERT( rEvent.GetWindow() && GetWindow(), "Window???" );
397     ProcessWindowEvent( rEvent );
398 }
399 
400 namespace
401 {
402     struct CallWindow2Listener
403     {
CallWindow2Listener__anon1e280aab0111::CallWindow2Listener404         CallWindow2Listener( ::comphelper::OInterfaceContainerHelper2& i_rWindow2Listeners, const bool i_bEnabled, const EventObject& i_rEvent )
405             :m_rWindow2Listeners( i_rWindow2Listeners )
406             ,m_bEnabled( i_bEnabled )
407             ,m_aEvent( i_rEvent )
408         {
409         }
410 
operator ()__anon1e280aab0111::CallWindow2Listener411         void operator()()
412         {
413             m_rWindow2Listeners.notifyEach( m_bEnabled ? &XWindowListener2::windowEnabled : &XWindowListener2::windowDisabled, m_aEvent );
414         }
415 
416         ::comphelper::OInterfaceContainerHelper2&  m_rWindow2Listeners;
417         const bool                          m_bEnabled;
418         const EventObject                   m_aEvent;
419     };
420 }
421 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)422 void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
423 {
424     css::uno::Reference< css::uno::XInterface > xThis( static_cast<cppu::OWeakObject*>(this) );
425 
426     switch ( rVclWindowEvent.GetId() )
427     {
428         case VclEventId::WindowEnabled:
429         case VclEventId::WindowDisabled:
430         {
431             Callback aCallback = CallWindow2Listener(
432                 mpImpl->getWindow2Listeners(),
433                 ( VclEventId::WindowEnabled == rVclWindowEvent.GetId() ),
434                 EventObject( *this )
435             );
436             ImplExecuteAsyncWithoutSolarLock( aCallback );
437         }
438         break;
439 
440         case VclEventId::WindowPaint:
441         {
442             if ( mpImpl->getPaintListeners().getLength() )
443             {
444                 css::awt::PaintEvent aEvent;
445                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
446                 aEvent.UpdateRect = AWTRectangle( *static_cast<tools::Rectangle*>(rVclWindowEvent.GetData()) );
447                 aEvent.Count = 0;
448                 mpImpl->getPaintListeners().windowPaint( aEvent );
449             }
450         }
451         break;
452         case VclEventId::WindowMove:
453         {
454             if ( mpImpl->getWindowListeners().getLength() )
455             {
456                 css::awt::WindowEvent aEvent;
457                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
458                 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
459                 mpImpl->getWindowListeners().windowMoved( aEvent );
460             }
461         }
462         break;
463         case VclEventId::WindowResize:
464         {
465             if ( mpImpl->getWindowListeners().getLength() )
466             {
467                 css::awt::WindowEvent aEvent;
468                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
469                 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
470                 mpImpl->getWindowListeners().windowResized( aEvent );
471             }
472         }
473         break;
474         case VclEventId::WindowShow:
475         {
476             if ( mpImpl->getWindowListeners().getLength() )
477             {
478                 css::awt::WindowEvent aEvent;
479                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
480                 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
481                 mpImpl->getWindowListeners().windowShown( aEvent );
482             }
483 
484             // For TopWindows this means opened...
485             if ( mpImpl->getTopWindowListeners().getLength() )
486             {
487                 css::lang::EventObject aEvent;
488                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
489                 mpImpl->getTopWindowListeners().windowOpened( aEvent );
490             }
491         }
492         break;
493         case VclEventId::WindowHide:
494         {
495             if ( mpImpl->getWindowListeners().getLength() )
496             {
497                 css::awt::WindowEvent aEvent;
498                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
499                 ImplInitWindowEvent( aEvent, rVclWindowEvent.GetWindow() );
500                 mpImpl->getWindowListeners().windowHidden( aEvent );
501             }
502 
503             // For TopWindows this means closed...
504             if ( mpImpl->getTopWindowListeners().getLength() )
505             {
506                 css::lang::EventObject aEvent;
507                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
508                 mpImpl->getTopWindowListeners().windowClosed( aEvent );
509             }
510         }
511         break;
512         case VclEventId::WindowActivate:
513         case VclEventId::WindowDeactivate:
514         {
515             if (!mpImpl->getTopWindowListeners().getLength())
516                 return;
517 
518             // Suppress events which are unlikely to be interesting to our listeners.
519             vcl::Window* pWin = static_cast<vcl::Window*>(rVclWindowEvent.GetData());
520             bool bSuppress = false;
521 
522             while (pWin)
523             {
524                 // Either the event came from the same window, from its
525                 // child, or from a child of its border window (e.g.
526                 // menubar or notebookbar).
527                 if (pWin->GetWindow(GetWindowType::Client) == GetWindow())
528                     return;
529 
530                 if (pWin->IsMenuFloatingWindow())
531                     bSuppress = true;
532 
533                 if (pWin->GetType() == WindowType::FLOATINGWINDOW &&
534                     static_cast<FloatingWindow*>(pWin)->IsInPopupMode())
535                     bSuppress = true;
536 
537                 // Otherwise, don't suppress if the event came from a different frame.
538                 if (!bSuppress && pWin->GetWindow(GetWindowType::Frame) == pWin)
539                     break;
540 
541                 pWin = pWin->GetWindow(GetWindowType::RealParent);
542             }
543 
544             css::lang::EventObject aEvent;
545             aEvent.Source = static_cast<cppu::OWeakObject*>(this);
546             if (rVclWindowEvent.GetId() == VclEventId::WindowActivate)
547                 mpImpl->getTopWindowListeners().windowActivated( aEvent );
548             else
549                 mpImpl->getTopWindowListeners().windowDeactivated( aEvent );
550         }
551         break;
552         case VclEventId::WindowClose:
553         {
554             if ( mpImpl->getDockableWindowListeners().getLength() )
555             {
556                 css::lang::EventObject aEvent;
557                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
558                 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::closed, aEvent );
559             }
560             if ( mpImpl->getTopWindowListeners().getLength() )
561             {
562                 css::lang::EventObject aEvent;
563                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
564                 mpImpl->getTopWindowListeners().windowClosing( aEvent );
565             }
566         }
567         break;
568         case VclEventId::ControlGetFocus:
569         case VclEventId::WindowGetFocus:
570         {
571             if  (   (   rVclWindowEvent.GetWindow()->IsCompoundControl()
572                     &&  rVclWindowEvent.GetId() == VclEventId::ControlGetFocus
573                     )
574                 ||  (   !rVclWindowEvent.GetWindow()->IsCompoundControl()
575                     &&  rVclWindowEvent.GetId() == VclEventId::WindowGetFocus
576                     )
577                 )
578             {
579                 if ( mpImpl->getFocusListeners().getLength() )
580                 {
581                     css::awt::FocusEvent aEvent;
582                     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
583                     aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags());
584                     aEvent.Temporary = false;
585                     mpImpl->getFocusListeners().focusGained( aEvent );
586                 }
587             }
588         }
589         break;
590         case VclEventId::ControlLoseFocus:
591         case VclEventId::WindowLoseFocus:
592         {
593             if  (   (   rVclWindowEvent.GetWindow()->IsCompoundControl()
594                     &&  rVclWindowEvent.GetId() == VclEventId::ControlLoseFocus
595                     )
596                 ||  (   !rVclWindowEvent.GetWindow()->IsCompoundControl()
597                     &&  rVclWindowEvent.GetId() == VclEventId::WindowLoseFocus
598                     )
599                 )
600             {
601                 if ( mpImpl->getFocusListeners().getLength() )
602                 {
603                     css::awt::FocusEvent aEvent;
604                     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
605                     aEvent.FocusFlags = static_cast<sal_Int16>(rVclWindowEvent.GetWindow()->GetGetFocusFlags());
606                     aEvent.Temporary = false;
607 
608                     vcl::Window* pNext = Application::GetFocusWindow();
609                     if ( pNext )
610                     {
611                         // Don't care about internals if this control is compound
612                         vcl::Window* pNextC = pNext;
613                         while ( pNextC && !pNextC->IsCompoundControl() )
614                             pNextC = pNextC->GetParent();
615                         if ( pNextC )
616                             pNext = pNextC;
617 
618                         pNext->GetComponentInterface();
619                         aEvent.NextFocus = static_cast<cppu::OWeakObject*>(pNext->GetWindowPeer());
620                     }
621                     mpImpl->getFocusListeners().focusLost( aEvent );
622                 }
623             }
624         }
625         break;
626         case VclEventId::WindowMinimize:
627         {
628             if ( mpImpl->getTopWindowListeners().getLength() )
629             {
630                 css::lang::EventObject aEvent;
631                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
632                 mpImpl->getTopWindowListeners().windowMinimized( aEvent );
633             }
634         }
635         break;
636         case VclEventId::WindowNormalize:
637         {
638             if ( mpImpl->getTopWindowListeners().getLength() )
639             {
640                 css::lang::EventObject aEvent;
641                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
642                 mpImpl->getTopWindowListeners().windowNormalized( aEvent );
643             }
644         }
645         break;
646         case VclEventId::WindowKeyInput:
647         {
648             if ( mpImpl->getKeyListeners().getLength() )
649             {
650                 css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
651                     *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
652                 ) );
653                 mpImpl->getKeyListeners().keyPressed( aEvent );
654             }
655         }
656         break;
657         case VclEventId::WindowKeyUp:
658         {
659             if ( mpImpl->getKeyListeners().getLength() )
660             {
661                 css::awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent(
662                     *static_cast<KeyEvent*>(rVclWindowEvent.GetData()), *this
663                 ) );
664                 mpImpl->getKeyListeners().keyReleased( aEvent );
665             }
666         }
667         break;
668         case VclEventId::WindowCommand:
669         {
670             CommandEvent* pCmdEvt = static_cast<CommandEvent*>(rVclWindowEvent.GetData());
671             if ( mpImpl->getMouseListeners().getLength() && ( pCmdEvt->GetCommand() == CommandEventId::ContextMenu ) )
672             {
673                 // CommandEventId::ContextMenu: send as mousePressed with PopupTrigger = true ...
674                 Point aWhere = static_cast< CommandEvent* >( rVclWindowEvent.GetData() )->GetMousePosPixel();
675                 if ( !pCmdEvt->IsMouseEvent() )
676                 {   // for keyboard events, we set the coordinates to -1,-1. This is a slight HACK, but the current API
677                     // handles a context menu command as special case of a mouse event, which is simply wrong.
678                     // Without extending the API, we would not have another chance to notify listeners of a
679                     // keyboard-triggered context menu request
680                     aWhere = Point( -1, -1 );
681                 }
682 
683                 MouseEvent aMEvt( aWhere, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT, 0 );
684                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( aMEvt, *this ) );
685                 aEvent.PopupTrigger = true;
686 
687                 Callback aCallback = [ this, aEvent ]()
688                                      { this->mpImpl->getMouseListeners().mousePressed( aEvent ); };
689 
690                 ImplExecuteAsyncWithoutSolarLock( aCallback );
691             }
692         }
693         break;
694         case VclEventId::WindowMouseMove:
695         {
696             MouseEvent* pMouseEvt = static_cast<MouseEvent*>(rVclWindowEvent.GetData());
697             if ( mpImpl->getMouseListeners().getLength() && ( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) )
698             {
699                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
700                 bool const isEnter(pMouseEvt->IsEnterWindow());
701                 Callback aCallback = [ this, isEnter, aEvent ]()
702                      { MouseListenerMultiplexer& rMouseListeners = this->mpImpl->getMouseListeners();
703                        isEnter
704                            ? rMouseListeners.mouseEntered(aEvent)
705                            : rMouseListeners.mouseExited(aEvent); };
706 
707                 ImplExecuteAsyncWithoutSolarLock( aCallback );
708             }
709 
710             if ( mpImpl->getMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
711             {
712                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *pMouseEvt, *this ) );
713                 aEvent.ClickCount = 0;
714                 if ( pMouseEvt->GetMode() & MouseEventModifiers::SIMPLEMOVE )
715                     mpImpl->getMouseMotionListeners().mouseMoved( aEvent );
716                 else
717                     mpImpl->getMouseMotionListeners().mouseDragged( aEvent );
718             }
719         }
720         break;
721         case VclEventId::WindowMouseButtonDown:
722         {
723             if ( mpImpl->getMouseListeners().getLength() )
724             {
725                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
726                 Callback aCallback = [ this, aEvent ]()
727                                      { this->mpImpl->getMouseListeners().mousePressed( aEvent ); };
728                 ImplExecuteAsyncWithoutSolarLock( aCallback );
729             }
730         }
731         break;
732         case VclEventId::WindowMouseButtonUp:
733         {
734             if ( mpImpl->getMouseListeners().getLength() )
735             {
736                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast<MouseEvent*>(rVclWindowEvent.GetData()), *this ) );
737 
738                 Callback aCallback = [ this, aEvent ]()
739                                      { this->mpImpl->getMouseListeners().mouseReleased( aEvent ); };
740                 ImplExecuteAsyncWithoutSolarLock( aCallback );
741             }
742         }
743         break;
744         case VclEventId::WindowStartDocking:
745         {
746             if ( mpImpl->getDockableWindowListeners().getLength() )
747             {
748                 DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData());
749 
750                 if( pData )
751                 {
752                     css::awt::DockingEvent aEvent;
753                     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
754                     aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
755                     aEvent.MousePos.X = pData->maMousePos.X();
756                     aEvent.MousePos.Y = pData->maMousePos.Y();
757                     aEvent.bLiveMode = false;
758                     aEvent.bInteractive = true;
759 
760                     mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::startDocking, aEvent );
761                 }
762             }
763         }
764         break;
765         case VclEventId::WindowDocking:
766         {
767             if ( mpImpl->getDockableWindowListeners().getLength() )
768             {
769                 DockingData *pData = static_cast<DockingData*>(rVclWindowEvent.GetData());
770 
771                 if( pData )
772                 {
773                     css::awt::DockingEvent aEvent;
774                     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
775                     aEvent.TrackingRectangle = AWTRectangle( pData->maTrackRect );
776                     aEvent.MousePos.X = pData->maMousePos.X();
777                     aEvent.MousePos.Y = pData->maMousePos.Y();
778                     aEvent.bLiveMode = false;
779                     aEvent.bInteractive = true;
780 
781                     Reference< XDockableWindowListener > xFirstListener;
782                     ::comphelper::OInterfaceIteratorHelper2 aIter( mpImpl->getDockableWindowListeners() );
783                     while ( aIter.hasMoreElements() && !xFirstListener.is() )
784                     {
785                         xFirstListener.set( aIter.next(), UNO_QUERY );
786                     }
787 
788                     css::awt::DockingData aDockingData =
789                         xFirstListener->docking( aEvent );
790                     pData->maTrackRect = VCLRectangle( aDockingData.TrackingRectangle );
791                     pData->mbFloating = aDockingData.bFloating;
792                 }
793             }
794         }
795         break;
796         case VclEventId::WindowEndDocking:
797         {
798             if ( mpImpl->getDockableWindowListeners().getLength() )
799             {
800                 EndDockingData *pData = static_cast<EndDockingData*>(rVclWindowEvent.GetData());
801 
802                 if( pData )
803                 {
804                     css::awt::EndDockingEvent aEvent;
805                     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
806                     aEvent.WindowRectangle = AWTRectangle( pData->maWindowRect );
807                     aEvent.bFloating = pData->mbFloating;
808                     aEvent.bCancelled = pData->mbCancelled;
809                     mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endDocking, aEvent );
810                 }
811             }
812         }
813         break;
814         case VclEventId::WindowPrepareToggleFloating:
815         {
816             if ( mpImpl->getDockableWindowListeners().getLength() )
817             {
818                 sal_Bool *p_bFloating = static_cast<sal_Bool*>(rVclWindowEvent.GetData());
819 
820                 css::lang::EventObject aEvent;
821                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
822 
823                 Reference< XDockableWindowListener > xFirstListener;
824                 ::comphelper::OInterfaceIteratorHelper2 aIter( mpImpl->getDockableWindowListeners() );
825                 while ( aIter.hasMoreElements() && !xFirstListener.is() )
826                 {
827                     xFirstListener.set( aIter.next(), UNO_QUERY );
828                 }
829 
830                 *p_bFloating = xFirstListener->prepareToggleFloatingMode( aEvent );
831             }
832         }
833         break;
834         case VclEventId::WindowToggleFloating:
835         {
836             if ( mpImpl->getDockableWindowListeners().getLength() )
837             {
838                 css::lang::EventObject aEvent;
839                 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
840                 mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::toggleFloatingMode, aEvent );
841             }
842         }
843         break;
844         case VclEventId::WindowEndPopupMode:
845         {
846             if ( mpImpl->getDockableWindowListeners().getLength() )
847             {
848                 EndPopupModeData *pData = static_cast<EndPopupModeData*>(rVclWindowEvent.GetData());
849 
850                 if( pData )
851                 {
852                     css::awt::EndPopupModeEvent aEvent;
853                     aEvent.Source = static_cast<cppu::OWeakObject*>(this);
854                     aEvent.FloatingPosition.X = pData->maFloatingPos.X();
855                     aEvent.FloatingPosition.Y = pData->maFloatingPos.Y();
856                     aEvent.bTearoff = pData->mbTearoff;
857                     mpImpl->getDockableWindowListeners().notifyEach( &XDockableWindowListener::endPopupMode, aEvent );
858                 }
859             }
860         }
861         break;
862         default: break;
863     }
864 }
865 
CreateAccessibleContext()866 uno::Reference< accessibility::XAccessibleContext > VCLXWindow::CreateAccessibleContext()
867 {
868     SolarMutexGuard aGuard;
869     return getAccessibleFactory().createAccessibleContext( this );
870 }
871 
SetSynthesizingVCLEvent(bool _b)872 void VCLXWindow::SetSynthesizingVCLEvent( bool _b )
873 {
874     mpImpl->mbSynthesizingVCLEvent = _b;
875 }
876 
IsSynthesizingVCLEvent() const877 bool VCLXWindow::IsSynthesizingVCLEvent() const
878 {
879     return mpImpl->mbSynthesizingVCLEvent;
880 }
881 
ImplCalcWindowSize(const Size & rOutSz) const882 Size VCLXWindow::ImplCalcWindowSize( const Size& rOutSz ) const
883 {
884     Size aSz = rOutSz;
885 
886     VclPtr<vcl::Window> pWindow = GetWindow();
887     if ( pWindow )
888     {
889         sal_Int32 nLeft, nTop, nRight, nBottom;
890         pWindow->GetBorder( nLeft, nTop, nRight, nBottom );
891         aSz.AdjustWidth(nLeft+nRight );
892         aSz.AdjustHeight(nTop+nBottom );
893     }
894     return aSz;
895 }
896 
897 
898 // css::lang::XUnoTunnel
899 UNO3_GETIMPLEMENTATION2_IMPL(VCLXWindow, VCLXDevice);
900 
901 
902 // css::lang::Component
dispose()903 void VCLXWindow::dispose(  )
904 {
905     SolarMutexGuard aGuard;
906 
907     mpImpl->mxViewGraphics = nullptr;
908 
909     if ( !mpImpl->mbDisposing )
910     {
911         mpImpl->mbDisposing = true;
912 
913         mpImpl->disposing();
914 
915         if ( GetWindow() )
916         {
917             VclPtr<OutputDevice> pOutDev = GetOutputDevice();
918             SetWindow( nullptr );  // so that handlers are logged off, if necessary (virtual)
919             SetOutputDevice( nullptr );
920             pOutDev.disposeAndClear();
921         }
922 
923         // #i14103# dispose the accessible context after the window has been destroyed,
924         // otherwise the old value in the child event fired in VCLXAccessibleComponent::ProcessWindowEvent()
925         // for VclEventId::WindowChildDestroyed contains a reference to an already disposed accessible object
926         try
927         {
928             css::uno::Reference< css::lang::XComponent > xComponent( mpImpl->mxAccessibleContext, css::uno::UNO_QUERY );
929             if ( xComponent.is() )
930                 xComponent->dispose();
931         }
932         catch ( const css::uno::Exception& )
933         {
934             OSL_FAIL( "VCLXWindow::dispose: could not dispose the accessible context!" );
935         }
936         mpImpl->mxAccessibleContext.clear();
937 
938         mpImpl->mbDisposing = false;
939     }
940 }
941 
addEventListener(const css::uno::Reference<css::lang::XEventListener> & rxListener)942 void VCLXWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
943 {
944     SolarMutexGuard aGuard;
945 
946     mpImpl->getEventListeners().addInterface( rxListener );
947 }
948 
removeEventListener(const css::uno::Reference<css::lang::XEventListener> & rxListener)949 void VCLXWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener )
950 {
951     SolarMutexGuard aGuard;
952 
953     mpImpl->getEventListeners().removeInterface( rxListener );
954 }
955 
956 
957 // css::awt::XWindow
setPosSize(sal_Int32 X,sal_Int32 Y,sal_Int32 Width,sal_Int32 Height,sal_Int16 Flags)958 void VCLXWindow::setPosSize( sal_Int32 X, sal_Int32 Y, sal_Int32 Width, sal_Int32 Height, sal_Int16 Flags )
959 {
960     SolarMutexGuard aGuard;
961     comphelper::ProfileZone aZone("setPosSize");
962 
963     if ( GetWindow() )
964     {
965         if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) )
966             vcl::Window::GetDockingManager()->SetPosSizePixel( GetWindow() , X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
967         else
968             GetWindow()->setPosSizePixel( X, Y, Width, Height, static_cast<PosSizeFlags>(Flags) );
969     }
970 }
971 
getPosSize()972 css::awt::Rectangle VCLXWindow::getPosSize(  )
973 {
974     SolarMutexGuard aGuard;
975 
976     css::awt::Rectangle aBounds;
977     if ( GetWindow() )
978     {
979         if( vcl::Window::GetDockingManager()->IsDockable( GetWindow() ) )
980             aBounds = AWTRectangle( vcl::Window::GetDockingManager()->GetPosSizePixel( GetWindow() ) );
981         else
982             aBounds = AWTRectangle( tools::Rectangle( GetWindow()->GetPosPixel(), GetWindow()->GetSizePixel() ) );
983     }
984 
985     return aBounds;
986 }
987 
setVisible(sal_Bool bVisible)988 void VCLXWindow::setVisible( sal_Bool bVisible )
989 {
990     SolarMutexGuard aGuard;
991 
992     VclPtr<vcl::Window> pWindow = GetWindow();
993     if ( pWindow )
994     {
995         mpImpl->setDirectVisible( bVisible );
996         pWindow->Show( bVisible &&  mpImpl->isEnableVisible() );
997     }
998 }
999 
setEnable(sal_Bool bEnable)1000 void VCLXWindow::setEnable( sal_Bool bEnable )
1001 {
1002     SolarMutexGuard aGuard;
1003 
1004     VclPtr<vcl::Window> pWindow = GetWindow();
1005     if ( pWindow )
1006     {
1007         pWindow->Enable( bEnable, false ); // #95824# without children!
1008         pWindow->EnableInput( bEnable );
1009     }
1010 }
1011 
setFocus()1012 void VCLXWindow::setFocus(  )
1013 {
1014     SolarMutexGuard aGuard;
1015 
1016     if ( GetWindow() )
1017         GetWindow()->GrabFocus();
1018 }
1019 
addWindowListener(const css::uno::Reference<css::awt::XWindowListener> & rxListener)1020 void VCLXWindow::addWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener )
1021 {
1022     SolarMutexGuard aGuard;
1023 
1024     mpImpl->getWindowListeners().addInterface( rxListener );
1025 
1026     Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
1027     if ( xListener2.is() )
1028         mpImpl->getWindow2Listeners().addInterface( xListener2 );
1029 
1030     // #100119# Get all resize events, even if height or width 0, or invisible
1031     if ( GetWindow() )
1032         GetWindow()->EnableAllResize();
1033 }
1034 
removeWindowListener(const css::uno::Reference<css::awt::XWindowListener> & rxListener)1035 void VCLXWindow::removeWindowListener( const css::uno::Reference< css::awt::XWindowListener >& rxListener )
1036 {
1037     SolarMutexGuard aGuard;
1038 
1039     Reference< XWindowListener2 > xListener2( rxListener, UNO_QUERY );
1040     if ( xListener2.is() )
1041         mpImpl->getWindow2Listeners().removeInterface( xListener2 );
1042 
1043     mpImpl->getWindowListeners().removeInterface( rxListener );
1044 }
1045 
addFocusListener(const css::uno::Reference<css::awt::XFocusListener> & rxListener)1046 void VCLXWindow::addFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
1047 {
1048     SolarMutexGuard aGuard;
1049     mpImpl->getFocusListeners().addInterface( rxListener );
1050 }
1051 
removeFocusListener(const css::uno::Reference<css::awt::XFocusListener> & rxListener)1052 void VCLXWindow::removeFocusListener( const css::uno::Reference< css::awt::XFocusListener >& rxListener )
1053 {
1054     SolarMutexGuard aGuard;
1055     mpImpl->getFocusListeners().removeInterface( rxListener );
1056 }
1057 
addKeyListener(const css::uno::Reference<css::awt::XKeyListener> & rxListener)1058 void VCLXWindow::addKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener )
1059 {
1060     SolarMutexGuard aGuard;
1061     mpImpl->getKeyListeners().addInterface( rxListener );
1062 }
1063 
removeKeyListener(const css::uno::Reference<css::awt::XKeyListener> & rxListener)1064 void VCLXWindow::removeKeyListener( const css::uno::Reference< css::awt::XKeyListener >& rxListener )
1065 {
1066     SolarMutexGuard aGuard;
1067     mpImpl->getKeyListeners().removeInterface( rxListener );
1068 }
1069 
addMouseListener(const css::uno::Reference<css::awt::XMouseListener> & rxListener)1070 void VCLXWindow::addMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
1071 {
1072     SolarMutexGuard aGuard;
1073     mpImpl->getMouseListeners().addInterface( rxListener );
1074 }
1075 
removeMouseListener(const css::uno::Reference<css::awt::XMouseListener> & rxListener)1076 void VCLXWindow::removeMouseListener( const css::uno::Reference< css::awt::XMouseListener >& rxListener )
1077 {
1078     SolarMutexGuard aGuard;
1079     mpImpl->getMouseListeners().removeInterface( rxListener );
1080 }
1081 
addMouseMotionListener(const css::uno::Reference<css::awt::XMouseMotionListener> & rxListener)1082 void VCLXWindow::addMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
1083 {
1084     SolarMutexGuard aGuard;
1085     mpImpl->getMouseMotionListeners().addInterface( rxListener );
1086 }
1087 
removeMouseMotionListener(const css::uno::Reference<css::awt::XMouseMotionListener> & rxListener)1088 void VCLXWindow::removeMouseMotionListener( const css::uno::Reference< css::awt::XMouseMotionListener >& rxListener )
1089 {
1090     SolarMutexGuard aGuard;
1091     mpImpl->getMouseMotionListeners().removeInterface( rxListener );
1092 }
1093 
addPaintListener(const css::uno::Reference<css::awt::XPaintListener> & rxListener)1094 void VCLXWindow::addPaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
1095 {
1096     SolarMutexGuard aGuard;
1097     mpImpl->getPaintListeners().addInterface( rxListener );
1098 }
1099 
removePaintListener(const css::uno::Reference<css::awt::XPaintListener> & rxListener)1100 void VCLXWindow::removePaintListener( const css::uno::Reference< css::awt::XPaintListener >& rxListener )
1101 {
1102     SolarMutexGuard aGuard;
1103     mpImpl->getPaintListeners().removeInterface( rxListener );
1104 }
1105 
1106 // css::awt::XWindowPeer
getToolkit()1107 css::uno::Reference< css::awt::XToolkit > VCLXWindow::getToolkit(  )
1108 {
1109     // no guard. nothing to guard here.
1110     // 82463 - 12/21/00 - fs
1111     return Application::GetVCLToolkit();
1112 }
1113 
setPointer(const css::uno::Reference<css::awt::XPointer> & rxPointer)1114 void VCLXWindow::setPointer( const css::uno::Reference< css::awt::XPointer >& rxPointer )
1115 {
1116     SolarMutexGuard aGuard;
1117 
1118     VCLXPointer* pPointer = comphelper::getUnoTunnelImplementation<VCLXPointer>( rxPointer );
1119     if ( pPointer && GetWindow() )
1120         GetWindow()->SetPointer( pPointer->GetPointer() );
1121 }
1122 
setBackground(sal_Int32 nColor)1123 void VCLXWindow::setBackground( sal_Int32 nColor )
1124 {
1125     SolarMutexGuard aGuard;
1126 
1127     if ( GetWindow() )
1128     {
1129         Color aColor(nColor);
1130         GetWindow()->SetBackground( aColor );
1131         GetWindow()->SetControlBackground( aColor );
1132 
1133         WindowType eWinType = GetWindow()->GetType();
1134         if ( ( eWinType == WindowType::WINDOW ) ||
1135              ( eWinType == WindowType::WORKWINDOW ) ||
1136              ( eWinType == WindowType::FLOATINGWINDOW ) )
1137         {
1138             GetWindow()->Invalidate();
1139         }
1140     }
1141 }
1142 
invalidate(sal_Int16 nInvalidateFlags)1143 void VCLXWindow::invalidate( sal_Int16 nInvalidateFlags )
1144 {
1145     SolarMutexGuard aGuard;
1146 
1147     if ( GetWindow() )
1148         GetWindow()->Invalidate( static_cast<InvalidateFlags>(nInvalidateFlags) );
1149 }
1150 
invalidateRect(const css::awt::Rectangle & rRect,sal_Int16 nInvalidateFlags)1151 void VCLXWindow::invalidateRect( const css::awt::Rectangle& rRect, sal_Int16 nInvalidateFlags )
1152 {
1153     SolarMutexGuard aGuard;
1154 
1155     if ( GetWindow() )
1156         GetWindow()->Invalidate( VCLRectangle(rRect), static_cast<InvalidateFlags>(nInvalidateFlags) );
1157 }
1158 
1159 
1160 // css::awt::XVclWindowPeer
isChild(const css::uno::Reference<css::awt::XWindowPeer> & rxPeer)1161 sal_Bool VCLXWindow::isChild( const css::uno::Reference< css::awt::XWindowPeer >& rxPeer )
1162 {
1163     SolarMutexGuard aGuard;
1164 
1165     bool bIsChild = false;
1166     VclPtr<vcl::Window> pWindow = GetWindow();
1167     if ( pWindow )
1168     {
1169         VclPtr<vcl::Window> pPeerWindow = VCLUnoHelper::GetWindow( rxPeer );
1170         bIsChild = pPeerWindow && pWindow->IsChild( pPeerWindow );
1171     }
1172 
1173     return bIsChild;
1174 }
1175 
setDesignMode(sal_Bool bOn)1176 void VCLXWindow::setDesignMode( sal_Bool bOn )
1177 {
1178     SolarMutexGuard aGuard;
1179 
1180     mpImpl->mbDesignMode = bOn;
1181 }
1182 
isDesignMode()1183 sal_Bool VCLXWindow::isDesignMode(  )
1184 {
1185     SolarMutexGuard aGuard;
1186     return mpImpl->mbDesignMode;
1187 }
1188 
enableClipSiblings(sal_Bool bClip)1189 void VCLXWindow::enableClipSiblings( sal_Bool bClip )
1190 {
1191     SolarMutexGuard aGuard;
1192 
1193     if ( GetWindow() )
1194         GetWindow()->EnableClipSiblings( bClip );
1195 }
1196 
setForeground(sal_Int32 nColor)1197 void VCLXWindow::setForeground( sal_Int32 nColor )
1198 {
1199     SolarMutexGuard aGuard;
1200 
1201     if ( GetWindow() )
1202     {
1203         GetWindow()->SetControlForeground( Color(nColor) );
1204     }
1205 }
1206 
setControlFont(const css::awt::FontDescriptor & rFont)1207 void VCLXWindow::setControlFont( const css::awt::FontDescriptor& rFont )
1208 {
1209     SolarMutexGuard aGuard;
1210 
1211     if ( GetWindow() )
1212         GetWindow()->SetControlFont( VCLUnoHelper::CreateFont( rFont, GetWindow()->GetControlFont() ) );
1213 }
1214 
getStyles(sal_Int16 nType,css::awt::FontDescriptor & Font,sal_Int32 & ForegroundColor,sal_Int32 & BackgroundColor)1215 void VCLXWindow::getStyles( sal_Int16 nType, css::awt::FontDescriptor& Font, sal_Int32& ForegroundColor, sal_Int32& BackgroundColor )
1216 {
1217     SolarMutexGuard aGuard;
1218 
1219     if ( GetWindow() )
1220     {
1221         const StyleSettings& rStyleSettings = GetWindow()->GetSettings().GetStyleSettings();
1222 
1223         switch ( nType )
1224         {
1225             case css::awt::Style::FRAME:
1226             {
1227                 Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
1228                 ForegroundColor = sal_Int32(rStyleSettings.GetWindowTextColor());
1229                 BackgroundColor = sal_Int32(rStyleSettings.GetWindowColor());
1230             }
1231             break;
1232             case css::awt::Style::DIALOG:
1233             {
1234                 Font = VCLUnoHelper::CreateFontDescriptor( rStyleSettings.GetAppFont() );
1235                 ForegroundColor = sal_Int32(rStyleSettings.GetDialogTextColor());
1236                 BackgroundColor = sal_Int32(rStyleSettings.GetDialogColor());
1237             }
1238             break;
1239             default: OSL_FAIL( "VCLWindow::getStyles() - unknown Type" );
1240         }
1241 
1242     }
1243 }
1244 
1245 namespace toolkit
1246 {
setColorSettings(vcl::Window * _pWindow,const css::uno::Any & _rValue,void (StyleSettings::* pSetter)(const Color &),const Color & (StyleSettings::* pGetter)()const)1247     static void setColorSettings( vcl::Window* _pWindow, const css::uno::Any& _rValue,
1248         void (StyleSettings::*pSetter)( const Color& ), const Color& (StyleSettings::*pGetter)( ) const )
1249     {
1250         sal_Int32 nColor = 0;
1251         if ( !( _rValue >>= nColor ) )
1252             nColor = sal_Int32((Application::GetSettings().GetStyleSettings().*pGetter)());
1253 
1254         AllSettings aSettings = _pWindow->GetSettings();
1255         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1256 
1257         (aStyleSettings.*pSetter)( Color( nColor ) );
1258 
1259         aSettings.SetStyleSettings( aStyleSettings );
1260         _pWindow->SetSettings( aSettings, true );
1261     }
1262 }
1263 
1264 // Terminated by BASEPROPERTY_NOTFOUND (or 0)
PushPropertyIds(std::vector<sal_uInt16> & rIds,int nFirstId,...)1265 void VCLXWindow::PushPropertyIds( std::vector< sal_uInt16 > &rIds,
1266                                   int nFirstId, ...)
1267 {
1268     va_list pVarArgs;
1269     va_start( pVarArgs, nFirstId );
1270 
1271     for ( int nId = nFirstId; nId != BASEPROPERTY_NOTFOUND;
1272           nId = va_arg( pVarArgs, int ) )
1273         rIds.push_back( static_cast<sal_uInt16>(nId) );
1274 
1275     va_end( pVarArgs );
1276 }
1277 
ImplGetPropertyIds(std::vector<sal_uInt16> & rIds,bool bWithDefaults)1278 void VCLXWindow::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds, bool bWithDefaults )
1279 {
1280     // These are common across ~all VCLXWindow derived classes
1281     if( bWithDefaults )
1282         PushPropertyIds( rIds,
1283                          BASEPROPERTY_ALIGN,
1284                          BASEPROPERTY_BACKGROUNDCOLOR,
1285                          BASEPROPERTY_BORDER,
1286                          BASEPROPERTY_BORDERCOLOR,
1287                          BASEPROPERTY_DEFAULTCONTROL,
1288                          BASEPROPERTY_ENABLED,
1289                          BASEPROPERTY_FONTDESCRIPTOR,
1290                          BASEPROPERTY_HELPTEXT,
1291                          BASEPROPERTY_HELPURL,
1292                          BASEPROPERTY_TEXT,
1293                          BASEPROPERTY_PRINTABLE,
1294                          BASEPROPERTY_ENABLEVISIBLE, // for visibility
1295                          BASEPROPERTY_TABSTOP,
1296                          0);
1297 
1298     // lovely hack from:
1299     // void UnoControlModel::ImplRegisterProperty( sal_uInt16 nPropId )
1300     if( std::find(rIds.begin(), rIds.end(), BASEPROPERTY_FONTDESCRIPTOR) != rIds.end() )
1301     {
1302         // some properties are not included in the FontDescriptor, but every time
1303         // when we have a FontDescriptor we want to have these properties too.
1304         // => Easier to register the here, instead everywhere where I register the FontDescriptor...
1305 
1306         rIds.push_back( BASEPROPERTY_TEXTCOLOR );
1307         rIds.push_back( BASEPROPERTY_TEXTLINECOLOR );
1308         rIds.push_back( BASEPROPERTY_FONTRELIEF );
1309         rIds.push_back( BASEPROPERTY_FONTEMPHASISMARK );
1310     }
1311 }
1312 
GetPropertyIds(std::vector<sal_uInt16> & _out_rIds)1313 void VCLXWindow::GetPropertyIds( std::vector< sal_uInt16 >& _out_rIds )
1314 {
1315     return ImplGetPropertyIds( _out_rIds, mpImpl->mbWithDefaultProps );
1316 }
1317 
GetContainerListeners()1318 ::comphelper::OInterfaceContainerHelper2& VCLXWindow::GetContainerListeners()
1319 {
1320     return mpImpl->getContainerListeners();
1321 }
1322 
GetTopWindowListeners()1323 ::comphelper::OInterfaceContainerHelper2& VCLXWindow::GetTopWindowListeners()
1324 {
1325     return mpImpl->getTopWindowListeners();
1326 }
1327 
1328 namespace
1329 {
lcl_updateWritingMode(vcl::Window & _rWindow,const sal_Int16 _nWritingMode,const sal_Int16 _nContextWritingMode)1330     void    lcl_updateWritingMode( vcl::Window& _rWindow, const sal_Int16 _nWritingMode, const sal_Int16 _nContextWritingMode )
1331     {
1332         bool bEnableRTL = false;
1333         switch ( _nWritingMode )
1334         {
1335         case WritingMode2::LR_TB:   bEnableRTL = false; break;
1336         case WritingMode2::RL_TB:   bEnableRTL = true; break;
1337         case WritingMode2::CONTEXT:
1338         {
1339             // consult our ContextWritingMode. If it has an explicit RTL/LTR value, then use
1340             // it. If it doesn't (but is CONTEXT itself), then just ask the parent window of our
1341             // own window for its RTL mode
1342             switch ( _nContextWritingMode )
1343             {
1344                 case WritingMode2::LR_TB:   bEnableRTL = false; break;
1345                 case WritingMode2::RL_TB:   bEnableRTL = true; break;
1346                 case WritingMode2::CONTEXT:
1347                 {
1348                     const vcl::Window* pParent = _rWindow.GetParent();
1349                     OSL_ENSURE( pParent, "lcl_updateWritingMode: cannot determine context's writing mode!" );
1350                     if ( pParent )
1351                         bEnableRTL = pParent->IsRTLEnabled();
1352                 }
1353                 break;
1354             }
1355         }
1356         break;
1357         default:
1358             OSL_FAIL( "lcl_updateWritingMode: unsupported WritingMode!" );
1359         }   // switch ( nWritingMode )
1360 
1361         _rWindow.EnableRTL( bEnableRTL );
1362     }
1363 }
1364 
setProperty(const OUString & PropertyName,const css::uno::Any & Value)1365 void VCLXWindow::setProperty( const OUString& PropertyName, const css::uno::Any& Value )
1366 {
1367     SolarMutexGuard aGuard;
1368 
1369     VclPtr<vcl::Window> pWindow = GetWindow();
1370     if ( !pWindow )
1371         return;
1372 
1373     bool bVoid = Value.getValueType().getTypeClass() == css::uno::TypeClass_VOID;
1374 
1375     WindowType eWinType = pWindow->GetType();
1376     sal_uInt16 nPropType = GetPropertyId( PropertyName );
1377     switch ( nPropType )
1378     {
1379         case BASEPROPERTY_REFERENCE_DEVICE:
1380         {
1381             Control* pControl = dynamic_cast< Control* >( pWindow.get() );
1382             OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
1383             if ( !pControl )
1384                 break;
1385             Reference< XDevice > xDevice( Value, UNO_QUERY );
1386             OutputDevice* pDevice = VCLUnoHelper::GetOutputDevice( xDevice );
1387             pControl->SetReferenceDevice( pDevice );
1388         }
1389         break;
1390 
1391         case BASEPROPERTY_CONTEXT_WRITING_MODE:
1392         {
1393             OSL_VERIFY( Value >>= mpImpl->mnContextWritingMode );
1394             if ( mpImpl->mnWritingMode == WritingMode2::CONTEXT )
1395                 lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
1396         }
1397         break;
1398 
1399         case BASEPROPERTY_WRITING_MODE:
1400         {
1401             bool bProperType = ( Value >>= mpImpl->mnWritingMode );
1402             OSL_ENSURE( bProperType, "VCLXWindow::setProperty( 'WritingMode' ): illegal value type!" );
1403             if ( bProperType )
1404                 lcl_updateWritingMode( *pWindow, mpImpl->mnWritingMode, mpImpl->mnContextWritingMode );
1405         }
1406         break;
1407 
1408         case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
1409         {
1410             sal_uInt16 nWheelBehavior( css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY );
1411             OSL_VERIFY( Value >>= nWheelBehavior );
1412 
1413             AllSettings aSettings = pWindow->GetSettings();
1414             MouseSettings aMouseSettings = aSettings.GetMouseSettings();
1415 
1416             MouseWheelBehaviour nVclBehavior( MouseWheelBehaviour::FocusOnly );
1417             switch ( nWheelBehavior )
1418             {
1419             case css::awt::MouseWheelBehavior::SCROLL_DISABLED:   nVclBehavior = MouseWheelBehaviour::Disable;     break;
1420             case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclBehavior = MouseWheelBehaviour::FocusOnly;  break;
1421             case css::awt::MouseWheelBehavior::SCROLL_ALWAYS:     nVclBehavior = MouseWheelBehaviour::ALWAYS;      break;
1422             default:
1423                 OSL_FAIL( "VCLXWindow::setProperty( 'MouseWheelBehavior' ): illegal property value!" );
1424             }
1425 
1426             aMouseSettings.SetWheelBehavior( nVclBehavior );
1427             aSettings.SetMouseSettings( aMouseSettings );
1428             pWindow->SetSettings( aSettings, true );
1429         }
1430         break;
1431 
1432         case BASEPROPERTY_NATIVE_WIDGET_LOOK:
1433         {
1434             bool bEnable( true );
1435             OSL_VERIFY( Value >>= bEnable );
1436             pWindow->EnableNativeWidget( bEnable );
1437         }
1438         break;
1439 
1440         case BASEPROPERTY_PLUGINPARENT:
1441         {
1442             // set parent handle
1443             SetSystemParent_Impl( Value );
1444         }
1445         break;
1446 
1447         case BASEPROPERTY_ENABLED:
1448         {
1449             bool b = bool();
1450             if ( Value >>= b )
1451                 setEnable( b );
1452         }
1453         break;
1454         case BASEPROPERTY_ENABLEVISIBLE:
1455         {
1456             bool b = false;
1457             if ( Value >>= b )
1458             {
1459                 if( b != mpImpl->isEnableVisible() )
1460                 {
1461                     mpImpl->setEnableVisible( b );
1462                     pWindow->Show( b && mpImpl->isDirectVisible() );
1463                 }
1464             }
1465         }
1466         break;
1467         case BASEPROPERTY_TEXT:
1468         case BASEPROPERTY_LABEL:
1469         case BASEPROPERTY_TITLE:
1470         {
1471             OUString aText;
1472             if ( Value >>= aText )
1473             {
1474                 switch (eWinType)
1475                 {
1476                     case WindowType::OKBUTTON:
1477                     case WindowType::CANCELBUTTON:
1478                     case WindowType::HELPBUTTON:
1479                         // Standard Button: overwrite only if not empty.
1480                         if (!aText.isEmpty())
1481                             pWindow->SetText( aText );
1482                         break;
1483 
1484                     default:
1485                         pWindow->SetText( aText );
1486                         break;
1487                 }
1488             }
1489         }
1490         break;
1491         case BASEPROPERTY_ACCESSIBLENAME:
1492         {
1493             OUString aText;
1494             if ( Value >>= aText )
1495                 pWindow->SetAccessibleName( aText );
1496         }
1497         break;
1498         case BASEPROPERTY_HELPURL:
1499         {
1500             OUString aURL;
1501             if ( Value >>= aURL )
1502             {
1503                 INetURLObject aHelpURL( aURL );
1504                 if ( aHelpURL.GetProtocol() == INetProtocol::Hid )
1505                     pWindow->SetHelpId( OUStringToOString( aHelpURL.GetURLPath(), RTL_TEXTENCODING_UTF8 ) );
1506                 else
1507                     pWindow->SetHelpId( OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ) );
1508             }
1509         }
1510         break;
1511         case BASEPROPERTY_HELPTEXT:
1512         {
1513             OUString aHelpText;
1514             if ( Value >>= aHelpText )
1515             {
1516                 pWindow->SetQuickHelpText( aHelpText );
1517             }
1518         }
1519         break;
1520         case BASEPROPERTY_FONTDESCRIPTOR:
1521         {
1522             if ( bVoid )
1523                 pWindow->SetControlFont( vcl::Font() );
1524             else
1525             {
1526                 css::awt::FontDescriptor aFont;
1527                 if ( Value >>= aFont )
1528                     pWindow->SetControlFont( VCLUnoHelper::CreateFont( aFont, pWindow->GetControlFont() ) );
1529             }
1530         }
1531         break;
1532         case BASEPROPERTY_FONTRELIEF:
1533         {
1534             sal_Int16 n = sal_Int16();
1535             if ( Value >>= n )
1536             {
1537                 vcl::Font aFont = pWindow->GetControlFont();
1538                 aFont.SetRelief( static_cast<FontRelief>(n) );
1539                 pWindow->SetControlFont( aFont );
1540             }
1541         }
1542         break;
1543         case BASEPROPERTY_FONTEMPHASISMARK:
1544         {
1545             sal_Int16 n = sal_Int16();
1546             if ( Value >>= n )
1547             {
1548                 vcl::Font aFont = pWindow->GetControlFont();
1549                 aFont.SetEmphasisMark( static_cast<FontEmphasisMark>(n) );
1550                 pWindow->SetControlFont( aFont );
1551             }
1552         }
1553         break;
1554         case BASEPROPERTY_BACKGROUNDCOLOR:
1555             if ( bVoid )
1556             {
1557                 switch ( eWinType )
1558                 {
1559                     // set dialog color for default
1560                     case WindowType::DIALOG:
1561                     case WindowType::MESSBOX:
1562                     case WindowType::INFOBOX:
1563                     case WindowType::WARNINGBOX:
1564                     case WindowType::ERRORBOX:
1565                     case WindowType::QUERYBOX:
1566                     case WindowType::TABPAGE:
1567                     {
1568                         Color aColor = pWindow->GetSettings().GetStyleSettings().GetDialogColor();
1569                         pWindow->SetBackground( aColor );
1570                         pWindow->SetControlBackground( aColor );
1571                         break;
1572                     }
1573 
1574                     case WindowType::FIXEDTEXT:
1575                     case WindowType::CHECKBOX:
1576                     case WindowType::RADIOBUTTON:
1577                     case WindowType::GROUPBOX:
1578                     case WindowType::FIXEDLINE:
1579                     {
1580                         // support transparency only for special controls
1581                         pWindow->SetBackground();
1582                         pWindow->SetControlBackground();
1583                         pWindow->SetPaintTransparent( true );
1584                         break;
1585                     }
1586 
1587                     default:
1588                     {
1589                         // default code which enables transparency for
1590                         // compound controls. It's not real transparency
1591                         // as most of these controls repaint their client
1592                         // area completely new.
1593                         if ( pWindow->IsCompoundControl() )
1594                             pWindow->SetBackground();
1595                         pWindow->SetControlBackground();
1596                         break;
1597                     }
1598                 }
1599             }
1600             else
1601             {
1602                 sal_Int32 nColor = 0;
1603                 if ( Value >>= nColor )
1604                 {
1605                     Color aColor( nColor );
1606                     pWindow->SetControlBackground( aColor );
1607                     pWindow->SetBackground( aColor );
1608                     switch ( eWinType )
1609                     {
1610                         // reset paint transparent mode
1611                         case WindowType::FIXEDTEXT:
1612                         case WindowType::CHECKBOX:
1613                         case WindowType::RADIOBUTTON:
1614                         case WindowType::GROUPBOX:
1615                         case WindowType::FIXEDLINE:
1616                             pWindow->SetPaintTransparent( false );
1617                             break;
1618                         default:
1619                             break;
1620                     }
1621                     pWindow->Invalidate();  // Invalidate if control does not respond to it
1622                 }
1623             }
1624         break;
1625         case BASEPROPERTY_TEXTCOLOR:
1626             if ( bVoid )
1627             {
1628                 pWindow->SetControlForeground();
1629             }
1630             else
1631             {
1632                 sal_Int32 nColor = 0;
1633                 if ( Value >>= nColor )
1634                 {
1635                     Color aColor( nColor );
1636                     pWindow->SetTextColor( aColor );
1637                     pWindow->SetControlForeground( aColor );
1638                 }
1639             }
1640         break;
1641         case BASEPROPERTY_TEXTLINECOLOR:
1642             if ( bVoid )
1643             {
1644                 pWindow->SetTextLineColor();
1645             }
1646             else
1647             {
1648                 sal_Int32 nColor = 0;
1649                 if ( Value >>= nColor )
1650                 {
1651                     Color aColor( nColor );
1652                     pWindow->SetTextLineColor( aColor );
1653                 }
1654             }
1655         break;
1656         case BASEPROPERTY_FILLCOLOR:
1657             if ( bVoid )
1658                 pWindow->SetFillColor();
1659             else
1660             {
1661                 sal_Int32 nColor = 0;
1662                 if ( Value >>= nColor )
1663                 {
1664                     Color aColor( nColor );
1665                     pWindow->SetFillColor( aColor );
1666                 }
1667             }
1668         break;
1669         case BASEPROPERTY_LINECOLOR:
1670             if ( bVoid )
1671                 pWindow->SetLineColor();
1672             else
1673             {
1674                 sal_Int32 nColor = 0;
1675                 if ( Value >>= nColor )
1676                 {
1677                     Color aColor( nColor );
1678                     pWindow->SetLineColor( aColor );
1679                 }
1680             }
1681         break;
1682         case BASEPROPERTY_BORDER:
1683         {
1684             WinBits nStyle = pWindow->GetStyle();
1685             sal_uInt16 nTmp = 0;
1686             Value >>= nTmp;
1687             // clear any dodgy bits passed in, can come from dodgy extensions
1688             nTmp &= o3tl::typed_flags<WindowBorderStyle>::mask;
1689             WindowBorderStyle nBorder = static_cast<WindowBorderStyle>(nTmp);
1690             if ( !bool(nBorder) )
1691             {
1692                 pWindow->SetStyle( nStyle & ~WB_BORDER );
1693             }
1694             else
1695             {
1696                 pWindow->SetStyle( nStyle | WB_BORDER );
1697                 pWindow->SetBorderStyle( nBorder );
1698             }
1699         }
1700         break;
1701         case BASEPROPERTY_TABSTOP:
1702         {
1703             WinBits nStyle = pWindow->GetStyle() & ~WB_TABSTOP;
1704             if ( !bVoid )
1705             {
1706                 bool bTab = false;
1707                 Value >>= bTab;
1708                 if ( bTab )
1709                     nStyle |= WB_TABSTOP;
1710                 else
1711                     nStyle |= WB_NOTABSTOP;
1712             }
1713             pWindow->SetStyle( nStyle );
1714         }
1715         break;
1716         case BASEPROPERTY_VERTICALALIGN:
1717         {
1718             VerticalAlignment eAlign = css::style::VerticalAlignment::VerticalAlignment_MAKE_FIXED_SIZE;
1719             WinBits nStyle = pWindow->GetStyle();
1720             nStyle &= ~(WB_TOP|WB_VCENTER|WB_BOTTOM);
1721             if ( !bVoid )
1722                 Value >>= eAlign;
1723             switch ( eAlign )
1724             {
1725             case VerticalAlignment_TOP:
1726                 nStyle |= WB_TOP;
1727                 break;
1728             case VerticalAlignment_MIDDLE:
1729                 nStyle |= WB_VCENTER;
1730                 break;
1731             case VerticalAlignment_BOTTOM:
1732                 nStyle |= WB_BOTTOM;
1733                 break;
1734             default: ; // for warning free code, MAKE_FIXED_SIZE
1735             }
1736             pWindow->SetStyle( nStyle );
1737         }
1738         break;
1739         case BASEPROPERTY_ALIGN:
1740         {
1741             sal_Int16 nAlign = PROPERTY_ALIGN_LEFT;
1742             switch ( eWinType )
1743             {
1744                 case WindowType::COMBOBOX:
1745                 case WindowType::PUSHBUTTON:
1746                 case WindowType::OKBUTTON:
1747                 case WindowType::CANCELBUTTON:
1748                 case WindowType::HELPBUTTON:
1749                     nAlign = PROPERTY_ALIGN_CENTER;
1750                     [[fallthrough]];
1751                 case WindowType::FIXEDTEXT:
1752                 case WindowType::EDIT:
1753                 case WindowType::MULTILINEEDIT:
1754                 case WindowType::CHECKBOX:
1755                 case WindowType::RADIOBUTTON:
1756                 case WindowType::LISTBOX:
1757                 {
1758                     WinBits nStyle = pWindow->GetStyle();
1759                     nStyle &= ~(WB_LEFT|WB_CENTER|WB_RIGHT);
1760                     if ( !bVoid )
1761                         Value >>= nAlign;
1762                     if ( nAlign == PROPERTY_ALIGN_LEFT )
1763                         nStyle |= WB_LEFT;
1764                     else if ( nAlign == PROPERTY_ALIGN_CENTER )
1765                         nStyle |= WB_CENTER;
1766                     else
1767                         nStyle |= WB_RIGHT;
1768                     pWindow->SetStyle( nStyle );
1769                 }
1770                 break;
1771                 default: break;
1772             }
1773         }
1774         break;
1775         case BASEPROPERTY_MULTILINE:
1776         {
1777             if  (  ( eWinType == WindowType::FIXEDTEXT )
1778                 || ( eWinType == WindowType::CHECKBOX )
1779                 || ( eWinType == WindowType::RADIOBUTTON )
1780                 || ( eWinType == WindowType::PUSHBUTTON )
1781                 || ( eWinType == WindowType::OKBUTTON )
1782                 || ( eWinType == WindowType::CANCELBUTTON )
1783                 || ( eWinType == WindowType::HELPBUTTON )
1784                 )
1785             {
1786                 WinBits nStyle = pWindow->GetStyle();
1787                 bool bMulti = false;
1788                 Value >>= bMulti;
1789                 if ( bMulti )
1790                     nStyle |= WB_WORDBREAK;
1791                 else
1792                     nStyle &= ~WB_WORDBREAK;
1793                 pWindow->SetStyle( nStyle );
1794             }
1795         }
1796         break;
1797         case BASEPROPERTY_ORIENTATION:
1798         {
1799             if ( eWinType == WindowType::FIXEDLINE)
1800             {
1801                 sal_Int32 nOrientation = 0;
1802                 if ( Value >>= nOrientation )
1803                 {
1804                     WinBits nStyle = pWindow->GetStyle();
1805                     nStyle &= ~(WB_HORZ|WB_VERT);
1806                     if ( nOrientation == 0 )
1807                         nStyle |= WB_HORZ;
1808                     else
1809                         nStyle |= WB_VERT;
1810 
1811                     pWindow->SetStyle( nStyle );
1812                 }
1813             }
1814         }
1815         break;
1816         case BASEPROPERTY_AUTOMNEMONICS:
1817         {
1818             bool bAutoMnemonics = false;
1819             Value >>= bAutoMnemonics;
1820             AllSettings aSettings = pWindow->GetSettings();
1821             StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1822             if ( aStyleSettings.GetAutoMnemonic() != bAutoMnemonics )
1823             {
1824                 aStyleSettings.SetAutoMnemonic( bAutoMnemonics );
1825                 aSettings.SetStyleSettings( aStyleSettings );
1826                 pWindow->SetSettings( aSettings );
1827             }
1828         }
1829         break;
1830         case BASEPROPERTY_MOUSETRANSPARENT:
1831         {
1832             bool bMouseTransparent = false;
1833             Value >>= bMouseTransparent;
1834             pWindow->SetMouseTransparent( bMouseTransparent );
1835         }
1836         break;
1837         case BASEPROPERTY_PAINTTRANSPARENT:
1838         {
1839             bool bPaintTransparent = false;
1840             Value >>= bPaintTransparent;
1841             pWindow->SetPaintTransparent( bPaintTransparent );
1842 //                pWindow->SetBackground();
1843         }
1844         break;
1845 
1846         case BASEPROPERTY_REPEAT:
1847         {
1848             bool bRepeat( false );
1849             Value >>= bRepeat;
1850 
1851             WinBits nStyle = pWindow->GetStyle();
1852             if ( bRepeat )
1853                 nStyle |= WB_REPEAT;
1854             else
1855                 nStyle &= ~WB_REPEAT;
1856             pWindow->SetStyle( nStyle );
1857         }
1858         break;
1859 
1860         case BASEPROPERTY_REPEAT_DELAY:
1861         {
1862             sal_Int32 nRepeatDelay = 0;
1863             if ( Value >>= nRepeatDelay )
1864             {
1865                 AllSettings aSettings = pWindow->GetSettings();
1866                 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
1867 
1868                 aMouseSettings.SetButtonRepeat( nRepeatDelay );
1869                 aSettings.SetMouseSettings( aMouseSettings );
1870 
1871                 pWindow->SetSettings( aSettings, true );
1872             }
1873         }
1874         break;
1875 
1876         case BASEPROPERTY_SYMBOL_COLOR:
1877             ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetButtonTextColor, &StyleSettings::GetButtonTextColor );
1878             break;
1879 
1880         case BASEPROPERTY_BORDERCOLOR:
1881             ::toolkit::setColorSettings( pWindow, Value, &StyleSettings::SetMonoColor, &StyleSettings::GetMonoColor);
1882             break;
1883     }
1884 }
1885 
getProperty(const OUString & PropertyName)1886 css::uno::Any VCLXWindow::getProperty( const OUString& PropertyName )
1887 {
1888     SolarMutexGuard aGuard;
1889 
1890     css::uno::Any aProp;
1891     if ( GetWindow() )
1892     {
1893         WindowType eWinType = GetWindow()->GetType();
1894         sal_uInt16 nPropType = GetPropertyId( PropertyName );
1895         switch ( nPropType )
1896         {
1897             case BASEPROPERTY_REFERENCE_DEVICE:
1898             {
1899                 VclPtr<Control> pControl = GetAsDynamic<Control >();
1900                 OSL_ENSURE( pControl, "VCLXWindow::setProperty( RefDevice ): need a Control for this!" );
1901                 if ( !pControl )
1902                     break;
1903 
1904                 VCLXDevice* pDevice = new VCLXDevice;
1905                 pDevice->SetOutputDevice( pControl->GetReferenceDevice() );
1906                 aProp <<= Reference< XDevice >( pDevice );
1907             }
1908             break;
1909 
1910             case BASEPROPERTY_CONTEXT_WRITING_MODE:
1911                 aProp <<= mpImpl->mnContextWritingMode;
1912                 break;
1913 
1914             case BASEPROPERTY_WRITING_MODE:
1915                 aProp <<= mpImpl->mnWritingMode;
1916                 break;
1917 
1918             case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:
1919             {
1920                 MouseWheelBehaviour nVclBehavior = GetWindow()->GetSettings().GetMouseSettings().GetWheelBehavior();
1921                 sal_uInt16 nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
1922                 switch ( nVclBehavior )
1923                 {
1924                 case MouseWheelBehaviour::Disable:       nBehavior = css::awt::MouseWheelBehavior::SCROLL_DISABLED;    break;
1925                 case MouseWheelBehaviour::FocusOnly:     nBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;  break;
1926                 case MouseWheelBehaviour::ALWAYS:        nBehavior = css::awt::MouseWheelBehavior::SCROLL_ALWAYS;      break;
1927                 default:
1928                     OSL_FAIL( "VCLXWindow::getProperty( 'MouseWheelBehavior' ): illegal VCL value!" );
1929                 }
1930                 aProp <<= nBehavior;
1931             }
1932             break;
1933 
1934             case BASEPROPERTY_NATIVE_WIDGET_LOOK:
1935                 aProp <<= GetWindow()->IsNativeWidgetEnabled();
1936                 break;
1937 
1938             case BASEPROPERTY_ENABLED:
1939                 aProp <<= GetWindow()->IsEnabled();
1940                 break;
1941 
1942             case BASEPROPERTY_ENABLEVISIBLE:
1943                 aProp <<= mpImpl->isEnableVisible();
1944                 break;
1945 
1946             case BASEPROPERTY_HIGHCONTRASTMODE:
1947                 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetHighContrastMode();
1948                 break;
1949 
1950             case BASEPROPERTY_TEXT:
1951             case BASEPROPERTY_LABEL:
1952             case BASEPROPERTY_TITLE:
1953             {
1954                 OUString aText = GetWindow()->GetText();
1955                 aProp <<= aText;
1956             }
1957             break;
1958             case BASEPROPERTY_ACCESSIBLENAME:
1959             {
1960                 OUString aText = GetWindow()->GetAccessibleName();
1961                 aProp <<= aText;
1962             }
1963             break;
1964             case BASEPROPERTY_HELPTEXT:
1965             {
1966                 OUString aText = GetWindow()->GetQuickHelpText();
1967                 aProp <<= aText;
1968             }
1969             break;
1970             case BASEPROPERTY_HELPURL:
1971             {
1972                 OUString aHelpId( OStringToOUString( GetWindow()->GetHelpId(), RTL_TEXTENCODING_UTF8 ) );
1973                 aProp <<= aHelpId;
1974             }
1975             break;
1976             case BASEPROPERTY_FONTDESCRIPTOR:
1977             {
1978                 vcl::Font aFont = GetWindow()->GetControlFont();
1979                 css::awt::FontDescriptor aFD = VCLUnoHelper::CreateFontDescriptor( aFont );
1980                 aProp <<= aFD;
1981             }
1982             break;
1983             case BASEPROPERTY_BACKGROUNDCOLOR:
1984                 aProp <<= GetWindow()->GetControlBackground();
1985             break;
1986             case BASEPROPERTY_DISPLAYBACKGROUNDCOLOR:
1987                 aProp <<= GetWindow()->GetBackgroundColor();
1988             break;
1989             case BASEPROPERTY_FONTRELIEF:
1990                 aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetRelief());
1991             break;
1992             case BASEPROPERTY_FONTEMPHASISMARK:
1993                 aProp <<= static_cast<sal_Int16>(GetWindow()->GetControlFont().GetEmphasisMark());
1994             break;
1995             case BASEPROPERTY_TEXTCOLOR:
1996                 aProp <<= GetWindow()->GetControlForeground();
1997             break;
1998             case BASEPROPERTY_TEXTLINECOLOR:
1999                 aProp <<= GetWindow()->GetTextLineColor();
2000             break;
2001             case BASEPROPERTY_FILLCOLOR:
2002                 aProp <<= GetWindow()->GetFillColor();
2003             break;
2004             case BASEPROPERTY_LINECOLOR:
2005                 aProp <<= GetWindow()->GetLineColor();
2006             break;
2007             case BASEPROPERTY_BORDER:
2008             {
2009                 WindowBorderStyle nBorder = WindowBorderStyle::NONE;
2010                 if ( GetWindow()->GetStyle() & WB_BORDER )
2011                     nBorder = GetWindow()->GetBorderStyle();
2012                 aProp <<= static_cast<sal_uInt16>(nBorder);
2013             }
2014             break;
2015             case BASEPROPERTY_TABSTOP:
2016                 aProp <<= ( GetWindow()->GetStyle() & WB_TABSTOP ) != 0;
2017             break;
2018             case BASEPROPERTY_VERTICALALIGN:
2019             {
2020                 WinBits nStyle = GetWindow()->GetStyle();
2021                 if ( nStyle & WB_TOP )
2022                     aProp <<= VerticalAlignment_TOP;
2023                 else if ( nStyle & WB_VCENTER )
2024                     aProp <<= VerticalAlignment_MIDDLE;
2025                 else if ( nStyle & WB_BOTTOM )
2026                     aProp <<= VerticalAlignment_BOTTOM;
2027             }
2028             break;
2029             case BASEPROPERTY_ALIGN:
2030             {
2031                 switch ( eWinType )
2032                 {
2033                     case WindowType::FIXEDTEXT:
2034                     case WindowType::EDIT:
2035                     case WindowType::MULTILINEEDIT:
2036                     case WindowType::CHECKBOX:
2037                     case WindowType::RADIOBUTTON:
2038                     case WindowType::LISTBOX:
2039                     case WindowType::COMBOBOX:
2040                     case WindowType::PUSHBUTTON:
2041                     case WindowType::OKBUTTON:
2042                     case WindowType::CANCELBUTTON:
2043                     case WindowType::HELPBUTTON:
2044                     {
2045                         WinBits nStyle = GetWindow()->GetStyle();
2046                         if ( nStyle & WB_LEFT )
2047                             aProp <<= sal_Int16(PROPERTY_ALIGN_LEFT);
2048                         else if ( nStyle & WB_CENTER )
2049                             aProp <<= sal_Int16(PROPERTY_ALIGN_CENTER);
2050                         else if ( nStyle & WB_RIGHT )
2051                             aProp <<= sal_Int16(PROPERTY_ALIGN_RIGHT);
2052                     }
2053                     break;
2054                     default: break;
2055                 }
2056             }
2057             break;
2058             case BASEPROPERTY_MULTILINE:
2059             {
2060                 if  (  ( eWinType == WindowType::FIXEDTEXT )
2061                     || ( eWinType == WindowType::CHECKBOX )
2062                     || ( eWinType == WindowType::RADIOBUTTON )
2063                     || ( eWinType == WindowType::PUSHBUTTON )
2064                     || ( eWinType == WindowType::OKBUTTON )
2065                     || ( eWinType == WindowType::CANCELBUTTON )
2066                     || ( eWinType == WindowType::HELPBUTTON )
2067                     )
2068                     aProp <<= ( GetWindow()->GetStyle() & WB_WORDBREAK ) != 0;
2069             }
2070             break;
2071             case BASEPROPERTY_AUTOMNEMONICS:
2072             {
2073                 bool bAutoMnemonics = GetWindow()->GetSettings().GetStyleSettings().GetAutoMnemonic();
2074                 aProp <<= bAutoMnemonics;
2075             }
2076             break;
2077             case BASEPROPERTY_MOUSETRANSPARENT:
2078             {
2079                 bool bMouseTransparent = GetWindow()->IsMouseTransparent();
2080                 aProp <<= bMouseTransparent;
2081             }
2082             break;
2083             case BASEPROPERTY_PAINTTRANSPARENT:
2084             {
2085                 bool bPaintTransparent = GetWindow()->IsPaintTransparent();
2086                 aProp <<= bPaintTransparent;
2087             }
2088             break;
2089 
2090             case BASEPROPERTY_REPEAT:
2091                 aProp <<= ( 0 != ( GetWindow()->GetStyle() & WB_REPEAT ) );
2092                 break;
2093 
2094             case BASEPROPERTY_REPEAT_DELAY:
2095             {
2096                 sal_Int32 nButtonRepeat = GetWindow()->GetSettings().GetMouseSettings().GetButtonRepeat();
2097                 aProp <<= nButtonRepeat;
2098             }
2099             break;
2100 
2101             case BASEPROPERTY_SYMBOL_COLOR:
2102                 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetButtonTextColor();
2103                 break;
2104 
2105             case BASEPROPERTY_BORDERCOLOR:
2106                 aProp <<= GetWindow()->GetSettings().GetStyleSettings().GetMonoColor();
2107                 break;
2108         }
2109     }
2110     return aProp;
2111 }
2112 
2113 
2114 // css::awt::XLayoutConstrains
getMinimumSize()2115 css::awt::Size VCLXWindow::getMinimumSize(  )
2116 {
2117     SolarMutexGuard aGuard;
2118 
2119     // Use this method only for those components which can be created through
2120     // css::awt::Toolkit , but do not have an interface
2121 
2122     Size aSz;
2123     if ( GetWindow() )
2124     {
2125         WindowType nWinType = GetWindow()->GetType();
2126         switch ( nWinType )
2127         {
2128             case WindowType::CONTROL:
2129                 aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*12 );
2130                 aSz.setHeight( GetWindow()->GetTextHeight()+2*6 );
2131             break;
2132 
2133             case WindowType::PATTERNBOX:
2134             case WindowType::NUMERICBOX:
2135             case WindowType::METRICBOX:
2136             case WindowType::CURRENCYBOX:
2137             case WindowType::DATEBOX:
2138             case WindowType::TIMEBOX:
2139             case WindowType::LONGCURRENCYBOX:
2140                 aSz.setWidth( GetWindow()->GetTextWidth( GetWindow()->GetText() )+2*2 );
2141                 aSz.setHeight( GetWindow()->GetTextHeight()+2*2 );
2142             break;
2143             case WindowType::SCROLLBARBOX:
2144                 return VCLXScrollBar::implGetMinimumSize( GetWindow() );
2145             default:
2146                 aSz = GetWindow()->get_preferred_size();
2147         }
2148     }
2149 
2150     return css::awt::Size( aSz.Width(), aSz.Height() );
2151 }
2152 
getPreferredSize()2153 css::awt::Size VCLXWindow::getPreferredSize(  )
2154 {
2155     return getMinimumSize();
2156 }
2157 
calcAdjustedSize(const css::awt::Size & rNewSize)2158 css::awt::Size VCLXWindow::calcAdjustedSize( const css::awt::Size& rNewSize )
2159 {
2160     SolarMutexGuard aGuard;
2161 
2162     css::awt::Size aNewSize( rNewSize );
2163     css::awt::Size aMinSize = getMinimumSize();
2164 
2165     if ( aNewSize.Width < aMinSize.Width )
2166         aNewSize.Width = aMinSize.Width;
2167     if ( aNewSize.Height < aMinSize.Height )
2168         aNewSize.Height = aMinSize.Height;
2169 
2170     return aNewSize;
2171 }
2172 
2173 
2174 // css::awt::XView
setGraphics(const css::uno::Reference<css::awt::XGraphics> & rxDevice)2175 sal_Bool VCLXWindow::setGraphics( const css::uno::Reference< css::awt::XGraphics >& rxDevice )
2176 {
2177     SolarMutexGuard aGuard;
2178 
2179     if ( VCLUnoHelper::GetOutputDevice( rxDevice ) )
2180         mpImpl->mxViewGraphics = rxDevice;
2181     else
2182         mpImpl->mxViewGraphics = nullptr;
2183 
2184     return mpImpl->mxViewGraphics.is();
2185 }
2186 
getGraphics()2187 css::uno::Reference< css::awt::XGraphics > VCLXWindow::getGraphics(  )
2188 {
2189     SolarMutexGuard aGuard;
2190 
2191     return mpImpl->mxViewGraphics;
2192 }
2193 
getSize()2194 css::awt::Size VCLXWindow::getSize(  )
2195 {
2196     SolarMutexGuard aGuard;
2197 
2198     Size aSz;
2199     if ( GetWindow() )
2200         aSz = GetWindow()->GetSizePixel();
2201     return css::awt::Size( aSz.Width(), aSz.Height() );
2202 }
2203 
draw(sal_Int32 nX,sal_Int32 nY)2204 void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY )
2205 {
2206     SolarMutexGuard aGuard;
2207 
2208     VclPtr<vcl::Window> pWindow = GetWindow();
2209     if ( !pWindow )
2210         return;
2211 
2212     if ( isDesignMode() || mpImpl->isEnableVisible() )
2213     {
2214         OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( mpImpl->mxViewGraphics );
2215         if (!pDev)
2216             pDev = pWindow->GetParent();
2217         TabPage* pTabPage = dynamic_cast< TabPage* >( pWindow.get() );
2218         if ( pTabPage )
2219         {
2220             Point aPos( nX, nY );
2221             Size  aSize = pWindow->GetSizePixel();
2222 
2223             aPos  = pDev->PixelToLogic( aPos );
2224             aSize = pDev->PixelToLogic( aSize );
2225 
2226             pTabPage->Draw( pDev, aPos, aSize, DrawFlags::NONE );
2227             return;
2228         }
2229 
2230         Point aPos( nX, nY );
2231 
2232         if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent() == pDev ) )
2233         {
2234             // #i40647# don't draw here if this is a recursive call
2235             // sometimes this is called recursively, because the Update call on the parent
2236             // (strangely) triggers another paint. Prevent a stack overflow here
2237             // Yes, this is only fixing symptoms for the moment...
2238             // #i40647# / 2005-01-18 / frank.schoenheit@sun.com
2239             if ( !mpImpl->getDrawingOntoParent_ref() )
2240             {
2241                 ::comphelper::FlagGuard aDrawingflagGuard( mpImpl->getDrawingOntoParent_ref() );
2242 
2243                 bool bWasVisible = pWindow->IsVisible();
2244                 Point aOldPos( pWindow->GetPosPixel() );
2245 
2246                 if ( bWasVisible && aOldPos == aPos )
2247                 {
2248                     pWindow->Update();
2249                     return;
2250                 }
2251 
2252                 pWindow->SetPosPixel( aPos );
2253 
2254                 // Update parent first to avoid painting the parent upon the update
2255                 // of this window, as it may otherwise cause the parent
2256                 // to hide this window again
2257                 if( pWindow->GetParent() )
2258                     pWindow->GetParent()->Update();
2259 
2260                 pWindow->Show();
2261                 pWindow->Update();
2262                 pWindow->SetParentUpdateMode( false );
2263                 pWindow->Hide();
2264                 pWindow->SetParentUpdateMode( true );
2265 
2266                 pWindow->SetPosPixel( aOldPos );
2267                 if ( bWasVisible )
2268                     pWindow->Show();
2269             }
2270         }
2271         else if ( pDev )
2272         {
2273             Size aSz = pWindow->GetSizePixel();
2274             aSz = pDev->PixelToLogic( aSz );
2275             Point aP = pDev->PixelToLogic( aPos );
2276 
2277             vcl::PDFExtOutDevData* pPDFExport   = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
2278             bool bDrawSimple =    ( pDev->GetOutDevType() == OUTDEV_PRINTER )
2279                                || ( pDev->GetOutDevViewType() == OutDevViewType::PrintPreview )
2280                                || ( pPDFExport != nullptr );
2281             if ( bDrawSimple )
2282             {
2283                 pWindow->Draw( pDev, aP, aSz, DrawFlags::NoControls );
2284             }
2285             else
2286             {
2287                 bool bOldNW =pWindow->IsNativeWidgetEnabled();
2288                 if( bOldNW )
2289                     pWindow->EnableNativeWidget(false);
2290                 pWindow->PaintToDevice( pDev, aP, aSz );
2291                 if( bOldNW )
2292                     pWindow->EnableNativeWidget();
2293             }
2294         }
2295     }
2296 }
2297 
setZoom(float fZoomX,float)2298 void VCLXWindow::setZoom( float fZoomX, float /*fZoomY*/ )
2299 {
2300     SolarMutexGuard aGuard;
2301 
2302     if ( GetWindow() )
2303     {
2304         // Fraction::Fraction takes a double, but we have a float only.
2305         // The implicit conversion from float to double can result in a precision loss, i.e. 1.2 is converted to
2306         // 1.200000000047something. To prevent this, we convert explicitly to double, and round it.
2307         double nZoom( fZoomX );
2308         Fraction aZoom(::rtl::math::round(nZoom, 4));
2309         aZoom.ReduceInaccurate(10); // to avoid runovers and BigInt mapping
2310         GetWindow()->SetZoom(aZoom);
2311     }
2312 }
2313 
2314 // css::lang::XEventListener
disposing(const css::lang::EventObject & _rSource)2315 void SAL_CALL VCLXWindow::disposing( const css::lang::EventObject& _rSource )
2316 {
2317     SolarMutexGuard aGuard;
2318 
2319     // check if it comes from our AccessibleContext
2320     uno::Reference< uno::XInterface > aAC( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
2321     uno::Reference< uno::XInterface > xSource( _rSource.Source, uno::UNO_QUERY );
2322 
2323     if ( aAC.get() == xSource.get() )
2324     {   // yep, it does
2325         mpImpl->mxAccessibleContext.clear();
2326     }
2327 }
2328 
2329 // css::accessibility::XAccessible
getAccessibleContext()2330 css::uno::Reference< css::accessibility::XAccessibleContext > VCLXWindow::getAccessibleContext(  )
2331 {
2332     SolarMutexGuard aGuard;
2333 
2334     // already disposed
2335     if( ! mpImpl )
2336         return uno::Reference< accessibility::XAccessibleContext >();
2337 
2338     if ( !mpImpl->mxAccessibleContext.is() && GetWindow() )
2339     {
2340         mpImpl->mxAccessibleContext = CreateAccessibleContext();
2341 
2342         // add as event listener to this component
2343         // in case somebody disposes it, we do not want to have a (though weak) reference to a dead
2344         // object
2345         uno::Reference< lang::XComponent > xComp( mpImpl->mxAccessibleContext, uno::UNO_QUERY );
2346         if ( xComp.is() )
2347             xComp->addEventListener( this );
2348     }
2349 
2350     return mpImpl->mxAccessibleContext;
2351 }
2352 
2353 // css::awt::XDockable
addDockableWindowListener(const css::uno::Reference<css::awt::XDockableWindowListener> & xListener)2354 void SAL_CALL VCLXWindow::addDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener )
2355 {
2356     SolarMutexGuard aGuard;
2357 
2358     if ( xListener.is() )
2359         mpImpl->getDockableWindowListeners().addInterface( xListener );
2360 
2361 }
2362 
removeDockableWindowListener(const css::uno::Reference<css::awt::XDockableWindowListener> & xListener)2363 void SAL_CALL VCLXWindow::removeDockableWindowListener( const css::uno::Reference< css::awt::XDockableWindowListener >& xListener )
2364 {
2365     SolarMutexGuard aGuard;
2366 
2367     mpImpl->getDockableWindowListeners().removeInterface( xListener );
2368 }
2369 
enableDocking(sal_Bool bEnable)2370 void SAL_CALL VCLXWindow::enableDocking( sal_Bool bEnable )
2371 {
2372     SolarMutexGuard aGuard;
2373 
2374     VclPtr<vcl::Window> pWindow = GetWindow();
2375     if ( pWindow )
2376         pWindow->EnableDocking( bEnable );
2377 }
2378 
isFloating()2379 sal_Bool SAL_CALL VCLXWindow::isFloating(  )
2380 {
2381     SolarMutexGuard aGuard;
2382 
2383     VclPtr<vcl::Window> pWindow = GetWindow();
2384     if( pWindow )
2385         return vcl::Window::GetDockingManager()->IsFloating( pWindow );
2386     else
2387         return false;
2388 }
2389 
setFloatingMode(sal_Bool bFloating)2390 void SAL_CALL VCLXWindow::setFloatingMode( sal_Bool bFloating )
2391 {
2392     SolarMutexGuard aGuard;
2393 
2394     VclPtr<vcl::Window> pWindow = GetWindow();
2395     if( pWindow )
2396         vcl::Window::GetDockingManager()->SetFloatingMode( pWindow, bFloating );
2397 }
2398 
isLocked()2399 sal_Bool SAL_CALL VCLXWindow::isLocked(  )
2400 {
2401     SolarMutexGuard aGuard;
2402 
2403     VclPtr<vcl::Window> pWindow = GetWindow();
2404     if( pWindow )
2405         return vcl::Window::GetDockingManager()->IsLocked( pWindow );
2406     else
2407         return false;
2408 }
2409 
lock()2410 void SAL_CALL VCLXWindow::lock(  )
2411 {
2412     SolarMutexGuard aGuard;
2413 
2414     VclPtr<vcl::Window> pWindow = GetWindow();
2415     if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) )
2416         vcl::Window::GetDockingManager()->Lock( pWindow );
2417 }
2418 
unlock()2419 void SAL_CALL VCLXWindow::unlock(  )
2420 {
2421     SolarMutexGuard aGuard;
2422 
2423     VclPtr<vcl::Window> pWindow = GetWindow();
2424     if( pWindow && !vcl::Window::GetDockingManager()->IsFloating( pWindow ) )
2425         vcl::Window::GetDockingManager()->Unlock( pWindow );
2426 }
2427 
startPopupMode(const css::awt::Rectangle &)2428 void SAL_CALL VCLXWindow::startPopupMode( const css::awt::Rectangle& )
2429 {
2430     // TODO: remove interface in the next incompatible build
2431 }
2432 
isInPopupMode()2433 sal_Bool SAL_CALL VCLXWindow::isInPopupMode(  )
2434 {
2435     // TODO: remove interface in the next incompatible build
2436     return false;
2437 }
2438 
2439 
2440 // css::awt::XWindow2
2441 
setOutputSize(const css::awt::Size & aSize)2442 void SAL_CALL VCLXWindow::setOutputSize( const css::awt::Size& aSize )
2443 {
2444     SolarMutexGuard aGuard;
2445     VclPtr<vcl::Window> pWindow;
2446     if( (pWindow = GetWindow()) != nullptr )
2447     {
2448         DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >(pWindow.get());
2449         if( pDockingWindow )
2450             pDockingWindow->SetOutputSizePixel( VCLSize( aSize ) );
2451         else
2452             pWindow->SetOutputSizePixel( VCLSize( aSize ) );
2453     }
2454 }
2455 
getOutputSize()2456 css::awt::Size SAL_CALL VCLXWindow::getOutputSize(  )
2457 {
2458     SolarMutexGuard aGuard;
2459     VclPtr<vcl::Window> pWindow;
2460     if( (pWindow = GetWindow()) != nullptr )
2461     {
2462         DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >(pWindow.get());
2463         if( pDockingWindow )
2464             return AWTSize( pDockingWindow->GetOutputSizePixel() );
2465         else
2466             return AWTSize( pWindow->GetOutputSizePixel() );
2467     }
2468     else
2469         return css::awt::Size();
2470 }
2471 
isVisible()2472 sal_Bool SAL_CALL VCLXWindow::isVisible(  )
2473 {
2474     SolarMutexGuard aGuard;
2475     if( GetWindow() )
2476         return GetWindow()->IsVisible();
2477     else
2478         return false;
2479 }
2480 
isActive()2481 sal_Bool SAL_CALL VCLXWindow::isActive(  )
2482 {
2483     SolarMutexGuard aGuard;
2484     if( GetWindow() )
2485         return GetWindow()->IsActive();
2486     else
2487         return false;
2488 
2489 }
2490 
isEnabled()2491 sal_Bool SAL_CALL VCLXWindow::isEnabled(  )
2492 {
2493     SolarMutexGuard aGuard;
2494     if( GetWindow() )
2495         return GetWindow()->IsEnabled();
2496     else
2497         return false;
2498 }
2499 
hasFocus()2500 sal_Bool SAL_CALL VCLXWindow::hasFocus(  )
2501 {
2502     SolarMutexGuard aGuard;
2503     if( GetWindow() )
2504         return GetWindow()->HasFocus();
2505     else
2506         return false;
2507 }
2508 
2509 // css::beans::XPropertySetInfo
2510 
2511 UnoPropertyArrayHelper *
GetPropHelper()2512 VCLXWindow::GetPropHelper()
2513 {
2514     SolarMutexGuard aGuard;
2515     if ( mpImpl->mpPropHelper == nullptr )
2516     {
2517         std::vector< sal_uInt16 > aIDs;
2518         GetPropertyIds( aIDs );
2519         mpImpl->mpPropHelper.reset( new UnoPropertyArrayHelper( aIDs ) );
2520     }
2521     return mpImpl->mpPropHelper.get();
2522 }
2523 
2524 css::uno::Sequence< css::beans::Property > SAL_CALL
getProperties()2525 VCLXWindow::getProperties()
2526 {
2527     return GetPropHelper()->getProperties();
2528 }
2529 css::beans::Property SAL_CALL
getPropertyByName(const OUString & rName)2530 VCLXWindow::getPropertyByName( const OUString& rName )
2531 {
2532     return GetPropHelper()->getPropertyByName( rName );
2533 }
2534 
2535 sal_Bool SAL_CALL
hasPropertyByName(const OUString & rName)2536 VCLXWindow::hasPropertyByName( const OUString& rName )
2537 {
2538     return GetPropHelper()->hasPropertyByName( rName );
2539 }
2540 
getStyleSettings()2541 Reference< XStyleSettings > SAL_CALL VCLXWindow::getStyleSettings()
2542 {
2543     return mpImpl->getStyleSettings();
2544 }
2545 
2546 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2547