LibreOffice Module UnoControls (master)  1
basecontainercontrol.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <basecontainercontrol.hxx>
21 
24 
25 #include <com/sun/star/container/ContainerEvent.hpp>
26 #include <com/sun/star/container/XContainerListener.hpp>
27 #include <com/sun/star/awt/XControlContainer.hpp>
28 
29 // namespaces
30 
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;
37 
38 namespace unocontrols {
39 
40 // construct/destruct
41 
43  : BaseControl ( rxContext )
45 {
46 }
47 
49 {
50 }
51 
52 // XInterface
53 
55 {
56  // Attention:
57  // Don't use mutex or guard in this method!!! Is a method of XInterface.
58  Any aReturn;
60  if ( xDel.is() )
61  {
62  // If a delegator exists, forward question to its queryInterface.
63  // Delegator will ask its own queryAggregation!
64  aReturn = xDel->queryInterface( rType );
65  }
66  else
67  {
68  // If a delegator is unknown, forward question to own queryAggregation.
69  aReturn = queryAggregation( rType );
70  }
71 
72  return aReturn;
73 }
74 
75 // XTypeProvider
76 
77 Sequence< Type > SAL_CALL BaseContainerControl::getTypes()
78 {
79  static OTypeCollection ourTypeCollection(
83 
84  return ourTypeCollection.getTypes();
85 }
86 
87 // XAggregation
88 
90 {
91  // Ask for my own supported interfaces ...
92  // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
93  Any aReturn ( ::cppu::queryInterface( aType ,
94  static_cast< XControlModel* > ( this ) ,
95  static_cast< XControlContainer* > ( this )
96  )
97  );
98 
99  // If searched interface supported by this class ...
100  if ( aReturn.hasValue() )
101  {
102  // ... return this information.
103  return aReturn;
104  }
105  else
106  {
107  // Else; ... ask baseclass for interfaces!
108  return BaseControl::queryAggregation( aType );
109  }
110 }
111 
112 // XControl
113 
114 void SAL_CALL BaseContainerControl::createPeer( const Reference< XToolkit >& xToolkit ,
115  const Reference< XWindowPeer >& xParent )
116 {
117  if ( getPeer().is() )
118  return;
119 
120  // create own peer
121  BaseControl::createPeer( xToolkit, xParent );
122 
123  // create peers at all children
124  Sequence< Reference< XControl > > seqControlList = getControls();
125 
126  for ( auto& rxControl : seqControlList )
127  {
128  rxControl->createPeer( xToolkit, getPeer() );
129  }
130 }
131 
132 // XControl
133 
134 sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& )
135 {
136  // This object has NO model.
137  return false;
138 }
139 
140 // XControl
141 
142 Reference< XControlModel > SAL_CALL BaseContainerControl::getModel()
143 {
144  // This object has NO model.
145  // return (XControlModel*)this;
146  return Reference< XControlModel >();
147 }
148 
149 // XComponent
150 
152 {
153  // Tell everything that this container is now gone.
154  // It's faster if you listen to both the control and the container.
155 
156  // Ready for multithreading
157  MutexGuard aGuard( m_aMutex );
158 
159  // remove listeners
160  EventObject aObject;
161 
162  aObject.Source.set( static_cast<XControlContainer*>(this), UNO_QUERY );
163  m_aListeners.disposeAndClear( aObject );
164 
165  // remove controls
166  const Sequence< Reference< XControl > > seqCtrls = getControls();
167 
168  maControlInfoList.clear();
169 
170  for ( Reference< XControl > const & control : seqCtrls )
171  {
172  control->removeEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) );
173  control->dispose ( );
174  }
175 
176  // call baseclass
178 }
179 
180 // XEventListener
181 
182 void SAL_CALL BaseContainerControl::disposing( const EventObject& rEvent )
183 {
184  Reference< XControl > xControl( rEvent.Source, UNO_QUERY );
185 
186  // "removeControl" remove only, when control is an active control
187  removeControl( xControl );
188 }
189 
190 // XControlContainer
191 
192 void SAL_CALL BaseContainerControl::addControl ( const OUString& rName, const Reference< XControl > & rControl )
193 {
194  if ( !rControl.is () )
195  return;
196 
197  // take memory for new item
198  IMPL_ControlInfo* pNewControl = new IMPL_ControlInfo;
199 
200  // Ready for multithreading
201  MutexGuard aGuard (m_aMutex);
202 
203  // set control
204  pNewControl->sName = rName;
205  pNewControl->xControl = rControl;
206 
207  // and insert in list
208  maControlInfoList.emplace_back( pNewControl );
209 
210  // initialize new control
211  pNewControl->xControl->setContext ( static_cast<OWeakObject*>(this) );
212  pNewControl->xControl->addEventListener ( static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ) );
213 
214  // when container has a peer...
215  if (getPeer().is())
216  {
217  // ... then create a peer on child
218  pNewControl->xControl->createPeer ( getPeer()->getToolkit(), getPeer() );
219  }
220 
221  // Send message to all listener
222  OInterfaceContainerHelper* pInterfaceContainer = m_aListeners.getContainer( cppu::UnoType<XContainerListener>::get());
223 
224  if (!pInterfaceContainer)
225  return;
226 
227  // Build event
228  ContainerEvent aEvent;
229 
230  aEvent.Source = *this;
231  aEvent.Element <<= rControl;
232 
233  // Get all listener
234  OInterfaceIteratorHelper aIterator (*pInterfaceContainer);
235 
236  // Send event
237  while ( aIterator.hasMoreElements() )
238  {
239  static_cast<XContainerListener*>(aIterator.next())->elementInserted (aEvent);
240  }
241 }
242 
243 // XControlContainer
244 
245 void SAL_CALL BaseContainerControl::removeControl ( const Reference< XControl > & rControl )
246 {
247  if ( !rControl.is() )
248  return;
249 
250  // Ready for multithreading
251  MutexGuard aGuard (m_aMutex);
252 
253  size_t nControls = maControlInfoList.size();
254 
255  for ( size_t n = 0; n < nControls; n++ )
256  {
257  // Search for right control
258  IMPL_ControlInfo* pControl = maControlInfoList[ n ].get();
259  if ( rControl == pControl->xControl )
260  {
261  //.is it found ... remove listener from control
262  pControl->xControl->removeEventListener (static_cast< XEventListener* >( static_cast< XWindowListener* >( this ) ));
263  pControl->xControl->setContext ( Reference< XInterface > () );
264 
265  // ... free memory
266  maControlInfoList.erase(maControlInfoList.begin() + n);
267 
268  // Send message to all other listener
269  OInterfaceContainerHelper * pInterfaceContainer = m_aListeners.getContainer( cppu::UnoType<XContainerListener>::get());
270 
271  if (pInterfaceContainer)
272  {
273  ContainerEvent aEvent;
274 
275  aEvent.Source = *this;
276  aEvent.Element <<= rControl;
277 
278  OInterfaceIteratorHelper aIterator (*pInterfaceContainer);
279 
280  while ( aIterator.hasMoreElements() )
281  {
282  static_cast<XContainerListener*>(aIterator.next())->elementRemoved (aEvent);
283  }
284  }
285  // Break "for" !
286  break;
287  }
288  }
289 }
290 
291 // XControlContainer
292 
293 void SAL_CALL BaseContainerControl::setStatusText ( const OUString& rStatusText )
294 {
295  // go down to each parent
296  Reference< XControlContainer > xContainer ( getContext(), UNO_QUERY );
297 
298  if ( xContainer.is () )
299  {
300  xContainer->setStatusText ( rStatusText );
301  }
302 }
303 
304 // XControlContainer
305 
306 Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName )
307 {
308  // Ready for multithreading
309  MutexGuard aGuard ( Mutex::getGlobalMutex() );
310 
311  size_t nControls = maControlInfoList.size();
312 
313  // Search for right control
314  for( size_t nCount = 0; nCount < nControls; ++nCount )
315  {
316  IMPL_ControlInfo* pSearchControl = maControlInfoList[ nCount ].get();
317 
318  if ( pSearchControl->sName == rName )
319  {
320  // We have found it ...
321  // Break operation and return.
322  return pSearchControl->xControl;
323  }
324  }
325 
326  // We have not found it ... return NULL.
327  return Reference< XControl > ();
328 }
329 
330 // XControlContainer
331 
332 Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls ()
333 {
334  // Ready for multithreading
335  MutexGuard aGuard ( Mutex::getGlobalMutex() );
336 
337  size_t nControls = maControlInfoList.size();
338  size_t nCount = 0;
339  Sequence< Reference< XControl > > aDescriptor ( nControls );
340  Reference< XControl > * pDestination = aDescriptor.getArray ();
341 
342  // Copy controls to sequence
343  for( nCount = 0; nCount < nControls; ++nCount )
344  {
345  IMPL_ControlInfo* pCopyControl = maControlInfoList[ nCount ].get();
346  pDestination [ nCount ] = pCopyControl->xControl;
347  }
348 
349  // Return sequence
350  return aDescriptor;
351 }
352 
353 // XWindow
354 
355 void SAL_CALL BaseContainerControl::setVisible ( sal_Bool bVisible )
356 {
357  // override baseclass definition
358  BaseControl::setVisible ( bVisible );
359 
360  // is it a top window ?
361  if ( !getContext().is() && bVisible )
362  {
363  // then show it automatically
364  createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () );
365  }
366 }
367 
368 // protected method
369 
370 WindowDescriptor BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
371 {
372  WindowDescriptor aDescriptor;
373 
374  aDescriptor.Type = WindowClass_CONTAINER;
375  aDescriptor.WindowServiceName = "window";
376  aDescriptor.ParentIndex = -1;
377  aDescriptor.Parent = rParentPeer;
378  aDescriptor.Bounds = getPosSize ();
379  aDescriptor.WindowAttributes = 0;
380 
381  return aDescriptor;
382 }
383 
384 // protected method
385 
386 void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
387 {
388 }
389 
390 } // namespace unocontrols
391 
392 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
osl::Mutex m_aMutex
exports com.sun.star.form. control
virtual void SAL_CALL setVisible(sal_Bool bVisible) override
sal_Int64 n
css::uno::Reference< css::awt::XControl > xControl
virtual css::uno::Reference< css::awt::XControl > SAL_CALL getControl(const OUString &sName) override
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &xToolkit, const css::uno::Reference< css::awt::XWindowPeer > &xParent) override
BaseContainerControl(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &xToolkit, const css::uno::Reference< css::awt::XWindowPeer > &xParent) override
::cppu::OMultiTypeInterfaceContainerHelper m_aListeners
virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel > &xModel) override
virtual void SAL_CALL dispose() override
int nCount
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
give answer, if interface is supported The interfaces are searched by type.
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces XTypeProvider
virtual css::awt::WindowDescriptor impl_getWindowDescriptor(const css::uno::Reference< css::awt::XWindowPeer > &xParentPeer) override
virtual void SAL_CALL setStatusText(const OUString &sStatusText) override
virtual void SAL_CALL disposing()
void SAL_CALL disposeAndClear(const css::lang::EventObject &rEvt)
virtual css::uno::Sequence< css::uno::Reference< css::awt::XControl > > SAL_CALL getControls() override
::std::vector< std::unique_ptr< IMPL_ControlInfo > > maControlInfoList
unsigned char sal_Bool
virtual void SAL_CALL addControl(const OUString &sName, const css::uno::Reference< css::awt::XControl > &xControl) override
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
virtual css::awt::Rectangle SAL_CALL getPosSize() override
virtual void SAL_CALL setVisible(sal_Bool bVisible) override
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
virtual css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getPeer() override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getContext() override
virtual void SAL_CALL removeControl(const css::uno::Reference< css::awt::XControl > &xControl) override
virtual void SAL_CALL dispose() override
const css::uno::Reference< css::uno::XInterface > & impl_getDelegator() const
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces XTypeProvider
virtual void impl_paint(sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< css::awt::XGraphics > &xGraphics) override
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
AnyEventRef aEvent
OInterfaceContainerHelper *SAL_CALL getContainer(const css::uno::Type &rKey) const