bump product version to 5.0.4.1
[LibreOffice.git] / UnoControls / source / base / basecontainercontrol.cxx
blob7c8e5e0e67e77647d90f93528455075cba23158a
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 "basecontainercontrol.hxx"
22 #include <cppuhelper/queryinterface.hxx>
23 #include <cppuhelper/typeprovider.hxx>
25 // namespaces
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{
36 // construct/destruct
38 BaseContainerControl::BaseContainerControl( const Reference< XComponentContext >& rxContext )
39 : BaseControl ( rxContext )
40 , m_aListeners ( m_aMutex )
44 BaseContainerControl::~BaseContainerControl()
46 impl_cleanMemory();
49 // XInterface
51 Any SAL_CALL BaseContainerControl::queryInterface( const Type& rType ) throw( RuntimeException, std::exception )
53 // Attention:
54 // Don't use mutex or guard in this method!!! Is a method of XInterface.
55 Any aReturn;
56 Reference< XInterface > xDel = BaseControl::impl_getDelegator();
57 if ( xDel.is() )
59 // If an delegator exist, forward question to his queryInterface.
60 // Delegator will ask his own queryAggregation!
61 aReturn = xDel->queryInterface( rType );
63 else
65 // If an delegator unknown, forward question to own queryAggregation.
66 aReturn = queryAggregation( rType );
69 return aReturn;
72 // XTypeProvider
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();
102 // XAggregation
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.
118 return aReturn;
120 else
122 // Else; ... ask baseclass for interfaces!
123 return BaseControl::queryAggregation( aType );
127 // XControl
129 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
130 const Reference< XWindowPeer >& xParent ) throw( RuntimeException, std::exception )
132 if ( !getPeer().is() )
134 // create own peer
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();
152 // XControl
154 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& ) throw( RuntimeException, std::exception )
156 // This object has NO model.
157 return false;
160 // XControl
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 >();
169 // XComponent
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 );
179 // remove listeners
180 EventObject aObject;
182 aObject.Source = Reference< XComponent > ( (XControlContainer*)this, UNO_QUERY );
183 m_aListeners.disposeAndClear( aObject );
185 // remove controls
186 Sequence< Reference< XControl > > seqCtrls = getControls();
187 Reference< XControl > * pCtrls = seqCtrls.getArray();
188 sal_uInt32 nCtrls = seqCtrls.getLength();
189 size_t nMaxCount = maControlInfoList.size();
190 size_t nCount = 0;
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 ( );
204 // call baseclass
205 BaseControl::dispose();
208 // XEventListener
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 );
218 // XControlContainer
220 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl ) throw( RuntimeException, std::exception )
222 if ( !rControl.is () )
223 return;
225 // take memory for new item
226 IMPL_ControlInfo* pNewControl = new IMPL_ControlInfo;
228 // Ready for multithreading
229 MutexGuard aGuard (m_aMutex);
231 // set control
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 ...
243 if (getPeer().is())
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)
255 // Build event
256 ContainerEvent aEvent;
258 aEvent.Source = *this;
259 aEvent.Element <<= rControl;
261 // Get all listener
262 OInterfaceIteratorHelper aIterator (*pInterfaceContainer);
264 // Send event
265 while ( aIterator.hasMoreElements() )
267 static_cast<XContainerListener*>(aIterator.next())->elementInserted (aEvent);
272 // XControlContainer
274 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl ) throw( RuntimeException, std::exception )
276 if ( rControl.is() )
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 > () );
293 // ... free memory
294 delete pControl;
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);
316 // Break "for" !
317 break;
323 // XControlContainer
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 );
336 // XControlContainer
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 > ();
362 // XControlContainer
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();
370 size_t nCount = 0;
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;
381 // Return sequence
382 return aDescriptor;
385 // XWindow
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 > () );
400 // protected method
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;
417 return aDescriptor;
420 // protected method
422 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
426 // private method
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 ( );
443 // private method
445 void BaseContainerControl::impl_cleanMemory ()
447 // Get count of listitems.
448 size_t nMaxCount = maControlInfoList.size();
449 size_t nCount = 0;
451 // Delete all items.
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: */