bump product version to 5.0.4.1
[LibreOffice.git] / UnoControls / source / base / basecontrol.cxx
blob5da9907b88ef3615e65e40d1ccb6998927bb842c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
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>
33 // namespaces
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
44 #define DEFAULT_X 0
45 #define DEFAULT_Y 0
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
52 // construct/destruct
54 BaseControl::BaseControl( const Reference< XComponentContext >& rxContext )
55 : IMPL_MutexContainer ( )
56 , OComponentHelper ( m_aMutex )
57 , m_xComponentContext ( rxContext )
58 , m_pMultiplexer ( DEFAULT_PMULTIPLEXER )
59 , m_nX ( DEFAULT_X )
60 , m_nY ( DEFAULT_Y )
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()
73 // XInterface
75 Any SAL_CALL BaseControl::queryInterface( const Type& rType ) throw( RuntimeException, std::exception )
77 Any aReturn;
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 );
84 else
86 // If an delegator unknown, forward question to own queryAggregation.
87 aReturn = queryAggregation( rType );
90 return aReturn;
93 // XInterface
95 void SAL_CALL BaseControl::acquire() throw()
97 // Attention:
98 // Don't use mutex or guard in this method!!! Is a method of XInterface.
100 // Forward to baseclass
101 OComponentHelper::acquire();
104 // XInterface
106 void SAL_CALL BaseControl::release() throw()
108 // Attention:
109 // Don't use mutex or guard in this method!!! Is a method of XInterface.
111 // Forward to baseclass
112 OComponentHelper::release();
115 // XTypeProvider
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();
150 // XTypeProvider
152 Sequence< sal_Int8 > SAL_CALL BaseControl::getImplementationId() throw( RuntimeException, std::exception )
154 return css::uno::Sequence<sal_Int8>();
157 // XAggregation
159 void SAL_CALL BaseControl::setDelegator( const Reference< XInterface >& xDel ) throw( RuntimeException, std::exception )
161 // Ready for multithreading
162 MutexGuard aGuard( m_aMutex );
163 m_xDelegator = xDel;
166 // XAggregation
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.
186 return aReturn;
188 else
190 // Else; ... ask baseclass for interfaces!
191 return OComponentHelper::queryAggregation( aType );
195 // XServiceInfo
197 OUString SAL_CALL BaseControl::getImplementationName() throw( RuntimeException, std::exception )
199 return impl_getStaticImplementationName();
202 // XServiceInfo
204 sal_Bool SAL_CALL BaseControl::supportsService( const OUString& sServiceName ) throw( RuntimeException, std::exception )
206 return cppu::supportsService(this, sServiceName);
209 // XServiceInfo
211 Sequence< OUString > SAL_CALL BaseControl::getSupportedServiceNames() throw( RuntimeException, std::exception )
213 return impl_getStaticSupportedServiceNames();
216 // XComponent
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
233 m_xContext.clear();
234 impl_releasePeer();
236 // release view
237 if ( m_xGraphicsView.is() )
239 m_xGraphicsView.clear();
243 // XComponent
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 );
252 // XComponent
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 );
261 // XControl
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 );
269 if ( !m_xPeer.is() )
271 // use method "BaseControl::getWindowDescriptor()" fot change window attributes !!!
272 WindowDescriptor* pDescriptor = impl_getWindowDescriptor( xParentPeer );
274 if ( m_bVisible )
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!
291 delete pDescriptor;
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 );
304 if ( xDevice.is() )
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 );
322 // XControl
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;
331 // XControl
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;
340 // XControl
342 Reference< XInterface > SAL_CALL BaseControl::getContext() throw( RuntimeException, std::exception )
344 // Ready for multithreading
345 MutexGuard aGuard( m_aMutex );
346 return m_xContext;
349 // XControl
351 Reference< XWindowPeer > SAL_CALL BaseControl::getPeer() throw( RuntimeException, std::exception )
353 // Ready for multithreading
354 MutexGuard aGuard( m_aMutex );
355 return m_xPeer;
358 // XControl
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 );
367 // XControl
369 sal_Bool SAL_CALL BaseControl::isDesignMode() throw( RuntimeException, std::exception )
371 // Ready for multithreading
372 MutexGuard aGuard( m_aMutex );
373 return m_bInDesignMode;
376 // XControl
378 sal_Bool SAL_CALL BaseControl::isTransparent() throw( RuntimeException, std::exception )
380 return false;
383 // XWindow
385 void SAL_CALL BaseControl::setPosSize( sal_Int32 nX ,
386 sal_Int32 nY ,
387 sal_Int32 nWidth ,
388 sal_Int32 nHeight ,
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 );
424 // XWindow
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 );
441 // XWindow
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
449 m_bEnable = bEnable;
451 if ( m_xPeerWindow.is() )
453 // Set it also on peerwindow
454 m_xPeerWindow->setEnable( m_bEnable );
458 // XWindow
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();
471 // XWindow
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 );
480 // XWindow
482 void SAL_CALL BaseControl::addWindowListener( const Reference< XWindowListener >& xListener ) throw( RuntimeException, std::exception )
484 impl_getMultiplexer()->advise( cppu::UnoType<XWindowListener>::get(), xListener );
487 // XWindow
489 void SAL_CALL BaseControl::addFocusListener( const Reference< XFocusListener >& xListener ) throw( RuntimeException, std::exception )
491 impl_getMultiplexer()->advise( cppu::UnoType<XFocusListener>::get(), xListener );
494 // XWindow
496 void SAL_CALL BaseControl::addKeyListener( const Reference< XKeyListener >& xListener ) throw( RuntimeException, std::exception )
498 impl_getMultiplexer()->advise( cppu::UnoType<XKeyListener>::get(), xListener );
501 // XWindow
503 void SAL_CALL BaseControl::addMouseListener( const Reference< XMouseListener >& xListener ) throw( RuntimeException, std::exception )
505 impl_getMultiplexer()->advise( cppu::UnoType<XMouseListener>::get(), xListener );
508 // XWindow
510 void SAL_CALL BaseControl::addMouseMotionListener( const Reference< XMouseMotionListener >& xListener ) throw( RuntimeException, std::exception )
512 impl_getMultiplexer()->advise( cppu::UnoType<XMouseMotionListener>::get(), xListener );
515 // XWindow
517 void SAL_CALL BaseControl::addPaintListener( const Reference< XPaintListener >& xListener ) throw( RuntimeException, std::exception )
519 impl_getMultiplexer()->advise( cppu::UnoType<XPaintListener>::get(), xListener );
522 // XWindow
524 void SAL_CALL BaseControl::removeWindowListener( const Reference< XWindowListener >& xListener ) throw( RuntimeException, std::exception )
526 impl_getMultiplexer()->unadvise( cppu::UnoType<XWindowListener>::get(), xListener );
529 // XWindow
531 void SAL_CALL BaseControl::removeFocusListener( const Reference< XFocusListener >& xListener ) throw( RuntimeException, std::exception )
533 impl_getMultiplexer()->unadvise( cppu::UnoType<XFocusListener>::get(), xListener );
536 // XWindow
538 void SAL_CALL BaseControl::removeKeyListener( const Reference< XKeyListener >& xListener ) throw( RuntimeException, std::exception )
540 impl_getMultiplexer()->unadvise( cppu::UnoType<XKeyListener>::get(), xListener );
543 // XWindow
545 void SAL_CALL BaseControl::removeMouseListener( const Reference< XMouseListener >& xListener ) throw( RuntimeException, std::exception )
547 impl_getMultiplexer()->unadvise( cppu::UnoType<XMouseListener>::get(), xListener );
550 // XWindow
552 void SAL_CALL BaseControl::removeMouseMotionListener( const Reference< XMouseMotionListener >& xListener ) throw( RuntimeException, std::exception )
554 impl_getMultiplexer()->unadvise( cppu::UnoType<XMouseMotionListener>::get(), xListener );
557 // XWindow
559 void SAL_CALL BaseControl::removePaintListener( const Reference< XPaintListener >& xListener ) throw( RuntimeException, std::exception )
561 impl_getMultiplexer()->unadvise( cppu::UnoType<XPaintListener>::get(), xListener );
564 // XView
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 );
578 // XView
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;
586 if ( xDevice.is() )
588 // Ready for multithreading
589 MutexGuard aGuard( m_aMutex );
591 m_xGraphicsView = xDevice;
592 bReturn = true;
595 return bReturn;
598 // XView
600 void SAL_CALL BaseControl::setZoom( float /*fZoomX*/ ,
601 float /*fZoomY*/ ) throw( RuntimeException, std::exception )
603 // Not implemented yet
606 // XView
608 Reference< XGraphics > SAL_CALL BaseControl::getGraphics() throw( RuntimeException, std::exception )
610 // Ready for multithreading
611 MutexGuard aGuard( m_aMutex );
612 return m_xGraphicsView;
615 // XView
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 );
624 // XEventListener
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
632 // - it must be !!!
633 if ( m_xGraphicsPeer.is() )
635 removePaintListener( this );
636 removeWindowListener( this );
637 m_xGraphicsPeer.clear();
640 if ( m_xGraphicsView.is() )
642 m_xGraphicsView.clear();
646 // XPaintListener
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 );
659 // XWindowListener
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;
669 aMappedEvent.X = 0;
670 aMappedEvent.Y = 0;
671 impl_recalcLayout( aMappedEvent );
674 // XWindowListener
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;
684 aMappedEvent.X = 0;
685 aMappedEvent.Y = 0;
686 impl_recalcLayout( aMappedEvent );
689 // XWindowListener
691 void SAL_CALL BaseControl::windowShown( const EventObject& /*aEvent*/ ) throw( RuntimeException, std::exception )
695 // XWindowListener
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()
714 return OUString();
717 // protected method
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;
734 return pDescriptor;
737 // protected method
739 void BaseControl::impl_paint( sal_Int32 /*nX*/ ,
740 sal_Int32 /*nY*/ ,
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 !!!
748 // protected method
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!
756 // protected method
759 // private method
761 void BaseControl::impl_releasePeer()
763 if ( m_xPeer.is() )
765 if ( m_xGraphicsPeer.is() )
767 removePaintListener( this );
768 removeWindowListener( this );
769 m_xGraphicsPeer.clear();
772 m_xPeer->dispose();
773 m_xPeerWindow.clear();
774 m_xPeer.clear();
776 if ( m_pMultiplexer != NULL )
778 // take changes on multiplexer
779 m_pMultiplexer->setPeer( Reference< XWindow >() );
784 // private method
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: */