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