1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 //____________________________________________________________________________________________________________
24 //	my own include
25 //____________________________________________________________________________________________________________
26 
27 #include "multiplexer.hxx"
28 
29 //____________________________________________________________________________________________________________
30 //	includes of other projects
31 //____________________________________________________________________________________________________________
32 #include <vos/diagnose.hxx>
33 
34 //____________________________________________________________________________________________________________
35 //	includes of my own project
36 //____________________________________________________________________________________________________________
37 
38 //____________________________________________________________________________________________________________
39 //	namespaces
40 //____________________________________________________________________________________________________________
41 
42 using namespace	::cppu					;
43 using namespace	::osl					;
44 using namespace	::com::sun::star::uno	;
45 using namespace	::com::sun::star::awt	;
46 using namespace	::com::sun::star::lang	;
47 
48 namespace unocontrols{
49 
50 //____________________________________________________________________________________________________________
51 //	macros
52 //____________________________________________________________________________________________________________
53 
54 #define MULTIPLEX( INTERFACE, METHOD, EVENTTYP, EVENT )																				\
55 																																	\
56 	/* First get all interfaces from container with right type.*/																	\
57 	OInterfaceContainerHelper* pContainer = m_aListenerHolder.getContainer( ::getCppuType((const Reference< INTERFACE >*)0) );	\
58 	/* Do the follow only, if elements in container exist.*/																		\
59 	if( pContainer != NULL )																										\
60 	{																																\
61 		OInterfaceIteratorHelper aIterator( *pContainer );																			\
62 		EVENTTYP aLocalEvent = EVENT;																								\
63 		/* Remark: The control is the event source not the peer.*/																	\
64 		/*         We must change the source of the event.		*/																	\
65 		aLocalEvent.Source = m_xControl ;																							\
66 		/* Is the control not destroyed? */																							\
67 		if( aLocalEvent.Source.is() == sal_True )																					\
68 		{																															\
69 			if( aIterator.hasMoreElements() )																						\
70 			{																														\
71 				INTERFACE * pListener = (INTERFACE *)aIterator.next();															\
72 				try																													\
73 				{																													\
74 					pListener->METHOD( aLocalEvent );																				\
75 				}																													\
76 				catch( RuntimeException& )																							\
77 				{																													\
78 					/* Ignore all system exceptions from the listener! */															\
79 				}																													\
80 			}																														\
81 		}																															\
82 	}
83 
84 //____________________________________________________________________________________________________________
85 //	construct/destruct
86 //____________________________________________________________________________________________________________
87 
OMRCListenerMultiplexerHelper(const Reference<XWindow> & xControl,const Reference<XWindow> & xPeer)88 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper(	const	Reference< XWindow >&	xControl	,
89 																const	Reference< XWindow >&	xPeer		)
90 	: m_xPeer			( xPeer		)
91 	, m_xControl		( xControl	)
92 	, m_aListenerHolder	( m_aMutex	)
93 {
94 }
95 
OMRCListenerMultiplexerHelper(const OMRCListenerMultiplexerHelper &)96 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const OMRCListenerMultiplexerHelper& /*aCopyInstance*/ )
97 	: XFocusListener()
98     , XWindowListener()
99     , XKeyListener()
100     , XMouseListener()
101     , XMouseMotionListener()
102     , XPaintListener()
103     , XTopWindowListener()
104     , OWeakObject()
105     , m_aListenerHolder	( m_aMutex	)
106 {
107 }
108 
~OMRCListenerMultiplexerHelper()109 OMRCListenerMultiplexerHelper::~OMRCListenerMultiplexerHelper()
110 {
111 }
112 
113 //____________________________________________________________________________________________________________
114 //	XInterface
115 //____________________________________________________________________________________________________________
116 
queryInterface(const Type & rType)117 Any SAL_CALL OMRCListenerMultiplexerHelper::queryInterface( const Type& rType ) throw( RuntimeException )
118 {
119 	// Attention:
120 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
121 
122 	// Ask for my own supported interfaces ...
123 	// Attention: XTypeProvider and XInterface are supported by OComponentHelper!
124 	Any aReturn	( ::cppu::queryInterface(	rType											,
125 											static_cast< XWindowListener*		> ( this )	,
126 											static_cast< XKeyListener*			> ( this )	,
127 											static_cast< XFocusListener*		> ( this )	,
128 											static_cast< XMouseListener*		> ( this )	,
129 											static_cast< XMouseMotionListener*	> ( this )	,
130 											static_cast< XPaintListener*		> ( this )	,
131 											static_cast< XTopWindowListener*	> ( this )	,
132 											static_cast< XTopWindowListener*	> ( this )
133 										)
134 				);
135 
136 	// If searched interface supported by this class ...
137 	if ( aReturn.hasValue() == sal_True )
138 	{
139 		// ... return this information.
140 		return aReturn ;
141 	}
142 	else
143 	{
144 		// Else; ... ask baseclass for interfaces!
145 		return OWeakObject::queryInterface( rType );
146 	}
147 }
148 
149 //____________________________________________________________________________________________________________
150 //	XInterface
151 //____________________________________________________________________________________________________________
152 
acquire()153 void SAL_CALL OMRCListenerMultiplexerHelper::acquire() throw()
154 {
155 	// Attention:
156 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
157 
158 	// Forward to baseclass
159 	OWeakObject::acquire();
160 }
161 
162 //____________________________________________________________________________________________________________
163 //	XInterface
164 //____________________________________________________________________________________________________________
165 
release()166 void SAL_CALL OMRCListenerMultiplexerHelper::release() throw()
167 {
168 	// Attention:
169 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
170 
171 	// Forward to baseclass
172 	OWeakObject::release();
173 }
174 
175 //____________________________________________________________________________________________________________
176 //	operator
177 //____________________________________________________________________________________________________________
178 
operator Reference<XInterface>() const179 OMRCListenerMultiplexerHelper::operator Reference< XInterface >() const
180 {
181 	return ((OWeakObject*)this) ;
182 }
183 
184 //____________________________________________________________________________________________________________
185 //	operator
186 //____________________________________________________________________________________________________________
187 
188 //OMRCListenerMultiplexerHelper& OMRCListenerMultiplexerHelper::operator= ( const OMRCListenerMultiplexerHelper& aCopyInstance )
189 //{
190 //	return this ;
191 //}
192 
193 //____________________________________________________________________________________________________________
194 //	container method
195 //____________________________________________________________________________________________________________
196 
setPeer(const Reference<XWindow> & xPeer)197 void OMRCListenerMultiplexerHelper::setPeer( const Reference< XWindow >& xPeer )
198 {
199 	MutexGuard aGuard( m_aMutex );
200 	if( m_xPeer != xPeer )
201 	{
202 		if( m_xPeer.is() )
203 		{
204 			// get all types from the listener added to the peer
205 			Sequence< Type >	aContainedTypes	= m_aListenerHolder.getContainedTypes();
206 			const Type*			pArray			= aContainedTypes.getConstArray();
207 			sal_Int32			nCount			= aContainedTypes.getLength();
208 			// loop over all listener types and remove the listeners from the peer
209 			for( sal_Int32 i=0; i<nCount; i++ )
210 				impl_unadviseFromPeer( m_xPeer, pArray[i] );
211 		}
212 		m_xPeer = xPeer;
213 		if( m_xPeer.is() )
214 		{
215 			// get all types from the listener added to the peer
216 			Sequence< Type >	aContainedTypes	= m_aListenerHolder.getContainedTypes();
217 			const Type*			pArray			= aContainedTypes.getConstArray();
218 			sal_Int32			nCount			= aContainedTypes.getLength();
219 			// loop over all listener types and add the listeners to the peer
220 			for( sal_Int32 i = 0; i < nCount; i++ )
221 				impl_adviseToPeer( m_xPeer, pArray[i] );
222 		}
223 	}
224 }
225 
226 //____________________________________________________________________________________________________________
227 //	container method
228 //____________________________________________________________________________________________________________
229 
disposeAndClear()230 void OMRCListenerMultiplexerHelper::disposeAndClear()
231 {
232 	EventObject aEvent ;
233 	aEvent.Source = m_xControl ;
234 	m_aListenerHolder.disposeAndClear( aEvent );
235 }
236 
237 //____________________________________________________________________________________________________________
238 //	container method
239 //____________________________________________________________________________________________________________
240 
advise(const Type & aType,const Reference<XInterface> & xListener)241 void OMRCListenerMultiplexerHelper::advise(	const	Type&						aType		,
242 											const	Reference< XInterface >&	xListener	)
243 {
244 	MutexGuard aGuard( m_aMutex );
245 	if( m_aListenerHolder.addInterface( aType, xListener ) == 1 )
246 	{
247 		// the first listener is added
248 		if( m_xPeer.is() )
249 		{
250 			impl_adviseToPeer( m_xPeer, aType );
251 		}
252 	}
253 }
254 
255 //____________________________________________________________________________________________________________
256 //	container method
257 //____________________________________________________________________________________________________________
258 
unadvise(const Type & aType,const Reference<XInterface> & xListener)259 void OMRCListenerMultiplexerHelper::unadvise(	const	Type&						aType		,
260 												const	Reference< XInterface >&	xListener	)
261 {
262 	MutexGuard aGuard( m_aMutex );
263 	if( m_aListenerHolder.removeInterface( aType, xListener ) == 0 )
264 	{
265 		// the last listener is removed
266 		if ( m_xPeer.is() )
267 		{
268 			impl_unadviseFromPeer( m_xPeer, aType );
269 		}
270 	}
271 }
272 
273 //____________________________________________________________________________________________________________
274 //	XEventListener
275 //____________________________________________________________________________________________________________
276 
disposing(const EventObject &)277 void SAL_CALL OMRCListenerMultiplexerHelper::disposing( const EventObject& /*aSource*/ ) throw( RuntimeException )
278 {
279 	MutexGuard aGuard( m_aMutex );
280 	// peer is disposed, clear the reference
281 	m_xPeer = Reference< XWindow >();
282 }
283 
284 //____________________________________________________________________________________________________________
285 //	XFcousListener
286 //____________________________________________________________________________________________________________
287 
focusGained(const FocusEvent & aEvent)288 void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
289 {
290 /*
291 	OInterfaceContainerHelper * pCont = aListenerHolder.getContainer( ::getCppuType((const Reference< XFocusListener >*)0) );
292 	if( pCont )
293 	{
294 		OInterfaceIteratorHelper	aIt( *pCont );
295 		FocusEvent aEvt = e;
296 		// Reamark: The control is the event source not the peer. We must change
297 		// the source of the event
298 		xControl.queryHardRef( ((XInterface*)NULL)->getSmartUik(), aEvt.Source );
299 		//.is the control not destroyed
300 		if( aEvt.Source.is() )
301 		{
302 			if( aIt.hasMoreElements() )
303 			{
304 				XFocusListener * pListener = (XFocusListener *)aIt.next();
305 				try
306 				{
307 					pListener->focusGained( aEvt );
308 				}
309 				catch( RuntimeException, e )
310 				{
311 					// ignore all usr system exceptions from the listener
312 				}
313 			}
314 		}
315 	}
316 */
317 	MULTIPLEX( XFocusListener, focusGained, FocusEvent, aEvent )
318 }
319 
320 //____________________________________________________________________________________________________________
321 //	XFcousListener
322 //____________________________________________________________________________________________________________
323 
focusLost(const FocusEvent & aEvent)324 void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
325 {
326 	MULTIPLEX( XFocusListener, focusLost, FocusEvent, aEvent )
327 }
328 
329 //____________________________________________________________________________________________________________
330 //	XWindowListener
331 //____________________________________________________________________________________________________________
332 
windowResized(const WindowEvent & aEvent)333 void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
334 {
335 	MULTIPLEX( XWindowListener, windowResized, WindowEvent, aEvent )
336 }
337 
338 //____________________________________________________________________________________________________________
339 //	XWindowListener
340 //____________________________________________________________________________________________________________
341 
windowMoved(const WindowEvent & aEvent)342 void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
343 {
344 	MULTIPLEX( XWindowListener, windowMoved, WindowEvent, aEvent )
345 }
346 
347 //____________________________________________________________________________________________________________
348 //	XWindowListener
349 //____________________________________________________________________________________________________________
350 
windowShown(const EventObject & aEvent)351 void OMRCListenerMultiplexerHelper::windowShown(const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
352 {
353 	MULTIPLEX( XWindowListener, windowShown, EventObject, aEvent )
354 }
355 
356 //____________________________________________________________________________________________________________
357 //	XWindowListener
358 //____________________________________________________________________________________________________________
359 
windowHidden(const EventObject & aEvent)360 void OMRCListenerMultiplexerHelper::windowHidden(const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
361 {
362 	MULTIPLEX( XWindowListener, windowHidden, EventObject, aEvent )
363 }
364 
365 //____________________________________________________________________________________________________________
366 //	XKeyListener
367 //____________________________________________________________________________________________________________
368 
keyPressed(const KeyEvent & aEvent)369 void OMRCListenerMultiplexerHelper::keyPressed(const KeyEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
370 {
371 	MULTIPLEX( XKeyListener, keyPressed, KeyEvent, aEvent )
372 }
373 
374 //____________________________________________________________________________________________________________
375 //	XKeyListener
376 //____________________________________________________________________________________________________________
377 
keyReleased(const KeyEvent & aEvent)378 void OMRCListenerMultiplexerHelper::keyReleased(const KeyEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
379 {
380 	MULTIPLEX( XKeyListener, keyReleased, KeyEvent, aEvent )
381 }
382 
383 //____________________________________________________________________________________________________________
384 //	XMouseListener
385 //____________________________________________________________________________________________________________
386 
mousePressed(const MouseEvent & aEvent)387 void OMRCListenerMultiplexerHelper::mousePressed(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
388 {
389 	MULTIPLEX( XMouseListener, mousePressed, MouseEvent, aEvent )
390 }
391 
392 //____________________________________________________________________________________________________________
393 //	XMouseListener
394 //____________________________________________________________________________________________________________
395 
mouseReleased(const MouseEvent & aEvent)396 void OMRCListenerMultiplexerHelper::mouseReleased(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
397 {
398 	MULTIPLEX( XMouseListener, mouseReleased, MouseEvent, aEvent )
399 }
400 
401 //____________________________________________________________________________________________________________
402 //	XMouseListener
403 //____________________________________________________________________________________________________________
404 
mouseEntered(const MouseEvent & aEvent)405 void OMRCListenerMultiplexerHelper::mouseEntered(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
406 {
407 	MULTIPLEX( XMouseListener, mouseEntered, MouseEvent, aEvent )
408 }
409 
410 //____________________________________________________________________________________________________________
411 //	XMouseListener
412 //____________________________________________________________________________________________________________
413 
mouseExited(const MouseEvent & aEvent)414 void OMRCListenerMultiplexerHelper::mouseExited(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
415 {
416 	MULTIPLEX( XMouseListener, mouseExited, MouseEvent, aEvent )
417 }
418 
419 //____________________________________________________________________________________________________________
420 //	XMouseMotionListener
421 //____________________________________________________________________________________________________________
422 
mouseDragged(const MouseEvent & aEvent)423 void OMRCListenerMultiplexerHelper::mouseDragged(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
424 {
425 	MULTIPLEX( XMouseMotionListener, mouseDragged, MouseEvent, aEvent )
426 }
427 
428 //____________________________________________________________________________________________________________
429 //	XMouseMotionListener
430 //____________________________________________________________________________________________________________
431 
mouseMoved(const MouseEvent & aEvent)432 void OMRCListenerMultiplexerHelper::mouseMoved(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
433 {
434 	MULTIPLEX( XMouseMotionListener, mouseMoved, MouseEvent, aEvent )
435 }
436 
437 //____________________________________________________________________________________________________________
438 //	XPaintListener
439 //____________________________________________________________________________________________________________
440 
windowPaint(const PaintEvent & aEvent)441 void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
442 {
443 	MULTIPLEX( XPaintListener, windowPaint, PaintEvent, aEvent )
444 }
445 
446 //____________________________________________________________________________________________________________
447 //	XTopWindowListener
448 //____________________________________________________________________________________________________________
449 
windowOpened(const EventObject & aEvent)450 void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
451 {
452 	MULTIPLEX( XTopWindowListener, windowOpened, EventObject, aEvent )
453 }
454 
455 //____________________________________________________________________________________________________________
456 //	XTopWindowListener
457 //____________________________________________________________________________________________________________
458 
windowClosing(const EventObject & aEvent)459 void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
460 {
461 	MULTIPLEX( XTopWindowListener, windowClosing, EventObject, aEvent )
462 }
463 
464 //____________________________________________________________________________________________________________
465 //	XTopWindowListener
466 //____________________________________________________________________________________________________________
467 
windowClosed(const EventObject & aEvent)468 void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
469 {
470 	MULTIPLEX( XTopWindowListener, windowClosed, EventObject, aEvent )
471 }
472 
473 //____________________________________________________________________________________________________________
474 //	XTopWindowListener
475 //____________________________________________________________________________________________________________
476 
windowMinimized(const EventObject & aEvent)477 void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
478 {
479 	MULTIPLEX( XTopWindowListener, windowMinimized, EventObject, aEvent )
480 }
481 
482 //____________________________________________________________________________________________________________
483 //	XTopWindowListener
484 //____________________________________________________________________________________________________________
485 
windowNormalized(const EventObject & aEvent)486 void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
487 {
488 	MULTIPLEX( XTopWindowListener, windowNormalized, EventObject, aEvent )
489 }
490 
491 //____________________________________________________________________________________________________________
492 //	XTopWindowListener
493 //____________________________________________________________________________________________________________
494 
windowActivated(const EventObject & aEvent)495 void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
496 {
497 	MULTIPLEX( XTopWindowListener, windowActivated, EventObject, aEvent )
498 }
499 
500 //____________________________________________________________________________________________________________
501 //	XTopWindowListener
502 //____________________________________________________________________________________________________________
503 
windowDeactivated(const EventObject & aEvent)504 void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
505 {
506 	MULTIPLEX( XTopWindowListener, windowDeactivated, EventObject, aEvent )
507 }
508 
509 //____________________________________________________________________________________________________________
510 //	protected method
511 //____________________________________________________________________________________________________________
512 
impl_adviseToPeer(const Reference<XWindow> & xPeer,const Type & aType)513 void OMRCListenerMultiplexerHelper::impl_adviseToPeer(	const	Reference< XWindow >&	xPeer	,
514 														const	Type&					aType	)
515 {
516 	// add a listener to the source (peer)
517 	if( aType == ::getCppuType((const Reference< XWindowListener >*)0) )
518 		xPeer->addWindowListener( this );
519 	else if( aType == ::getCppuType((const Reference< XKeyListener >*)0) )
520 		xPeer->addKeyListener( this );
521 	else if( aType == ::getCppuType((const Reference< XFocusListener >*)0) )
522 		xPeer->addFocusListener( this );
523 	else if( aType == ::getCppuType((const Reference< XMouseListener >*)0) )
524 		xPeer->addMouseListener( this );
525 	else if( aType == ::getCppuType((const Reference< XMouseMotionListener >*)0) )
526 		xPeer->addMouseMotionListener( this );
527 	else if( aType == ::getCppuType((const Reference< XPaintListener >*)0) )
528 		xPeer->addPaintListener( this );
529 	else if( aType == ::getCppuType((const Reference< XTopWindowListener >*)0) )
530 	{
531 		Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
532 		if( xTop.is() )
533 			xTop->addTopWindowListener( this );
534 	}
535 	else
536 	{
537 		VOS_ENSHURE( sal_False, "unknown listener" );
538 	}
539 }
540 
541 //____________________________________________________________________________________________________________
542 //	protected method
543 //____________________________________________________________________________________________________________
544 
impl_unadviseFromPeer(const Reference<XWindow> & xPeer,const Type & aType)545 void OMRCListenerMultiplexerHelper::impl_unadviseFromPeer(	const	Reference< XWindow >&	xPeer	,
546 															const	Type&					aType	)
547 {
548 	// the last listener is removed, remove the listener from the source (peer)
549 	if( aType == ::getCppuType((const Reference< XWindowListener >*)0) )
550 		xPeer->removeWindowListener( this );
551 	else if( aType == ::getCppuType((const Reference< XKeyListener >*)0) )
552 		xPeer->removeKeyListener( this );
553 	else if( aType == ::getCppuType((const Reference< XFocusListener >*)0) )
554 		xPeer->removeFocusListener( this );
555 	else if( aType == ::getCppuType((const Reference< XMouseListener >*)0) )
556 		xPeer->removeMouseListener( this );
557 	else if( aType == ::getCppuType((const Reference< XMouseMotionListener >*)0) )
558 		xPeer->removeMouseMotionListener( this );
559 	else if( aType == ::getCppuType((const Reference< XPaintListener >*)0) )
560 		xPeer->removePaintListener( this );
561 	else if( aType == ::getCppuType((const Reference< XTopWindowListener >*)0) )
562 	{
563 		Reference< XTopWindow >  xTop( xPeer, UNO_QUERY );
564 		if( xTop.is() )
565 			xTop->removeTopWindowListener( this );
566 	}
567 	else
568 	{
569 		VOS_ENSHURE( sal_False, "unknown listener" );
570 	}
571 }
572 
573 } // namespace unocontrols
574