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
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
31using namespace ::cppu;
32using namespace ::osl;
33using namespace ::com::sun::star::uno;
34using namespace ::com::sun::star::lang;
35using namespace ::com::sun::star::awt;
36using namespace ::com::sun::star::container;
37
38namespace unocontrols {
39
40// construct/destruct
41
42BaseContainerControl::BaseContainerControl( const Reference< XComponentContext >& rxContext )
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;
59 Reference< XInterface > xDel = BaseControl::impl_getDelegator();
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
77Sequence< 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
114void 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 : asNonConstRange(seqControlList) )
127 {
128 rxControl->createPeer( xToolkit, getPeer() );
129 }
130}
131
132// XControl
133
134sal_Bool SAL_CALL BaseContainerControl::setModel( const Reference< XControlModel >& )
135{
136 // This object has NO model.
137 return false;
138}
139
140// XControl
141
142Reference< 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
182void 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
192void 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 aNewControl;
199
200 // Ready for multithreading
201 MutexGuard aGuard (m_aMutex);
202
203 // set control
204 aNewControl.sName = rName;
205 aNewControl.xControl = rControl;
206
207 // and insert in list
208 maControlInfoList.emplace_back( aNewControl );
209
210 // initialize new control
211 aNewControl.xControl->setContext ( static_cast<OWeakObject*>(this) );
212 aNewControl.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 aNewControl.xControl->createPeer ( getPeer()->getToolkit(), getPeer() );
219 }
220
221 // Send message to all listener
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 comphelper::OInterfaceIteratorHelper2 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
245void 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 ];
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
270
271 if (pInterfaceContainer)
272 {
273 ContainerEvent aEvent;
274
275 aEvent.Source = *this;
276 aEvent.Element <<= rControl;
277
278 comphelper::OInterfaceIteratorHelper2 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
293void 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
306Reference< XControl > SAL_CALL BaseContainerControl::getControl ( const OUString& rName )
307{
308 // Ready for multithreading
309 MutexGuard aGuard ( Mutex::getGlobalMutex() );
310
311 // Search for right control
312 for( const IMPL_ControlInfo& rSearchControl : maControlInfoList )
313 {
314 if ( rSearchControl.sName == rName )
315 {
316 // We have found it ...
317 // Break operation and return.
318 return rSearchControl.xControl;
319 }
320 }
321
322 // We have not found it ... return NULL.
323 return Reference< XControl > ();
324}
325
326// XControlContainer
327
328Sequence< Reference< XControl > > SAL_CALL BaseContainerControl::getControls ()
329{
330 // Ready for multithreading
331 MutexGuard aGuard ( Mutex::getGlobalMutex() );
332
333 size_t nControls = maControlInfoList.size();
334 size_t nCount = 0;
335 Sequence< Reference< XControl > > aDescriptor ( nControls );
336 Reference< XControl > * pDestination = aDescriptor.getArray ();
337
338 // Copy controls to sequence
339 for( const IMPL_ControlInfo& rCopyControl : maControlInfoList )
340 {
341 pDestination [ nCount++ ] = rCopyControl.xControl;
342 }
343
344 // Return sequence
345 return aDescriptor;
346}
347
348// XWindow
349
351{
352 // override baseclass definition
354
355 // is it a top window ?
356 if ( !getContext().is() && bVisible )
357 {
358 // then show it automatically
359 createPeer ( Reference< XToolkit > (), Reference< XWindowPeer > () );
360 }
361}
362
363// protected method
364
365WindowDescriptor BaseContainerControl::impl_getWindowDescriptor ( const Reference< XWindowPeer > & rParentPeer )
366{
367 WindowDescriptor aDescriptor;
368
369 aDescriptor.Type = WindowClass_CONTAINER;
370 aDescriptor.WindowServiceName = "window";
371 aDescriptor.ParentIndex = -1;
372 aDescriptor.Parent = rParentPeer;
373 aDescriptor.Bounds = getPosSize ();
374 aDescriptor.WindowAttributes = 0;
375
376 return aDescriptor;
377}
378
379// protected method
380
381void BaseContainerControl::impl_paint ( sal_Int32 /*nX*/, sal_Int32 /*nY*/, const Reference< XGraphics > & /*rGraphics*/ )
382{
383}
384
385} // namespace unocontrols
386
387/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
css::uno::XInterface * next()
OInterfaceContainerHelper2 * getContainer(const css::uno::Type &rKey) const
void disposeAndClear(const css::lang::EventObject &rEvt)
mutable::osl::Mutex m_aMutex
virtual void SAL_CALL disposing()
virtual css::uno::Reference< css::awt::XControl > SAL_CALL getControl(const OUString &sName) override
virtual void SAL_CALL dispose() override
virtual void impl_paint(sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< css::awt::XGraphics > &xGraphics) override
virtual css::awt::WindowDescriptor impl_getWindowDescriptor(const css::uno::Reference< css::awt::XWindowPeer > &xParentPeer) override
comphelper::OMultiTypeInterfaceContainerHelper2 m_aListeners
BaseContainerControl(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces @seealso XTypeProvider
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
give answer, if interface is supported @descr The interfaces are searched by type.
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &xToolkit, const css::uno::Reference< css::awt::XWindowPeer > &xParent) override
virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel > &xModel) override
virtual void SAL_CALL setVisible(sal_Bool bVisible) override
::std::vector< IMPL_ControlInfo > maControlInfoList
virtual void SAL_CALL setStatusText(const OUString &sStatusText) override
virtual css::uno::Sequence< css::uno::Reference< css::awt::XControl > > SAL_CALL getControls() override
virtual void SAL_CALL removeControl(const css::uno::Reference< css::awt::XControl > &xControl) override
virtual void SAL_CALL addControl(const OUString &sName, const css::uno::Reference< css::awt::XControl > &xControl) override
virtual void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &xToolkit, const css::uno::Reference< css::awt::XWindowPeer > &xParent) override
const css::uno::Reference< css::uno::XInterface > & impl_getDelegator() const
virtual void SAL_CALL setVisible(sal_Bool bVisible) override
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
get information about supported interfaces @seealso XTypeProvider
virtual css::uno::Reference< css::awt::XWindowPeer > SAL_CALL getPeer() override
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &aType) override
virtual void SAL_CALL dispose() override
virtual css::awt::Rectangle SAL_CALL getPosSize() override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getContext() override
int nCount
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
std::mutex m_aMutex
sal_Int64 n
void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
Type
css::uno::Reference< css::awt::XControl > xControl
bool bVisible
unsigned char sal_Bool