LibreOffice Module dbaccess (master) 1
databaseobjectview.cxx
Go to the documentation of this file.
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
21#include <strings.hxx>
22#include <asyncmodaldialog.hxx>
23
24#include <com/sun/star/lang/XSingleServiceFactory.hpp>
25#include <com/sun/star/frame/TaskCreator.hpp>
26#include <com/sun/star/frame/XFrame.hpp>
27#include <com/sun/star/sdb/CommandType.hpp>
28#include <com/sun/star/sdb/application/XTableUIProvider.hpp>
29#include <com/sun/star/beans/NamedValue.hpp>
30
32#include <osl/diagnose.h>
35#include <utility>
36#include <vcl/window.hxx>
37
38namespace dbaui
39{
40
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::sdbc;
43 using namespace ::com::sun::star::sdb;
44 using namespace ::com::sun::star::sdb::application;
45 using namespace ::com::sun::star::ui::dialogs;
46 using namespace ::com::sun::star::frame;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::awt;
50
51 // DatabaseObjectView
53 const Reference< XDatabaseDocumentUI >& _rxApplication,
54 const Reference< XFrame >& _rxParentFrame,
55 OUString _sComponentURL )
56 :m_xORB ( _rxORB )
57 ,m_xParentFrame ( _rxParentFrame )
58 ,m_xApplication ( _rxApplication )
59 ,m_sComponentURL (std::move( _sComponentURL ))
60 {
61 OSL_ENSURE( m_xORB.is(), "DatabaseObjectView::DatabaseObjectView: invalid service factory!" );
62 OSL_ENSURE( m_xApplication.is(), "DatabaseObjectView::DatabaseObjectView: invalid connection!" );
63 }
64
66 {
67 Reference< XConnection > xConnection;
68 if ( m_xApplication.is() )
69 xConnection = m_xApplication->getActiveConnection();
70 return xConnection;
71 }
72
73 Reference< XComponent > DatabaseObjectView::createNew( const Reference< XDataSource >& _xDataSource, const ::comphelper::NamedValueCollection& i_rDispatchArgs )
74 {
75 return doCreateView( Any( _xDataSource ), OUString(), i_rDispatchArgs );
76 }
77
78 Reference< XComponent > DatabaseObjectView::openExisting( const Any& _rDataSource, const OUString& _rName,
79 const ::comphelper::NamedValueCollection& i_rDispatchArgs )
80 {
81 return doCreateView( _rDataSource, _rName, i_rDispatchArgs );
82 }
83
84 Reference< XComponent > DatabaseObjectView::doCreateView( const Any& _rDataSource, const OUString& _rObjectName,
85 const ::comphelper::NamedValueCollection& i_rCreationArgs )
86 {
88
89 aDispatchArgs.merge( i_rCreationArgs, false ); // false => do not overwrite
90 fillDispatchArgs( aDispatchArgs, _rDataSource, _rObjectName );
91 aDispatchArgs.merge( i_rCreationArgs, true ); // true => do overwrite
92
93 return doDispatch( aDispatchArgs );
94 }
95
96 Reference< XComponent > DatabaseObjectView::doDispatch( const ::comphelper::NamedValueCollection& i_rDispatchArgs )
97 {
99 if ( m_xORB.is() )
100 {
101 try
102 {
103 // if we have no externally provided frame, create one
104 if ( !m_xFrameLoader.is() )
105 {
106 Reference< XSingleServiceFactory > xFact = TaskCreator::create(m_xORB);
107 Sequence< Any > lArgs{ Any(NamedValue("ParentFrame", Any(m_xParentFrame))),
108 Any(NamedValue("TopWindow", Any(true))),
109 Any(NamedValue("SupportPersistentWindowState",
110 Any(true))) };
111
112 m_xFrameLoader.set(xFact->createInstanceWithArguments(lArgs), UNO_QUERY_THROW);
113
114 // everything we load can be considered a "top level document", so set the respective bit at the window.
115 // This, amongst other things, triggers that the component in this task participates in the
116 // "ThisComponent"-game for the global application Basic.
117 const Reference< XFrame > xFrame( m_xFrameLoader, UNO_QUERY_THROW );
118 const Reference< XWindow > xFrameWindow( xFrame->getContainerWindow(), UNO_SET_THROW );
119 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xFrameWindow );
120 ENSURE_OR_THROW( pContainerWindow, "no implementation access to the frame's container window!" );
121 pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WindowExtendedStyle::Document );
122 }
123
124 Reference< XComponentLoader > xFrameLoader( m_xFrameLoader, UNO_SET_THROW );
125 xReturn = xFrameLoader->loadComponentFromURL(
127 "_self",
128 0,
129 i_rDispatchArgs.getPropertyValues()
130 );
131 }
132 catch( const Exception& )
133 {
134 DBG_UNHANDLED_EXCEPTION("dbaccess");
135 }
136 }
137 return xReturn;
138 }
139
141 ::comphelper::NamedValueCollection& i_rDispatchArgs,
142 const Any& _aDataSource,
143 const OUString& /* _rName */
144 )
145 {
146 OUString sDataSource;
147 Reference<XDataSource> xDataSource;
148 if ( _aDataSource >>= sDataSource )
149 {
150 i_rDispatchArgs.put( PROPERTY_DATASOURCENAME, sDataSource );
151 }
152 else if ( _aDataSource >>= xDataSource )
153 {
154 i_rDispatchArgs.put( PROPERTY_DATASOURCE, xDataSource );
155 }
156
157 i_rDispatchArgs.put( PROPERTY_ACTIVE_CONNECTION, getConnection() );
158 }
159
160 // QueryDesigner
162 const Reference< XFrame >& _rxParentFrame, bool _bCreateView )
163 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, _bCreateView ? OUString(URL_COMPONENT_VIEWDESIGN) : OUString(URL_COMPONENT_QUERYDESIGN) )
164 ,m_nCommandType( _bCreateView ? CommandType::TABLE : CommandType::QUERY )
165 {
166 }
167
168 void QueryDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource,
169 const OUString& _rObjectName )
170 {
171 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName );
172
173 const bool bIncludeQueryName = !_rObjectName.isEmpty();
174 const bool bGraphicalDesign = i_rDispatchArgs.getOrDefault( PROPERTY_GRAPHICAL_DESIGN, true );
175 const bool bEditViewAsSQLCommand = ( m_nCommandType == CommandType::TABLE ) && !bGraphicalDesign;
176
177 i_rDispatchArgs.put( PROPERTY_COMMAND_TYPE, m_nCommandType );
178
179 if ( bIncludeQueryName )
180 {
181 i_rDispatchArgs.put( PROPERTY_COMMAND, _rObjectName );
182 }
183
184 if ( bEditViewAsSQLCommand )
185 {
186 i_rDispatchArgs.put( PROPERTY_ESCAPE_PROCESSING, false );
187 }
188 }
189
190 // TableDesigner
192 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< OUString >( URL_COMPONENT_TABLEDESIGN ) )
193 {
194 }
195
196 void TableDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource,
197 const OUString& _rObjectName )
198 {
199 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName );
200
201 if ( !_rObjectName.isEmpty() )
202 {
203 i_rDispatchArgs.put( PROPERTY_CURRENTTABLE, _rObjectName );
204 }
205 }
206
207 Reference< XComponent > TableDesigner::doCreateView( const Any& _rDataSource, const OUString& _rObjectName,
208 const ::comphelper::NamedValueCollection& i_rCreationArgs )
209 {
210 bool bIsNewDesign = _rObjectName.isEmpty();
211
212 // let's see whether the connection can provide a dedicated table designer
213 Reference< XInterface > xDesigner;
214 if ( !bIsNewDesign )
215 xDesigner = impl_getConnectionProvidedDesigner_nothrow( _rObjectName );
216
217 if ( !xDesigner.is() )
218 return DatabaseObjectView::doCreateView( _rDataSource, _rObjectName, i_rCreationArgs );
219
220 // try whether the designer is a dialog
221 Reference< XExecutableDialog > xDialog( xDesigner, UNO_QUERY_THROW );
223 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); }
224 return nullptr;
225 }
226
228 {
229 Reference< XInterface > xDesigner;
230 try
231 {
232 Reference< XTableUIProvider > xTableUIProv( getConnection(), UNO_QUERY );
233 if ( xTableUIProv.is() )
234 xDesigner = xTableUIProv->getTableEditor( getApplicationUI(), _rTableName );
235 }
236 catch( const Exception& )
237 {
238 DBG_UNHANDLED_EXCEPTION("dbaccess");
239 }
240 return xDesigner;
241 }
242
243 // ResultSetBrowser
245 bool _bTable )
246 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast < OUString >( URL_COMPONENT_DATASOURCEBROWSER ) )
247 ,m_bTable(_bTable)
248 {
249 }
250
251 void ResultSetBrowser::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource,
252 const OUString& _rQualifiedName)
253 {
254 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rQualifiedName );
255 OSL_ENSURE( !_rQualifiedName.isEmpty(),"A Table name must be set");
256 i_rDispatchArgs.put( PROPERTY_COMMAND, _rQualifiedName );
257 i_rDispatchArgs.put( PROPERTY_ENABLE_BROWSER, false );
258
259 if ( m_bTable )
260 {
261 OUString sCatalog;
262 OUString sSchema;
263 OUString sTable;
264 ::dbtools::qualifiedNameComponents( getConnection()->getMetaData(), _rQualifiedName, sCatalog, sSchema, sTable, ::dbtools::EComposeRule::InDataManipulation );
265 i_rDispatchArgs.put( PROPERTY_UPDATE_CATALOGNAME, sCatalog );
266 i_rDispatchArgs.put( PROPERTY_UPDATE_SCHEMANAME, sSchema );
267 i_rDispatchArgs.put( PROPERTY_UPDATE_TABLENAME, sTable );
268 i_rDispatchArgs.put( PROPERTY_COMMAND_TYPE, CommandType::TABLE );
269 }
270 else
271 i_rDispatchArgs.put( PROPERTY_COMMAND_TYPE, CommandType::QUERY );
272 }
273
274 // RelationDesigner
276 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< OUString >( URL_COMPONENT_RELATIONDESIGN ) )
277 {
278 }
279} // namespace dbaui
280
281/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sSchema
OptionalString sCatalog
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
NamedValueCollection & merge(const NamedValueCollection &_rAdditionalValues, bool _bOverwriteExisting)
VALUE_TYPE getOrDefault(const OUString &_rValueName, const VALUE_TYPE &_rDefault) const
static void executeModalDialogAsync(const css::uno::Reference< css::ui::dialogs::XExecutableDialog > &_rxDialog)
executes the given dialog asynchronously, but still modal
encapsulates access to the view of a database object.
css::uno::Reference< css::lang::XComponent > openExisting(const css::uno::Any &_aDataSource, const OUString &_rName, const ::comphelper::NamedValueCollection &i_rDispatchArgs)
opens a view for an existent object
css::uno::Reference< css::lang::XComponent > doDispatch(const ::comphelper::NamedValueCollection &i_rDispatchArgs)
css::uno::Reference< css::frame::XFrame > m_xParentFrame
virtual void fillDispatchArgs(::comphelper::NamedValueCollection &i_rDispatchArgs, const css::uno::Any &_rDataSource, const OUString &_rObjectName)
css::uno::Reference< css::sdbc::XConnection > getConnection() const
css::uno::Reference< css::lang::XComponent > createNew(const css::uno::Reference< css::sdbc::XDataSource > &_xDataSource, const ::comphelper::NamedValueCollection &i_rDispatchArgs=::comphelper::NamedValueCollection())
opens a view for a to-be-created object
css::uno::Reference< css::frame::XComponentLoader > m_xFrameLoader
css::uno::Reference< css::uno::XComponentContext > m_xORB
css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > m_xApplication
const css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > & getApplicationUI() const
DatabaseObjectView(const css::uno::Reference< css::uno::XComponentContext > &_rxORB, const css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > &_rxApplication, const css::uno::Reference< css::frame::XFrame > &_rxParentFrame, OUString _sComponentURL)
virtual css::uno::Reference< css::lang::XComponent > doCreateView(const css::uno::Any &_rDataSource, const OUString &_rObjectName, const ::comphelper::NamedValueCollection &i_rCreationArgs)
creates the desired view
virtual void fillDispatchArgs(::comphelper::NamedValueCollection &i_rDispatchArgs, const css::uno::Any &_aDataSource, const OUString &_rObjectName) override
QueryDesigner(const css::uno::Reference< css::uno::XComponentContext > &_rxORB, const css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > &_rxApplication, const css::uno::Reference< css::frame::XFrame > &_rxParentFrame, bool _bCreateView)
RelationDesigner(const css::uno::Reference< css::uno::XComponentContext > &_rxORB, const css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > &_rxApplication, const css::uno::Reference< css::frame::XFrame > &_rxParentFrame)
virtual void fillDispatchArgs(::comphelper::NamedValueCollection &i_rDispatchArgs, const css::uno::Any &_aDataSource, const OUString &_rQualifiedName) override
ResultSetBrowser(const css::uno::Reference< css::uno::XComponentContext > &_rxORB, const css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > &_rxApplication, const css::uno::Reference< css::frame::XFrame > &_rxParentFrame, bool _bTable)
css::uno::Reference< css::uno::XInterface > impl_getConnectionProvidedDesigner_nothrow(const OUString &_rTableName)
retrieves the table designer component as provided by the connection, if any
virtual void fillDispatchArgs(::comphelper::NamedValueCollection &i_rDispatchArgs, const css::uno::Any &_aDataSource, const OUString &_rObjectName) override
TableDesigner(const css::uno::Reference< css::uno::XComponentContext > &_rxORB, const css::uno::Reference< css::sdb::application::XDatabaseDocumentUI > &_rxApplication, const css::uno::Reference< css::frame::XFrame > &_rxParentFrame)
virtual css::uno::Reference< css::lang::XComponent > doCreateView(const css::uno::Any &_rDataSource, const OUString &_rObjectName, const ::comphelper::NamedValueCollection &i_rCreationArgs) override
creates the desired view
sal_Int32 m_nCommandType
#define ENSURE_OR_THROW(c, m)
#define DBG_UNHANDLED_EXCEPTION(...)
@ Exception
constexpr OUStringLiteral PROPERTY_COMMAND(u"Command")
constexpr OUStringLiteral PROPERTY_UPDATE_TABLENAME(u"UpdateTableName")
constexpr OUStringLiteral PROPERTY_UPDATE_SCHEMANAME(u"UpdateSchemaName")
constexpr OUStringLiteral URL_COMPONENT_RELATIONDESIGN
Definition: strings.hxx:243
constexpr OUStringLiteral PROPERTY_ACTIVE_CONNECTION(u"ActiveConnection")
constexpr OUStringLiteral URL_COMPONENT_DATASOURCEBROWSER
Definition: strings.hxx:242
constexpr OUStringLiteral URL_COMPONENT_QUERYDESIGN
Definition: strings.hxx:237
constexpr OUStringLiteral PROPERTY_ESCAPE_PROCESSING(u"EscapeProcessing")
constexpr OUStringLiteral URL_COMPONENT_VIEWDESIGN
Definition: strings.hxx:238
constexpr OUStringLiteral PROPERTY_CURRENTTABLE(u"CurrentTable")
constexpr OUStringLiteral PROPERTY_DATASOURCE(u"DataSource")
constexpr OUStringLiteral PROPERTY_ENABLE_BROWSER(u"EnableBrowser")
constexpr OUStringLiteral PROPERTY_UPDATE_CATALOGNAME(u"UpdateCatalogName")
constexpr OUStringLiteral PROPERTY_DATASOURCENAME(u"DataSourceName")
constexpr OUStringLiteral PROPERTY_GRAPHICAL_DESIGN(u"GraphicalDesign")
constexpr OUStringLiteral PROPERTY_COMMAND_TYPE(u"CommandType")
constexpr OUStringLiteral URL_COMPONENT_TABLEDESIGN
Definition: strings.hxx:239
Reference< XFrame > xFrame
the frame which the component resides in. Must not be <NULL>
QUERY
TABLE