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 //______________________________________________________________________________________________________________
25 //	my own include
26 //______________________________________________________________________________________________________________
27 
28 #include "framecontrol.hxx"
29 
30 //______________________________________________________________________________________________________________
31 //	includes of other projects
32 //______________________________________________________________________________________________________________
33 #include <com/sun/star/frame/XDispatchProvider.hpp>
34 #include <com/sun/star/util/XURLTransformer.hpp>
35 #include <com/sun/star/frame/XDispatch.hpp>
36 #include <com/sun/star/frame/FrameSearchFlag.hpp>
37 #include <com/sun/star/frame/FrameSearchFlag.hpp>
38 #include <com/sun/star/beans/PropertyAttribute.hpp>
39 #include <cppuhelper/typeprovider.hxx>
40 #include <vos/diagnose.hxx>
41 
42 //______________________________________________________________________________________________________________
43 //	include of my own project
44 //______________________________________________________________________________________________________________
45 
46 //______________________________________________________________________________________________________________
47 //	namespaces
48 //______________________________________________________________________________________________________________
49 
50 using namespace	::rtl					;
51 using namespace	::osl					;
52 using namespace	::cppu					;
53 using namespace	::com::sun::star::uno	;
54 using namespace	::com::sun::star::lang	;
55 using namespace	::com::sun::star::beans	;
56 using namespace	::com::sun::star::awt	;
57 using namespace	::com::sun::star::frame	;
58 using namespace	::com::sun::star::util	;
59 
60 namespace unocontrols{
61 
62 //______________________________________________________________________________________________________________
63 //	construct/destruct
64 //______________________________________________________________________________________________________________
65 
FrameControl(const Reference<XMultiServiceFactory> & xFactory)66 FrameControl::FrameControl( const Reference< XMultiServiceFactory >& xFactory )
67 	: BaseControl					( xFactory																				)
68 	, OBroadcastHelper				( m_aMutex																				)
69 	, OPropertySetHelper			( *SAL_STATIC_CAST( OBroadcastHelper *, this )	)
70 	, m_aInterfaceContainer			( m_aMutex																				)
71 	, m_aConnectionPointContainer	( m_aMutex																				)
72 {
73 }
74 
~FrameControl()75 FrameControl::~FrameControl()
76 {
77 }
78 
79 //____________________________________________________________________________________________________________
80 //	XInterface
81 //____________________________________________________________________________________________________________
82 
queryInterface(const Type & rType)83 Any SAL_CALL FrameControl::queryInterface( const Type& rType ) throw( RuntimeException )
84 {
85 	// Attention:
86 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
87 	Any aReturn ;
88 	Reference< XInterface > xDel = BaseControl::impl_getDelegator();
89 	if ( xDel.is() )
90 	{
91 		// If a delegator exists, forward question to his queryInterface.
92 		// Delegator will ask his own queryAggregation!
93 		aReturn = xDel->queryInterface( rType );
94 	}
95 	else
96 	{
97 		// If a delegator unknown, forward question to own queryAggregation.
98 		aReturn = queryAggregation( rType );
99 	}
100 
101 	return aReturn ;
102 }
103 
104 //____________________________________________________________________________________________________________
105 //	XInterface
106 //____________________________________________________________________________________________________________
107 
acquire()108 void SAL_CALL FrameControl::acquire() throw()
109 {
110 	// Attention:
111 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
112 
113 	// Forward to baseclass
114 	BaseControl::acquire();
115 }
116 
117 //____________________________________________________________________________________________________________
118 //	XInterface
119 //____________________________________________________________________________________________________________
120 
release()121 void SAL_CALL FrameControl::release() throw()
122 {
123 	// Attention:
124 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
125 
126 	// Forward to baseclass
127 	BaseControl::release();
128 }
129 
130 //____________________________________________________________________________________________________________
131 //	XTypeProvider
132 //____________________________________________________________________________________________________________
133 
getTypes()134 Sequence< Type > SAL_CALL FrameControl::getTypes() throw( RuntimeException )
135 {
136 	// Optimize this method !
137 	// We initialize a static variable only one time. And we don't must use a mutex at every call!
138 	// For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
139 	static OTypeCollection* pTypeCollection = NULL ;
140 
141 	if ( pTypeCollection == NULL )
142 	{
143 		// Ready for multithreading; get global mutex for first call of this method only! see before
144 		MutexGuard aGuard( Mutex::getGlobalMutex() );
145 
146 		// Control these pointer again ... it can be, that another instance will be faster then these!
147 		if ( pTypeCollection == NULL )
148 		{
149 			// Create a static typecollection ...
150 			static OTypeCollection aTypeCollection	(	::getCppuType(( const Reference< XControlModel				>*)NULL )	,
151 														::getCppuType(( const Reference< XControlContainer			>*)NULL )	,
152 														::getCppuType(( const Reference< XConnectionPointContainer	>*)NULL )	,
153 														BaseControl::getTypes()
154 													);
155 			// ... and set his address to static pointer!
156 			pTypeCollection = &aTypeCollection ;
157 		}
158 	}
159 
160 	return pTypeCollection->getTypes();
161 }
162 
163 //____________________________________________________________________________________________________________
164 //	XAggregation
165 //____________________________________________________________________________________________________________
166 
queryAggregation(const Type & aType)167 Any SAL_CALL FrameControl::queryAggregation( const Type& aType ) throw( RuntimeException )
168 {
169 	// Ask for my own supported interfaces ...
170 	// Attention: XTypeProvider and XInterface are supported by OComponentHelper!
171 	Any aReturn	( ::cppu::queryInterface(	aType												,
172 									 		static_cast< XControlModel*				> ( this )	,
173 									 		static_cast< XConnectionPointContainer*	> ( this )
174 										)
175 				);
176 
177 	// If searched interface not supported by this class ...
178 	if ( aReturn.hasValue() == sal_False )
179 	{
180 		// ... ask baseclasses.
181 		aReturn = OPropertySetHelper::queryInterface( aType );
182 		if ( aReturn.hasValue() == sal_False )
183 		{
184 			aReturn = BaseControl::queryAggregation( aType );
185 		}
186 	}
187 
188 	return aReturn ;
189 }
190 
191 //____________________________________________________________________________________________________________
192 //	XControl
193 //____________________________________________________________________________________________________________
194 
createPeer(const Reference<XToolkit> & xToolkit,const Reference<XWindowPeer> & xParentPeer)195 void SAL_CALL FrameControl::createPeer(	const	Reference< XToolkit >&		xToolkit	,
196 										const	Reference< XWindowPeer >&	xParentPeer	) throw( RuntimeException )
197 {
198 	BaseControl::createPeer( xToolkit, xParentPeer );
199 	if ( impl_getPeerWindow().is() )
200 	{
201 		if( m_sComponentURL.getLength() > 0 )
202 		{
203 			impl_createFrame( getPeer(), m_sComponentURL, m_seqLoaderArguments );
204 		}
205 	}
206 }
207 
208 //____________________________________________________________________________________________________________
209 //	XControl
210 //____________________________________________________________________________________________________________
211 
setModel(const Reference<XControlModel> &)212 sal_Bool SAL_CALL FrameControl::setModel( const Reference< XControlModel >& /*xModel*/ ) throw( RuntimeException )
213 {
214 	// We have no model.
215 	return sal_False ;
216 }
217 
218 //____________________________________________________________________________________________________________
219 //	XControl
220 //____________________________________________________________________________________________________________
221 
getModel()222 Reference< XControlModel > SAL_CALL FrameControl::getModel() throw( RuntimeException )
223 {
224 	// We have no model.
225 	return Reference< XControlModel >();
226 }
227 
228 //____________________________________________________________________________________________________________
229 //	XControl
230 //____________________________________________________________________________________________________________
231 
dispose()232 void SAL_CALL FrameControl::dispose() throw( RuntimeException )
233 {
234 	impl_deleteFrame();
235 	BaseControl::dispose();
236 }
237 
238 //____________________________________________________________________________________________________________
239 //	XView
240 //____________________________________________________________________________________________________________
241 
setGraphics(const Reference<XGraphics> &)242 sal_Bool SAL_CALL FrameControl::setGraphics( const Reference< XGraphics >& /*xDevice*/ ) throw( RuntimeException )
243 {
244 	// it is not possible to print this control
245 	return sal_False ;
246 }
247 
248 //____________________________________________________________________________________________________________
249 //	XView
250 //____________________________________________________________________________________________________________
251 
getGraphics()252 Reference< XGraphics > SAL_CALL FrameControl::getGraphics() throw( RuntimeException )
253 {
254 	// when it's not possible to set graphics ! then it's possible to return null
255 	return Reference< XGraphics >();
256 }
257 
258 //____________________________________________________________________________________________________________
259 //	XConnectionPointContainer
260 //____________________________________________________________________________________________________________
261 
getConnectionPointTypes()262 Sequence< Type > SAL_CALL FrameControl::getConnectionPointTypes() throw( RuntimeException )
263 {
264 	// Forwarded to helper class
265 	return m_aConnectionPointContainer.getConnectionPointTypes();
266 }
267 
268 //____________________________________________________________________________________________________________
269 //	XConnectionPointContainer
270 //____________________________________________________________________________________________________________
271 
queryConnectionPoint(const Type & aType)272 Reference< XConnectionPoint > SAL_CALL FrameControl::queryConnectionPoint( const Type& aType ) throw( RuntimeException )
273 {
274 	// Forwarded to helper class
275 	return m_aConnectionPointContainer.queryConnectionPoint( aType );
276 }
277 
278 //____________________________________________________________________________________________________________
279 //	XConnectionPointContainer
280 //____________________________________________________________________________________________________________
281 
advise(const Type & aType,const Reference<XInterface> & xListener)282 void SAL_CALL FrameControl::advise(	const	Type&						aType		,
283 									const	Reference< XInterface >&	xListener	) throw( RuntimeException )
284 {
285 	// Forwarded to helper class
286 	m_aConnectionPointContainer.advise( aType, xListener );
287 }
288 
289 //____________________________________________________________________________________________________________
290 //	XConnectionPointContainer
291 //____________________________________________________________________________________________________________
292 
unadvise(const Type & aType,const Reference<XInterface> & xListener)293 void SAL_CALL FrameControl::unadvise(	const	Type&						aType		,
294 										const	Reference< XInterface >&	xListener	) throw( RuntimeException )
295 {
296 	// Forwarded to helper class
297 	m_aConnectionPointContainer.unadvise( aType, xListener );
298 }
299 
300 //____________________________________________________________________________________________________________
301 //	impl but public method to register service
302 //____________________________________________________________________________________________________________
303 
impl_getStaticSupportedServiceNames()304 const Sequence< OUString > FrameControl::impl_getStaticSupportedServiceNames()
305 {
306 	MutexGuard aGuard( Mutex::getGlobalMutex() );
307 	Sequence< OUString > seqServiceNames( 1 );
308 	seqServiceNames.getArray() [0] = OUString::createFromAscii( SERVICENAME_FRAMECONTROL );
309 	return seqServiceNames ;
310 }
311 
312 //____________________________________________________________________________________________________________
313 //	impl but public method to register service
314 //____________________________________________________________________________________________________________
315 
impl_getStaticImplementationName()316 const OUString FrameControl::impl_getStaticImplementationName()
317 {
318 	return OUString::createFromAscii( IMPLEMENTATIONNAME_FRAMECONTROL );
319 }
320 
321 //____________________________________________________________________________________________________________
322 //	OPropertySetHelper
323 //____________________________________________________________________________________________________________
324 
convertFastPropertyValue(Any & rConvertedValue,Any & rOldValue,sal_Int32 nHandle,const Any & rValue)325 sal_Bool FrameControl::convertFastPropertyValue(		Any&		rConvertedValue	,
326 														Any&		rOldValue		,
327 														sal_Int32	nHandle			,
328 												const	Any&		rValue			) throw( IllegalArgumentException )
329 {
330 	sal_Bool bReturn = sal_False ;
331 	switch (nHandle)
332 	{
333 		case PROPERTYHANDLE_COMPONENTURL		:		rConvertedValue	  = rValue					;
334 														rOldValue		<<= m_sComponentURL			;
335 														bReturn			  = sal_True				;
336 														break ;
337 
338 		case PROPERTYHANDLE_LOADERARGUMENTS		:		rConvertedValue	  = rValue					;
339 														rOldValue		<<= m_seqLoaderArguments	;
340 														bReturn			  = sal_True				;
341 														break ;
342 	}
343 
344 	if ( bReturn == sal_False )
345 	{
346 		throw IllegalArgumentException();
347 	}
348 
349 	return bReturn ;
350 }
351 
352 //____________________________________________________________________________________________________________
353 //	OPropertySetHelper
354 //____________________________________________________________________________________________________________
355 
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any & rValue)356 void FrameControl::setFastPropertyValue_NoBroadcast(			sal_Int32	nHandle	,
357 														const	Any&		rValue	)
358 														throw ( ::com::sun::star::uno::Exception )
359 {
360 	// this method only set the value
361 	MutexGuard	aGuard (m_aMutex) ;
362 	switch (nHandle)
363 	{
364 		case PROPERTYHANDLE_COMPONENTURL		:		rValue >>= m_sComponentURL ;
365 														if (getPeer().is())
366 														{
367 															impl_createFrame ( getPeer(), m_sComponentURL, m_seqLoaderArguments ) ;
368 														}
369 														break ;
370 
371 		case PROPERTYHANDLE_LOADERARGUMENTS		:		rValue >>= m_seqLoaderArguments ;
372 														break ;
373 
374 		default	:										VOS_ENSHURE ( nHandle == -1, ERRORTEXT_VOSENSHURE ) ;
375 	}
376 }
377 
378 //____________________________________________________________________________________________________________
379 //	OPropertySetHelper
380 //____________________________________________________________________________________________________________
381 
getFastPropertyValue(Any & rRet,sal_Int32 nHandle) const382 void FrameControl::getFastPropertyValue(	Any&		rRet	,
383 											sal_Int32	nHandle	) const
384 {
385 	MutexGuard	aGuard ( Mutex::getGlobalMutex() ) ;
386 
387 	switch (nHandle)
388 	{
389 		case PROPERTYHANDLE_COMPONENTURL	:		rRet <<= m_sComponentURL ;
390 													break ;
391 
392 		case PROPERTYHANDLE_LOADERARGUMENTS	:		rRet <<= m_seqLoaderArguments ;
393 													break ;
394 
395 		case PROPERTYHANDLE_FRAME			:		rRet <<= m_xFrame ;
396 							 						break ;
397 
398 		default	:									VOS_ENSHURE ( nHandle == -1, ERRORTEXT_VOSENSHURE ) ;
399 	}
400 }
401 
402 //____________________________________________________________________________________________________________
403 //	OPropertySetHelper
404 //____________________________________________________________________________________________________________
405 
getInfoHelper()406 IPropertyArrayHelper& FrameControl::getInfoHelper()
407 {
408 	// Create a table that map names to index values.
409 	static OPropertyArrayHelper* pInfo ;
410 
411 	if (!pInfo)
412 	{
413 		// global method must be guarded
414 		MutexGuard	aGuard ( Mutex::getGlobalMutex() ) ;
415 
416 		if (!pInfo)
417 		{
418 			pInfo = new OPropertyArrayHelper( impl_getStaticPropertyDescriptor(), sal_True );
419 		}
420 	}
421 
422 	return *pInfo ;
423 }
424 /*
425 //--------------------------------------------------------------------------------------------------
426 // start OConnectionPointContainerHelper
427 //--------------------------------------------------------------------------------------------------
428 Uik* FrameControl::getConnectionPointUiks ( sal_Int32* pCount ) const
429 {
430 	static Uik szUiks[] =
431 	{
432 		((XEventListener*)NULL)->getSmartUik  (),
433 		::getCppuType((const Reference< XPropertyChangeListener >*)0),
434 		::getCppuType((const Reference< XVetoableChangeListener >*)0),
435 		::getCppuType((const Reference< XPropertiesChangeListener >*)0)
436 	} ;
437 
438 	*pCount = 4 ;
439 
440 	return szUiks ;
441 }
442 //--------------------------------------------------------------------------------------------------
443 // end OConnectionPointContainerHelper
444 //--------------------------------------------------------------------------------------------------
445 */
446 
447 //____________________________________________________________________________________________________________
448 //	OPropertySetHelper
449 //____________________________________________________________________________________________________________
450 
getPropertySetInfo()451 Reference< XPropertySetInfo > SAL_CALL FrameControl::getPropertySetInfo() throw( RuntimeException )
452 {
453 	// Optimize this method !
454 	// We initialize a static variable only one time. And we don't must use a mutex at every call!
455 	// For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
456 	static Reference< XPropertySetInfo >* pInfo = (Reference< XPropertySetInfo >*)0 ;
457 	if ( pInfo == (Reference< XPropertySetInfo >*)0 )
458 	{
459 		// Ready for multithreading
460 		MutexGuard aGuard ( Mutex::getGlobalMutex () ) ;
461 		// Control this pointer again, another instance can be faster then these!
462 		if ( pInfo == (Reference< XPropertySetInfo >*)0 )
463 		{
464 			// Create structure of propertysetinfo for baseclass "OPropertySetHelper".
465 			// (Use method "getInfoHelper()".)
466 			static Reference< XPropertySetInfo > xInfo ( createPropertySetInfo ( getInfoHelper () ) ) ;
467 			pInfo = &xInfo ;
468 		}
469 	}
470 	return ( *pInfo ) ;
471 }
472 
473 //____________________________________________________________________________________________________________
474 //	BaseControl
475 //____________________________________________________________________________________________________________
476 
impl_getWindowDescriptor(const Reference<XWindowPeer> & xParentPeer)477 WindowDescriptor* FrameControl::impl_getWindowDescriptor( const Reference< XWindowPeer >& xParentPeer )
478 {
479 	WindowDescriptor* pDescriptor	= new WindowDescriptor	;
480 
481 	pDescriptor->Type				= WindowClass_CONTAINER	;
482 	pDescriptor->ParentIndex		= -1					;
483 	pDescriptor->Parent				= xParentPeer			;
484 	pDescriptor->Bounds				= getPosSize ()			;
485 	pDescriptor->WindowAttributes	= 0						;
486 
487 	return pDescriptor ;
488 }
489 
490 //____________________________________________________________________________________________________________
491 //	private method
492 //____________________________________________________________________________________________________________
493 
impl_createFrame(const Reference<XWindowPeer> & xPeer,const OUString & rURL,const Sequence<PropertyValue> & rArguments)494 void FrameControl::impl_createFrame(	const	Reference< XWindowPeer >&	xPeer		,
495 										const	OUString&					rURL		,
496 										const	Sequence< PropertyValue >&	rArguments	)
497 {
498 	Reference< XFrame > 	xOldFrame	;
499 	Reference< XFrame > 	xNewFrame	;
500 
501 	{
502 		MutexGuard	aGuard ( m_aMutex ) ;
503 		xOldFrame = m_xFrame ;
504 	}
505 
506 	xNewFrame = Reference< XFrame >  ( impl_getMultiServiceFactory()->createInstance ( OUString::createFromAscii( "com.sun.star.frame.Frame" ) ), UNO_QUERY ) ;
507 	Reference< XDispatchProvider >  xDSP ( xNewFrame, UNO_QUERY ) ;
508 
509 	if (xDSP.is())
510 	{
511 		Reference< XWindow >  xWP ( xPeer, UNO_QUERY ) ;
512 		xNewFrame->initialize ( xWP ) ;
513 
514 		//	option
515 		//xFrame->setName( "WhatYouWant" );
516 
517 		Reference< XURLTransformer >  xTrans ( impl_getMultiServiceFactory()->createInstance ( OUString::createFromAscii( "com.sun.star.util.URLTransformer" ) ), UNO_QUERY ) ;
518 		if(xTrans.is())
519 		{
520 			// load file
521 			URL	aURL ;
522 
523 			aURL.Complete = rURL ;
524 			xTrans->parseStrict( aURL ) ;
525 
526 			Reference< XDispatch >  xDisp = xDSP->queryDispatch ( aURL, OUString (), FrameSearchFlag::SELF ) ;
527 			if (xDisp.is())
528 			{
529 				xDisp->dispatch ( aURL, rArguments ) ;
530 			}
531 		}
532 	}
533 
534 	// set the frame
535 	{
536 		MutexGuard aGuard ( m_aMutex ) ;
537 		m_xFrame = xNewFrame ;
538 	}
539 
540 	// notify the listeners
541 	sal_Int32	nFrameId = PROPERTYHANDLE_FRAME ;
542 	Any	aNewFrame ( &xNewFrame, ::getCppuType((const Reference< XFrame >*)0) ) ;
543 	Any	aOldFrame ( &xOldFrame, ::getCppuType((const Reference< XFrame >*)0) ) ;
544 
545 	fire ( &nFrameId, &aNewFrame, &aOldFrame, 1, sal_False ) ;
546 
547 	if (xOldFrame.is())
548 	{
549 		xOldFrame->dispose () ;
550 	}
551 }
552 
553 //____________________________________________________________________________________________________________
554 //	private method
555 //____________________________________________________________________________________________________________
556 
impl_deleteFrame()557 void FrameControl::impl_deleteFrame()
558 {
559 	Reference< XFrame >  xOldFrame;
560 	Reference< XFrame >  xNullFrame;
561 
562 	{
563 		// do not dispose the frame in this guarded section (deadlock?)
564 		MutexGuard aGuard( m_aMutex );
565 		xOldFrame = m_xFrame;
566 		m_xFrame = Reference< XFrame > ();
567 	}
568 
569 	// notify the listeners
570 	sal_Int32 nFrameId = PROPERTYHANDLE_FRAME;
571 	Any aNewFrame( &xNullFrame, ::getCppuType((const Reference< XFrame >*)0) );
572 	Any aOldFrame( &xOldFrame, ::getCppuType((const Reference< XFrame >*)0) );
573 	fire( &nFrameId, &aNewFrame, &aOldFrame, 1, sal_False );
574 
575 	// dispose the frame
576 	if( xOldFrame.is() )
577 		xOldFrame->dispose();
578 }
579 
580 //____________________________________________________________________________________________________________
581 //	private method
582 //____________________________________________________________________________________________________________
583 
impl_getStaticPropertyDescriptor()584 const Sequence< Property > FrameControl::impl_getStaticPropertyDescriptor()
585 {
586 	// All Properties of this implementation. The array must be sorted!
587 	static const Property pPropertys[PROPERTY_COUNT] =
588 	{
589 		Property( OUString::createFromAscii( PROPERTYNAME_COMPONENTURL		), PROPERTYHANDLE_COMPONENTURL		, ::getCppuType((const OUString*)0)					, PropertyAttribute::BOUND | PropertyAttribute::CONSTRAINED	),
590 		Property( OUString::createFromAscii( PROPERTYNAME_FRAME				), PROPERTYHANDLE_FRAME				, ::getCppuType((const Reference< XFrame >*)0)		, PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT	),
591 		Property( OUString::createFromAscii( PROPERTYNAME_LOADERARGUMENTS	), PROPERTYHANDLE_LOADERARGUMENTS	, ::getCppuType((const Sequence< PropertyValue >*)0), PropertyAttribute::BOUND | PropertyAttribute::CONSTRAINED	)
592 	};
593 
594 	static const Sequence< Property > seqPropertys( pPropertys, PROPERTY_COUNT );
595 
596 	return seqPropertys ;
597 }
598 
599 }	// namespace unocontrols
600 
601 /* vim: set noet sw=4 ts=4: */
602