blob: 51d1f3d8e39bffd22bb0d80895635e9b2340742b [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
//____________________________________________________________________________________________________________
// my own includes
//____________________________________________________________________________________________________________
#include "basecontainercontrol.hxx"
//____________________________________________________________________________________________________________
// includes of other projects
//____________________________________________________________________________________________________________
#include <cppuhelper/typeprovider.hxx>
//____________________________________________________________________________________________________________
// includes of my own project
//____________________________________________________________________________________________________________
//____________________________________________________________________________________________________________
// namespaces
//____________________________________________________________________________________________________________
using namespace ::cppu ;
using namespace ::osl ;
using namespace ::rtl ;
using namespace ::com::sun::star::uno ;
using namespace ::com::sun::star::lang ;
using namespace ::com::sun::star::awt ;
using namespace ::com::sun::star::container ;
namespace unocontrols{
//____________________________________________________________________________________________________________
// construct/destruct
//____________________________________________________________________________________________________________
BaseContainerControl::BaseContainerControl( const Reference< XMultiServiceFactory >& xFactory )
: BaseControl ( xFactory )
, m_aListeners ( m_aMutex )
{
// initialize info list for controls
m_pControlInfoList = new IMPL_ControlInfoList ;
}
BaseContainerControl::~BaseContainerControl()
{
impl_cleanMemory();
}
//____________________________________________________________________________________________________________
// XInterface
//____________________________________________________________________________________________________________
Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException )
{
// Attention:
// Don't use mutex or guard in this method!!! Is a method of XInterface.
Any aReturn ;
Reference< XInterface > xDel = BaseControl::impl_getDelegator();
if ( xDel.is() == sal_True )
{
// If an delegator exist, forward question to his queryInterface.
// Delegator will ask his own queryAggregation!
aReturn = xDel->queryInterface( rType );
}
else
{
// If an delegator unknown, forward question to own queryAggregation.
aReturn = queryAggregation( rType );
}
return aReturn ;
}
//____________________________________________________________________________________________________________
// XTypeProvider
//____________________________________________________________________________________________________________
Sequence< Type > SAL_CALL BaseContainerControl::getTypes() throw( RuntimeException )
{
// Optimize this method !
// We initialize a static variable only one time. And we don't must use a mutex at every call!
// For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
static OTypeCollection* pTypeCollection = NULL ;
if ( pTypeCollection == NULL )
{
// Ready for multithreading; get global mutex for first call of this method only! see before
MutexGuard aGuard( Mutex::getGlobalMutex() );
// Control these pointer again ... it can be, that another instance will be faster then these!
if ( pTypeCollection == NULL )
{
// Create a static typecollection ...
static OTypeCollection aTypeCollection ( ::getCppuType(( const Reference< XControlModel >*)NULL ) ,
::getCppuType(( const Reference< XControlContainer >*)NULL ) ,
BaseControl::getTypes()
);
// ... and set his address to static pointer!
pTypeCollection = &aTypeCollection ;
}
}
return pTypeCollection->getTypes();
}
//____________________________________________________________________________________________________________
// XAggregation
//____________________________________________________________________________________________________________
Any SAL_CALL BaseContainerControl::queryAggregation( const Type& aType ) throw( RuntimeException )
{
// Ask for my own supported interfaces ...
// Attention: XTypeProvider and XInterface are supported by OComponentHelper!
Any aReturn ( ::cppu::queryInterface( aType ,
static_cast< XControlModel* > ( this ) ,
static_cast< XControlContainer* > ( this )
)
);
// If searched interface supported by this class ...
if ( aReturn.hasValue() == sal_True )
{
// ... return this information.
return aReturn ;
}
else
{
// Else; ... ask baseclass for interfaces!
return BaseControl::queryAggregation( aType );
}
}
//____________________________________________________________________________________________________________
// XControl
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
const Reference< XWindowPeer >& xParent ) throw( RuntimeException )
{
if ( getPeer().is() == sal_False )
{
// create own peer
BaseControl::createPeer( xToolkit, xParent );
// create peers at all childs
Sequence< Reference< XControl > > seqControlList = getControls();
sal_uInt32 nControls = seqControlList.getLength();
for ( sal_uInt32 n=0; n<nControls; n++ )
{
seqControlList.getArray()[n]->createPeer( xToolkit, getPeer() );
}
// activate new tab order
impl_activateTabControllers();
/*
Reference< XVclContainerPeer > xC;
mxPeer->queryInterface( ::getCppuType((const Reference< XVclContainerPeer >*)0), xC );
xC->enableDialogControl( sal_True );
*/
}
}
//____________________________________________________________________________________________________________
// XControl
//____________________________________________________________________________________________________________
sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException )
{
// This object has NO model.
return sal_False ;
}
//____________________________________________________________________________________________________________
// XControl
//____________________________________________________________________________________________________________
Reference< XControlModel > SAL_CALL BaseContainerControl::getModel() throw( RuntimeException )
{
// This object has NO model.
// return (XControlModel*)this ;
return Reference< XControlModel >();
}
//____________________________________________________________________________________________________________
// XComponent
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::dispose() throw( RuntimeException )
{
// 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
// Ready for multithreading
MutexGuard aGuard( m_aMutex );
// remove listeners
EventObject aObject ;
aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY );
m_aListeners.disposeAndClear( aObject );
// remove controls
Sequence< Reference< XControl > > seqCtrls = getControls();
Reference< XControl > * pCtrls = seqCtrls.getArray();
sal_uInt32 nCtrls = seqCtrls.getLength();
sal_uInt32 nMaxCount = m_pControlInfoList->Count();
sal_uInt32 nCount = 0;
for ( nCount = 0; nCount < nMaxCount; ++nCount )
{
delete m_pControlInfoList->GetObject( 0 );
}
m_pControlInfoList->Clear();
for ( nCount = 0; nCount < nCtrls; ++nCount )
{
pCtrls [ nCount ] -> removeEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ;
pCtrls [ nCount ] -> dispose ( ) ;
}
// call baseclass
BaseControl::dispose();
}
//____________________________________________________________________________________________________________
// XEventListener
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent ) throw( RuntimeException )
{
Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
// "removeControl" remove only, when control is an active control
removeControl( xControl );
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException )
{
if ( !rControl.is () )
return;
// take memory for new item
IMPL_ControlInfo* pNewControl = new IMPL_ControlInfo ;
if (pNewControl!=(IMPL_ControlInfo*)0)
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
// set control
pNewControl->sName = rName ;
pNewControl->xControl = rControl ;
// and insert in list
m_pControlInfoList->Insert ( pNewControl, LIST_APPEND ) ;
// initialize new control
pNewControl->xControl->setContext ( (OWeakObject*)this ) ;
pNewControl->xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) ) ;
// when container has a peer ...
if (getPeer().is())
{
// .. then create a peer on child
pNewControl->xControl->createPeer ( getPeer()->getToolkit(), getPeer() ) ;
impl_activateTabControllers () ;
}
// Send message to all listener
OInterfaceContainerHelper* pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ;
if (pInterfaceContainer)
{
// Build event
ContainerEvent aEvent ;
aEvent.Source = *this ;
aEvent.Element <<= rControl ;
// Get all listener
OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ;
// Send event
while ( aIterator.hasMoreElements() )
{
((XContainerListener*)aIterator.next())->elementInserted (aEvent) ;
}
}
}
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::addContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard ( m_aMutex ) ;
m_aListeners.addInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ;
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException )
{
if ( rControl.is() )
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
sal_uInt32 nControls = m_pControlInfoList->Count () ;
for ( sal_uInt32 n=0; n<nControls; n++ )
{
// Search for right control
IMPL_ControlInfo* pControl = m_pControlInfoList->GetObject (n) ;
if ( rControl == pControl->xControl )
{
//.is it found ... remove listener from control
pControl->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) )) ;
pControl->xControl->setContext ( Reference< XInterface > () ) ;
// ... free memory
delete pControl ;
m_pControlInfoList->Remove (n) ;
// Send message to all other listener
OInterfaceContainerHelper * pInterfaceContainer = m_aListeners.getContainer( ::getCppuType((const Reference< XContainerListener >*)0) ) ;
if (pInterfaceContainer)
{
ContainerEvent aEvent ;
aEvent.Source = *this ;
aEvent.Element <<= rControl ;
OInterfaceIteratorHelper aIterator (*pInterfaceContainer) ;
while ( aIterator.hasMoreElements() )
{
((XContainerListener*)aIterator.next())->elementRemoved (aEvent) ;
}
}
// Break "for" !
break ;
}
}
}
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::removeContainerListener ( const Reference< XContainerListener > & rListener ) throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard ( m_aMutex ) ;
m_aListeners.removeInterface ( ::getCppuType((const Reference< XContainerListener >*)0), rListener ) ;
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText ) throw( RuntimeException )
{
// go down to each parent
Reference< XControlContainer > xContainer ( getContext(), UNO_QUERY ) ;
if ( xContainer.is () )
{
xContainer->setStatusText ( rStatusText ) ;
}
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName ) throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard ( Mutex::getGlobalMutex() ) ;
Reference< XControl > xRetControl = Reference< XControl > () ;
sal_uInt32 nControls = m_pControlInfoList->Count () ;
// Search for right control
for( sal_uInt32 nCount = 0; nCount < nControls; ++nCount )
{
IMPL_ControlInfo* pSearchControl = m_pControlInfoList->GetObject ( nCount ) ;
if ( pSearchControl->sName == rName )
{
// We have found it ...
// Break operation and return.
return pSearchControl->xControl ;
}
}
// We have not found it ... return NULL.
return Reference< XControl > () ;
}
//____________________________________________________________________________________________________________
// XControlContainer
//____________________________________________________________________________________________________________
Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls () throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard ( Mutex::getGlobalMutex() ) ;
sal_uInt32 nControls = m_pControlInfoList->Count () ;
Sequence< Reference< XControl > > aDescriptor ( nControls ) ;
Reference< XControl > * pDestination = aDescriptor.getArray () ;
sal_uInt32 nCount = 0 ;
// Copy controls to sequence
for( nCount = 0; nCount < nControls; ++nCount )
{
IMPL_ControlInfo* pCopyControl = m_pControlInfoList->GetObject ( nCount ) ;
pDestination [ nCount ] = pCopyControl->xControl ;
}
// Return sequence
return aDescriptor ;
}
//____________________________________________________________________________________________________________
// XUnoControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::addTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
sal_uInt32 nOldCount = m_xTabControllerList.getLength () ;
Sequence< Reference< XTabController > > aNewList ( nOldCount + 1 ) ;
sal_uInt32 nCount = 0 ;
// Copy old elements of sequence to new list.
for ( nCount = 0; nCount < nOldCount; ++nCount )
{
aNewList.getArray () [nCount] = m_xTabControllerList.getConstArray () [nCount] ;
}
// Add new controller
aNewList.getArray () [nOldCount] = rTabController ;
// change old and new list
m_xTabControllerList = aNewList ;
}
//____________________________________________________________________________________________________________
// XUnoControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::removeTabController ( const Reference< XTabController > & rTabController ) throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
sal_uInt32 nMaxCount = m_xTabControllerList.getLength () ;
sal_uInt32 nCount = 0 ;
// Search right tabcontroller ...
for ( nCount = 0; nCount < nMaxCount; ++nCount )
{
if ( m_xTabControllerList.getConstArray () [nCount] == rTabController )
{
// ... if is it found ... remove it from list.
m_xTabControllerList.getArray()[ nCount ] = Reference< XTabController >() ;
break ;
}
}
}
//____________________________________________________________________________________________________________
// XUnoControlContainer
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::setTabControllers ( const Sequence< Reference< XTabController > >& rTabControllers ) throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
m_xTabControllerList = rTabControllers ;
}
Sequence<Reference< XTabController > > SAL_CALL BaseContainerControl::getTabControllers () throw( RuntimeException )
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
return m_xTabControllerList ;
}
//____________________________________________________________________________________________________________
// XWindow
//____________________________________________________________________________________________________________
void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible ) throw( RuntimeException )
{
// override baseclass definition
BaseControl::setVisible ( bVisible ) ;
// is it a top window ?
if ( !getContext().is() && bVisible )
{
// then show it automaticly
createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () ) ;
}
}
//____________________________________________________________________________________________________________
// protected method
//____________________________________________________________________________________________________________
WindowDescriptor* BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
{
// - used from "createPeer()" to set the values of an WindowDescriptor !!!
// - if you will change the descriptor-values, you must override thid virtuell function
// - the caller must release the memory for this dynamical descriptor !!!
WindowDescriptor * aDescriptor = new WindowDescriptor ;
aDescriptor->Type = WindowClass_CONTAINER ;
aDescriptor->WindowServiceName = OUString(RTL_CONSTASCII_USTRINGPARAM("window")) ;
aDescriptor->ParentIndex = -1 ;
aDescriptor->Parent = rParentPeer ;
aDescriptor->Bounds = getPosSize () ;
aDescriptor->WindowAttributes = 0 ;
return aDescriptor ;
}
//____________________________________________________________________________________________________________
// protected method
//____________________________________________________________________________________________________________
void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
{
/*
if (rGraphics.is())
{
for ( sal_uInt32 n=m_pControlInfoList->Count(); n; )
{
ControlInfo* pSearchControl = m_pControlInfoList->GetObject (--n) ;
pSearchControl->xControl->paint ( nX, nY, rGraphics ) ;
}
}
*/
}
//____________________________________________________________________________________________________________
// private method
//____________________________________________________________________________________________________________
void BaseContainerControl::impl_activateTabControllers ()
{
// Ready for multithreading
MutexGuard aGuard (m_aMutex) ;
sal_uInt32 nMaxCount = m_xTabControllerList.getLength () ;
sal_uInt32 nCount = 0 ;
for ( nCount = 0; nCount < nMaxCount; ++nCount )
{
m_xTabControllerList.getArray () [nCount]->setContainer ( this ) ;
m_xTabControllerList.getArray () [nCount]->activateTabOrder ( ) ;
}
}
//____________________________________________________________________________________________________________
// private method
//____________________________________________________________________________________________________________
void BaseContainerControl::impl_cleanMemory ()
{
// Get count of listitems.
sal_uInt32 nMaxCount = m_pControlInfoList->Count () ;
sal_uInt32 nCount = 0 ;
// Delete all items.
for ( nCount = 0; nCount < nMaxCount; ++nCount )
{
// Delete everytime first element of list!
// We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements!
// If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements!
IMPL_ControlInfo* pSearchControl = m_pControlInfoList->GetObject ( 0 ) ;
delete pSearchControl ;
}
// Delete list himself.
m_pControlInfoList->Clear () ;
delete m_pControlInfoList ;
}
} // namespace unocontrols