/************************************************************************* * * $RCSfile: unocontrolcontainer.cxx,v $ * * $Revision: 1.11 $ * * last change: $Author: hr $ $Date: 2003-03-27 17:03:21 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (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.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifndef _COM_SUN_STAR_AWT_XVCLCONTAINERPEER_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_ #include #endif #include #include #include #include #include #include #include #ifndef _COMPHELPER_SEQUENCE_HXX_ #include #endif #include #include using namespace ::com::sun::star; // ---------------------------------------------------- // class UnoControlHolder // ---------------------------------------------------- struct UnoControlHolder { public: ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > xCtrl; ::rtl::OUString aName; UnoControlHolder( const ::rtl::OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > & rControl ) : aName( rName ) { xCtrl = rControl; } }; DECLARE_LIST( UnoControlHolderList, UnoControlHolder* ); // ---------------------------------------------------- // Function to set the controls' visibility according // to the dialog's "Step" property // ---------------------------------------------------- void implUpdateVisibility ( sal_Int32 nDialogStep, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > xControlContainer ) { ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > aCtrls = xControlContainer->getControls(); const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >* pCtrls = aCtrls.getConstArray(); sal_uInt32 nCtrls = aCtrls.getLength(); sal_Bool bCompleteVisible = (nDialogStep == 0); for( sal_uInt32 n = 0; n < nCtrls; n++ ) { ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > xControl = pCtrls[ n ]; sal_Bool bVisible = bCompleteVisible; if( !bVisible ) { ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xModel( xControl->getModel() ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPSet ( xModel, ::com::sun::star::uno::UNO_QUERY ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = xPSet->getPropertySetInfo(); ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); sal_Int32 nControlStep = 0; if ( xInfo->hasPropertyByName( aPropName ) ) { ::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName ); aVal >>= nControlStep; } bVisible = (nControlStep == 0) || (nControlStep == nDialogStep); } ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow> xWindow ( xControl, ::com::sun::star::uno::UNO_QUERY ); if( xWindow.is() ) xWindow->setVisible( bVisible ); } } // ---------------------------------------------------- // class DialogStepChangedListener // ---------------------------------------------------- typedef ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertyChangeListener > PropertyChangeListenerHelper; class DialogStepChangedListener: public PropertyChangeListenerHelper { private: ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > mxControlContainer; public: DialogStepChangedListener( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > xControlContainer ) : mxControlContainer( xControlContainer ) {} // XEventListener virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw( ::com::sun::star::uno::RuntimeException); // XPropertyChangeListener virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw( ::com::sun::star::uno::RuntimeException); }; void SAL_CALL DialogStepChangedListener::disposing( const ::com::sun::star::lang::EventObject& _rSource) throw( ::com::sun::star::uno::RuntimeException) { mxControlContainer.clear(); } void SAL_CALL DialogStepChangedListener::propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw( ::com::sun::star::uno::RuntimeException) { // evt.PropertyName HAS to be "Step" because we only use the listener for that sal_Int32 nDialogStep; evt.NewValue >>= nDialogStep; implUpdateVisibility( nDialogStep, mxControlContainer ); } // ---------------------------------------------------- // class UnoControlContainer // ---------------------------------------------------- UnoControlContainer::UnoControlContainer() : maCListeners( *this ) { mpControls = new UnoControlHolderList; } UnoControlContainer::UnoControlContainer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xP ) : maCListeners( *this ) { setPeer( xP ); mbDisposePeer = sal_False; mpControls = new UnoControlHolderList; } UnoControlContainer::~UnoControlContainer() { for ( sal_uInt32 n = mpControls->Count(); n; ) { UnoControlHolder* pHolder = mpControls->GetObject( --n ); delete pHolder; } mpControls->Clear(); delete mpControls; } void UnoControlContainer::ImplActivateTabControllers() { sal_uInt32 nCount = maTabControllers.getLength(); for ( sal_uInt32 n = 0; n < nCount; n++ ) { maTabControllers.getArray()[n]->setContainer( this ); maTabControllers.getArray()[n]->activateTabOrder(); } } // ::com::sun::star::uno::XInterface ::com::sun::star::uno::Any UnoControlContainer::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) { ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, SAL_STATIC_CAST( ::com::sun::star::awt::XUnoControlContainer*, this ), SAL_STATIC_CAST( ::com::sun::star::awt::XControlContainer*, this ), SAL_STATIC_CAST( ::com::sun::star::container::XContainer*, this ) ); return (aRet.hasValue() ? aRet : UnoControlBase::queryAggregation( rType )); } // ::com::sun::star::lang::XTypeProvider IMPL_XTYPEPROVIDER_START( UnoControlContainer ) getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XUnoControlContainer>* ) NULL ), getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer>* ) NULL ), getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer>* ) NULL ), UnoControlBase::getTypes() IMPL_XTYPEPROVIDER_END // ::com::sun::star::lang::XComponent void UnoControlContainer::dispose( ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); lang::EventObject aDisposeEvent; aDisposeEvent.Source = static_cast< uno::XAggregation* >( this ); // DG: zuerst der Welt mitteilen, daß der Container wegfliegt. Dieses ist um einiges // schneller wenn die Welt sowohl an den Controls als auch am Container horcht maDisposeListeners.disposeAndClear( aDisposeEvent ); maCListeners.disposeAndClear( aDisposeEvent ); uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls(); uno::Reference< awt::XControl >* pCtrls = aCtrls.getArray(); uno::Reference< awt::XControl >* pCtrlsEnd = pCtrls + aCtrls.getLength(); for( ; pCtrls < pCtrlsEnd; ++pCtrls ) { removingControl( *pCtrls ); // Control wegwerfen (*pCtrls)->dispose(); } // alle Strukturen entfernen for ( sal_Int32 n = mpControls->Count(); n; ) delete mpControls->GetObject( --n ); mpControls->Clear(); UnoControlBase::dispose(); } // ::com::sun::star::lang::XEventListener void UnoControlContainer::disposing( const ::com::sun::star::lang::EventObject& _rEvt ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); uno::Reference< awt::XControl > xControl( _rEvt.Source, uno::UNO_QUERY ); if ( xControl.is() ) removeControl( xControl ); UnoControlBase::disposing( _rEvt ); } // ::com::sun::star::container::XContainer void UnoControlContainer::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); maCListeners.addInterface( rxListener ); } void UnoControlContainer::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& rxListener ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); maCListeners.removeInterface( rxListener ); } // ::com::sun::star::awt::XControlContainer void UnoControlContainer::setStatusText( const ::rtl::OUString& rStatusText ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); // In der Parenthierarchie nach unten gehen ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > xContainer( mxContext, ::com::sun::star::uno::UNO_QUERY ); if( xContainer.is() ) xContainer->setStatusText( rStatusText ); } ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > UnoControlContainer::getControls( ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); sal_uInt32 nCtrls = mpControls->Count(); ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > aD( nCtrls ); ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > * pDest = aD.getArray(); for( sal_uInt32 n = 0; n < nCtrls; n++ ) { UnoControlHolder* pHolder= mpControls->GetObject( n ); pDest[n] = pHolder->xCtrl; } return aD; } ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > UnoControlContainer::getControl( const ::rtl::OUString& rName ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > xCtrl; sal_uInt32 nCtrls = mpControls->Count(); for( sal_uInt32 n = 0; n < nCtrls; n++ ) { UnoControlHolder* pHolder = mpControls->GetObject( n ); if ( pHolder->aName == rName ) { xCtrl = pHolder->xCtrl; break; } } return xCtrl; } void UnoControlContainer::addingControl( const uno::Reference< awt::XControl >& _rxControl ) { if ( _rxControl.is() ) { uno::Reference< uno::XInterface > xThis; OWeakAggObject::queryInterface( ::getCppuType( static_cast< uno::Reference< uno::XInterface >* >( NULL ) ) ) >>= xThis; _rxControl->setContext( xThis ); _rxControl->addEventListener( this ); } } void UnoControlContainer::addControl( const ::rtl::OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >& rControl ) throw(::com::sun::star::uno::RuntimeException) { if ( rControl.is() ) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); UnoControlHolder* pHolder = new UnoControlHolder( rName, rControl ); mpControls->Insert( pHolder, LIST_APPEND ); addingControl( rControl ); if( getPeer().is() ) { // Hat der Container ein Peer, dann auch gleich im Child erzeugen rControl->createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (), getPeer() ); ImplActivateTabControllers(); } if ( maCListeners.getLength() ) { ::com::sun::star::container::ContainerEvent aEvent; aEvent.Source = *this; aEvent.Element <<= rControl; maCListeners.elementInserted( aEvent ); } } } void UnoControlContainer::removingControl( const uno::Reference< awt::XControl >& _rxControl ) { if ( _rxControl.is() ) { _rxControl->removeEventListener( this ); _rxControl->setContext( NULL ); } } void UnoControlContainer::removeControl( const uno::Reference< awt::XControl >& _rxControl ) throw(::com::sun::star::uno::RuntimeException) { if ( _rxControl.is() ) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); sal_uInt32 nCtrls = mpControls->Count(); for( sal_uInt32 n = 0; n < nCtrls; n++ ) { UnoControlHolder* pHolder = mpControls->GetObject( n ); if ( _rxControl.get() == pHolder->xCtrl.get() ) { removingControl( _rxControl ); delete pHolder; mpControls->Remove( n ); if ( maCListeners.getLength() ) { ::com::sun::star::container::ContainerEvent aEvent; aEvent.Source = *this; aEvent.Element <<= _rxControl; maCListeners.elementRemoved( aEvent ); } break; } } } } // ::com::sun::star::awt::XUnoControlContainer void UnoControlContainer::setTabControllers( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > >& TabControllers ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); maTabControllers = TabControllers; } ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController > > UnoControlContainer::getTabControllers( ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); return maTabControllers; } void UnoControlContainer::addTabController( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController >& TabController ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); sal_uInt32 nCount = maTabControllers.getLength(); maTabControllers.realloc( nCount + 1 ); maTabControllers[ nCount ] = TabController; } void UnoControlContainer::removeTabController( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabController >& TabController ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); sal_uInt32 nCount = maTabControllers.getLength(); const uno::Reference< awt::XTabController >* pLoop = maTabControllers.getConstArray(); for ( sal_uInt32 n = 0; n < nCount; ++n, ++pLoop ) { if( pLoop->get() == TabController.get() ) { ::comphelper::removeElementAt( maTabControllers, n ); break; } } } // ::com::sun::star::awt::XControl void UnoControlContainer::createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& rxToolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& rParent ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); if( !getPeer().is() ) { sal_Bool bVis = maComponentInfos.bVisible; if( bVis ) UnoControl::setVisible( sal_False ); // eigenes Peer erzeugen UnoControl::createPeer( rxToolkit, rParent ); // alle Peers der Childs erzeugen if ( !mbCreatingCompatiblePeer ) { // Evaluate "Step" property ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xModel( getModel() ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPSet ( xModel, ::com::sun::star::uno::UNO_QUERY ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > xInfo = xPSet->getPropertySetInfo(); ::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) ); if ( xInfo->hasPropertyByName( aPropName ) ) { ::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName ); sal_Int32 nDialogStep; aVal >>= nDialogStep; ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > xContainer = SAL_STATIC_CAST( ::com::sun::star::awt::XControlContainer*, this ); implUpdateVisibility( nDialogStep, xContainer ); ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener > xListener = SAL_STATIC_CAST( ::com::sun::star::beans::XPropertyChangeListener*, new DialogStepChangedListener( xContainer ) ); xPSet->addPropertyChangeListener( aPropName, xListener ); } ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > aCtrls = getControls(); sal_uInt32 nCtrls = aCtrls.getLength(); for( sal_uInt32 n = 0; n < nCtrls; n++ ) aCtrls.getArray()[n]->createPeer( rxToolkit, getPeer() ); ::com::sun::star::uno::Reference< ::com::sun::star::awt::XVclContainerPeer > xC( getPeer(), ::com::sun::star::uno::UNO_QUERY ); xC->enableDialogControl( sal_True ); ImplActivateTabControllers(); } if( bVis && !isDesignMode() ) UnoControl::setVisible( sal_True ); } } // ::com::sun::star::awt::XWindow void UnoControlContainer::setVisible( sal_Bool bVisible ) throw(::com::sun::star::uno::RuntimeException) { ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); UnoControl::setVisible( bVisible ); if( !mxContext.is() && bVisible ) // Es ist ein TopWindow, also automatisch anzeigen createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (), ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () ); }