cid#1640468 Dereference after null check
[LibreOffice.git] / UnoControls / source / base / basecontainercontrol.cxx
blobf78ed4552eacc09b34324ceca60564b8b9d95315
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 #include <com/sun/star/container/ContainerEvent.hpp>
26 #include <com/sun/star/container/XContainerListener.hpp>
27 #include <com/sun/star/awt/XControlContainer.hpp>
29 // namespaces
31 using namespace ::cppu;
32 using namespace ::osl;
33 using namespace ::com::sun::star::uno;
34 using namespace ::com::sun::star::lang;
35 using namespace ::com::sun::star::awt;
36 using namespace ::com::sun::star::container;
38 namespace unocontrols {
40 // construct/destruct
42 BaseContainerControl::BaseContainerControl( const Reference< XComponentContext >& rxContext )
43 : BaseContainerControl_BASE(rxContext)
44 , m_aListeners ( m_aMutex )
48 BaseContainerControl::~BaseContainerControl()
52 // XControl
54 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
55 const Reference< XWindowPeer >& xParent )
57 if ( getPeer().is() )
58 return;
60 // create own peer
61 BaseControl::createPeer( xToolkit, xParent );
63 // create peers at all children
64 Sequence< Reference< XControl > > seqControlList = getControls();
66 for ( auto& rxControl : asNonConstRange(seqControlList) )
68 rxControl->createPeer( xToolkit, getPeer() );
72 // XControl
74 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& )
76 // This object has NO model.
77 return false;
80 // XControl
82 Reference< XControlModel > SAL_CALL BaseContainerControl::getModel()
84 // This object has NO model.
85 // return (XControlModel*)this;
86 return Reference< XControlModel >();
89 // XComponent
91 void SAL_CALL BaseContainerControl::dispose()
93 // Tell everything that this container is now gone.
94 // It's faster if you listen to both the control and the container.
96 // Ready for multithreading
97 MutexGuard aGuard( m_aMutex );
99 // remove listeners
100 EventObject aObject;
102 aObject.Source.set( static_cast<XControlContainer*>(this), UNO_QUERY );
103 m_aListeners.disposeAndClear( aObject );
105 // remove controls
106 const Sequence< Reference< XControl > > seqCtrls = getControls();
108 maControlInfoList.clear();
110 for ( Reference< XControl > const & control : seqCtrls )
112 control->removeEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) );
113 control->dispose ( );
116 // call baseclass
117 BaseControl::dispose();
120 // XEventListener
122 void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent )
124 Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
126 // "removeControl" remove only, when control is an active control
127 removeControl( xControl );
130 // XControlContainer
132 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl )
134 if ( !rControl.is () )
135 return;
137 // take memory for new item
138 IMPL_ControlInfo aNewControl;
140 // Ready for multithreading
141 MutexGuard aGuard (m_aMutex);
143 // set control
144 aNewControl.sName = rName;
145 aNewControl.xControl = rControl;
147 // and insert in list
148 maControlInfoList.emplace_back( aNewControl );
150 // initialize new control
151 aNewControl.xControl->setContext (getXWeak());
152 aNewControl.xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) );
154 // when container has a peer...
155 if (getPeer().is())
157 // ... then create a peer on child
158 aNewControl.xControl->createPeer ( getPeer()->getToolkit(), getPeer() );
161 // Send message to all listener
162 comphelper::OInterfaceContainerHelper2* pInterfaceContainer = m_aListeners.getContainer( cppu::UnoType<XContainerListener>::get());
164 if (!pInterfaceContainer)
165 return;
167 // Build event
168 ContainerEvent aEvent;
170 aEvent.Source = *this;
171 aEvent.Element <<= rControl;
173 // Get all listener
174 comphelper::OInterfaceIteratorHelper2 aIterator (*pInterfaceContainer);
176 // Send event
177 while ( aIterator.hasMoreElements() )
179 static_cast<XContainerListener*>(aIterator.next())->elementInserted (aEvent);
183 // XControlContainer
185 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl )
187 if ( !rControl.is() )
188 return;
190 // Ready for multithreading
191 MutexGuard aGuard (m_aMutex);
193 size_t nControls = maControlInfoList.size();
195 for ( size_t n = 0; n < nControls; n++ )
197 // Search for right control
198 IMPL_ControlInfo* pControl = &maControlInfoList[ n ];
199 if ( rControl == pControl->xControl )
201 //.is it found ... remove listener from control
202 pControl->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ));
203 pControl->xControl->setContext ( Reference< XInterface > () );
205 // ... free memory
206 maControlInfoList.erase(maControlInfoList.begin() + n);
208 // Send message to all other listener
209 comphelper::OInterfaceContainerHelper2 * pInterfaceContainer = m_aListeners.getContainer( cppu::UnoType<XContainerListener>::get());
211 if (pInterfaceContainer)
213 ContainerEvent aEvent;
215 aEvent.Source = *this;
216 aEvent.Element <<= rControl;
218 comphelper::OInterfaceIteratorHelper2 aIterator (*pInterfaceContainer);
220 while ( aIterator.hasMoreElements() )
222 static_cast<XContainerListener*>(aIterator.next())->elementRemoved (aEvent);
225 // Break "for" !
226 break;
231 // XControlContainer
233 void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText )
235 // go down to each parent
236 Reference< XControlContainer > xContainer ( getContext(), UNO_QUERY );
238 if ( xContainer.is () )
240 xContainer->setStatusText ( rStatusText );
244 // XControlContainer
246 Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName )
248 // Ready for multithreading
249 MutexGuard aGuard ( Mutex::getGlobalMutex() );
251 // Search for right control
252 for( const IMPL_ControlInfo& rSearchControl : maControlInfoList )
254 if ( rSearchControl.sName == rName )
256 // We have found it ...
257 // Break operation and return.
258 return rSearchControl.xControl;
262 // We have not found it ... return NULL.
263 return Reference< XControl > ();
266 // XControlContainer
268 Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls ()
270 // Ready for multithreading
271 MutexGuard aGuard ( Mutex::getGlobalMutex() );
273 size_t nControls = maControlInfoList.size();
274 size_t nCount = 0;
275 Sequence< Reference< XControl > > aDescriptor ( nControls );
276 Reference< XControl > * pDestination = aDescriptor.getArray ();
278 // Copy controls to sequence
279 for( const IMPL_ControlInfo& rCopyControl : maControlInfoList )
281 pDestination [ nCount++ ] = rCopyControl.xControl;
284 // Return sequence
285 return aDescriptor;
288 // XWindow
290 void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible )
292 // override baseclass definition
293 BaseControl::setVisible ( bVisible );
295 // is it a top window ?
296 if ( !getContext().is() && bVisible )
298 // then show it automatically
299 createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () );
303 // protected method
305 WindowDescriptor BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
307 WindowDescriptor aDescriptor;
309 aDescriptor.Type = WindowClass_CONTAINER;
310 aDescriptor.WindowServiceName = "window";
311 aDescriptor.ParentIndex = -1;
312 aDescriptor.Parent = rParentPeer;
313 aDescriptor.Bounds = getPosSize ();
314 aDescriptor.WindowAttributes = 0;
316 return aDescriptor;
319 // protected method
321 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
325 } // namespace unocontrols
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */