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