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 "basecontainercontrol.hxx"
22 #include <cppuhelper/queryinterface.hxx>
23 #include <cppuhelper/typeprovider.hxx>
27 using namespace ::cppu
;
28 using namespace ::osl
;
29 using namespace ::com::sun::star::uno
;
30 using namespace ::com::sun::star::lang
;
31 using namespace ::com::sun::star::awt
;
32 using namespace ::com::sun::star::container
;
34 namespace unocontrols
{
38 BaseContainerControl::BaseContainerControl( const Reference
< XComponentContext
>& rxContext
)
39 : BaseControl ( rxContext
)
40 , m_aListeners ( m_aMutex
)
44 BaseContainerControl::~BaseContainerControl()
51 Any SAL_CALL
BaseContainerControl::queryInterface( const Type
& rType
) throw( RuntimeException
, std::exception
)
54 // Don't use mutex or guard in this method!!! Is a method of XInterface.
56 Reference
< XInterface
> xDel
= BaseControl::impl_getDelegator();
59 // If an delegator exist, forward question to his queryInterface.
60 // Delegator will ask his own queryAggregation!
61 aReturn
= xDel
->queryInterface( rType
);
65 // If an delegator unknown, forward question to own queryAggregation.
66 aReturn
= queryAggregation( rType
);
74 Sequence
< Type
> SAL_CALL
BaseContainerControl::getTypes() throw( RuntimeException
, std::exception
)
76 // Optimize this method !
77 // We initialize a static variable only one time. And we don't must use a mutex at every call!
78 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
79 static OTypeCollection
* pTypeCollection
= NULL
;
81 if ( pTypeCollection
== NULL
)
83 // Ready for multithreading; get global mutex for first call of this method only! see before
84 MutexGuard
aGuard( Mutex::getGlobalMutex() );
86 // Control these pointer again ... it can be, that another instance will be faster then these!
87 if ( pTypeCollection
== NULL
)
89 // Create a static typecollection ...
90 static OTypeCollection
aTypeCollection ( cppu::UnoType
<XControlModel
>::get(),
91 cppu::UnoType
<XControlContainer
>::get(),
92 BaseControl::getTypes()
94 // ... and set his address to static pointer!
95 pTypeCollection
= &aTypeCollection
;
99 return pTypeCollection
->getTypes();
104 Any SAL_CALL
BaseContainerControl::queryAggregation( const Type
& aType
) throw( RuntimeException
, std::exception
)
106 // Ask for my own supported interfaces ...
107 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
108 Any
aReturn ( ::cppu::queryInterface( aType
,
109 static_cast< XControlModel
* > ( this ) ,
110 static_cast< XControlContainer
* > ( this )
114 // If searched interface supported by this class ...
115 if ( aReturn
.hasValue() )
117 // ... return this information.
122 // Else; ... ask baseclass for interfaces!
123 return BaseControl::queryAggregation( aType
);
129 void SAL_CALL
BaseContainerControl::createPeer( const Reference
< XToolkit
>& xToolkit
,
130 const Reference
< XWindowPeer
>& xParent
) throw( RuntimeException
, std::exception
)
132 if ( !getPeer().is() )
135 BaseControl::createPeer( xToolkit
, xParent
);
137 // create peers at all children
138 Sequence
< Reference
< XControl
> > seqControlList
= getControls();
139 sal_uInt32 nControls
= seqControlList
.getLength();
141 for ( sal_uInt32 n
=0; n
<nControls
; n
++ )
143 seqControlList
.getArray()[n
]->createPeer( xToolkit
, getPeer() );
146 // activate new tab order
147 impl_activateTabControllers();
154 sal_Bool SAL_CALL
BaseContainerControl::setModel( const Reference
< XControlModel
>& ) throw( RuntimeException
, std::exception
)
156 // This object has NO model.
162 Reference
< XControlModel
> SAL_CALL
BaseContainerControl::getModel() throw( RuntimeException
, std::exception
)
164 // This object has NO model.
165 // return (XControlModel*)this;
166 return Reference
< XControlModel
>();
171 void SAL_CALL
BaseContainerControl::dispose() throw( RuntimeException
, std::exception
)
173 // Tell everything that this container is now gone.
174 // It's faster if you listen to both the control and the container.
176 // Ready for multithreading
177 MutexGuard
aGuard( m_aMutex
);
182 aObject
.Source
= Reference
< XComponent
> ( (XControlContainer
*)this, UNO_QUERY
);
183 m_aListeners
.disposeAndClear( aObject
);
186 Sequence
< Reference
< XControl
> > seqCtrls
= getControls();
187 Reference
< XControl
> * pCtrls
= seqCtrls
.getArray();
188 sal_uInt32 nCtrls
= seqCtrls
.getLength();
189 size_t nMaxCount
= maControlInfoList
.size();
192 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
194 delete maControlInfoList
[ nCount
];
196 maControlInfoList
.clear();
198 for ( nCount
= 0; nCount
< nCtrls
; ++nCount
)
200 pCtrls
[ nCount
] -> removeEventListener ( static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ) );
201 pCtrls
[ nCount
] -> dispose ( );
205 BaseControl::dispose();
210 void SAL_CALL
BaseContainerControl::disposing( const EventObject
& rEvent
) throw( RuntimeException
, std::exception
)
212 Reference
< XControl
> xControl( rEvent
.Source
, UNO_QUERY
);
214 // "removeControl" remove only, when control is an active control
215 removeControl( xControl
);
220 void SAL_CALL
BaseContainerControl::addControl ( const OUString
& rName
, const Reference
< XControl
> & rControl
) throw( RuntimeException
, std::exception
)
222 if ( !rControl
.is () )
225 // take memory for new item
226 IMPL_ControlInfo
* pNewControl
= new IMPL_ControlInfo
;
228 // Ready for multithreading
229 MutexGuard
aGuard (m_aMutex
);
232 pNewControl
->sName
= rName
;
233 pNewControl
->xControl
= rControl
;
235 // and insert in list
236 maControlInfoList
.push_back( pNewControl
);
238 // initialize new control
239 pNewControl
->xControl
->setContext ( (OWeakObject
*)this );
240 pNewControl
->xControl
->addEventListener ( static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ) );
242 // when container has a peer ...
245 // .. then create a peer on child
246 pNewControl
->xControl
->createPeer ( getPeer()->getToolkit(), getPeer() );
247 impl_activateTabControllers ();
250 // Send message to all listener
251 OInterfaceContainerHelper
* pInterfaceContainer
= m_aListeners
.getContainer( cppu::UnoType
<XContainerListener
>::get());
253 if (pInterfaceContainer
)
256 ContainerEvent aEvent
;
258 aEvent
.Source
= *this;
259 aEvent
.Element
<<= rControl
;
262 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
);
265 while ( aIterator
.hasMoreElements() )
267 static_cast<XContainerListener
*>(aIterator
.next())->elementInserted (aEvent
);
274 void SAL_CALL
BaseContainerControl::removeControl ( const Reference
< XControl
> & rControl
) throw( RuntimeException
, std::exception
)
278 // Ready for multithreading
279 MutexGuard
aGuard (m_aMutex
);
281 size_t nControls
= maControlInfoList
.size();
283 for ( size_t n
= 0; n
< nControls
; n
++ )
285 // Search for right control
286 IMPL_ControlInfo
* pControl
= maControlInfoList
[ n
];
287 if ( rControl
== pControl
->xControl
)
289 //.is it found ... remove listener from control
290 pControl
->xControl
->removeEventListener (static_cast< XEventListener
* >( static_cast< XWindowListener
* >( this ) ));
291 pControl
->xControl
->setContext ( Reference
< XInterface
> () );
295 ::std::vector
<IMPL_ControlInfo
*>::iterator itr
= maControlInfoList
.begin();
296 ::std::advance(itr
, n
);
297 maControlInfoList
.erase(itr
);
299 // Send message to all other listener
300 OInterfaceContainerHelper
* pInterfaceContainer
= m_aListeners
.getContainer( cppu::UnoType
<XContainerListener
>::get());
302 if (pInterfaceContainer
)
304 ContainerEvent aEvent
;
306 aEvent
.Source
= *this;
307 aEvent
.Element
<<= rControl
;
309 OInterfaceIteratorHelper
aIterator (*pInterfaceContainer
);
311 while ( aIterator
.hasMoreElements() )
313 static_cast<XContainerListener
*>(aIterator
.next())->elementRemoved (aEvent
);
325 void SAL_CALL
BaseContainerControl::setStatusText ( const OUString
& rStatusText
) throw( RuntimeException
, std::exception
)
327 // go down to each parent
328 Reference
< XControlContainer
> xContainer ( getContext(), UNO_QUERY
);
330 if ( xContainer
.is () )
332 xContainer
->setStatusText ( rStatusText
);
338 Reference
< XControl
> SAL_CALL
BaseContainerControl::getControl ( const OUString
& rName
) throw( RuntimeException
, std::exception
)
340 // Ready for multithreading
341 MutexGuard
aGuard ( Mutex::getGlobalMutex() );
343 size_t nControls
= maControlInfoList
.size();
345 // Search for right control
346 for( size_t nCount
= 0; nCount
< nControls
; ++nCount
)
348 IMPL_ControlInfo
* pSearchControl
= maControlInfoList
[ nCount
];
350 if ( pSearchControl
->sName
== rName
)
352 // We have found it ...
353 // Break operation and return.
354 return pSearchControl
->xControl
;
358 // We have not found it ... return NULL.
359 return Reference
< XControl
> ();
364 Sequence
< Reference
< XControl
> > SAL_CALL
BaseContainerControl::getControls () throw( RuntimeException
, std::exception
)
366 // Ready for multithreading
367 MutexGuard
aGuard ( Mutex::getGlobalMutex() );
369 size_t nControls
= maControlInfoList
.size();
371 Sequence
< Reference
< XControl
> > aDescriptor ( nControls
);
372 Reference
< XControl
> * pDestination
= aDescriptor
.getArray ();
374 // Copy controls to sequence
375 for( nCount
= 0; nCount
< nControls
; ++nCount
)
377 IMPL_ControlInfo
* pCopyControl
= maControlInfoList
[ nCount
];
378 pDestination
[ nCount
] = pCopyControl
->xControl
;
387 void SAL_CALL
BaseContainerControl::setVisible ( sal_Bool bVisible
) throw( RuntimeException
, std::exception
)
389 // override baseclass definition
390 BaseControl::setVisible ( bVisible
);
392 // is it a top window ?
393 if ( !getContext().is() && bVisible
)
395 // then show it automatically
396 createPeer ( Reference
< XToolkit
> (), Reference
< XWindowPeer
> () );
402 WindowDescriptor
* BaseContainerControl::impl_getWindowDescriptor ( const Reference
< XWindowPeer
> & rParentPeer
)
404 // - used from "createPeer()" to set the values of an WindowDescriptor !!!
405 // - if you will change the descriptor-values, you must override thid virtuell function
406 // - the caller must release the memory for this dynamical descriptor !!!
408 WindowDescriptor
* aDescriptor
= new WindowDescriptor
;
410 aDescriptor
->Type
= WindowClass_CONTAINER
;
411 aDescriptor
->WindowServiceName
= "window";
412 aDescriptor
->ParentIndex
= -1;
413 aDescriptor
->Parent
= rParentPeer
;
414 aDescriptor
->Bounds
= getPosSize ();
415 aDescriptor
->WindowAttributes
= 0;
422 void BaseContainerControl::impl_paint ( sal_Int32
/*nX*/, sal_Int32
/*nY*/, const Reference
< XGraphics
> & /*rGraphics*/ )
428 void BaseContainerControl::impl_activateTabControllers ()
430 // Ready for multithreading
431 MutexGuard
aGuard (m_aMutex
);
433 sal_uInt32 nMaxCount
= m_xTabControllerList
.getLength ();
434 sal_uInt32 nCount
= 0;
436 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
438 m_xTabControllerList
.getArray () [nCount
]->setContainer ( this );
439 m_xTabControllerList
.getArray () [nCount
]->activateTabOrder ( );
445 void BaseContainerControl::impl_cleanMemory ()
447 // Get count of listitems.
448 size_t nMaxCount
= maControlInfoList
.size();
452 for ( nCount
= 0; nCount
< nMaxCount
; ++nCount
)
454 // Delete every time first element of list!
455 // We count from 0 to MAX, where "MAX=count of items" BEFORE we delete some elements!
456 // If we use "GetObject ( nCount )" ... it can be, that we have an index greater then count of current elements!
458 IMPL_ControlInfo
* pSearchControl
= maControlInfoList
[ nCount
];
459 delete pSearchControl
;
462 // Delete list himself.
463 maControlInfoList
.clear ();
466 } // namespace unocontrols
468 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */