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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_scripting.hxx"
26 
27 #include "DialogModelProvider.hxx"
28 #include "dlgprov.hxx"
29 #include "dlgevtatt.hxx"
30 #include <com/sun/star/awt/XControlContainer.hpp>
31 #include <com/sun/star/awt/XWindowPeer.hpp>
32 #include <com/sun/star/io/XInputStreamProvider.hpp>
33 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
34 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
35 #include <com/sun/star/script/XLibraryContainer.hpp>
36 #include <cppuhelper/implementationentry.hxx>
37 #include <cppuhelper/exc_hlp.hxx>
38 #include <com/sun/star/beans/XIntrospection.hpp>
39 #include <com/sun/star/resource/XStringResourceSupplier.hpp>
40 #include <com/sun/star/resource/XStringResourceManager.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
43 #include <com/sun/star/resource/XStringResourceWithLocation.hpp>
44 #include <com/sun/star/document/XEmbeddedScripts.hpp>
45 #include <sfx2/app.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <xmlscript/xmldlg_imexp.hxx>
48 #include <tools/urlobj.hxx>
49 #include <comphelper/namedvaluecollection.hxx>
50 
51 #include <com/sun/star/uri/XUriReference.hpp>
52 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
53 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
54 #include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
55 #include <com/sun/star/util/XMacroExpander.hpp>
56 
57 #include <util/MiscUtils.hxx>
58 
59 using namespace ::com::sun::star;
60 using namespace awt;
61 using namespace lang;
62 using namespace uno;
63 using namespace script;
64 using namespace beans;
65 using namespace document;
66 using namespace ::sf_misc;
67 
68 // component helper namespace
69 namespace comp_DialogModelProvider
70 {
71 
_getImplementationName()72     ::rtl::OUString SAL_CALL _getImplementationName()
73     {
74         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.scripting.DialogModelProvider"));
75     }
76 
_getSupportedServiceNames()77     uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
78     {
79         uno::Sequence< ::rtl::OUString > s(1);
80         s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialogModelProvider"));
81         return s;
82     }
83 
_create(const uno::Reference<uno::XComponentContext> & context)84     uno::Reference< uno::XInterface > SAL_CALL _create(const uno::Reference< uno::XComponentContext > & context) SAL_THROW((uno::Exception))
85     {
86         return static_cast< ::cppu::OWeakObject * >(new dlgprov::DialogModelProvider(context));
87     }
88 } // closing component helper namespace
89 //.........................................................................
90 namespace dlgprov
91 {
92 //.........................................................................
93 
94 static ::rtl::OUString aResourceResolverPropName = ::rtl::OUString::createFromAscii( "ResourceResolver" );
95 
lcl_getStringResourceManager(const Reference<XComponentContext> & i_xContext,const::rtl::OUString & i_sURL)96     Reference< resource::XStringResourceManager > lcl_getStringResourceManager(const Reference< XComponentContext >& i_xContext,const ::rtl::OUString& i_sURL)
97     {
98         INetURLObject aInetObj( i_sURL );
99 	    ::rtl::OUString aDlgName = aInetObj.GetBase();
100 	    aInetObj.removeSegment();
101 	    ::rtl::OUString aDlgLocation = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
102 	    bool bReadOnly = true;
103 	    ::com::sun::star::lang::Locale aLocale = Application::GetSettings().GetUILocale();
104 	    ::rtl::OUString aComment;
105 
106 	    Sequence<Any> aArgs( 6 );
107 	    aArgs[0] <<= aDlgLocation;
108 	    aArgs[1] <<= bReadOnly;
109 	    aArgs[2] <<= aLocale;
110 	    aArgs[3] <<= aDlgName;
111 	    aArgs[4] <<= aComment;
112 
113 	    Reference< task::XInteractionHandler > xDummyHandler;
114 	    aArgs[5] <<= xDummyHandler;
115 	    Reference< XMultiComponentFactory > xSMgr_( i_xContext->getServiceManager(), UNO_QUERY_THROW );
116 	    // TODO: Ctor
117 	    Reference< resource::XStringResourceManager > xStringResourceManager( xSMgr_->createInstanceWithContext
118 		    ( ::rtl::OUString::createFromAscii( "com.sun.star.resource.StringResourceWithLocation" ),
119 			    i_xContext ), UNO_QUERY );
120 	    if( xStringResourceManager.is() )
121 	    {
122 		    Reference< XInitialization > xInit( xStringResourceManager, UNO_QUERY );
123 		    if( xInit.is() )
124 			    xInit->initialize( aArgs );
125 	    }
126         return xStringResourceManager;
127     }
lcl_createControlModel(const Reference<XComponentContext> & i_xContext)128     Reference< container::XNameContainer > lcl_createControlModel(const Reference< XComponentContext >& i_xContext)
129     {
130         Reference< XMultiComponentFactory > xSMgr_( i_xContext->getServiceManager(), UNO_QUERY_THROW );
131         Reference< container::XNameContainer > xControlModel( xSMgr_->createInstanceWithContext( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialogModel" ) ), i_xContext ), UNO_QUERY_THROW );
132         return xControlModel;
133     }
lcl_createDialogModel(const Reference<XComponentContext> & i_xContext,const Reference<io::XInputStream> & xInput,const Reference<resource::XStringResourceManager> & xStringResourceManager,const Any & aDialogSourceURL)134     Reference< container::XNameContainer > lcl_createDialogModel( const Reference< XComponentContext >& i_xContext,
135 		const Reference< io::XInputStream >& xInput,
136 		const Reference< resource::XStringResourceManager >& xStringResourceManager,
137 		const Any &aDialogSourceURL) throw ( Exception )
138     {
139         Reference< container::XNameContainer > xDialogModel(  lcl_createControlModel(i_xContext) );
140 
141 		::rtl::OUString aDlgSrcUrlPropName( RTL_CONSTASCII_USTRINGPARAM( "DialogSourceURL" ) );
142 		Reference< beans::XPropertySet > xDlgPropSet( xDialogModel, UNO_QUERY );
143 		xDlgPropSet->setPropertyValue( aDlgSrcUrlPropName, aDialogSourceURL );
144 
145         ::xmlscript::importDialogModel( xInput, xDialogModel, i_xContext );
146         // Set resource property
147         if( xStringResourceManager.is() )
148         {
149             Reference< beans::XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY );
150             Any aStringResourceManagerAny;
151             aStringResourceManagerAny <<= xStringResourceManager;
152             xDlgPSet->setPropertyValue( aResourceResolverPropName, aStringResourceManagerAny );
153         }
154 
155         return xDialogModel;
156     }
157     // =============================================================================
158     // component operations
159     // =============================================================================
160 
getImplementationName_DialogProviderImpl()161     static ::rtl::OUString getImplementationName_DialogProviderImpl()
162     {
163         static ::rtl::OUString* pImplName = 0;
164 	    if ( !pImplName )
165 	    {
166             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
167             if ( !pImplName )
168 		    {
169                 static ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.DialogProvider" ) );
170 			    pImplName = &aImplName;
171 		    }
172 	    }
173 	    return *pImplName;
174     }
175 
176     // -----------------------------------------------------------------------------
177 
getSupportedServiceNames_DialogProviderImpl()178     static Sequence< ::rtl::OUString > getSupportedServiceNames_DialogProviderImpl()
179     {
180         static Sequence< ::rtl::OUString >* pNames = 0;
181 	    if ( !pNames )
182 	    {
183             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
184 		    if ( !pNames )
185 		    {
186                 static Sequence< ::rtl::OUString > aNames(3);
187                 aNames.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider" ) );
188                 aNames.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.DialogProvider2" ) );
189                 aNames.getArray()[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.ContainerWindowProvider" ) );
190                 pNames = &aNames;
191 		    }
192 	    }
193 	    return *pNames;
194     }
195 
196 
197     // =============================================================================
198     // mutex
199     // =============================================================================
200 
getMutex()201     ::osl::Mutex& getMutex()
202     {
203         static ::osl::Mutex* s_pMutex = 0;
204         if ( !s_pMutex )
205         {
206             ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
207 	        if ( !s_pMutex )
208 	        {
209                 static ::osl::Mutex s_aMutex;
210 		        s_pMutex = &s_aMutex;
211 	        }
212         }
213         return *s_pMutex;
214     }
215 
216 
217     // =============================================================================
218     // DialogProviderImpl
219     // =============================================================================
220 
DialogProviderImpl(const Reference<XComponentContext> & rxContext)221     DialogProviderImpl::DialogProviderImpl( const Reference< XComponentContext >& rxContext )
222         :m_xContext( rxContext )
223         ,m_xModel( 0 )
224     {
225     }
226 
227     // -----------------------------------------------------------------------------
228 
~DialogProviderImpl()229     DialogProviderImpl::~DialogProviderImpl()
230     {
231     }
232 
233     // -----------------------------------------------------------------------------
234 
getStringResourceFromDialogLibrary(Reference<container::XNameContainer> xDialogLib)235 	Reference< resource::XStringResourceManager > getStringResourceFromDialogLibrary
236 		( Reference< container::XNameContainer > xDialogLib )
237 	{
238 		Reference< resource::XStringResourceManager > xStringResourceManager;
239 		if( xDialogLib.is() )
240 		{
241 			Reference< resource::XStringResourceSupplier > xStringResourceSupplier( xDialogLib, UNO_QUERY );
242 			if( xStringResourceSupplier.is() )
243 			{
244 				Reference< resource::XStringResourceResolver >
245 					xStringResourceResolver = xStringResourceSupplier->getStringResource();
246 
247 				xStringResourceManager =
248 					Reference< resource::XStringResourceManager >( xStringResourceResolver, UNO_QUERY );
249 			}
250 		}
251 		return xStringResourceManager;
252 	}
253 
createControlModel()254     Reference< container::XNameContainer > DialogProviderImpl::createControlModel() throw ( Exception )
255     {
256         return lcl_createControlModel(m_xContext);
257     }
258 
createDialogModel(const Reference<io::XInputStream> & xInput,const Reference<resource::XStringResourceManager> & xStringResourceManager,const Any & aDialogSourceURL)259     Reference< container::XNameContainer > DialogProviderImpl::createDialogModel(
260 		const Reference< io::XInputStream >& xInput,
261 		const Reference< resource::XStringResourceManager >& xStringResourceManager,
262 		const Any &aDialogSourceURL) throw ( Exception )
263     {
264 
265 
266         return lcl_createDialogModel(m_xContext,xInput,xStringResourceManager,aDialogSourceURL);
267     }
268 
createDialogModelForBasic()269     Reference< XControlModel > DialogProviderImpl::createDialogModelForBasic() throw ( Exception )
270     {
271         if ( !m_BasicInfo.get() )
272             // shouln't get here
273             throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("No information to create dialog" ) ), Reference< XInterface >() );
274         Reference< resource::XStringResourceManager > xStringResourceManager = getStringResourceFromDialogLibrary( m_BasicInfo->mxDlgLib );
275 
276 		rtl::OUString aURL(RTL_CONSTASCII_USTRINGPARAM("" ));
277 		Any aDialogSourceURL;
278 		aDialogSourceURL <<= aURL;
279         Reference< XControlModel > xCtrlModel( createDialogModel( m_BasicInfo->mxInput, xStringResourceManager, aDialogSourceURL ), UNO_QUERY_THROW );
280         return xCtrlModel;
281     }
282 
createDialogModel(const::rtl::OUString & sURL)283     Reference< XControlModel > DialogProviderImpl::createDialogModel( const ::rtl::OUString& sURL )
284     {
285 
286         ::rtl::OUString aURL( sURL );
287 
288         // parse URL
289         // TODO: use URL parsing class
290         // TODO: decoding of location
291         Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
292 
293         if ( !xSMgr.is() )
294         {
295             throw RuntimeException(
296                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialogModel: Couldn't instantiate MultiComponent factory" ) ),
297                     Reference< XInterface >() );
298         }
299 
300         Reference< uri::XUriReferenceFactory > xFac (
301             xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii(
302             "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY );
303 
304         if  ( !xFac.is() )
305         {
306             throw RuntimeException(
307                 ::rtl::OUString::createFromAscii( "DialogProviderImpl::getDialogModel(), could not instatiate UriReferenceFactory." ),
308                 Reference< XInterface >() );
309         }
310 
311 		// i75778: Support non-script URLs
312 		Reference< io::XInputStream > xInput;
313         Reference< container::XNameContainer > xDialogLib;
314 
315 		// Accept file URL to single dialog
316 		bool bSingleDialog = false;
317 
318 		Reference< util::XMacroExpander > xMacroExpander(
319             m_xContext->getValueByName(
320             ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
321             UNO_QUERY_THROW );
322 
323         Reference< uri::XUriReference > uriRef;
324         for (;;)
325         {
326             uriRef = Reference< uri::XUriReference >( xFac->parse( aURL ), UNO_QUERY );
327             if ( !uriRef.is() )
328             {
329                 ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "DialogProviderImpl::getDialogModel: failed to parse URI: " );
330                 errorMsg += aURL;
331                 throw IllegalArgumentException( errorMsg,
332                                                 Reference< XInterface >(), 1 );
333             }
334             Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
335             if( !sxUri.is() )
336                 break;
337 
338             aURL = sxUri->expand( xMacroExpander );
339         }
340 
341 		Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY );
342         if( !sfUri.is() )
343         {
344 			bSingleDialog = true;
345 
346 			// Try any other URL with SimpleFileAccess
347 			Reference< ucb::XSimpleFileAccess > xSFI =
348 				Reference< ucb::XSimpleFileAccess >( xSMgr->createInstanceWithContext
349 				( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), m_xContext ), UNO_QUERY );
350 
351 			try
352 			{
353 				xInput = xSFI->openFileRead( aURL );
354 			}
355 			catch( Exception& )
356 			{}
357 		}
358 		else
359         {
360 			::rtl::OUString sDescription = sfUri->getName();
361 
362 			sal_Int32 nIndex = 0;
363 
364 			::rtl::OUString sLibName = sDescription.getToken( 0, (sal_Unicode)'.', nIndex );
365 			::rtl::OUString sDlgName;
366 			if ( nIndex != -1 )
367 				sDlgName = sDescription.getToken( 0, (sal_Unicode)'.', nIndex );
368 
369 			::rtl::OUString sLocation = sfUri->getParameter(
370 				::rtl::OUString::createFromAscii( "location" ) );
371 
372 
373 			// get dialog library container
374 			// TODO: dialogs in packages
375 			Reference< XLibraryContainer > xLibContainer;
376 
377 			if ( sLocation == ::rtl::OUString::createFromAscii( "application" ) )
378 			{
379 				xLibContainer = Reference< XLibraryContainer >( SFX_APP()->GetDialogContainer(), UNO_QUERY );
380 			}
381 			else if ( sLocation == ::rtl::OUString::createFromAscii( "document" ) )
382 			{
383                 Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
384                 if ( xDocumentScripts.is() )
385                 {
386                     xLibContainer.set( xDocumentScripts->getDialogLibraries(), UNO_QUERY );
387                     OSL_ENSURE( xLibContainer.is(),
388                         "DialogProviderImpl::createDialogModel: invalid dialog container!" );
389                 }
390 			}
391 			else
392 			{
393                 Sequence< ::rtl::OUString > aOpenDocsTdocURLs( MiscUtils::allOpenTDocUrls( m_xContext ) );
394                 const ::rtl::OUString* pTdocURL = aOpenDocsTdocURLs.getConstArray();
395                 const ::rtl::OUString* pTdocURLEnd = aOpenDocsTdocURLs.getConstArray() + aOpenDocsTdocURLs.getLength();
396                 for ( ; pTdocURL != pTdocURLEnd; ++pTdocURL )
397                 {
398                     Reference< frame::XModel > xModel( MiscUtils::tDocUrlToModel( *pTdocURL ) );
399                     OSL_ENSURE( xModel.is(), "DialogProviderImpl::createDialogModel: invalid document model!" );
400                     if ( !xModel.is() )
401                         continue;
402 
403                     ::rtl::OUString sDocURL = xModel->getURL();
404 					if ( sDocURL.getLength() == 0 )
405 					{
406                         ::comphelper::NamedValueCollection aModelArgs( xModel->getArgs() );
407                         sDocURL = aModelArgs.getOrDefault( "Title", sDocURL );
408 					}
409 
410 					if ( sLocation != sDocURL )
411                         continue;
412 
413                     Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
414                     if ( !xDocumentScripts.is() )
415                         continue;
416 
417                     xLibContainer.set( xDocumentScripts->getDialogLibraries(), UNO_QUERY );
418                     OSL_ENSURE( xLibContainer.is(),
419                         "DialogProviderImpl::createDialogModel: invalid dialog container!" );
420                 }
421 			}
422 
423 			// get input stream provider
424 			Reference< io::XInputStreamProvider > xISP;
425 			if ( xLibContainer.is() )
426 			{
427 				// load dialog library
428 				if ( !xLibContainer->isLibraryLoaded( sLibName ) )
429 					xLibContainer->loadLibrary( sLibName );
430 
431 				// get dialog library
432 				if ( xLibContainer->hasByName( sLibName ) )
433 				{
434 					Any aElement = xLibContainer->getByName( sLibName );
435 					aElement >>= xDialogLib;
436 				}
437 
438 				if ( xDialogLib.is() )
439 				{
440 					// get input stream provider
441 					if ( xDialogLib->hasByName( sDlgName ) )
442 					{
443 						Any aElement = xDialogLib->getByName( sDlgName );
444 						aElement >>= xISP;
445 					}
446 
447 					if ( !xISP.is() )
448 					{
449 						throw IllegalArgumentException(
450 							::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialogModel: dialog not found!" ) ),
451 							Reference< XInterface >(), 1 );
452 					}
453 				}
454 				else
455 				{
456 					throw IllegalArgumentException(
457 						::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialogModel: library not found!" ) ),
458 						Reference< XInterface >(), 1 );
459 				}
460 			}
461 			else
462 			{
463 				throw IllegalArgumentException(
464 					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getDialog: library container not found!" ) ),
465 					Reference< XInterface >(), 1 );
466 			}
467 
468 			if ( xISP.is() )
469 				xInput = xISP->createInputStream();
470 		}
471 
472         // import dialog model
473         Reference< XControlModel > xCtrlModel;
474         if ( xInput.is() && m_xContext.is() )
475         {
476 			Reference< resource::XStringResourceManager > xStringResourceManager;
477 			if( bSingleDialog )
478 			{
479 				xStringResourceManager = lcl_getStringResourceManager(m_xContext,aURL);
480 			}
481 			else if( xDialogLib.is() )
482             {
483 				xStringResourceManager = getStringResourceFromDialogLibrary( xDialogLib );
484 			}
485 
486 			Any aDialogSourceURLAny;
487 			aDialogSourceURLAny <<= aURL;
488 
489 			Reference< container::XNameContainer > xDialogModel( createDialogModel( xInput , xStringResourceManager, aDialogSourceURLAny  ), UNO_QUERY_THROW);
490 
491 			xCtrlModel = Reference< XControlModel >( xDialogModel, UNO_QUERY );
492         }
493         return xCtrlModel;
494     }
495 
496     // -----------------------------------------------------------------------------
497 
createDialogControl(const Reference<XControlModel> & rxDialogModel,const Reference<XWindowPeer> & xParent)498     Reference< XControl > DialogProviderImpl::createDialogControl
499 		( const Reference< XControlModel >& rxDialogModel, const Reference< XWindowPeer >& xParent )
500     {
501         OSL_ENSURE( rxDialogModel.is(), "DialogProviderImpl::getDialogControl: no dialog model" );
502 
503         Reference< XControl > xDialogControl;
504 
505         if ( m_xContext.is() )
506         {
507             Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
508 
509             if ( xSMgr.is() )
510             {
511                 xDialogControl = Reference< XControl >( xSMgr->createInstanceWithContext(
512                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlDialog" ) ), m_xContext ), UNO_QUERY );
513 
514                 if ( xDialogControl.is() )
515                 {
516                     // set the model
517                     if ( rxDialogModel.is() )
518                         xDialogControl->setModel( rxDialogModel );
519 
520                     // set visible
521                     Reference< XWindow > xW( xDialogControl, UNO_QUERY );
522                     if ( xW.is() )
523                         xW->setVisible( sal_False );
524 
525                     // get the parent of the dialog control
526                     Reference< XWindowPeer > xPeer;
527 					if( xParent.is() )
528 					{
529 						xPeer = xParent;
530 					}
531                     else if ( m_xModel.is() )
532                     {
533                         Reference< frame::XController > xController( m_xModel->getCurrentController(), UNO_QUERY );
534                         if ( xController.is() )
535                         {
536                             Reference< frame::XFrame > xFrame( xController->getFrame(), UNO_QUERY );
537                             if ( xFrame.is() )
538                                 xPeer = Reference< XWindowPeer>( xFrame->getContainerWindow(), UNO_QUERY );
539                         }
540                     }
541 
542                     // create a peer
543                     Reference< XToolkit> xToolkit( xSMgr->createInstanceWithContext(
544                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ), m_xContext ), UNO_QUERY );
545                     if ( xToolkit.is() )
546                         xDialogControl->createPeer( xToolkit, xPeer );
547                 }
548             }
549         }
550 
551         return xDialogControl;
552     }
553 
554     // -----------------------------------------------------------------------------
555 
attachControlEvents(const Reference<XControl> & rxControl,const Reference<XInterface> & rxHandler,const Reference<XIntrospectionAccess> & rxIntrospectionAccess,bool bDialogProviderMode)556     void DialogProviderImpl::attachControlEvents(
557 		const Reference< XControl >& rxControl,
558 		const Reference< XInterface >& rxHandler,
559 		const Reference< XIntrospectionAccess >& rxIntrospectionAccess,
560 		bool bDialogProviderMode )
561     {
562         if ( rxControl.is() )
563         {
564             Reference< XControlContainer > xControlContainer( rxControl, UNO_QUERY );
565 
566             if ( xControlContainer.is() )
567             {
568                 Sequence< Reference< XControl > > aControls = xControlContainer->getControls();
569                 const Reference< XControl >* pControls = aControls.getConstArray();
570                 sal_Int32 nControlCount = aControls.getLength();
571 
572                 Sequence< Reference< XInterface > > aObjects( nControlCount + 1 );
573                 Reference< XInterface >* pObjects = aObjects.getArray();
574                 for ( sal_Int32 i = 0; i < nControlCount; ++i )
575                 {
576                     pObjects[i] = Reference< XInterface >( pControls[i], UNO_QUERY );
577                 }
578 
579                 // also add the dialog control itself to the sequence
580                 pObjects[nControlCount] = Reference< XInterface >( rxControl, UNO_QUERY );
581 
582 				Reference< XScriptEventsAttacher > xScriptEventsAttacher = new DialogEventsAttacherImpl
583 					( m_xContext, m_xModel, rxControl, rxHandler, rxIntrospectionAccess,
584 					  bDialogProviderMode, ( m_BasicInfo.get() ? m_BasicInfo->mxBasicRTLListener : NULL ) );
585 
586                 Any aHelper;
587                 xScriptEventsAttacher->attachEvents( aObjects, Reference< XScriptListener >(), aHelper );
588             }
589         }
590     }
591 
inspectHandler(const Reference<XInterface> & rxHandler)592 	Reference< XIntrospectionAccess > DialogProviderImpl::inspectHandler( const Reference< XInterface >& rxHandler )
593 	{
594 		Reference< XIntrospectionAccess > xIntrospectionAccess;
595 		static Reference< XIntrospection > xIntrospection;
596 
597 		if( !rxHandler.is() )
598 			return xIntrospectionAccess;
599 
600 		if( !xIntrospection.is() )
601 		{
602 			Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
603 			if ( !xSMgr.is() )
604 			{
605 				throw RuntimeException(
606 					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::getIntrospectionAccess: Couldn't instantiate MultiComponent factory" ) ),
607 						Reference< XInterface >() );
608 			}
609 
610 			// Get introspection service
611 			Reference< XInterface > xI = xSMgr->createInstanceWithContext
612 				( rtl::OUString::createFromAscii("com.sun.star.beans.Introspection"), m_xContext );
613 			if (xI.is())
614 				xIntrospection = Reference< XIntrospection >::query( xI );
615 		}
616 
617 		if( xIntrospection.is() )
618 		{
619 			// Do introspection
620 			try
621 			{
622 		        Any aHandlerAny;
623 				aHandlerAny <<= rxHandler;
624 				xIntrospectionAccess = xIntrospection->inspect( aHandlerAny );
625 			}
626 			catch( RuntimeException& )
627 			{
628 				xIntrospectionAccess.clear();
629 			}
630 		}
631 		return xIntrospectionAccess;
632 	}
633 
634 
635     // -----------------------------------------------------------------------------
636     // XServiceInfo
637     // -----------------------------------------------------------------------------
638 
getImplementationName()639     ::rtl::OUString DialogProviderImpl::getImplementationName(  ) throw (RuntimeException)
640     {
641         return getImplementationName_DialogProviderImpl();
642     }
643 
644     // -----------------------------------------------------------------------------
645 
supportsService(const::rtl::OUString & rServiceName)646     sal_Bool DialogProviderImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
647     {
648 	    Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
649 	    const ::rtl::OUString* pNames = aNames.getConstArray();
650 	    const ::rtl::OUString* pEnd = pNames + aNames.getLength();
651 	    for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
652 		    ;
653 
654 	    return pNames != pEnd;
655     }
656 
657     // -----------------------------------------------------------------------------
658 
getSupportedServiceNames()659     Sequence< ::rtl::OUString > DialogProviderImpl::getSupportedServiceNames(  ) throw (RuntimeException)
660     {
661         return getSupportedServiceNames_DialogProviderImpl();
662     }
663 
664     // -----------------------------------------------------------------------------
665     // XInitialization
666     // -----------------------------------------------------------------------------
667 
initialize(const Sequence<Any> & aArguments)668     void DialogProviderImpl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
669     {
670         ::osl::MutexGuard aGuard( getMutex() );
671 
672         if ( aArguments.getLength() == 1 )
673         {
674             aArguments[0] >>= m_xModel;
675 
676             if ( !m_xModel.is() )
677             {
678                 throw RuntimeException(
679                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::initialize: invalid argument format!" ) ),
680                     Reference< XInterface >() );
681             }
682         }
683         else if ( aArguments.getLength() == 4 )
684         {
685             // call from RTL_Impl_CreateUnoDialog
686             aArguments[0] >>= m_xModel;
687             m_BasicInfo.reset( new BasicRTLParams() );
688             m_BasicInfo->mxInput.set( aArguments[ 1 ], UNO_QUERY_THROW );
689             m_BasicInfo->mxDlgLib.set( aArguments[ 2 ], UNO_QUERY_THROW );
690             // leave the possibility to optionally allow the old dialog creation
691             // to use the new XScriptListener ( which converts the old style macro
692             // to a SF url )
693             m_BasicInfo->mxBasicRTLListener.set( aArguments[ 3 ], UNO_QUERY);
694         }
695         else if ( aArguments.getLength() > 4 )
696         {
697             throw RuntimeException(
698                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::initialize: invalid number of arguments!" ) ),
699                 Reference< XInterface >() );
700         }
701     }
702 
703     // -----------------------------------------------------------------------------
704     // XDialogProvider
705     // -----------------------------------------------------------------------------
706 
707 	static ::rtl::OUString aDecorationPropName =
708 		::rtl::OUString::createFromAscii( "Decoration" );
709 	static ::rtl::OUString aTitlePropName =
710 		::rtl::OUString::createFromAscii( "Title" );
711 
createDialogImpl(const::rtl::OUString & URL,const Reference<XInterface> & xHandler,const Reference<XWindowPeer> & xParent,bool bDialogProviderMode)712 	Reference < XControl > DialogProviderImpl::createDialogImpl(
713 		const ::rtl::OUString& URL, const Reference< XInterface >& xHandler,
714 		const Reference< XWindowPeer >& xParent, bool bDialogProviderMode )
715 			throw (IllegalArgumentException, RuntimeException)
716 	{
717         // if the dialog is located in a document, the document must already be open!
718 
719         ::osl::MutexGuard aGuard( getMutex() );
720 
721 
722 		// m_xHandler = xHandler;
723 
724         //Reference< XDialog > xDialog;
725 		Reference< XControl > xCtrl;
726         Reference< XControlModel > xCtrlMod;
727         try
728         {
729             // add support for basic RTL_FUNCTION
730             if ( m_BasicInfo.get() )
731                 xCtrlMod = createDialogModelForBasic();
732             else
733             {
734                 OSL_ENSURE( URL.getLength(), "DialogProviderImpl::getDialog: no URL!" );
735                 xCtrlMod = createDialogModel( URL );
736             }
737         }
738         catch ( const RuntimeException& ) { throw; }
739         catch ( const Exception& )
740         {
741             const Any aError( ::cppu::getCaughtException() );
742             throw WrappedTargetRuntimeException( ::rtl::OUString(), *this, aError );
743         }
744         if ( xCtrlMod.is() )
745         {
746 			// i83963 Force decoration
747 			if( bDialogProviderMode )
748 			{
749 				uno::Reference< beans::XPropertySet > xDlgModPropSet( xCtrlMod, uno::UNO_QUERY );
750 				if( xDlgModPropSet.is() )
751 				{
752 					bool bDecoration = true;
753 					try
754 					{
755 						Any aDecorationAny = xDlgModPropSet->getPropertyValue( aDecorationPropName );
756 						aDecorationAny >>= bDecoration;
757 						if( !bDecoration )
758 						{
759 							xDlgModPropSet->setPropertyValue( aDecorationPropName, makeAny( true ) );
760 							xDlgModPropSet->setPropertyValue( aTitlePropName, makeAny( ::rtl::OUString() ) );
761 						}
762 					}
763 					catch( UnknownPropertyException& )
764 					{}
765 				}
766 			}
767 
768             xCtrl = Reference< XControl >( createDialogControl( xCtrlMod, xParent ) );
769             if ( xCtrl.is() )
770             {
771                 //xDialog = Reference< XDialog >( xCtrl, UNO_QUERY );
772 	            Reference< XIntrospectionAccess > xIntrospectionAccess = inspectHandler( xHandler );
773                 attachControlEvents( xCtrl, xHandler, xIntrospectionAccess, bDialogProviderMode );
774             }
775         }
776 
777         return xCtrl;
778 	}
779 
createDialog(const::rtl::OUString & URL)780     Reference < XDialog > DialogProviderImpl::createDialog( const ::rtl::OUString& URL )
781         throw (IllegalArgumentException, RuntimeException)
782     {
783         Reference< XInterface > xDummyHandler;
784 		Reference< XWindowPeer > xDummyPeer;
785 		Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xDummyHandler, xDummyPeer, true );
786 	    Reference< XDialog > xDialog( xControl, UNO_QUERY );
787         return xDialog;
788     }
789 
createDialogWithHandler(const::rtl::OUString & URL,const Reference<XInterface> & xHandler)790 	Reference < XDialog > DialogProviderImpl::createDialogWithHandler(
791 		const ::rtl::OUString& URL, const Reference< XInterface >& xHandler )
792 			throw (IllegalArgumentException, RuntimeException)
793 	{
794 		if( !xHandler.is() )
795 		{
796             throw IllegalArgumentException(
797                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::createDialogWithHandler: Invalid xHandler!" ) ),
798                 Reference< XInterface >(), 1 );
799 		}
800 		Reference< XWindowPeer > xDummyPeer;
801 		Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xDummyPeer, true );
802 	    Reference< XDialog > xDialog( xControl, UNO_QUERY );
803         return xDialog;
804 	}
805 
createDialogWithArguments(const::rtl::OUString & URL,const Sequence<NamedValue> & Arguments)806     Reference < XDialog > DialogProviderImpl::createDialogWithArguments(
807 		const ::rtl::OUString& URL, const Sequence< NamedValue >& Arguments )
808 			throw (IllegalArgumentException, RuntimeException)
809 	{
810         ::comphelper::NamedValueCollection aArguments( Arguments );
811 
812         Reference< XWindowPeer > xParentPeer;
813         if ( aArguments.has( "ParentWindow" ) )
814         {
815             const Any aParentWindow( aArguments.get( "ParentWindow" ) );
816             if ( !( aParentWindow >>= xParentPeer ) )
817             {
818                 const Reference< XControl > xParentControl( aParentWindow, UNO_QUERY );
819                 if ( xParentControl.is() )
820                     xParentPeer = xParentControl->getPeer();
821             }
822         }
823 
824         const Reference< XInterface > xHandler( aArguments.get( "EventHandler" ), UNO_QUERY );
825 
826 		Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParentPeer, true );
827 	    Reference< XDialog > xDialog( xControl, UNO_QUERY );
828         return xDialog;
829 	}
830 
createContainerWindow(const::rtl::OUString & URL,const::rtl::OUString & WindowType,const Reference<XWindowPeer> & xParent,const Reference<XInterface> & xHandler)831     Reference< XWindow > DialogProviderImpl::createContainerWindow(
832 		const ::rtl::OUString& URL, const ::rtl::OUString& WindowType,
833 		const Reference< XWindowPeer >& xParent, const Reference< XInterface >& xHandler )
834 			throw (lang::IllegalArgumentException, RuntimeException)
835 	{
836 		(void)WindowType;	// for future use
837 		if( !xParent.is() )
838 		{
839             throw IllegalArgumentException(
840                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogProviderImpl::createContainerWindow: Invalid xParent!" ) ),
841                 Reference< XInterface >(), 1 );
842 		}
843 		Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParent, false );
844 	    Reference< XWindow> xWindow( xControl, UNO_QUERY );
845 		return xWindow;
846 	}
847 
848 
849     // =============================================================================
850     // component operations
851     // =============================================================================
852 
create_DialogProviderImpl(Reference<XComponentContext> const & xContext)853     static Reference< XInterface > SAL_CALL create_DialogProviderImpl(
854         Reference< XComponentContext > const & xContext )
855         SAL_THROW( () )
856     {
857         return static_cast< lang::XTypeProvider * >( new DialogProviderImpl( xContext ) );
858     }
859 
860     // -----------------------------------------------------------------------------
861 
862     static struct ::cppu::ImplementationEntry s_component_entries [] =
863     {
864         {create_DialogProviderImpl, getImplementationName_DialogProviderImpl,getSupportedServiceNames_DialogProviderImpl, ::cppu::createSingleComponentFactory,0, 0},
865         { &comp_DialogModelProvider::_create,&comp_DialogModelProvider::_getImplementationName,&comp_DialogModelProvider::_getSupportedServiceNames,&::cppu::createSingleComponentFactory, 0, 0 },
866         { 0, 0, 0, 0, 0, 0 }
867     };
868 
869     // -----------------------------------------------------------------------------
870 
871 //.........................................................................
872 }	// namespace dlgprov
873 //.........................................................................
874 
875 
876 // =============================================================================
877 // component exports
878 // =============================================================================
879 
880 extern "C"
881 {
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment ** ppEnv)882     void SAL_CALL component_getImplementationEnvironment(
883         const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
884     {
885 		(void)ppEnv;
886 
887         *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
888     }
889 
component_getFactory(const sal_Char * pImplName,lang::XMultiServiceFactory * pServiceManager,registry::XRegistryKey * pRegistryKey)890     void * SAL_CALL component_getFactory(
891         const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager,
892         registry::XRegistryKey * pRegistryKey )
893     {
894         return ::cppu::component_getFactoryHelper(
895             pImplName, pServiceManager, pRegistryKey, ::dlgprov::s_component_entries );
896     }
897 }
898