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 "flt_reghelper.hxx"
22 : #include "xmlstrings.hrc"
23 :
24 : #include <com/sun/star/beans/NamedValue.hpp>
25 : #include <com/sun/star/beans/XPropertySet.hpp>
26 : #include <com/sun/star/document/XEventListener.hpp>
27 : #include <com/sun/star/document/XExtendedFilterDetection.hpp>
28 : #include <com/sun/star/document/XFilter.hpp>
29 : #include <com/sun/star/embed/ElementModes.hpp>
30 : #include <com/sun/star/embed/XStorage.hpp>
31 : #include <com/sun/star/frame/Desktop.hpp>
32 : #include <com/sun/star/frame/XController.hpp>
33 : #include <com/sun/star/frame/XFrame.hpp>
34 : #include <com/sun/star/frame/XFrameLoader.hpp>
35 : #include <com/sun/star/frame/XFramesSupplier.hpp>
36 : #include <com/sun/star/frame/XLoadEventListener.hpp>
37 : #include <com/sun/star/frame/XModel2.hpp>
38 : #include <com/sun/star/io/XInputStream.hpp>
39 : #include <com/sun/star/lang/XInitialization.hpp>
40 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 : #include <com/sun/star/lang/XServiceInfo.hpp>
42 : #include <com/sun/star/registry/XRegistryKey.hpp>
43 : #include <com/sun/star/sdb/DatabaseContext.hpp>
44 : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
45 : #include <com/sun/star/task/XJobExecutor.hpp>
46 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
47 : #include <com/sun/star/task/InteractionHandler.hpp>
48 : #include <com/sun/star/util/URLTransformer.hpp>
49 : #include <com/sun/star/util/XURLTransformer.hpp>
50 : #include <com/sun/star/view/XSelectionSupplier.hpp>
51 : #include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
52 : #include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
53 : #include <com/sun/star/frame/XLoadable.hpp>
54 :
55 : #include <comphelper/componentcontext.hxx>
56 : #include <comphelper/documentconstants.hxx>
57 : #include <comphelper/namedvaluecollection.hxx>
58 : #include <comphelper/processfactory.hxx>
59 : #include <comphelper/sequenceashashmap.hxx>
60 : #include <comphelper/stl_types.hxx>
61 : #include <comphelper/storagehelper.hxx>
62 : #include <comphelper/types.hxx>
63 : #include <cppuhelper/implbase2.hxx>
64 : #include <osl/file.hxx>
65 : #include <sfx2/docfile.hxx>
66 : #include <unotools/moduleoptions.hxx>
67 : #include <toolkit/awt/vclxwindow.hxx>
68 : #include <toolkit/helper/vclunohelper.hxx>
69 : #include <tools/diagnose_ex.h>
70 : #include <ucbhelper/commandenvironment.hxx>
71 : #include <ucbhelper/content.hxx>
72 : #include <vcl/msgbox.hxx>
73 : #include <vcl/svapp.hxx>
74 :
75 : using namespace ::ucbhelper;
76 : using namespace ::com::sun::star::task;
77 : using namespace ::com::sun::star::uno;
78 : using namespace ::com::sun::star::ucb;
79 : using namespace ::com::sun::star::io;
80 : using namespace ::com::sun::star::util;
81 : using namespace ::com::sun::star::frame;
82 : using namespace ::com::sun::star::beans;
83 : using namespace ::com::sun::star::container;
84 : using namespace ::com::sun::star::lang;
85 : using namespace ::com::sun::star::document;
86 : using namespace ::com::sun::star::registry;
87 : using namespace ::com::sun::star::sdb;
88 : using namespace ::com::sun::star::embed;
89 : using namespace ::com::sun::star::ui::dialogs;
90 : using ::com::sun::star::awt::XWindow;
91 : using ::com::sun::star::sdb::application::NamedDatabaseObject;
92 :
93 : // -------------------------------------------------------------------------
94 : namespace dbaxml
95 : {
96 :
97 0 : class DBTypeDetection : public ::cppu::WeakImplHelper2< XExtendedFilterDetection, XServiceInfo>
98 : {
99 : ::comphelper::ComponentContext m_aContext;
100 :
101 : public:
102 : DBTypeDetection(const Reference< XMultiServiceFactory >&);
103 :
104 : // XServiceInfo
105 : ::rtl::OUString SAL_CALL getImplementationName() throw( );
106 : sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw( );
107 : Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( );
108 :
109 : // static methods
110 0 : static ::rtl::OUString getImplementationName_Static() throw( )
111 : {
112 0 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbflt.DBTypeDetection"));
113 : }
114 : static Sequence< ::rtl::OUString> getSupportedServiceNames_Static(void) throw( );
115 : static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
116 : SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);
117 :
118 : virtual ::rtl::OUString SAL_CALL detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Descriptor ) throw (::com::sun::star::uno::RuntimeException);
119 : };
120 : // -------------------------------------------------------------------------
121 0 : DBTypeDetection::DBTypeDetection(const Reference< XMultiServiceFactory >& _rxFactory)
122 0 : :m_aContext( _rxFactory )
123 : {
124 0 : }
125 : // -------------------------------------------------------------------------
126 0 : ::rtl::OUString SAL_CALL DBTypeDetection::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Descriptor ) throw (::com::sun::star::uno::RuntimeException)
127 : {
128 : try
129 : {
130 0 : ::comphelper::NamedValueCollection aMedia( Descriptor );
131 0 : sal_Bool bStreamFromDescr = sal_False;
132 0 : ::rtl::OUString sURL = aMedia.getOrDefault( "URL", ::rtl::OUString() );
133 :
134 0 : Reference< XInputStream > xInStream( aMedia.getOrDefault( "InputStream", Reference< XInputStream >() ) );
135 0 : Reference< XPropertySet > xStorageProperties;
136 0 : if ( xInStream.is() )
137 : {
138 0 : bStreamFromDescr = sal_True;
139 : xStorageProperties.set( ::comphelper::OStorageHelper::GetStorageFromInputStream(
140 0 : xInStream, m_aContext.getUNOContext() ), UNO_QUERY );
141 : }
142 : else
143 : {
144 0 : ::rtl::OUString sSalvagedURL( aMedia.getOrDefault( "SalvagedFile", ::rtl::OUString() ) );
145 :
146 0 : ::rtl::OUString sFileLocation( sSalvagedURL.isEmpty() ? sURL : sSalvagedURL );
147 0 : if ( !sFileLocation.isEmpty() )
148 : {
149 : xStorageProperties.set( ::comphelper::OStorageHelper::GetStorageFromURL(
150 0 : sFileLocation, ElementModes::READ, m_aContext.getUNOContext() ), UNO_QUERY );
151 0 : }
152 : }
153 :
154 0 : if ( xStorageProperties.is() )
155 : {
156 0 : ::rtl::OUString sMediaType;
157 0 : xStorageProperties->getPropertyValue( INFO_MEDIATYPE ) >>= sMediaType;
158 0 : if ( sMediaType == MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII || sMediaType == MIMETYPE_VND_SUN_XML_BASE_ASCII )
159 : {
160 0 : if ( bStreamFromDescr && sURL.compareTo( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) ), 14 ) != COMPARE_EQUAL )
161 : {
162 : // After fixing of the i88522 issue ( use the new file locking for database files ) the stream from the type detection can be used further
163 : // for now the file should be reopened to have read/write access
164 0 : aMedia.remove( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) ) );
165 0 : aMedia.remove( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Stream" ) ) );
166 0 : aMedia >>= Descriptor;
167 : try
168 : {
169 0 : ::comphelper::disposeComponent(xStorageProperties);
170 0 : if ( xInStream.is() )
171 0 : xInStream->closeInput();
172 : }
173 0 : catch( Exception& )
174 : {
175 : DBG_UNHANDLED_EXCEPTION();
176 : }
177 : }
178 :
179 0 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StarBase"));
180 : }
181 0 : ::comphelper::disposeComponent(xStorageProperties);
182 0 : }
183 0 : } catch(Exception&){}
184 0 : return ::rtl::OUString();
185 : }
186 : // -------------------------------------------------------------------------
187 0 : Reference< XInterface > SAL_CALL DBTypeDetection::Create( const Reference< XMultiServiceFactory > & rSMgr )
188 : {
189 0 : return *(new DBTypeDetection(rSMgr));
190 : }
191 : // -------------------------------------------------------------------------
192 : // XServiceInfo
193 0 : ::rtl::OUString SAL_CALL DBTypeDetection::getImplementationName() throw( )
194 : {
195 0 : return getImplementationName_Static();
196 : }
197 : // -------------------------------------------------------------------------
198 :
199 : // XServiceInfo
200 0 : sal_Bool SAL_CALL DBTypeDetection::supportsService(const ::rtl::OUString& ServiceName) throw( )
201 : {
202 0 : Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
203 0 : const ::rtl::OUString * pBegin = aSNL.getConstArray();
204 0 : const ::rtl::OUString * pEnd = pBegin + aSNL.getLength();
205 0 : for( ; pBegin != pEnd; ++pBegin)
206 0 : if( *pBegin == ServiceName )
207 0 : return sal_True;
208 0 : return sal_False;
209 : }
210 : // -------------------------------------------------------------------------
211 : // XServiceInfo
212 0 : Sequence< ::rtl::OUString > SAL_CALL DBTypeDetection::getSupportedServiceNames(void) throw( )
213 : {
214 0 : return getSupportedServiceNames_Static();
215 : }
216 : // -------------------------------------------------------------------------
217 : // ORegistryServiceManager_Static
218 0 : Sequence< ::rtl::OUString > DBTypeDetection::getSupportedServiceNames_Static(void) throw( )
219 : {
220 0 : Sequence< ::rtl::OUString > aSNS( 1 );
221 0 : aSNS.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.ExtendedTypeDetection"));
222 0 : return aSNS;
223 : }
224 : // -------------------------------------------------------------------------
225 0 : extern "C" void SAL_CALL createRegistryInfo_DBTypeDetection()
226 : {
227 0 : static ::dbaxml::OMultiInstanceAutoRegistration< ::dbaxml::DBTypeDetection > aAutoRegistration;
228 0 : }
229 : // -----------------------------------------------------------------------------
230 :
231 : class DBContentLoader : public ::cppu::WeakImplHelper2< XFrameLoader, XServiceInfo>
232 : {
233 : private:
234 : ::comphelper::ComponentContext m_aContext;
235 : Reference< XFrameLoader > m_xMySelf;
236 : ::rtl::OUString m_sCurrentURL;
237 : sal_uLong m_nStartWizard;
238 :
239 : DECL_LINK( OnStartTableWizard, void* );
240 : public:
241 : DBContentLoader(const Reference< XMultiServiceFactory >&);
242 : ~DBContentLoader();
243 :
244 : // XServiceInfo
245 : ::rtl::OUString SAL_CALL getImplementationName() throw( );
246 : sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw( );
247 : Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( );
248 :
249 : // static methods
250 0 : static ::rtl::OUString getImplementationName_Static() throw( )
251 : {
252 0 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbflt.DBContentLoader2"));
253 : }
254 : static Sequence< ::rtl::OUString> getSupportedServiceNames_Static(void) throw( );
255 : static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
256 : SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);
257 :
258 : // XLoader
259 : virtual void SAL_CALL load( const Reference< XFrame > & _rFrame, const ::rtl::OUString& _rURL,
260 : const Sequence< PropertyValue >& _rArgs,
261 : const Reference< XLoadEventListener > & _rListener) throw(::com::sun::star::uno::RuntimeException);
262 : virtual void SAL_CALL cancel(void) throw();
263 :
264 : private:
265 : sal_Bool impl_executeNewDatabaseWizard( Reference< XModel >& _rxModel, sal_Bool& _bShouldStartTableWizard );
266 : };
267 : DBG_NAME(DBContentLoader)
268 :
269 0 : DBContentLoader::DBContentLoader(const Reference< XMultiServiceFactory >& _rxFactory)
270 : :m_aContext( _rxFactory )
271 0 : ,m_nStartWizard(0)
272 : {
273 : DBG_CTOR(DBContentLoader,NULL);
274 :
275 0 : }
276 : // -------------------------------------------------------------------------
277 :
278 0 : DBContentLoader::~DBContentLoader()
279 : {
280 :
281 : DBG_DTOR(DBContentLoader,NULL);
282 0 : }
283 : // -------------------------------------------------------------------------
284 :
285 : // -------------------------------------------------------------------------
286 0 : Reference< XInterface > SAL_CALL DBContentLoader::Create( const Reference< XMultiServiceFactory > & rSMgr )
287 : {
288 0 : return *(new DBContentLoader(rSMgr));
289 : }
290 : // -------------------------------------------------------------------------
291 : // XServiceInfo
292 0 : ::rtl::OUString SAL_CALL DBContentLoader::getImplementationName() throw( )
293 : {
294 0 : return getImplementationName_Static();
295 : }
296 : // -------------------------------------------------------------------------
297 :
298 : // XServiceInfo
299 0 : sal_Bool SAL_CALL DBContentLoader::supportsService(const ::rtl::OUString& ServiceName) throw( )
300 : {
301 0 : Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
302 0 : const ::rtl::OUString * pBegin = aSNL.getConstArray();
303 0 : const ::rtl::OUString * pEnd = pBegin + aSNL.getLength();
304 0 : for( ; pBegin != pEnd; ++pBegin)
305 0 : if( *pBegin == ServiceName )
306 0 : return sal_True;
307 0 : return sal_False;
308 : }
309 : // -------------------------------------------------------------------------
310 : // XServiceInfo
311 0 : Sequence< ::rtl::OUString > SAL_CALL DBContentLoader::getSupportedServiceNames(void) throw( )
312 : {
313 0 : return getSupportedServiceNames_Static();
314 : }
315 : // -------------------------------------------------------------------------
316 : // ORegistryServiceManager_Static
317 0 : Sequence< ::rtl::OUString > DBContentLoader::getSupportedServiceNames_Static(void) throw( )
318 : {
319 0 : Sequence< ::rtl::OUString > aSNS( 1 );
320 0 : aSNS.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.FrameLoader"));
321 0 : return aSNS;
322 : }
323 :
324 : // -----------------------------------------------------------------------
325 : namespace
326 : {
327 : // ...................................................................
328 0 : sal_Bool lcl_urlAllowsInteraction( const ::comphelper::ComponentContext& _rContext, const ::rtl::OUString& _rURL )
329 : {
330 0 : bool bDoesAllow = sal_False;
331 : try
332 : {
333 0 : Reference< XURLTransformer > xTransformer( URLTransformer::create(_rContext.getUNOContext()) );
334 0 : URL aURL;
335 0 : aURL.Complete = _rURL;
336 0 : xTransformer->parseStrict( aURL );
337 0 : bDoesAllow = aURL.Arguments == "Interactive";
338 : }
339 0 : catch( const Exception& )
340 : {
341 : OSL_FAIL( "lcl_urlAllowsInteraction: caught an exception while analyzing the URL!" );
342 : }
343 0 : return bDoesAllow;
344 : }
345 :
346 : // ...................................................................
347 0 : Reference< XWindow > lcl_getTopMostWindow( const Reference<XComponentContext> & _rxContext )
348 : {
349 0 : Reference< XWindow > xWindow;
350 : // get the top most window
351 0 : Reference < XDesktop2 > xDesktop = Desktop::create(_rxContext);
352 0 : Reference < XFrame > xActiveFrame = xDesktop->getActiveFrame();
353 0 : if ( xActiveFrame.is() )
354 : {
355 0 : xWindow = xActiveFrame->getContainerWindow();
356 0 : Reference<XFrame> xFrame = xActiveFrame;
357 0 : while ( xFrame.is() && !xFrame->isTop() )
358 0 : xFrame.set(xFrame->getCreator(),UNO_QUERY);
359 :
360 0 : if ( xFrame.is() )
361 0 : xWindow = xFrame->getContainerWindow();
362 : }
363 0 : return xWindow;
364 : }
365 : }
366 :
367 : // -----------------------------------------------------------------------
368 0 : sal_Bool DBContentLoader::impl_executeNewDatabaseWizard( Reference< XModel >& _rxModel, sal_Bool& _bShouldStartTableWizard )
369 : {
370 0 : Sequence< Any > aWizardArgs(2);
371 0 : aWizardArgs[0] <<= PropertyValue(
372 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")),
373 : 0,
374 : makeAny( lcl_getTopMostWindow( m_aContext.getUNOContext() ) ),
375 0 : PropertyState_DIRECT_VALUE);
376 :
377 0 : aWizardArgs[1] <<= PropertyValue(
378 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InitialSelection")),
379 : 0,
380 : makeAny( _rxModel ),
381 0 : PropertyState_DIRECT_VALUE);
382 :
383 : // create the dialog
384 0 : Reference< XExecutableDialog > xAdminDialog;
385 0 : OSL_VERIFY( m_aContext.createComponentWithArguments( "com.sun.star.sdb.DatabaseWizardDialog", aWizardArgs, xAdminDialog ) );
386 :
387 : // execute it
388 0 : if ( !xAdminDialog.is() || ( RET_OK != xAdminDialog->execute() ) )
389 0 : return sal_False;
390 :
391 0 : Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
392 0 : sal_Bool bSuccess = sal_False;
393 0 : xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OpenDatabase"))) >>= bSuccess;
394 0 : xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("StartTableWizard"))) >>= _bShouldStartTableWizard;
395 0 : return bSuccess;
396 : }
397 :
398 : // -----------------------------------------------------------------------
399 0 : void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::rtl::OUString& _rURL,
400 : const Sequence< PropertyValue >& rArgs,
401 : const Reference< XLoadEventListener > & rListener) throw(::com::sun::star::uno::RuntimeException)
402 : {
403 : // first check if preview is true, if so return with out creating a controller. Preview is not supported
404 0 : ::comphelper::NamedValueCollection aMediaDesc( rArgs );
405 0 : sal_Bool bPreview = aMediaDesc.getOrDefault( "Preview", sal_False );
406 0 : if ( bPreview )
407 : {
408 0 : if (rListener.is())
409 0 : rListener->loadCancelled(this);
410 : return;
411 : }
412 :
413 0 : Reference< XModel > xModel = aMediaDesc.getOrDefault( "Model", Reference< XModel >() );
414 0 : ::rtl::OUString sSalvagedURL = aMediaDesc.getOrDefault( "SalvagedFile", _rURL );
415 :
416 0 : sal_Bool bCreateNew = sal_False; // does the URL denote the private:factory URL?
417 0 : sal_Bool bStartTableWizard = sal_False; // start the table wizard after everything was loaded successfully?
418 :
419 0 : sal_Bool bSuccess = sal_True;
420 :
421 : // If there's no interaction handler in the media descriptor, put one.
422 : // By definition, loading via loadComponentFromURL (and thus via the content loader here)
423 : // is allowed to raise UI. To not burden every place inside the document with creating
424 : // a default handler, we simply ensure there is one.
425 : // If a handler is present in the media descriptor, even if it is NULL, we will
426 : // not touch it.
427 0 : if ( !aMediaDesc.has( "InteractionHandler" ) )
428 : {
429 0 : Reference< XInteractionHandler2 > xHandler( InteractionHandler::createWithParent(m_aContext.getUNOContext(), 0) );
430 0 : aMediaDesc.put( "InteractionHandler", xHandler );
431 : }
432 :
433 : // it's allowed to pass an existing document
434 0 : Reference< XOfficeDatabaseDocument > xExistentDBDoc;
435 0 : xModel.set( aMediaDesc.getOrDefault( "Model", xExistentDBDoc ), UNO_QUERY );
436 0 : aMediaDesc.remove( "Model" );
437 :
438 : // also, it's allowed to specify the type of view which should be created
439 0 : ::rtl::OUString sViewName = aMediaDesc.getOrDefault( "ViewName", ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ) );
440 0 : aMediaDesc.remove( "ViewName" );
441 :
442 0 : sal_Int32 nInitialSelection = -1;
443 0 : if ( !xModel.is() )
444 : {
445 0 : Reference< XDatabaseContext > xDatabaseContext( DatabaseContext::create(m_aContext.getUNOContext()) );
446 :
447 0 : ::rtl::OUString sFactoryName = SvtModuleOptions().GetFactoryEmptyDocumentURL(SvtModuleOptions::E_DATABASE);
448 0 : bCreateNew = sFactoryName.match(_rURL);
449 :
450 0 : Reference< XDocumentDataSource > xDocumentDataSource;
451 0 : bool bNewAndInteractive = false;
452 0 : if ( bCreateNew )
453 : {
454 0 : bNewAndInteractive = lcl_urlAllowsInteraction( m_aContext, _rURL );
455 0 : xDocumentDataSource.set( xDatabaseContext->createInstance(), UNO_QUERY_THROW );
456 : }
457 : else
458 : {
459 0 : ::comphelper::NamedValueCollection aCreationArgs;
460 0 : aCreationArgs.put( (::rtl::OUString)INFO_POOLURL, sSalvagedURL );
461 0 : xDocumentDataSource.set( xDatabaseContext->createInstanceWithArguments( aCreationArgs.getWrappedNamedValues() ), UNO_QUERY_THROW );
462 : }
463 :
464 0 : xModel.set( xDocumentDataSource->getDatabaseDocument(), UNO_QUERY );
465 :
466 0 : if ( bCreateNew && xModel.is() )
467 : {
468 0 : if ( bNewAndInteractive )
469 : {
470 0 : bSuccess = impl_executeNewDatabaseWizard( xModel, bStartTableWizard );
471 : }
472 : else
473 : {
474 : try
475 : {
476 0 : Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
477 0 : xLoad->initNew();
478 0 : bSuccess = true;
479 : }
480 0 : catch( const Exception& )
481 : {
482 0 : bSuccess = false;
483 : }
484 : }
485 :
486 : // initially select the "Tables" category (will be done below)
487 0 : nInitialSelection = ::com::sun::star::sdb::application::DatabaseObjectContainer::TABLES;
488 0 : }
489 : }
490 :
491 0 : if ( !xModel.is() )
492 : {
493 0 : if ( rListener.is() )
494 0 : rListener->loadCancelled(this);
495 : return;
496 : }
497 :
498 0 : if ( !bCreateNew )
499 : {
500 : // We need to XLoadable::load the document if it does not yet have an URL.
501 : // If it already *does* have an URL, then it was either passed in the arguments, or a previous incarnation
502 : // of that model existed before (which can happen if a model is closed, but an associated DataSource is kept
503 : // alive 'til loading the document again).
504 0 : bool bNeedLoad = ( xModel->getURL().isEmpty() );
505 : try
506 : {
507 0 : aMediaDesc.put( "FileName", _rURL );
508 0 : Sequence< PropertyValue > aResource( aMediaDesc.getPropertyValues() );
509 :
510 0 : if ( bNeedLoad )
511 : {
512 0 : Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
513 0 : xLoad->load( aResource );
514 : }
515 :
516 : // always attach the resource, even if the document has not been freshly loaded
517 0 : xModel->attachResource( _rURL, aResource );
518 : }
519 0 : catch(const Exception&)
520 : {
521 : DBG_UNHANDLED_EXCEPTION();
522 0 : bSuccess = sal_False;
523 : }
524 : }
525 :
526 0 : if ( bSuccess )
527 : {
528 : try
529 : {
530 0 : Reference< XModel2 > xModel2( xModel, UNO_QUERY_THROW );
531 0 : Reference< XController2 > xController( xModel2->createViewController( sViewName, Sequence< PropertyValue >(), rFrame ), UNO_QUERY_THROW );
532 :
533 0 : xController->attachModel( xModel );
534 0 : xModel->connectController( xController.get() );
535 0 : rFrame->setComponent( xController->getComponentWindow(), xController.get() );
536 0 : xController->attachFrame( rFrame );
537 0 : xModel->setCurrentController( xController.get() );
538 :
539 0 : bSuccess = sal_True;
540 : }
541 0 : catch( const Exception& )
542 : {
543 : DBG_UNHANDLED_EXCEPTION();
544 0 : bSuccess = sal_False;
545 : }
546 : }
547 :
548 0 : if (bSuccess)
549 : {
550 0 : if ( rListener.is() )
551 0 : rListener->loadFinished(this);
552 :
553 0 : if ( nInitialSelection != -1 )
554 : {
555 0 : Reference< css::view::XSelectionSupplier > xDocView( xModel->getCurrentController(), UNO_QUERY );
556 0 : if ( xDocView.is() )
557 : {
558 0 : NamedDatabaseObject aSelection;
559 0 : aSelection.Type = nInitialSelection;
560 0 : xDocView->select( makeAny( aSelection ) );
561 0 : }
562 : }
563 :
564 0 : if ( bStartTableWizard )
565 : {
566 : // reset the data of the previous async drop (if any)
567 0 : if ( m_nStartWizard )
568 0 : Application::RemoveUserEvent(m_nStartWizard);
569 0 : m_sCurrentURL = xModel->getURL();
570 0 : m_xMySelf = this;
571 0 : m_nStartWizard = Application::PostUserEvent(LINK(this, DBContentLoader, OnStartTableWizard));
572 : }
573 : }
574 : else
575 : {
576 0 : if ( rListener.is() )
577 0 : rListener->loadCancelled( this );
578 : }
579 :
580 0 : if ( !bSuccess )
581 0 : ::comphelper::disposeComponent(xModel);
582 : }
583 :
584 : // -----------------------------------------------------------------------
585 0 : void DBContentLoader::cancel(void) throw()
586 : {
587 0 : }
588 : // -----------------------------------------------------------------------------
589 0 : IMPL_LINK( DBContentLoader, OnStartTableWizard, void*, /*NOTINTERESTEDIN*/ )
590 : {
591 0 : m_nStartWizard = 0;
592 : try
593 : {
594 0 : Sequence< Any > aWizArgs(1);
595 0 : PropertyValue aValue;
596 0 : aValue.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DatabaseLocation"));
597 0 : aValue.Value <<= m_sCurrentURL;
598 0 : aWizArgs[0] <<= aValue;
599 :
600 0 : SolarMutexGuard aGuard;
601 0 : Reference< XJobExecutor > xTableWizard;
602 0 : if ( m_aContext.createComponentWithArguments( "com.sun.star.wizards.table.CallTableWizard", aWizArgs, xTableWizard ) )
603 0 : xTableWizard->trigger(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("start")));
604 : }
605 0 : catch(const Exception&)
606 : {
607 : OSL_FAIL("caught an exception while starting the table wizard!");
608 : }
609 0 : m_xMySelf = NULL;
610 0 : return 0L;
611 : }
612 : }
613 : // -------------------------------------------------------------------------
614 0 : extern "C" void SAL_CALL createRegistryInfo_DBContentLoader2()
615 : {
616 0 : static ::dbaxml::OMultiInstanceAutoRegistration< ::dbaxml::DBContentLoader > aAutoRegistration;
617 0 : }
618 : // -------------------------------------------------------------------------
619 0 : extern "C" void SAL_CALL writeDBLoaderInfo2(void* pRegistryKey)
620 : {
621 0 : Reference< XRegistryKey> xKey(reinterpret_cast< XRegistryKey*>(pRegistryKey));
622 :
623 : // register content loader for dispatch
624 0 : ::rtl::OUString aImpl(RTL_CONSTASCII_USTRINGPARAM("/"));
625 0 : aImpl += ::dbaxml::DBContentLoader::getImplementationName_Static();
626 :
627 0 : ::rtl::OUString aImpltwo = aImpl;
628 0 : aImpltwo += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/Loader"));
629 0 : Reference< XRegistryKey> xNewKey = xKey->createKey( aImpltwo );
630 0 : aImpltwo = aImpl;
631 0 : aImpltwo += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/Loader"));
632 0 : Reference< XRegistryKey > xLoaderKey = xKey->createKey( aImpltwo );
633 0 : xNewKey = xLoaderKey->createKey( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Pattern")) );
634 0 : xNewKey->setAsciiValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("private:factory/sdatabase")) );
635 0 : }
636 : // -----------------------------------------------------------------------------
637 :
638 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|