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