xref: /AOO41X/main/scripting/source/dlgprov/dlgprov.cxx (revision 2c6962431ffb1d162132ad55cb49d102a52ae3e3) !
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