Branch data 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/XControlContainer.hpp>
25 : : #include <com/sun/star/awt/XWindowPeer.hpp>
26 : : #include <com/sun/star/io/XInputStreamProvider.hpp>
27 : : #include <com/sun/star/lang/XMultiComponentFactory.hpp>
28 : : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
29 : : #include <com/sun/star/script/XLibraryContainer.hpp>
30 : : #include <cppuhelper/implementationentry.hxx>
31 : : #include <cppuhelper/exc_hlp.hxx>
32 : : #include <com/sun/star/beans/XIntrospection.hpp>
33 : : #include <com/sun/star/resource/XStringResourceSupplier.hpp>
34 : : #include <com/sun/star/resource/XStringResourceManager.hpp>
35 : : #include <com/sun/star/beans/XPropertySet.hpp>
36 : : #include <com/sun/star/ucb/SimpleFileAccess.hpp>
37 : : #include <com/sun/star/ucb/XSimpleFileAccess2.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/XUriReferenceFactory.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().GetUILocale();
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 : 0 : Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
289 : :
290 : 0 : if ( !xSMgr.is() )
291 : : {
292 : : throw RuntimeException(
293 : : ::rtl::OUString( "DialogProviderImpl::getDialogModel: Couldn't instantiate MultiComponent factory" ),
294 : 0 : Reference< XInterface >() );
295 : : }
296 : :
297 : : Reference< uri::XUriReferenceFactory > xFac (
298 : 0 : xSMgr->createInstanceWithContext( rtl::OUString(
299 : 0 : "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY );
300 : :
301 : 0 : if ( !xFac.is() )
302 : : {
303 : : throw RuntimeException(
304 : : ::rtl::OUString("DialogProviderImpl::getDialogModel(), could not instatiate UriReferenceFactory."),
305 : 0 : Reference< XInterface >() );
306 : : }
307 : :
308 : : // i75778: Support non-script URLs
309 : 0 : Reference< io::XInputStream > xInput;
310 : 0 : Reference< container::XNameContainer > xDialogLib;
311 : :
312 : : // Accept file URL to single dialog
313 : 0 : bool bSingleDialog = false;
314 : :
315 : : Reference< util::XMacroExpander > xMacroExpander(
316 : 0 : m_xContext->getValueByName(
317 : 0 : ::rtl::OUString("/singletons/com.sun.star.util.theMacroExpander") ),
318 : 0 : UNO_QUERY_THROW );
319 : :
320 : 0 : Reference< uri::XUriReference > uriRef;
321 : 0 : for (;;)
322 : : {
323 : 0 : uriRef = Reference< uri::XUriReference >( xFac->parse( aURL ), UNO_QUERY );
324 : 0 : if ( !uriRef.is() )
325 : : {
326 : 0 : ::rtl::OUString errorMsg("DialogProviderImpl::getDialogModel: failed to parse URI: ");
327 : 0 : errorMsg += aURL;
328 : : throw IllegalArgumentException( errorMsg,
329 : 0 : Reference< XInterface >(), 1 );
330 : : }
331 : 0 : Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
332 : 0 : if( !sxUri.is() )
333 : : break;
334 : :
335 : 0 : aURL = sxUri->expand( xMacroExpander );
336 : 0 : }
337 : :
338 : 0 : Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY );
339 : 0 : if( !sfUri.is() )
340 : : {
341 : 0 : bSingleDialog = true;
342 : :
343 : : // Try any other URL with SimpleFileAccess
344 : 0 : Reference< ucb::XSimpleFileAccess2 > xSFI = ucb::SimpleFileAccess::create(m_xContext);
345 : :
346 : : try
347 : : {
348 : 0 : xInput = xSFI->openFileRead( aURL );
349 : : }
350 : 0 : catch( Exception& )
351 : 0 : {}
352 : : }
353 : : else
354 : : {
355 : 0 : ::rtl::OUString sDescription = sfUri->getName();
356 : :
357 : 0 : sal_Int32 nIndex = 0;
358 : :
359 : 0 : ::rtl::OUString sLibName = sDescription.getToken( 0, (sal_Unicode)'.', nIndex );
360 : 0 : ::rtl::OUString sDlgName;
361 : 0 : if ( nIndex != -1 )
362 : 0 : sDlgName = sDescription.getToken( 0, (sal_Unicode)'.', nIndex );
363 : :
364 : 0 : ::rtl::OUString sLocation = sfUri->getParameter(
365 : 0 : ::rtl::OUString("location") );
366 : :
367 : :
368 : : // get dialog library container
369 : : // TODO: dialogs in packages
370 : 0 : Reference< XLibraryContainer > xLibContainer;
371 : :
372 : 0 : if ( sLocation == "application" )
373 : : {
374 : 0 : xLibContainer = Reference< XLibraryContainer >( SFX_APP()->GetDialogContainer(), UNO_QUERY );
375 : : }
376 : 0 : else if ( sLocation == "document" )
377 : : {
378 : 0 : Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
379 : 0 : if ( xDocumentScripts.is() )
380 : : {
381 : 0 : xLibContainer.set( xDocumentScripts->getDialogLibraries(), UNO_QUERY );
382 : : OSL_ENSURE( xLibContainer.is(),
383 : : "DialogProviderImpl::createDialogModel: invalid dialog container!" );
384 : 0 : }
385 : : }
386 : : else
387 : : {
388 : 0 : Sequence< ::rtl::OUString > aOpenDocsTdocURLs( MiscUtils::allOpenTDocUrls( m_xContext ) );
389 : 0 : const ::rtl::OUString* pTdocURL = aOpenDocsTdocURLs.getConstArray();
390 : 0 : const ::rtl::OUString* pTdocURLEnd = aOpenDocsTdocURLs.getConstArray() + aOpenDocsTdocURLs.getLength();
391 : 0 : for ( ; pTdocURL != pTdocURLEnd; ++pTdocURL )
392 : : {
393 : 0 : Reference< frame::XModel > xModel( MiscUtils::tDocUrlToModel( *pTdocURL ) );
394 : : OSL_ENSURE( xModel.is(), "DialogProviderImpl::createDialogModel: invalid document model!" );
395 : 0 : if ( !xModel.is() )
396 : 0 : continue;
397 : :
398 : 0 : ::rtl::OUString sDocURL = xModel->getURL();
399 : 0 : if ( sDocURL.isEmpty() )
400 : : {
401 : 0 : ::comphelper::NamedValueCollection aModelArgs( xModel->getArgs() );
402 : 0 : sDocURL = aModelArgs.getOrDefault( "Title", sDocURL );
403 : : }
404 : :
405 : 0 : if ( sLocation != sDocURL )
406 : 0 : continue;
407 : :
408 : 0 : Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
409 : 0 : if ( !xDocumentScripts.is() )
410 : 0 : continue;
411 : :
412 : 0 : xLibContainer.set( xDocumentScripts->getDialogLibraries(), UNO_QUERY );
413 : : OSL_ENSURE( xLibContainer.is(),
414 : : "DialogProviderImpl::createDialogModel: invalid dialog container!" );
415 : 0 : }
416 : : }
417 : :
418 : : // get input stream provider
419 : 0 : Reference< io::XInputStreamProvider > xISP;
420 : 0 : if ( xLibContainer.is() )
421 : : {
422 : : // load dialog library
423 : 0 : if ( !xLibContainer->isLibraryLoaded( sLibName ) )
424 : 0 : xLibContainer->loadLibrary( sLibName );
425 : :
426 : : // get dialog library
427 : 0 : if ( xLibContainer->hasByName( sLibName ) )
428 : : {
429 : 0 : Any aElement = xLibContainer->getByName( sLibName );
430 : 0 : aElement >>= xDialogLib;
431 : : }
432 : :
433 : 0 : if ( xDialogLib.is() )
434 : : {
435 : : // get input stream provider
436 : 0 : if ( xDialogLib->hasByName( sDlgName ) )
437 : : {
438 : 0 : Any aElement = xDialogLib->getByName( sDlgName );
439 : 0 : aElement >>= xISP;
440 : : }
441 : :
442 : 0 : if ( !xISP.is() )
443 : : {
444 : : throw IllegalArgumentException(
445 : : ::rtl::OUString( "DialogProviderImpl::getDialogModel: dialog not found!" ),
446 : 0 : Reference< XInterface >(), 1 );
447 : : }
448 : : }
449 : : else
450 : : {
451 : : throw IllegalArgumentException(
452 : : ::rtl::OUString( "DialogProviderImpl::getDialogModel: library not found!" ),
453 : 0 : Reference< XInterface >(), 1 );
454 : : }
455 : : }
456 : : else
457 : : {
458 : : throw IllegalArgumentException(
459 : : ::rtl::OUString( "DialogProviderImpl::getDialog: library container not found!" ),
460 : 0 : Reference< XInterface >(), 1 );
461 : : }
462 : :
463 : 0 : if ( xISP.is() )
464 : 0 : xInput = xISP->createInputStream();
465 : 0 : msDialogLibName = sLibName;
466 : : }
467 : :
468 : : // import dialog model
469 : 0 : Reference< XControlModel > xCtrlModel;
470 : 0 : if ( xInput.is() && m_xContext.is() )
471 : : {
472 : 0 : Reference< resource::XStringResourceManager > xStringResourceManager;
473 : 0 : if( bSingleDialog )
474 : : {
475 : 0 : xStringResourceManager = lcl_getStringResourceManager(m_xContext,aURL);
476 : : }
477 : 0 : else if( xDialogLib.is() )
478 : : {
479 : 0 : xStringResourceManager = getStringResourceFromDialogLibrary( xDialogLib );
480 : : }
481 : :
482 : 0 : Any aDialogSourceURLAny;
483 : 0 : aDialogSourceURLAny <<= aURL;
484 : :
485 : 0 : Reference< container::XNameContainer > xDialogModel( createDialogModel( xInput , xStringResourceManager, aDialogSourceURLAny ), UNO_QUERY_THROW);
486 : :
487 : 0 : xCtrlModel = Reference< XControlModel >( xDialogModel, UNO_QUERY );
488 : : }
489 : 0 : return xCtrlModel;
490 : : }
491 : :
492 : : // -----------------------------------------------------------------------------
493 : :
494 : 0 : Reference< XControl > DialogProviderImpl::createDialogControl
495 : : ( const Reference< XControlModel >& rxDialogModel, const Reference< XWindowPeer >& xParent )
496 : : {
497 : : OSL_ENSURE( rxDialogModel.is(), "DialogProviderImpl::getDialogControl: no dialog model" );
498 : :
499 : 0 : Reference< XControl > xDialogControl;
500 : :
501 : 0 : if ( m_xContext.is() )
502 : : {
503 : 0 : Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
504 : :
505 : 0 : if ( xSMgr.is() )
506 : : {
507 : 0 : xDialogControl = Reference< XControl >( xSMgr->createInstanceWithContext(
508 : 0 : ::rtl::OUString( "com.sun.star.awt.UnoControlDialog" ), m_xContext ), UNO_QUERY );
509 : :
510 : 0 : if ( xDialogControl.is() )
511 : : {
512 : : // set the model
513 : 0 : if ( rxDialogModel.is() )
514 : 0 : xDialogControl->setModel( rxDialogModel );
515 : :
516 : : // set visible
517 : 0 : Reference< XWindow > xW( xDialogControl, UNO_QUERY );
518 : 0 : if ( xW.is() )
519 : 0 : xW->setVisible( sal_False );
520 : :
521 : : // get the parent of the dialog control
522 : 0 : Reference< XWindowPeer > xPeer;
523 : 0 : if( xParent.is() )
524 : : {
525 : 0 : xPeer = xParent;
526 : : }
527 : 0 : else if ( m_xModel.is() )
528 : : {
529 : 0 : Reference< frame::XController > xController( m_xModel->getCurrentController(), UNO_QUERY );
530 : 0 : if ( xController.is() )
531 : : {
532 : 0 : Reference< frame::XFrame > xFrame( xController->getFrame(), UNO_QUERY );
533 : 0 : if ( xFrame.is() )
534 : 0 : xPeer = Reference< XWindowPeer>( xFrame->getContainerWindow(), UNO_QUERY );
535 : 0 : }
536 : : }
537 : :
538 : : // create a peer
539 : 0 : Reference< XToolkit> xToolkit( xSMgr->createInstanceWithContext(
540 : 0 : ::rtl::OUString( "com.sun.star.awt.Toolkit" ), m_xContext ), UNO_QUERY );
541 : 0 : if ( xToolkit.is() )
542 : 0 : xDialogControl->createPeer( xToolkit, xPeer );
543 : : }
544 : 0 : }
545 : : }
546 : :
547 : 0 : return xDialogControl;
548 : : }
549 : :
550 : : // -----------------------------------------------------------------------------
551 : :
552 : 0 : void DialogProviderImpl::attachControlEvents(
553 : : const Reference< XControl >& rxControl,
554 : : const Reference< XInterface >& rxHandler,
555 : : const Reference< XIntrospectionAccess >& rxIntrospectionAccess,
556 : : bool bDialogProviderMode )
557 : : {
558 : 0 : if ( rxControl.is() )
559 : : {
560 : 0 : Reference< XControlContainer > xControlContainer( rxControl, UNO_QUERY );
561 : :
562 : 0 : if ( xControlContainer.is() )
563 : : {
564 : 0 : Sequence< Reference< XControl > > aControls = xControlContainer->getControls();
565 : 0 : const Reference< XControl >* pControls = aControls.getConstArray();
566 : 0 : sal_Int32 nControlCount = aControls.getLength();
567 : :
568 : 0 : Sequence< Reference< XInterface > > aObjects( nControlCount + 1 );
569 : 0 : Reference< XInterface >* pObjects = aObjects.getArray();
570 : 0 : for ( sal_Int32 i = 0; i < nControlCount; ++i )
571 : : {
572 : 0 : pObjects[i] = Reference< XInterface >( pControls[i], UNO_QUERY );
573 : : }
574 : :
575 : : // also add the dialog control itself to the sequence
576 : 0 : pObjects[nControlCount] = Reference< XInterface >( rxControl, UNO_QUERY );
577 : :
578 : : Reference< XScriptEventsAttacher > xScriptEventsAttacher = new DialogEventsAttacherImpl
579 : : ( m_xContext, m_xModel, rxControl, rxHandler, rxIntrospectionAccess,
580 : 0 : bDialogProviderMode, ( m_BasicInfo.get() ? m_BasicInfo->mxBasicRTLListener : NULL ), msDialogLibName );
581 : :
582 : 0 : Any aHelper;
583 : 0 : xScriptEventsAttacher->attachEvents( aObjects, Reference< XScriptListener >(), aHelper );
584 : 0 : }
585 : : }
586 : 0 : }
587 : :
588 : 0 : Reference< XIntrospectionAccess > DialogProviderImpl::inspectHandler( const Reference< XInterface >& rxHandler )
589 : : {
590 : 0 : Reference< XIntrospectionAccess > xIntrospectionAccess;
591 : 0 : static Reference< XIntrospection > xIntrospection;
592 : :
593 : 0 : if( !rxHandler.is() )
594 : 0 : return xIntrospectionAccess;
595 : :
596 : 0 : if( !xIntrospection.is() )
597 : : {
598 : 0 : Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
599 : 0 : if ( !xSMgr.is() )
600 : : {
601 : : throw RuntimeException(
602 : : ::rtl::OUString( "DialogProviderImpl::getIntrospectionAccess: Couldn't instantiate MultiComponent factory" ),
603 : 0 : Reference< XInterface >() );
604 : : }
605 : :
606 : : // Get introspection service
607 : 0 : Reference< XInterface > xI = xSMgr->createInstanceWithContext
608 : 0 : ( rtl::OUString("com.sun.star.beans.Introspection"), m_xContext );
609 : 0 : if (xI.is())
610 : 0 : xIntrospection = Reference< XIntrospection >::query( xI );
611 : : }
612 : :
613 : 0 : if( xIntrospection.is() )
614 : : {
615 : : // Do introspection
616 : : try
617 : : {
618 : 0 : Any aHandlerAny;
619 : 0 : aHandlerAny <<= rxHandler;
620 : 0 : xIntrospectionAccess = xIntrospection->inspect( aHandlerAny );
621 : : }
622 : 0 : catch( RuntimeException& )
623 : : {
624 : 0 : xIntrospectionAccess.clear();
625 : : }
626 : : }
627 : 0 : return xIntrospectionAccess;
628 : : }
629 : :
630 : :
631 : : // -----------------------------------------------------------------------------
632 : : // XServiceInfo
633 : : // -----------------------------------------------------------------------------
634 : :
635 : 0 : ::rtl::OUString DialogProviderImpl::getImplementationName( ) throw (RuntimeException)
636 : : {
637 : 0 : return getImplementationName_DialogProviderImpl();
638 : : }
639 : :
640 : : // -----------------------------------------------------------------------------
641 : :
642 : 0 : sal_Bool DialogProviderImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
643 : : {
644 : 0 : Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
645 : 0 : const ::rtl::OUString* pNames = aNames.getConstArray();
646 : 0 : const ::rtl::OUString* pEnd = pNames + aNames.getLength();
647 : 0 : for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
648 : : ;
649 : :
650 : 0 : return pNames != pEnd;
651 : : }
652 : :
653 : : // -----------------------------------------------------------------------------
654 : :
655 : 0 : Sequence< ::rtl::OUString > DialogProviderImpl::getSupportedServiceNames( ) throw (RuntimeException)
656 : : {
657 : 0 : return getSupportedServiceNames_DialogProviderImpl();
658 : : }
659 : :
660 : : // -----------------------------------------------------------------------------
661 : : // XInitialization
662 : : // -----------------------------------------------------------------------------
663 : :
664 : 0 : void DialogProviderImpl::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException)
665 : : {
666 : 0 : ::osl::MutexGuard aGuard( getMutex() );
667 : :
668 : 0 : if ( aArguments.getLength() == 1 )
669 : : {
670 : 0 : aArguments[0] >>= m_xModel;
671 : :
672 : 0 : if ( !m_xModel.is() )
673 : : {
674 : : throw RuntimeException(
675 : : ::rtl::OUString( "DialogProviderImpl::initialize: invalid argument format!" ),
676 : 0 : Reference< XInterface >() );
677 : : }
678 : : }
679 : 0 : else if ( aArguments.getLength() == 4 )
680 : : {
681 : : // call from RTL_Impl_CreateUnoDialog
682 : 0 : aArguments[0] >>= m_xModel;
683 : 0 : m_BasicInfo.reset( new BasicRTLParams() );
684 : 0 : m_BasicInfo->mxInput.set( aArguments[ 1 ], UNO_QUERY_THROW );
685 : : // allow null mxDlgLib, a document dialog instantiated from
686 : : // from application basic is unable to provide ( or find ) it's
687 : : // Library
688 : 0 : aArguments[ 2 ] >>= m_BasicInfo->mxDlgLib;
689 : : // leave the possibility to optionally allow the old dialog creation
690 : : // to use the new XScriptListener ( which converts the old style macro
691 : : // to a SF url )
692 : 0 : m_BasicInfo->mxBasicRTLListener.set( aArguments[ 3 ], UNO_QUERY);
693 : : }
694 : 0 : else if ( aArguments.getLength() > 4 )
695 : : {
696 : : throw RuntimeException(
697 : : ::rtl::OUString( "DialogProviderImpl::initialize: invalid number of arguments!" ),
698 : 0 : Reference< XInterface >() );
699 : 0 : }
700 : 0 : }
701 : :
702 : : // -----------------------------------------------------------------------------
703 : : // XDialogProvider
704 : : // -----------------------------------------------------------------------------
705 : :
706 : 0 : static ::rtl::OUString aDecorationPropName("Decoration");
707 : 0 : static ::rtl::OUString aTitlePropName("Title");
708 : :
709 : 0 : Reference < XControl > DialogProviderImpl::createDialogImpl(
710 : : const ::rtl::OUString& URL, const Reference< XInterface >& xHandler,
711 : : const Reference< XWindowPeer >& xParent, bool bDialogProviderMode )
712 : : throw (IllegalArgumentException, RuntimeException)
713 : : {
714 : : // if the dialog is located in a document, the document must already be open!
715 : :
716 : 0 : ::osl::MutexGuard aGuard( getMutex() );
717 : :
718 : :
719 : : // m_xHandler = xHandler;
720 : :
721 : : //Reference< XDialog > xDialog;
722 : 0 : Reference< XControl > xCtrl;
723 : 0 : Reference< XControlModel > xCtrlMod;
724 : : try
725 : : {
726 : : // add support for basic RTL_FUNCTION
727 : 0 : if ( m_BasicInfo.get() )
728 : 0 : xCtrlMod = createDialogModelForBasic();
729 : : else
730 : : {
731 : : OSL_ENSURE( !URL.isEmpty(), "DialogProviderImpl::getDialog: no URL!" );
732 : 0 : xCtrlMod = createDialogModel( URL );
733 : : }
734 : : }
735 : 0 : catch ( const RuntimeException& ) { throw; }
736 : 0 : catch ( const Exception& )
737 : : {
738 : 0 : const Any aError( ::cppu::getCaughtException() );
739 : 0 : throw WrappedTargetRuntimeException( ::rtl::OUString(), *this, aError );
740 : : }
741 : 0 : if ( xCtrlMod.is() )
742 : : {
743 : : // i83963 Force decoration
744 : 0 : if( bDialogProviderMode )
745 : : {
746 : 0 : uno::Reference< beans::XPropertySet > xDlgModPropSet( xCtrlMod, uno::UNO_QUERY );
747 : 0 : if( xDlgModPropSet.is() )
748 : : {
749 : 0 : bool bDecoration = true;
750 : : try
751 : : {
752 : 0 : Any aDecorationAny = xDlgModPropSet->getPropertyValue( aDecorationPropName );
753 : 0 : aDecorationAny >>= bDecoration;
754 : 0 : if( !bDecoration )
755 : : {
756 : 0 : xDlgModPropSet->setPropertyValue( aDecorationPropName, makeAny( true ) );
757 : 0 : xDlgModPropSet->setPropertyValue( aTitlePropName, makeAny( ::rtl::OUString() ) );
758 : 0 : }
759 : : }
760 : 0 : catch( UnknownPropertyException& )
761 : : {}
762 : 0 : }
763 : : }
764 : :
765 : 0 : xCtrl = Reference< XControl >( createDialogControl( xCtrlMod, xParent ) );
766 : 0 : if ( xCtrl.is() )
767 : : {
768 : : //xDialog = Reference< XDialog >( xCtrl, UNO_QUERY );
769 : 0 : Reference< XIntrospectionAccess > xIntrospectionAccess = inspectHandler( xHandler );
770 : 0 : attachControlEvents( xCtrl, xHandler, xIntrospectionAccess, bDialogProviderMode );
771 : : }
772 : : }
773 : :
774 : 0 : return xCtrl;
775 : : }
776 : :
777 : 0 : Reference < XDialog > DialogProviderImpl::createDialog( const ::rtl::OUString& URL )
778 : : throw (IllegalArgumentException, RuntimeException)
779 : : {
780 : 0 : Reference< XInterface > xDummyHandler;
781 : 0 : Reference< XWindowPeer > xDummyPeer;
782 : 0 : Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xDummyHandler, xDummyPeer, true );
783 : 0 : Reference< XDialog > xDialog( xControl, UNO_QUERY );
784 : 0 : return xDialog;
785 : : }
786 : :
787 : 0 : Reference < XDialog > DialogProviderImpl::createDialogWithHandler(
788 : : const ::rtl::OUString& URL, const Reference< XInterface >& xHandler )
789 : : throw (IllegalArgumentException, RuntimeException)
790 : : {
791 : 0 : if( !xHandler.is() )
792 : : {
793 : : throw IllegalArgumentException(
794 : : ::rtl::OUString( "DialogProviderImpl::createDialogWithHandler: Invalid xHandler!" ),
795 : 0 : Reference< XInterface >(), 1 );
796 : : }
797 : 0 : Reference< XWindowPeer > xDummyPeer;
798 : 0 : Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xDummyPeer, true );
799 : 0 : Reference< XDialog > xDialog( xControl, UNO_QUERY );
800 : 0 : return xDialog;
801 : : }
802 : :
803 : 0 : Reference < XDialog > DialogProviderImpl::createDialogWithArguments(
804 : : const ::rtl::OUString& URL, const Sequence< NamedValue >& Arguments )
805 : : throw (IllegalArgumentException, RuntimeException)
806 : : {
807 : 0 : ::comphelper::NamedValueCollection aArguments( Arguments );
808 : :
809 : 0 : Reference< XWindowPeer > xParentPeer;
810 : 0 : if ( aArguments.has( "ParentWindow" ) )
811 : : {
812 : 0 : const Any aParentWindow( aArguments.get( "ParentWindow" ) );
813 : 0 : if ( !( aParentWindow >>= xParentPeer ) )
814 : : {
815 : 0 : const Reference< XControl > xParentControl( aParentWindow, UNO_QUERY );
816 : 0 : if ( xParentControl.is() )
817 : 0 : xParentPeer = xParentControl->getPeer();
818 : 0 : }
819 : : }
820 : :
821 : 0 : const Reference< XInterface > xHandler( aArguments.get( "EventHandler" ), UNO_QUERY );
822 : :
823 : 0 : Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParentPeer, true );
824 : 0 : Reference< XDialog > xDialog( xControl, UNO_QUERY );
825 : 0 : return xDialog;
826 : : }
827 : :
828 : 0 : Reference< XWindow > DialogProviderImpl::createContainerWindow(
829 : : const ::rtl::OUString& URL, const ::rtl::OUString& WindowType,
830 : : const Reference< XWindowPeer >& xParent, const Reference< XInterface >& xHandler )
831 : : throw (lang::IllegalArgumentException, RuntimeException)
832 : : {
833 : : (void)WindowType; // for future use
834 : 0 : if( !xParent.is() )
835 : : {
836 : : throw IllegalArgumentException(
837 : : ::rtl::OUString( "DialogProviderImpl::createContainerWindow: Invalid xParent!" ),
838 : 0 : Reference< XInterface >(), 1 );
839 : : }
840 : 0 : Reference < XControl > xControl = DialogProviderImpl::createDialogImpl( URL, xHandler, xParent, false );
841 : 0 : Reference< XWindow> xWindow( xControl, UNO_QUERY );
842 : 0 : return xWindow;
843 : : }
844 : :
845 : :
846 : : // =============================================================================
847 : : // component operations
848 : : // =============================================================================
849 : :
850 : 0 : static Reference< XInterface > SAL_CALL create_DialogProviderImpl(
851 : : Reference< XComponentContext > const & xContext )
852 : : SAL_THROW(())
853 : : {
854 : 0 : return static_cast< lang::XTypeProvider * >( new DialogProviderImpl( xContext ) );
855 : : }
856 : :
857 : : // -----------------------------------------------------------------------------
858 : :
859 : : static struct ::cppu::ImplementationEntry s_component_entries [] =
860 : : {
861 : : {create_DialogProviderImpl, getImplementationName_DialogProviderImpl,getSupportedServiceNames_DialogProviderImpl, ::cppu::createSingleComponentFactory,0, 0},
862 : : { &comp_DialogModelProvider::_create,&comp_DialogModelProvider::_getImplementationName,&comp_DialogModelProvider::_getSupportedServiceNames,&::cppu::createSingleComponentFactory, 0, 0 },
863 : : { 0, 0, 0, 0, 0, 0 }
864 : : };
865 : :
866 : : // -----------------------------------------------------------------------------
867 : :
868 : : //.........................................................................
869 : : } // namespace dlgprov
870 : : //.........................................................................
871 : :
872 : :
873 : : // =============================================================================
874 : : // component exports
875 : : // =============================================================================
876 : :
877 : : extern "C"
878 : : {
879 : 0 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
880 : : const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager,
881 : : registry::XRegistryKey * pRegistryKey )
882 : : {
883 : : return ::cppu::component_getFactoryHelper(
884 : 0 : pImplName, pServiceManager, pRegistryKey, ::dlgprov::s_component_entries );
885 : : }
886 : 0 : }
887 : :
888 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|