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 "dbu_reghelper.hxx"
22 : : #include "dbustrings.hrc"
23 : : #include "UITools.hxx"
24 : :
25 : : #include <com/sun/star/container/XChild.hpp>
26 : : #include <com/sun/star/container/XNameAccess.hpp>
27 : : #include <com/sun/star/container/XSet.hpp>
28 : : #include <com/sun/star/document/XEventListener.hpp>
29 : : #include <com/sun/star/frame/XController2.hpp>
30 : : #include <com/sun/star/frame/XFrame.hpp>
31 : : #include <com/sun/star/frame/XFrameLoader.hpp>
32 : : #include <com/sun/star/frame/XLoadEventListener.hpp>
33 : : #include <com/sun/star/lang/XInitialization.hpp>
34 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 : : #include <com/sun/star/lang/XServiceInfo.hpp>
36 : : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 : : #include <com/sun/star/registry/XRegistryKey.hpp>
38 : : #include <com/sun/star/sdbc/XConnection.hpp>
39 : : #include <com/sun/star/frame/XModule.hpp>
40 : :
41 : : #include <com/sun/star/sdbc/XDataSource.hpp>
42 : : #include <comphelper/namedvaluecollection.hxx>
43 : : #include <comphelper/componentcontext.hxx>
44 : : #include <cppuhelper/implbase2.hxx>
45 : : #include <toolkit/awt/vclxwindow.hxx>
46 : : #include <toolkit/helper/vclunohelper.hxx>
47 : : #include <tools/diagnose_ex.h>
48 : : #include <tools/urlobj.hxx>
49 : : #include <vcl/svapp.hxx>
50 : :
51 : : using namespace ::com::sun::star;
52 : : using namespace ::com::sun::star::uno;
53 : : using namespace ::com::sun::star::frame;
54 : : using namespace ::com::sun::star::beans;
55 : : using namespace ::com::sun::star::sdbc;
56 : : using namespace ::com::sun::star::container;
57 : : using namespace ::com::sun::star::lang;
58 : : using namespace ::com::sun::star::registry;
59 : : using ::com::sun::star::sdbc::XDataSource;
60 : : using namespace dbaui;
61 : :
62 : : class DBContentLoader : public ::cppu::WeakImplHelper2< XFrameLoader, XServiceInfo>
63 : : {
64 : : private:
65 : : ::rtl::OUString m_aURL;
66 : : Sequence< PropertyValue> m_aArgs;
67 : : Reference< XLoadEventListener > m_xListener;
68 : : Reference< XFrame > m_xFrame;
69 : : Reference< XMultiServiceFactory > m_xServiceFactory;
70 : : public:
71 : : DBContentLoader(const Reference< XMultiServiceFactory >&);
72 : : ~DBContentLoader();
73 : :
74 : : // XServiceInfo
75 : : ::rtl::OUString SAL_CALL getImplementationName() throw( );
76 : : sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw( );
77 : : Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( );
78 : :
79 : : // static methods
80 : 18 : static ::rtl::OUString getImplementationName_Static() throw( )
81 : : {
82 : 18 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.DBContentLoader"));
83 : : }
84 : : static Sequence< ::rtl::OUString> getSupportedServiceNames_Static(void) throw( );
85 : : static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
86 : : SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&);
87 : :
88 : : // XLoader
89 : : virtual void SAL_CALL load( const Reference< XFrame > & _rFrame, const ::rtl::OUString& _rURL,
90 : : const Sequence< PropertyValue >& _rArgs,
91 : : const Reference< XLoadEventListener > & _rListener) throw(::com::sun::star::uno::RuntimeException);
92 : : virtual void SAL_CALL cancel(void) throw();
93 : : };
94 : : DBG_NAME(DBContentLoader)
95 : :
96 : 6 : DBContentLoader::DBContentLoader(const Reference< XMultiServiceFactory >& _rxFactory)
97 [ + - ]: 6 : :m_xServiceFactory(_rxFactory)
98 : : {
99 : : DBG_CTOR(DBContentLoader,NULL);
100 : :
101 : 6 : }
102 : : // -------------------------------------------------------------------------
103 : :
104 [ + - ]: 6 : DBContentLoader::~DBContentLoader()
105 : : {
106 : :
107 : : DBG_DTOR(DBContentLoader,NULL);
108 [ - + ]: 12 : }
109 : : // -------------------------------------------------------------------------
110 : : // -------------------------------------------------------------------------
111 : 8 : extern "C" void SAL_CALL createRegistryInfo_DBContentLoader()
112 : : {
113 [ + - ][ + - ]: 8 : static ::dbaui::OMultiInstanceAutoRegistration< DBContentLoader > aAutoRegistration;
[ + - ][ # # ]
114 : 8 : }
115 : : // -------------------------------------------------------------------------
116 : 6 : Reference< XInterface > SAL_CALL DBContentLoader::Create( const Reference< XMultiServiceFactory > & rSMgr )
117 : : {
118 [ + - ]: 6 : return *(new DBContentLoader(rSMgr));
119 : : }
120 : : // -------------------------------------------------------------------------
121 : : // XServiceInfo
122 : 2 : ::rtl::OUString SAL_CALL DBContentLoader::getImplementationName() throw( )
123 : : {
124 : 2 : return getImplementationName_Static();
125 : : }
126 : : // -------------------------------------------------------------------------
127 : :
128 : : // XServiceInfo
129 : 0 : sal_Bool SAL_CALL DBContentLoader::supportsService(const ::rtl::OUString& ServiceName) throw( )
130 : : {
131 : 0 : Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames();
132 : 0 : const ::rtl::OUString * pBegin = aSNL.getConstArray();
133 : 0 : const ::rtl::OUString * pEnd = pBegin + aSNL.getLength();
134 [ # # ]: 0 : for( ; pBegin != pEnd; ++pBegin)
135 [ # # ]: 0 : if( *pBegin == ServiceName )
136 : 0 : return sal_True;
137 [ # # ]: 0 : return sal_False;
138 : : }
139 : : // -------------------------------------------------------------------------
140 : : // XServiceInfo
141 : 0 : Sequence< ::rtl::OUString > SAL_CALL DBContentLoader::getSupportedServiceNames(void) throw( )
142 : : {
143 : 0 : return getSupportedServiceNames_Static();
144 : : }
145 : : // -------------------------------------------------------------------------
146 : : // ORegistryServiceManager_Static
147 : 8 : Sequence< ::rtl::OUString > DBContentLoader::getSupportedServiceNames_Static(void) throw( )
148 : : {
149 : 8 : Sequence< ::rtl::OUString > aSNS( 2 );
150 [ + - ][ + - ]: 8 : aSNS.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.FrameLoader"));
151 [ + - ][ + - ]: 8 : aSNS.getArray()[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ContentLoader"));
152 : 8 : return aSNS;
153 : : }
154 : : // -------------------------------------------------------------------------
155 : 0 : extern "C" void SAL_CALL writeDBLoaderInfo(void* pRegistryKey)
156 : : {
157 [ # # ]: 0 : Reference< XRegistryKey> xKey(reinterpret_cast< XRegistryKey*>(pRegistryKey));
158 : :
159 : : // register content loader for dispatch
160 [ # # ]: 0 : ::rtl::OUString aImpl(RTL_CONSTASCII_USTRINGPARAM("/"));
161 : 0 : aImpl += DBContentLoader::getImplementationName_Static();
162 : :
163 : 0 : ::rtl::OUString aImpltwo = aImpl;
164 [ # # ]: 0 : aImpltwo += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/UNO/Loader"));
165 [ # # ][ # # ]: 0 : Reference< XRegistryKey> xNewKey = xKey->createKey( aImpltwo );
166 : 0 : aImpltwo = aImpl;
167 [ # # ]: 0 : aImpltwo += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/Loader"));
168 [ # # ][ # # ]: 0 : Reference< XRegistryKey > xLoaderKey = xKey->createKey( aImpltwo );
169 [ # # ][ # # ]: 0 : xNewKey = xLoaderKey->createKey( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Pattern")) );
[ # # ][ # # ]
170 [ # # ][ # # ]: 0 : xNewKey->setAsciiValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".component:DB*")) );
[ # # ]
171 : 0 : }
172 : :
173 : : // -----------------------------------------------------------------------
174 : 2 : void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::rtl::OUString& rURL,
175 : : const Sequence< PropertyValue >& rArgs,
176 : : const Reference< XLoadEventListener > & rListener) throw(::com::sun::star::uno::RuntimeException)
177 : : {
178 [ + - ]: 2 : m_xFrame = rFrame;
179 [ + - ]: 2 : m_xListener = rListener;
180 : 2 : m_aURL = rURL;
181 [ + - ]: 2 : m_aArgs = rArgs;
182 : :
183 [ + - ]: 2 : ::comphelper::ComponentContext aContext( m_xServiceFactory );
184 : :
185 : : struct ServiceNameToImplName
186 : : {
187 : : const sal_Char* pAsciiServiceName;
188 : : const sal_Char* pAsciiImplementationName;
189 : 12 : ServiceNameToImplName( const sal_Char* _pService, const sal_Char* _pImpl )
190 : : :pAsciiServiceName( _pService )
191 : 12 : ,pAsciiImplementationName( _pImpl )
192 : : {
193 : 12 : }
194 : : } aImplementations[] = {
195 : : ServiceNameToImplName( URL_COMPONENT_FORMGRIDVIEW.ascii, "org.openoffice.comp.dbu.OFormGridView" ),
196 : : ServiceNameToImplName( URL_COMPONENT_DATASOURCEBROWSER.ascii, "org.openoffice.comp.dbu.ODatasourceBrowser" ),
197 : : ServiceNameToImplName( URL_COMPONENT_QUERYDESIGN.ascii, "org.openoffice.comp.dbu.OQueryDesign" ),
198 : : ServiceNameToImplName( URL_COMPONENT_TABLEDESIGN.ascii, "org.openoffice.comp.dbu.OTableDesign" ),
199 : : ServiceNameToImplName( URL_COMPONENT_RELATIONDESIGN.ascii, "org.openoffice.comp.dbu.ORelationDesign" ),
200 : : ServiceNameToImplName( URL_COMPONENT_VIEWDESIGN.ascii, "org.openoffice.comp.dbu.OViewDesign" )
201 : 2 : };
202 : :
203 [ + - ]: 2 : INetURLObject aParser( rURL );
204 : 2 : Reference< XController2 > xController;
205 : :
206 [ + - ]: 2 : const ::rtl::OUString sComponentURL( aParser.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
207 [ + - ]: 4 : for ( size_t i=0; i < sizeof( aImplementations ) / sizeof( aImplementations[0] ); ++i )
208 : : {
209 [ + + ]: 4 : if ( sComponentURL.equalsAscii( aImplementations[i].pAsciiServiceName ) )
210 : : {
211 [ + - ]: 2 : aContext.createComponent( aImplementations[i].pAsciiImplementationName, xController );
212 : 2 : break;
213 : : }
214 : : }
215 : :
216 : : // if a data source browser is loaded without its tree pane, then we assume it to be a
217 : : // table data view, effectively. In this case, we need to adjust the module identifier.
218 : : // #i85879#
219 [ + - ]: 2 : ::comphelper::NamedValueCollection aLoadArgs( rArgs );
220 : :
221 [ + - ][ + - ]: 2 : if ( sComponentURL == URL_COMPONENT_DATASOURCEBROWSER )
222 : : {
223 [ + - ][ + - ]: 4 : sal_Bool bDisableBrowser = ( sal_False == aLoadArgs.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name
[ # # ]
224 [ + - ][ + - ]: 2 : || ( sal_False == aLoadArgs.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) );
[ + - ][ - + ]
[ + - ][ + - ]
[ # # # # ]
225 : :
226 [ - + ]: 2 : if ( bDisableBrowser )
227 : : {
228 : : try
229 : : {
230 [ # # ]: 0 : Reference< XModule > xModule( xController, UNO_QUERY_THROW );
231 [ # # ][ # # ]: 0 : xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TableDataView" ) ) );
[ # # ][ # # ]
232 : : }
233 [ # # ]: 0 : catch( const Exception& )
234 : : {
235 : : DBG_UNHANDLED_EXCEPTION();
236 : : }
237 : : }
238 : : }
239 : :
240 [ + - ][ - + ]: 2 : if ( sComponentURL == URL_COMPONENT_REPORTDESIGN )
241 : : {
242 [ # # ]: 0 : sal_Bool bPreview = aLoadArgs.getOrDefault( "Preview", sal_False );
243 [ # # ]: 0 : if ( bPreview )
244 : : { // report designs cannot be previewed
245 [ # # ]: 0 : if ( rListener.is() )
246 [ # # ][ # # ]: 0 : rListener->loadCancelled( this );
[ # # ]
247 : 2 : return;
248 : : }
249 [ # # ]: 0 : Reference< XModel > xReportModel( aLoadArgs.getOrDefault( "Model", Reference< XModel >() ) );
250 [ # # ]: 0 : if ( xReportModel.is() )
251 : : {
252 [ # # ]: 0 : xController.set( m_xServiceFactory->createInstance(
253 [ # # ][ # # ]: 0 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.ReportDesign" ) ) ), UNO_QUERY );
[ # # ]
254 [ # # ]: 0 : if ( xController.is() )
255 : : {
256 [ # # ][ # # ]: 0 : xController->attachModel( xReportModel );
257 [ # # ][ # # ]: 0 : xReportModel->connectController( xController.get() );
[ # # ][ # # ]
258 [ # # ][ # # ]: 0 : xReportModel->setCurrentController( xController.get() );
[ # # ][ # # ]
259 : : }
260 : 0 : }
261 : : }
262 : :
263 : 2 : sal_Bool bSuccess = xController.is();
264 : 2 : Reference< XModel > xDatabaseDocument;
265 [ + - ]: 2 : if ( bSuccess )
266 : : {
267 [ + - ]: 2 : Reference< XDataSource > xDataSource ( aLoadArgs.getOrDefault( "DataSource", Reference< XDataSource >() ) );
268 [ + - ]: 2 : ::rtl::OUString sDataSourceName( aLoadArgs.getOrDefault( "DataSourceName", ::rtl::OUString() ) );
269 [ + - ]: 2 : Reference< XConnection > xConnection ( aLoadArgs.getOrDefault( "ActiveConnection", Reference< XConnection >() ) );
270 [ - + ]: 2 : if ( xDataSource.is() )
271 : : {
272 [ # # ][ # # ]: 0 : xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY );
273 : : }
274 [ - + ]: 2 : else if ( !sDataSourceName.isEmpty() )
275 : : {
276 [ # # ]: 0 : ::dbtools::SQLExceptionInfo aError;
277 [ # # ][ # # ]: 0 : xDataSource.set( getDataSourceByName( sDataSourceName, NULL, m_xServiceFactory, &aError ) );
278 [ # # ][ # # ]: 0 : xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY );
[ # # ]
279 : : }
280 [ - + ]: 2 : else if ( xConnection.is() )
281 : : {
282 [ # # ]: 0 : Reference< XChild > xAsChild( xConnection, UNO_QUERY );
283 [ # # ]: 0 : if ( xAsChild.is() )
284 : : {
285 : : OSL_ENSURE( Reference< XDataSource >( xAsChild->getParent(), UNO_QUERY ).is(),
286 : : "DBContentLoader::load: a connection whose parent is no data source?" );
287 [ # # ][ # # ]: 0 : xDatabaseDocument.set( getDataSourceOrModel( xAsChild->getParent() ), UNO_QUERY );
[ # # ][ # # ]
288 : 0 : }
289 : : }
290 : :
291 : : // init controller
292 [ + - ]: 2 : SolarMutexGuard aGuard;
293 : : try
294 : : {
295 [ + - ]: 2 : Reference<XInitialization > xIni(xController,UNO_QUERY);
296 [ + - ][ + - ]: 2 : PropertyValue aFrame(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Frame")),0,makeAny(rFrame),PropertyState_DIRECT_VALUE);
297 [ + - ]: 2 : Sequence< Any > aInitArgs(m_aArgs.getLength()+1);
298 : :
299 [ + - ]: 2 : Any* pBegin = aInitArgs.getArray();
300 : 2 : Any* pEnd = pBegin + aInitArgs.getLength();
301 [ + - ]: 2 : *pBegin <<= aFrame;
302 : 2 : const PropertyValue* pIter = m_aArgs.getConstArray();
303 [ + + ]: 16 : for(++pBegin;pBegin != pEnd;++pBegin,++pIter)
304 : : {
305 [ + - ]: 14 : *pBegin <<= *pIter;
306 : : }
307 : :
308 [ + - ][ + - ]: 2 : xIni->initialize(aInitArgs);
[ + - ][ # # ]
309 : : }
310 [ # # # # ]: 0 : catch(const Exception&)
311 : : {
312 : : // Does this need to be shown to the user?
313 : 0 : bSuccess = false;
314 : : try
315 : : {
316 [ # # ]: 0 : ::comphelper::disposeComponent( xController );
317 : : }
318 [ # # ]: 0 : catch( const Exception& )
319 : : {
320 : : DBG_UNHANDLED_EXCEPTION();
321 : : }
322 [ + - ]: 2 : }
323 : : }
324 : :
325 : : // assign controller and frame
326 [ + - ]: 2 : if ( bSuccess )
327 : : {
328 [ + - ][ + - ]: 2 : if ( xController.is() && rFrame.is() )
[ + - ]
329 : : {
330 [ + - ][ + - ]: 2 : rFrame->setComponent( xController->getComponentWindow(), xController.get() );
[ + - ][ + - ]
[ + - ][ + - ]
331 [ + - ][ + - ]: 2 : xController->attachFrame(rFrame);
332 : : }
333 : :
334 [ + - ]: 2 : if ( rListener.is() )
335 [ + - ][ + - ]: 2 : rListener->loadFinished( this );
[ + - ]
336 : : }
337 : : else
338 [ # # ]: 0 : if ( rListener.is() )
339 [ # # ][ # # ]: 2 : rListener->loadCancelled( this );
[ # # ][ + - ]
[ - + ][ - + ]
[ - + ][ + - ]
[ - + ][ + - ]
[ + - ]
340 : : }
341 : :
342 : : // -----------------------------------------------------------------------
343 : 0 : void DBContentLoader::cancel(void) throw()
344 : : {
345 : 0 : }
346 : :
347 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|