diff options
Diffstat (limited to 'UnoControls/source/base/basecontrol.cxx')
-rw-r--r-- | UnoControls/source/base/basecontrol.cxx | 749 |
1 files changed, 749 insertions, 0 deletions
diff --git a/UnoControls/source/base/basecontrol.cxx b/UnoControls/source/base/basecontrol.cxx new file mode 100644 index 000000000..c2e2f23b1 --- /dev/null +++ b/UnoControls/source/base/basecontrol.cxx @@ -0,0 +1,749 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <basecontrol.hxx> +#include <multiplexer.hxx> + +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/Toolkit.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <cppuhelper/typeprovider.hxx> + +// namespaces + +using namespace ::cppu; +using namespace ::osl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::awt; + +namespace unocontrols { + +constexpr sal_Int32 DEFAULT_X = 0; +constexpr sal_Int32 DEFAULT_Y = 0; +constexpr sal_Int32 DEFAULT_WIDTH = 100; +constexpr sal_Int32 DEFAULT_HEIGHT = 100; +constexpr bool DEFAULT_VISIBLE = false; +constexpr bool DEFAULT_INDESIGNMODE = false; +constexpr bool DEFAULT_ENABLE = true; + +// construct/destruct + +BaseControl::BaseControl( const Reference< XComponentContext >& rxContext ) + : OComponentHelper ( m_aMutex ) + , m_xComponentContext ( rxContext ) + , m_nX ( DEFAULT_X ) + , m_nY ( DEFAULT_Y ) + , m_nWidth ( DEFAULT_WIDTH ) + , m_nHeight ( DEFAULT_HEIGHT ) + , m_bVisible ( DEFAULT_VISIBLE ) + , m_bInDesignMode ( DEFAULT_INDESIGNMODE ) + , m_bEnable ( DEFAULT_ENABLE ) +{ +} + +BaseControl::~BaseControl() +{ +} + +// XInterface + +Any SAL_CALL BaseControl::queryInterface( const Type& rType ) +{ + Any aReturn; + if ( m_xDelegator.is() ) + { + // If a delegator exists, forward question to its queryInterface. + // Delegator will ask its own queryAggregation! + aReturn = m_xDelegator->queryInterface( rType ); + } + else + { + // If a delegator is unknown, forward question to own queryAggregation. + aReturn = queryAggregation( rType ); + } + + return aReturn; +} + +// XInterface + +void SAL_CALL BaseControl::acquire() noexcept +{ + // Attention: + // Don't use mutex or guard in this method!!! Is a method of XInterface. + + // Forward to baseclass + OComponentHelper::acquire(); +} + +// XInterface + +void SAL_CALL BaseControl::release() noexcept +{ + // Attention: + // Don't use mutex or guard in this method!!! Is a method of XInterface. + + // Forward to baseclass + OComponentHelper::release(); +} + +// XTypeProvider + +Sequence< Type > SAL_CALL BaseControl::getTypes() +{ + static OTypeCollection ourTypeCollection( + cppu::UnoType<XPaintListener>::get(), + cppu::UnoType<XWindowListener>::get(), + cppu::UnoType<XView>::get(), + cppu::UnoType<XWindow>::get(), + cppu::UnoType<XServiceInfo>::get(), + cppu::UnoType<XControl>::get(), + OComponentHelper::getTypes() ); + + return ourTypeCollection.getTypes(); +} + +// XTypeProvider + +Sequence< sal_Int8 > SAL_CALL BaseControl::getImplementationId() +{ + return css::uno::Sequence<sal_Int8>(); +} + +// XAggregation + +void SAL_CALL BaseControl::setDelegator( const Reference< XInterface >& xDel ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + m_xDelegator = xDel; +} + +// XAggregation + +Any SAL_CALL BaseControl::queryAggregation( const Type& aType ) +{ + // Ask for my own supported interfaces ... + // Attention: XTypeProvider and XInterface are supported by OComponentHelper! + Any aReturn ( ::cppu::queryInterface( aType , + static_cast< XPaintListener*> ( this ) , + static_cast< XWindowListener*> ( this ) , + static_cast< XView* > ( this ) , + static_cast< XWindow* > ( this ) , + static_cast< XServiceInfo* > ( this ) , + static_cast< XControl* > ( this ) + ) + ); + + // If searched interface supported by this class ... + if ( aReturn.hasValue() ) + { + // ... return this information. + return aReturn; + } + else + { + // Else; ... ask baseclass for interfaces! + return OComponentHelper::queryAggregation( aType ); + } +} + +// XServiceInfo + +OUString SAL_CALL BaseControl::getImplementationName() +{ + return OUString(); +} + +// XServiceInfo + +sal_Bool SAL_CALL BaseControl::supportsService( const OUString& sServiceName ) +{ + return cppu::supportsService(this, sServiceName); +} + +// XServiceInfo + +Sequence< OUString > SAL_CALL BaseControl::getSupportedServiceNames() +{ + return Sequence< OUString >(); +} + +// XComponent + +void SAL_CALL BaseControl::dispose() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + if ( m_xMultiplexer.is() ) + { + // to all other paint, focus, etc. + m_xMultiplexer->disposeAndClear(); + } + + // set the service manager to disposed + OComponentHelper::dispose(); + + // release context and peer + m_xContext.clear(); + if ( m_xPeer.is() ) + { + if ( m_xGraphicsPeer.is() ) + { + removePaintListener( this ); + removeWindowListener( this ); + m_xGraphicsPeer.clear(); + } + + m_xPeer->dispose(); + m_xPeerWindow.clear(); + m_xPeer.clear(); + + if ( m_xMultiplexer.is() ) + { + // take changes on multiplexer + m_xMultiplexer->setPeer( Reference< XWindow >() ); + } + } + + // release view + if ( m_xGraphicsView.is() ) + { + m_xGraphicsView.clear(); + } +} + +// XComponent + +void SAL_CALL BaseControl::addEventListener( const Reference< XEventListener >& xListener ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + OComponentHelper::addEventListener( xListener ); +} + +// XComponent + +void SAL_CALL BaseControl::removeEventListener( const Reference< XEventListener >& xListener ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + OComponentHelper::removeEventListener( xListener ); +} + +// XControl + +void SAL_CALL BaseControl::createPeer( const Reference< XToolkit >& xToolkit , + const Reference< XWindowPeer >& xParentPeer ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + if ( m_xPeer.is() ) + return; + + // use method "BaseControl::getWindowDescriptor()" to change window attributes! + WindowDescriptor aDescriptor = impl_getWindowDescriptor( xParentPeer ); + + if ( m_bVisible ) + { + aDescriptor.WindowAttributes |= WindowAttribute::SHOW; + } + + // very slow under remote conditions! + // create the window on the server + Reference< XToolkit > xLocalToolkit = xToolkit; + if ( !xLocalToolkit.is() ) + { + // but first create well known toolkit, if it not exist + xLocalToolkit.set( Toolkit::create(m_xComponentContext), UNO_QUERY_THROW ); + } + m_xPeer = xLocalToolkit->createWindow( aDescriptor ); + m_xPeerWindow.set( m_xPeer, UNO_QUERY ); + + if ( !m_xPeerWindow.is() ) + return; + + if ( m_xMultiplexer.is() ) + { + m_xMultiplexer->setPeer( m_xPeerWindow ); + } + + // create new reference to xgraphics for painting on a peer + // and add a paint listener + Reference< XDevice > xDevice( m_xPeerWindow, UNO_QUERY ); + + if ( xDevice.is() ) + { + m_xGraphicsPeer = xDevice->createGraphics(); + } + + if ( m_xGraphicsPeer.is() ) + { + addPaintListener( this ); + addWindowListener( this ); + } + + m_xPeerWindow->setPosSize( m_nX, m_nY, m_nWidth, m_nHeight, PosSize::POSSIZE ); + m_xPeerWindow->setEnable( m_bEnable ); + m_xPeerWindow->setVisible( m_bVisible && !m_bInDesignMode ); +} + +// XControl + +void SAL_CALL BaseControl::setContext( const Reference< XInterface >& xContext ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + m_xContext = xContext; +} + +// XControl + +void SAL_CALL BaseControl::setDesignMode( sal_Bool bOn ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + m_bInDesignMode = bOn; +} + +// XControl + +Reference< XInterface > SAL_CALL BaseControl::getContext() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return m_xContext; +} + +// XControl + +Reference< XWindowPeer > SAL_CALL BaseControl::getPeer() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return m_xPeer; +} + +// XControl + +Reference< XView > SAL_CALL BaseControl::getView() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return this; +} + +// XControl + +sal_Bool SAL_CALL BaseControl::isDesignMode() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return m_bInDesignMode; +} + +// XControl + +sal_Bool SAL_CALL BaseControl::isTransparent() +{ + return false; +} + +// XWindow + +void SAL_CALL BaseControl::setPosSize( sal_Int32 nX , + sal_Int32 nY , + sal_Int32 nWidth , + sal_Int32 nHeight , + sal_Int16 nFlags ) +{ + // - change size and position of window and save the values + + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + bool bChanged = false; + + if ( nFlags & PosSize::X ) + { + bChanged |= m_nX != nX; + m_nX = nX; + } + + if ( nFlags & PosSize::Y ) + { + bChanged |= m_nY != nY; + m_nY = nY; + } + + if ( nFlags & PosSize::WIDTH ) + { + bChanged |= m_nWidth != nWidth; + m_nWidth = nWidth; + } + + if ( nFlags & PosSize::HEIGHT ) + { + bChanged |= m_nHeight != nHeight; + m_nHeight = nHeight; + } + + if ( bChanged && m_xPeerWindow.is() ) + { + m_xPeerWindow->setPosSize( m_nX, m_nY, m_nWidth, m_nHeight, nFlags ); + } +} + +// XWindow + +void SAL_CALL BaseControl::setVisible( sal_Bool bVisible ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + // Set new state of flag + m_bVisible = bVisible; + + if ( m_xPeerWindow.is() ) + { + // Set it also on peerwindow + m_xPeerWindow->setVisible( m_bVisible ); + } +} + +// XWindow + +void SAL_CALL BaseControl::setEnable( sal_Bool bEnable ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + // Set new state of flag + m_bEnable = bEnable; + + if ( m_xPeerWindow.is() ) + { + // Set it also on peerwindow + m_xPeerWindow->setEnable( m_bEnable ); + } +} + +// XWindow + +void SAL_CALL BaseControl::setFocus() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + if ( m_xPeerWindow.is() ) + { + m_xPeerWindow->setFocus(); + } +} + +// XWindow + +Rectangle SAL_CALL BaseControl::getPosSize() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return Rectangle( m_nX, m_nY , m_nWidth, m_nHeight ); +} + +// XWindow + +void SAL_CALL BaseControl::addWindowListener( const Reference< XWindowListener >& xListener ) +{ + impl_getMultiplexer()->advise( cppu::UnoType<XWindowListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::addFocusListener( const Reference< XFocusListener >& xListener ) +{ + impl_getMultiplexer()->advise( cppu::UnoType<XFocusListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::addKeyListener( const Reference< XKeyListener >& xListener ) +{ + impl_getMultiplexer()->advise( cppu::UnoType<XKeyListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::addMouseListener( const Reference< XMouseListener >& xListener ) +{ + impl_getMultiplexer()->advise( cppu::UnoType<XMouseListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::addMouseMotionListener( const Reference< XMouseMotionListener >& xListener ) +{ + impl_getMultiplexer()->advise( cppu::UnoType<XMouseMotionListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::addPaintListener( const Reference< XPaintListener >& xListener ) +{ + impl_getMultiplexer()->advise( cppu::UnoType<XPaintListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::removeWindowListener( const Reference< XWindowListener >& xListener ) +{ + impl_getMultiplexer()->unadvise( cppu::UnoType<XWindowListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::removeFocusListener( const Reference< XFocusListener >& xListener ) +{ + impl_getMultiplexer()->unadvise( cppu::UnoType<XFocusListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::removeKeyListener( const Reference< XKeyListener >& xListener ) +{ + impl_getMultiplexer()->unadvise( cppu::UnoType<XKeyListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::removeMouseListener( const Reference< XMouseListener >& xListener ) +{ + impl_getMultiplexer()->unadvise( cppu::UnoType<XMouseListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::removeMouseMotionListener( const Reference< XMouseMotionListener >& xListener ) +{ + impl_getMultiplexer()->unadvise( cppu::UnoType<XMouseMotionListener>::get(), xListener ); +} + +// XWindow + +void SAL_CALL BaseControl::removePaintListener( const Reference< XPaintListener >& xListener ) +{ + impl_getMultiplexer()->unadvise( cppu::UnoType<XPaintListener>::get(), xListener ); +} + +// XView + +void SAL_CALL BaseControl::draw( sal_Int32 nX , + sal_Int32 nY ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + // - paint to a view + // - use the method "paint()" + // - see also "windowPaint()" + impl_paint( nX, nY, m_xGraphicsView ); +} + +// XView + +sal_Bool SAL_CALL BaseControl::setGraphics( const Reference< XGraphics >& xDevice ) +{ + // - set the graphics for a view + // - in this class exist 2 graphics-member ... one for peer[_xGraphicsPeer] and one for view[_xGraphicsView] + // - they are used by "windowPaint() and draw()", forwarded to "paint ()" + bool bReturn = false; + if ( xDevice.is() ) + { + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + m_xGraphicsView = xDevice; + bReturn = true; + } + + return bReturn; +} + +// XView + +void SAL_CALL BaseControl::setZoom( float /*fZoomX*/ , + float /*fZoomY*/ ) +{ + // Not implemented yet +} + +// XView + +Reference< XGraphics > SAL_CALL BaseControl::getGraphics() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return m_xGraphicsView; +} + +// XView + +Size SAL_CALL BaseControl::getSize() +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + return Size( m_nWidth, m_nHeight ); +} + +// XEventListener + +void SAL_CALL BaseControl::disposing( const EventObject& /*aSource*/ ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + // - release ALL references + // - it must be !!! + if ( m_xGraphicsPeer.is() ) + { + removePaintListener( this ); + removeWindowListener( this ); + m_xGraphicsPeer.clear(); + } + + if ( m_xGraphicsView.is() ) + { + m_xGraphicsView.clear(); + } +} + +// XPaintListener + +void SAL_CALL BaseControl::windowPaint( const PaintEvent& /*aEvent*/ ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + // - repaint the peer + // - use the method "paint ()" for painting on a peer and a print device !!! + // - see also "draw ()" + impl_paint( 0, 0, m_xGraphicsPeer ); +} + +// XWindowListener + +void SAL_CALL BaseControl::windowResized( const WindowEvent& aEvent ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + m_nWidth = aEvent.Width; + m_nHeight = aEvent.Height; + WindowEvent aMappedEvent = aEvent; + aMappedEvent.X = 0; + aMappedEvent.Y = 0; + impl_recalcLayout( aMappedEvent ); +} + +// XWindowListener + +void SAL_CALL BaseControl::windowMoved( const WindowEvent& aEvent ) +{ + // Ready for multithreading + MutexGuard aGuard( m_aMutex ); + + m_nWidth = aEvent.Width; + m_nHeight = aEvent.Height; + WindowEvent aMappedEvent = aEvent; + aMappedEvent.X = 0; + aMappedEvent.Y = 0; + impl_recalcLayout( aMappedEvent ); +} + +// XWindowListener + +void SAL_CALL BaseControl::windowShown( const EventObject& /*aEvent*/ ) +{ +} + +// XWindowListener + +void SAL_CALL BaseControl::windowHidden( const EventObject& /*aEvent*/ ) +{ +} + +// protected method + +WindowDescriptor BaseControl::impl_getWindowDescriptor( const Reference< XWindowPeer >& xParentPeer ) +{ + // - used from "createPeer()" to set the values of a css::awt::WindowDescriptor !!! + // - if you will change the descriptor-values, you must override this virtual function + // - the caller must release the memory for this dynamical descriptor !!! + + WindowDescriptor aDescriptor; + + aDescriptor.Type = WindowClass_SIMPLE; + aDescriptor.WindowServiceName = "window"; + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = xParentPeer; + aDescriptor.Bounds = getPosSize (); + aDescriptor.WindowAttributes = 0; + + return aDescriptor; +} + +// protected method + +void BaseControl::impl_paint( sal_Int32 /*nX*/ , + sal_Int32 /*nY*/ , + const Reference< XGraphics >& /*xGraphics*/ ) +{ + // - one paint method for peer AND view !!! + // (see also => "windowPaint()" and "draw()") + // - not used in this implementation, but it's not necessary to make it pure virtual !!! +} + +// protected method + +void BaseControl::impl_recalcLayout( const WindowEvent& /*aEvent*/ ) +{ + // We need as virtual function to support automatically resizing of derived controls! + // But we make it not pure virtual because it's not necessary for all derived classes! +} + +// private method + +OMRCListenerMultiplexerHelper* BaseControl::impl_getMultiplexer() +{ + if ( !m_xMultiplexer.is() ) + { + m_xMultiplexer = new OMRCListenerMultiplexerHelper( static_cast<XWindow*>(this), m_xPeerWindow ); + } + + return m_xMultiplexer.get(); +} + +} // namespace unocontrols + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |