1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <strings.hxx>
21 #include <UITools.hxx>
23 #include <com/sun/star/container/XChild.hpp>
24 #include <com/sun/star/frame/XController2.hpp>
25 #include <com/sun/star/frame/XFrame.hpp>
26 #include <com/sun/star/frame/XFrameLoader.hpp>
27 #include <com/sun/star/frame/XLoadEventListener.hpp>
28 #include <com/sun/star/lang/XInitialization.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/sdb/ReportDesign.hpp>
31 #include <com/sun/star/sdbc/XConnection.hpp>
32 #include <com/sun/star/frame/XModule.hpp>
34 #include <com/sun/star/sdbc/XDataSource.hpp>
35 #include <comphelper/namedvaluecollection.hxx>
36 #include <comphelper/types.hxx>
37 #include <cppuhelper/implbase.hxx>
38 #include <cppuhelper/supportsservice.hxx>
39 #include <comphelper/diagnose_ex.hxx>
40 #include <tools/urlobj.hxx>
41 #include <unotools/fcm.hxx>
42 #include <vcl/svapp.hxx>
44 using namespace ::com::sun::star
;
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::frame
;
47 using namespace ::com::sun::star::beans
;
48 using namespace ::com::sun::star::sdb
;
49 using namespace ::com::sun::star::sdbc
;
50 using namespace ::com::sun::star::container
;
51 using namespace ::com::sun::star::lang
;
52 using namespace dbaui
;
56 class DBContentLoader
: public ::cppu::WeakImplHelper
< XFrameLoader
, XServiceInfo
>
59 Sequence
< PropertyValue
> m_aArgs
;
60 Reference
< XLoadEventListener
> m_xListener
;
61 Reference
< XComponentContext
> m_xContext
;
63 explicit DBContentLoader(const Reference
< XComponentContext
>&);
66 OUString SAL_CALL
getImplementationName() override
;
67 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) override
;
68 Sequence
< OUString
> SAL_CALL
getSupportedServiceNames() override
;
71 virtual void SAL_CALL
load( const Reference
< XFrame
> & _rFrame
, const OUString
& _rURL
,
72 const Sequence
< PropertyValue
>& _rArgs
,
73 const Reference
< XLoadEventListener
> & _rListener
) override
;
74 virtual void SAL_CALL
cancel() override
;
79 DBContentLoader::DBContentLoader(const Reference
< XComponentContext
>& _rxContext
)
80 :m_xContext(_rxContext
)
85 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
86 org_openoffice_comp_dbu_DBContentLoader_get_implementation(
87 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
89 return cppu::acquire(new DBContentLoader(context
));
93 OUString SAL_CALL
DBContentLoader::getImplementationName()
95 return u
"org.openoffice.comp.dbu.DBContentLoader"_ustr
;
99 sal_Bool SAL_CALL
DBContentLoader::supportsService(const OUString
& ServiceName
)
101 return cppu::supportsService(this, ServiceName
);
105 Sequence
< OUString
> SAL_CALL
DBContentLoader::getSupportedServiceNames()
107 return { u
"com.sun.star.frame.FrameLoader"_ustr
, u
"com.sun.star.sdb.ContentLoader"_ustr
};
110 void SAL_CALL
DBContentLoader::load(const Reference
< XFrame
> & rFrame
, const OUString
& rURL
,
111 const Sequence
< PropertyValue
>& rArgs
,
112 const Reference
< XLoadEventListener
> & rListener
)
114 m_xListener
= rListener
;
117 static constexpr struct ServiceNameToImplName
119 OUString sServiceName
;
120 OUString aAsciiImplementationName
;
121 } aImplementations
[] = {
122 { URL_COMPONENT_FORMGRIDVIEW
, u
"org.openoffice.comp.dbu.OFormGridView"_ustr
},
123 { URL_COMPONENT_DATASOURCEBROWSER
, u
"org.openoffice.comp.dbu.ODatasourceBrowser"_ustr
},
124 { URL_COMPONENT_QUERYDESIGN
, u
"org.openoffice.comp.dbu.OQueryDesign"_ustr
},
125 { URL_COMPONENT_TABLEDESIGN
, u
"org.openoffice.comp.dbu.OTableDesign"_ustr
},
126 { URL_COMPONENT_RELATIONDESIGN
, u
"org.openoffice.comp.dbu.ORelationDesign"_ustr
},
127 { URL_COMPONENT_VIEWDESIGN
, u
"org.openoffice.comp.dbu.OViewDesign"_ustr
}
130 INetURLObject
aParser( rURL
);
131 Reference
< XController2
> xController
;
133 const OUString
sComponentURL( aParser
.GetMainURL( INetURLObject::DecodeMechanism::ToIUri
) );
134 for (const ServiceNameToImplName
& aImplementation
: aImplementations
)
136 if ( sComponentURL
== aImplementation
.sServiceName
)
138 xController
.set( m_xContext
->getServiceManager()->
139 createInstanceWithContext( aImplementation
.aAsciiImplementationName
, m_xContext
), UNO_QUERY_THROW
);
144 // if a data source browser is loaded without its tree pane, then we assume it to be a
145 // table data view, effectively. In this case, we need to adjust the module identifier.
147 ::comphelper::NamedValueCollection
aLoadArgs( rArgs
);
149 if ( sComponentURL
== URL_COMPONENT_DATASOURCEBROWSER
)
151 bool bDisableBrowser
= !aLoadArgs
.getOrDefault( u
"ShowTreeViewButton"_ustr
, true ) // compatibility name
152 || !aLoadArgs
.getOrDefault( PROPERTY_ENABLE_BROWSER
, true );
154 if ( bDisableBrowser
)
158 Reference
< XModule
> xModule( xController
, UNO_QUERY_THROW
);
159 xModule
->setIdentifier( u
"com.sun.star.sdb.TableDataView"_ustr
);
161 catch( const Exception
& )
163 DBG_UNHANDLED_EXCEPTION("dbaccess");
168 if ( sComponentURL
== URL_COMPONENT_REPORTDESIGN
)
170 bool bPreview
= aLoadArgs
.getOrDefault( u
"Preview"_ustr
, false );
172 { // report designs cannot be previewed
173 if ( rListener
.is() )
174 rListener
->loadCancelled( this );
177 Reference
< XModel
> xReportModel( aLoadArgs
.getOrDefault( u
"Model"_ustr
, Reference
< XModel
>() ) );
178 if ( xReportModel
.is() )
180 xController
.set( ReportDesign::create( m_xContext
) );
181 utl::ConnectModelController(xReportModel
, xController
);
185 bool bSuccess
= xController
.is();
186 Reference
< XModel
> xDatabaseDocument
;
189 Reference
< XDataSource
> xDataSource ( aLoadArgs
.getOrDefault( u
"DataSource"_ustr
, Reference
< XDataSource
>() ) );
190 OUString
sDataSourceName( aLoadArgs
.getOrDefault( u
"DataSourceName"_ustr
, OUString() ) );
191 Reference
< XConnection
> xConnection ( aLoadArgs
.getOrDefault( u
"ActiveConnection"_ustr
, Reference
< XConnection
>() ) );
192 if ( xDataSource
.is() )
194 xDatabaseDocument
.set( getDataSourceOrModel( xDataSource
), UNO_QUERY
);
196 else if ( !sDataSourceName
.isEmpty() )
198 ::dbtools::SQLExceptionInfo aError
;
199 xDataSource
.set( getDataSourceByName( sDataSourceName
, nullptr, m_xContext
, &aError
) );
200 xDatabaseDocument
.set( getDataSourceOrModel( xDataSource
), UNO_QUERY
);
202 else if ( xConnection
.is() )
204 Reference
< XChild
> xAsChild( xConnection
, UNO_QUERY
);
207 OSL_ENSURE( Reference
< XDataSource
>( xAsChild
->getParent(), UNO_QUERY
).is(),
208 "DBContentLoader::load: a connection whose parent is no data source?" );
209 xDatabaseDocument
.set( getDataSourceOrModel( xAsChild
->getParent() ), UNO_QUERY
);
214 SolarMutexGuard aGuard
;
217 Reference
<XInitialization
> xIni(xController
,UNO_QUERY
);
218 PropertyValue
aFrame(u
"Frame"_ustr
,0,Any(rFrame
),PropertyState_DIRECT_VALUE
);
219 Sequence
< Any
> aInitArgs(m_aArgs
.getLength()+1);
221 Any
* pBegin
= aInitArgs
.getArray();
223 std::transform(m_aArgs
.begin(), m_aArgs
.end(), ++pBegin
,
224 [](auto& val
) { return Any(val
); });
226 xIni
->initialize(aInitArgs
);
228 catch(const Exception
&)
230 // Does this need to be shown to the user?
234 ::comphelper::disposeComponent( xController
);
236 catch( const Exception
& )
238 DBG_UNHANDLED_EXCEPTION("dbaccess");
243 // assign controller and frame
246 if ( xController
.is() && rFrame
.is() )
248 rFrame
->setComponent( xController
->getComponentWindow(), xController
);
249 xController
->attachFrame(rFrame
);
252 if ( rListener
.is() )
253 rListener
->loadFinished( this );
256 if ( rListener
.is() )
257 rListener
->loadCancelled( this );
260 void DBContentLoader::cancel()
264 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */