1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "basecontrol.hxx"
22 #include <com/sun/star/awt/XDevice.hpp>
23 #include <com/sun/star/awt/XDisplayBitmap.hpp>
24 #include <com/sun/star/awt/DeviceInfo.hpp>
25 #include <com/sun/star/awt/WindowAttribute.hpp>
26 #include <com/sun/star/awt/PosSize.hpp>
27 #include <com/sun/star/awt/Toolkit.hpp>
28 #include <comphelper/processfactory.hxx>
29 #include <cppuhelper/supportsservice.hxx>
30 #include <cppuhelper/queryinterface.hxx>
31 #include <cppuhelper/typeprovider.hxx>
35 using namespace ::cppu
;
36 using namespace ::osl
;
37 using namespace ::com::sun::star::uno
;
38 using namespace ::com::sun::star::lang
;
39 using namespace ::com::sun::star::awt
;
41 namespace unocontrols
{
43 #define DEFAULT_PMULTIPLEXER NULL
46 #define DEFAULT_WIDTH 100
47 #define DEFAULT_HEIGHT 100
48 #define DEFAULT_VISIBLE false
49 #define DEFAULT_INDESIGNMODE false
50 #define DEFAULT_ENABLE true
54 BaseControl::BaseControl( const Reference
< XComponentContext
>& rxContext
)
55 : IMPL_MutexContainer ( )
56 , OComponentHelper ( m_aMutex
)
57 , m_xComponentContext ( rxContext
)
58 , m_pMultiplexer ( DEFAULT_PMULTIPLEXER
)
61 , m_nWidth ( DEFAULT_WIDTH
)
62 , m_nHeight ( DEFAULT_HEIGHT
)
63 , m_bVisible ( DEFAULT_VISIBLE
)
64 , m_bInDesignMode ( DEFAULT_INDESIGNMODE
)
65 , m_bEnable ( DEFAULT_ENABLE
)
69 BaseControl::~BaseControl()
75 Any SAL_CALL
BaseControl::queryInterface( const Type
& rType
) throw( RuntimeException
, std::exception
)
78 if ( m_xDelegator
.is() )
80 // If an delegator exist, forward question to his queryInterface.
81 // Delegator will ask his own queryAggregation!
82 aReturn
= m_xDelegator
->queryInterface( rType
);
86 // If an delegator unknown, forward question to own queryAggregation.
87 aReturn
= queryAggregation( rType
);
95 void SAL_CALL
BaseControl::acquire() throw()
98 // Don't use mutex or guard in this method!!! Is a method of XInterface.
100 // Forward to baseclass
101 OComponentHelper::acquire();
106 void SAL_CALL
BaseControl::release() throw()
109 // Don't use mutex or guard in this method!!! Is a method of XInterface.
111 // Forward to baseclass
112 OComponentHelper::release();
117 Sequence
< Type
> SAL_CALL
BaseControl::getTypes() throw( RuntimeException
, std::exception
)
119 // Optimize this method !
120 // We initialize a static variable only one time. And we don't must use a mutex at every call!
121 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
122 static OTypeCollection
* pTypeCollection
= NULL
;
124 if ( pTypeCollection
== NULL
)
126 // Ready for multithreading; get global mutex for first call of this method only! see before
127 MutexGuard
aGuard( Mutex::getGlobalMutex() );
129 // Control these pointer again ... it can be, that another instance will be faster then these!
130 if ( pTypeCollection
== NULL
)
132 // Create a static typecollection ...
133 static OTypeCollection
aTypeCollection( cppu::UnoType
<XPaintListener
>::get(),
134 cppu::UnoType
<XWindowListener
>::get(),
135 cppu::UnoType
<XView
>::get(),
136 cppu::UnoType
<XWindow
>::get(),
137 cppu::UnoType
<XServiceInfo
>::get(),
138 cppu::UnoType
<XControl
>::get(),
139 OComponentHelper::getTypes()
142 // ... and set his address to static pointer!
143 pTypeCollection
= &aTypeCollection
;
147 return pTypeCollection
->getTypes();
152 Sequence
< sal_Int8
> SAL_CALL
BaseControl::getImplementationId() throw( RuntimeException
, std::exception
)
154 return css::uno::Sequence
<sal_Int8
>();
159 void SAL_CALL
BaseControl::setDelegator( const Reference
< XInterface
>& xDel
) throw( RuntimeException
, std::exception
)
161 // Ready for multithreading
162 MutexGuard
aGuard( m_aMutex
);
168 Any SAL_CALL
BaseControl::queryAggregation( const Type
& aType
) throw( RuntimeException
, std::exception
)
170 // Ask for my own supported interfaces ...
171 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
172 Any
aReturn ( ::cppu::queryInterface( aType
,
173 static_cast< XPaintListener
*> ( this ) ,
174 static_cast< XWindowListener
*> ( this ) ,
175 static_cast< XView
* > ( this ) ,
176 static_cast< XWindow
* > ( this ) ,
177 static_cast< XServiceInfo
* > ( this ) ,
178 static_cast< XControl
* > ( this )
182 // If searched interface supported by this class ...
183 if ( aReturn
.hasValue() )
185 // ... return this information.
190 // Else; ... ask baseclass for interfaces!
191 return OComponentHelper::queryAggregation( aType
);
197 OUString SAL_CALL
BaseControl::getImplementationName() throw( RuntimeException
, std::exception
)
199 return impl_getStaticImplementationName();
204 sal_Bool SAL_CALL
BaseControl::supportsService( const OUString
& sServiceName
) throw( RuntimeException
, std::exception
)
206 return cppu::supportsService(this, sServiceName
);
211 Sequence
< OUString
> SAL_CALL
BaseControl::getSupportedServiceNames() throw( RuntimeException
, std::exception
)
213 return impl_getStaticSupportedServiceNames();
218 void SAL_CALL
BaseControl::dispose() throw( RuntimeException
, std::exception
)
220 // Ready for multithreading
221 MutexGuard
aGuard( m_aMutex
);
223 if ( m_pMultiplexer
!= NULL
)
225 // to all other paint, focus, etc.
226 m_pMultiplexer
->disposeAndClear();
229 // set the service manager to disposed
230 OComponentHelper::dispose();
232 // release context and peer
237 if ( m_xGraphicsView
.is() )
239 m_xGraphicsView
.clear();
245 void SAL_CALL
BaseControl::addEventListener( const Reference
< XEventListener
>& xListener
) throw( RuntimeException
, std::exception
)
247 // Ready for multithreading
248 MutexGuard
aGuard( m_aMutex
);
249 OComponentHelper::addEventListener( xListener
);
254 void SAL_CALL
BaseControl::removeEventListener( const Reference
< XEventListener
>& xListener
) throw( RuntimeException
, std::exception
)
256 // Ready for multithreading
257 MutexGuard
aGuard( m_aMutex
);
258 OComponentHelper::removeEventListener( xListener
);
263 void SAL_CALL
BaseControl::createPeer( const Reference
< XToolkit
>& xToolkit
,
264 const Reference
< XWindowPeer
>& xParentPeer
) throw( RuntimeException
, std::exception
)
266 // Ready for multithreading
267 MutexGuard
aGuard( m_aMutex
);
271 // use method "BaseControl::getWindowDescriptor()" fot change window attributes !!!
272 WindowDescriptor
* pDescriptor
= impl_getWindowDescriptor( xParentPeer
);
276 pDescriptor
->WindowAttributes
|= WindowAttribute::SHOW
;
279 // very slow under remote conditions!
280 // create the window on the server
281 Reference
< XToolkit
> xLocalToolkit
= xToolkit
;
282 if ( !xLocalToolkit
.is() )
284 // but first create well known toolkit, if it not exist
285 xLocalToolkit
= Reference
< XToolkit
> ( Toolkit::create(m_xComponentContext
), UNO_QUERY_THROW
);
287 m_xPeer
= xLocalToolkit
->createWindow( *pDescriptor
);
288 m_xPeerWindow
= Reference
< XWindow
>( m_xPeer
, UNO_QUERY
);
290 // don't forget to release the memory!
293 if ( m_xPeerWindow
.is() )
295 if ( m_pMultiplexer
!= NULL
)
297 m_pMultiplexer
->setPeer( m_xPeerWindow
);
300 // create new referenz to xgraphics for painting on a peer
301 // and add a paint listener
302 Reference
< XDevice
> xDevice( m_xPeerWindow
, UNO_QUERY
);
306 m_xGraphicsPeer
= xDevice
->createGraphics();
309 if ( m_xGraphicsPeer
.is() )
311 addPaintListener( this );
312 addWindowListener( this );
315 m_xPeerWindow
->setPosSize( m_nX
, m_nY
, m_nWidth
, m_nHeight
, PosSize::POSSIZE
);
316 m_xPeerWindow
->setEnable( m_bEnable
);
317 m_xPeerWindow
->setVisible( m_bVisible
&& !m_bInDesignMode
);
324 void SAL_CALL
BaseControl::setContext( const Reference
< XInterface
>& xContext
) throw( RuntimeException
, std::exception
)
326 // Ready for multithreading
327 MutexGuard
aGuard( m_aMutex
);
328 m_xContext
= xContext
;
333 void SAL_CALL
BaseControl::setDesignMode( sal_Bool bOn
) throw( RuntimeException
, std::exception
)
335 // Ready for multithreading
336 MutexGuard
aGuard( m_aMutex
);
337 m_bInDesignMode
= bOn
;
342 Reference
< XInterface
> SAL_CALL
BaseControl::getContext() throw( RuntimeException
, std::exception
)
344 // Ready for multithreading
345 MutexGuard
aGuard( m_aMutex
);
351 Reference
< XWindowPeer
> SAL_CALL
BaseControl::getPeer() throw( RuntimeException
, std::exception
)
353 // Ready for multithreading
354 MutexGuard
aGuard( m_aMutex
);
360 Reference
< XView
> SAL_CALL
BaseControl::getView() throw( RuntimeException
, std::exception
)
362 // Ready for multithreading
363 MutexGuard
aGuard( m_aMutex
);
364 return Reference
< XView
>( (OWeakObject
*)this, UNO_QUERY
);
369 sal_Bool SAL_CALL
BaseControl::isDesignMode() throw( RuntimeException
, std::exception
)
371 // Ready for multithreading
372 MutexGuard
aGuard( m_aMutex
);
373 return m_bInDesignMode
;
378 sal_Bool SAL_CALL
BaseControl::isTransparent() throw( RuntimeException
, std::exception
)
385 void SAL_CALL
BaseControl::setPosSize( sal_Int32 nX
,
389 sal_Int16 nFlags
) throw( RuntimeException
, std::exception
)
391 // - change size and position of window and save the values
393 // Ready for multithreading
394 MutexGuard
aGuard( m_aMutex
);
396 bool bChanged
= false;
398 if ( nFlags
& PosSize::X
)
400 bChanged
|= m_nX
!= nX
, m_nX
= nX
;
403 if ( nFlags
& PosSize::Y
)
405 bChanged
|= m_nY
!= nY
, m_nY
= nY
;
408 if ( nFlags
& PosSize::WIDTH
)
410 bChanged
|= m_nWidth
!= nWidth
, m_nWidth
= nWidth
;
413 if ( nFlags
& PosSize::HEIGHT
)
415 bChanged
|= m_nHeight
!= nHeight
, m_nHeight
= nHeight
;
418 if ( bChanged
&& m_xPeerWindow
.is() )
420 m_xPeerWindow
->setPosSize( m_nX
, m_nY
, m_nWidth
, m_nHeight
, nFlags
);
426 void SAL_CALL
BaseControl::setVisible( sal_Bool bVisible
) throw( RuntimeException
, std::exception
)
428 // Ready for multithreading
429 MutexGuard
aGuard( m_aMutex
);
431 // Set new state of flag
432 m_bVisible
= bVisible
;
434 if ( m_xPeerWindow
.is() )
436 // Set it also on peerwindow
437 m_xPeerWindow
->setVisible( m_bVisible
);
443 void SAL_CALL
BaseControl::setEnable( sal_Bool bEnable
) throw( RuntimeException
, std::exception
)
445 // Ready for multithreading
446 MutexGuard
aGuard( m_aMutex
);
448 // Set new state of flag
451 if ( m_xPeerWindow
.is() )
453 // Set it also on peerwindow
454 m_xPeerWindow
->setEnable( m_bEnable
);
460 void SAL_CALL
BaseControl::setFocus() throw( RuntimeException
, std::exception
)
462 // Ready for multithreading
463 MutexGuard
aGuard( m_aMutex
);
465 if ( m_xPeerWindow
.is() )
467 m_xPeerWindow
->setFocus();
473 Rectangle SAL_CALL
BaseControl::getPosSize() throw( RuntimeException
, std::exception
)
475 // Ready for multithreading
476 MutexGuard
aGuard( m_aMutex
);
477 return Rectangle( m_nX
, m_nY
, m_nWidth
, m_nHeight
);
482 void SAL_CALL
BaseControl::addWindowListener( const Reference
< XWindowListener
>& xListener
) throw( RuntimeException
, std::exception
)
484 impl_getMultiplexer()->advise( cppu::UnoType
<XWindowListener
>::get(), xListener
);
489 void SAL_CALL
BaseControl::addFocusListener( const Reference
< XFocusListener
>& xListener
) throw( RuntimeException
, std::exception
)
491 impl_getMultiplexer()->advise( cppu::UnoType
<XFocusListener
>::get(), xListener
);
496 void SAL_CALL
BaseControl::addKeyListener( const Reference
< XKeyListener
>& xListener
) throw( RuntimeException
, std::exception
)
498 impl_getMultiplexer()->advise( cppu::UnoType
<XKeyListener
>::get(), xListener
);
503 void SAL_CALL
BaseControl::addMouseListener( const Reference
< XMouseListener
>& xListener
) throw( RuntimeException
, std::exception
)
505 impl_getMultiplexer()->advise( cppu::UnoType
<XMouseListener
>::get(), xListener
);
510 void SAL_CALL
BaseControl::addMouseMotionListener( const Reference
< XMouseMotionListener
>& xListener
) throw( RuntimeException
, std::exception
)
512 impl_getMultiplexer()->advise( cppu::UnoType
<XMouseMotionListener
>::get(), xListener
);
517 void SAL_CALL
BaseControl::addPaintListener( const Reference
< XPaintListener
>& xListener
) throw( RuntimeException
, std::exception
)
519 impl_getMultiplexer()->advise( cppu::UnoType
<XPaintListener
>::get(), xListener
);
524 void SAL_CALL
BaseControl::removeWindowListener( const Reference
< XWindowListener
>& xListener
) throw( RuntimeException
, std::exception
)
526 impl_getMultiplexer()->unadvise( cppu::UnoType
<XWindowListener
>::get(), xListener
);
531 void SAL_CALL
BaseControl::removeFocusListener( const Reference
< XFocusListener
>& xListener
) throw( RuntimeException
, std::exception
)
533 impl_getMultiplexer()->unadvise( cppu::UnoType
<XFocusListener
>::get(), xListener
);
538 void SAL_CALL
BaseControl::removeKeyListener( const Reference
< XKeyListener
>& xListener
) throw( RuntimeException
, std::exception
)
540 impl_getMultiplexer()->unadvise( cppu::UnoType
<XKeyListener
>::get(), xListener
);
545 void SAL_CALL
BaseControl::removeMouseListener( const Reference
< XMouseListener
>& xListener
) throw( RuntimeException
, std::exception
)
547 impl_getMultiplexer()->unadvise( cppu::UnoType
<XMouseListener
>::get(), xListener
);
552 void SAL_CALL
BaseControl::removeMouseMotionListener( const Reference
< XMouseMotionListener
>& xListener
) throw( RuntimeException
, std::exception
)
554 impl_getMultiplexer()->unadvise( cppu::UnoType
<XMouseMotionListener
>::get(), xListener
);
559 void SAL_CALL
BaseControl::removePaintListener( const Reference
< XPaintListener
>& xListener
) throw( RuntimeException
, std::exception
)
561 impl_getMultiplexer()->unadvise( cppu::UnoType
<XPaintListener
>::get(), xListener
);
566 void SAL_CALL
BaseControl::draw( sal_Int32 nX
,
567 sal_Int32 nY
) throw( RuntimeException
, std::exception
)
569 // Ready for multithreading
570 MutexGuard
aGuard( m_aMutex
);
572 // - paint to an view
573 // - use the method "paint()"
574 // - see also "windowPaint()"
575 impl_paint( nX
, nY
, m_xGraphicsView
);
580 sal_Bool SAL_CALL
BaseControl::setGraphics( const Reference
< XGraphics
>& xDevice
) throw( RuntimeException
, std::exception
)
582 // - set the graphics for an view
583 // - in this class exist 2 graphics-member ... one for peer[_xGraphicsPeer] and one for view[_xGraphicsView]
584 // - they are used by "windowPaint() and draw()", forwarded to "paint ()"
585 bool bReturn
= false;
588 // Ready for multithreading
589 MutexGuard
aGuard( m_aMutex
);
591 m_xGraphicsView
= xDevice
;
600 void SAL_CALL
BaseControl::setZoom( float /*fZoomX*/ ,
601 float /*fZoomY*/ ) throw( RuntimeException
, std::exception
)
603 // Not implemented yet
608 Reference
< XGraphics
> SAL_CALL
BaseControl::getGraphics() throw( RuntimeException
, std::exception
)
610 // Ready for multithreading
611 MutexGuard
aGuard( m_aMutex
);
612 return m_xGraphicsView
;
617 Size SAL_CALL
BaseControl::getSize() throw( RuntimeException
, std::exception
)
619 // Ready for multithreading
620 MutexGuard
aGuard( m_aMutex
);
621 return Size( m_nWidth
, m_nHeight
);
626 void SAL_CALL
BaseControl::disposing( const EventObject
& /*aSource*/ ) throw( RuntimeException
, std::exception
)
628 // Ready for multithreading
629 MutexGuard
aGuard( m_aMutex
);
631 // - release ALL references
633 if ( m_xGraphicsPeer
.is() )
635 removePaintListener( this );
636 removeWindowListener( this );
637 m_xGraphicsPeer
.clear();
640 if ( m_xGraphicsView
.is() )
642 m_xGraphicsView
.clear();
648 void SAL_CALL
BaseControl::windowPaint( const PaintEvent
& /*aEvent*/ ) throw( RuntimeException
, std::exception
)
650 // Ready for multithreading
651 MutexGuard
aGuard( m_aMutex
);
653 // - repaint the peer
654 // - use the method "paint ()" for painting on a peer and a print device !!!
655 // - see also "draw ()"
656 impl_paint( 0, 0, m_xGraphicsPeer
);
661 void SAL_CALL
BaseControl::windowResized( const WindowEvent
& aEvent
) throw( RuntimeException
, std::exception
)
663 // Ready for multithreading
664 MutexGuard
aGuard( m_aMutex
);
666 m_nWidth
= aEvent
.Width
;
667 m_nHeight
= aEvent
.Height
;
668 WindowEvent aMappedEvent
= aEvent
;
671 impl_recalcLayout( aMappedEvent
);
676 void SAL_CALL
BaseControl::windowMoved( const WindowEvent
& aEvent
) throw( RuntimeException
, std::exception
)
678 // Ready for multithreading
679 MutexGuard
aGuard( m_aMutex
);
681 m_nWidth
= aEvent
.Width
;
682 m_nHeight
= aEvent
.Height
;
683 WindowEvent aMappedEvent
= aEvent
;
686 impl_recalcLayout( aMappedEvent
);
691 void SAL_CALL
BaseControl::windowShown( const EventObject
& /*aEvent*/ ) throw( RuntimeException
, std::exception
)
697 void SAL_CALL
BaseControl::windowHidden( const EventObject
& /*aEvent*/ ) throw( RuntimeException
, std::exception
)
701 // impl but public method to register service in DLL
702 // (In this BASE-implementation not implemented! Overwrite it in derived classes.)
704 const Sequence
< OUString
> BaseControl::impl_getStaticSupportedServiceNames()
706 return Sequence
< OUString
>();
709 // impl but public method to register service in DLL
710 // (In this BASE-implementation not implemented! Overwrite it in derived classes.)
712 const OUString
BaseControl::impl_getStaticImplementationName()
719 WindowDescriptor
* BaseControl::impl_getWindowDescriptor( const Reference
< XWindowPeer
>& xParentPeer
)
721 // - used from "createPeer()" to set the values of an ::com::sun::star::awt::WindowDescriptor !!!
722 // - if you will change the descriptor-values, you must override this virtuell function
723 // - the caller must release the memory for this dynamical descriptor !!!
725 WindowDescriptor
* pDescriptor
= new WindowDescriptor
;
727 pDescriptor
->Type
= WindowClass_SIMPLE
;
728 pDescriptor
->WindowServiceName
= "window";
729 pDescriptor
->ParentIndex
= -1;
730 pDescriptor
->Parent
= xParentPeer
;
731 pDescriptor
->Bounds
= getPosSize ();
732 pDescriptor
->WindowAttributes
= 0;
739 void BaseControl::impl_paint( sal_Int32
/*nX*/ ,
741 const Reference
< XGraphics
>& /*xGraphics*/ )
743 // - one paint method for peer AND view !!!
744 // (see also => "windowPaint()" and "draw()")
745 // - not used in this implementation, but its not necessary to make it pure virtual !!!
750 void BaseControl::impl_recalcLayout( const WindowEvent
& /*aEvent*/ )
752 // We need as virtual function to support automatically resizing of derived controls!
753 // But we make it not pure virtual because it's not necessary for all derived classes!
761 void BaseControl::impl_releasePeer()
765 if ( m_xGraphicsPeer
.is() )
767 removePaintListener( this );
768 removeWindowListener( this );
769 m_xGraphicsPeer
.clear();
773 m_xPeerWindow
.clear();
776 if ( m_pMultiplexer
!= NULL
)
778 // take changes on multiplexer
779 m_pMultiplexer
->setPeer( Reference
< XWindow
>() );
786 OMRCListenerMultiplexerHelper
* BaseControl::impl_getMultiplexer()
788 if ( m_pMultiplexer
== NULL
)
790 m_pMultiplexer
= new OMRCListenerMultiplexerHelper( (XWindow
*)this, m_xPeerWindow
);
791 m_xMultiplexer
= Reference
< XInterface
>( (OWeakObject
*)m_pMultiplexer
, UNO_QUERY
);
794 return m_pMultiplexer
;
797 } // namespace unocontrols
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */