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 #include <databaseobjectview.hxx> 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 31 #include <connectivity/dbtools.hxx> 32 #include <osl/diagnose.h> 33 #include <toolkit/helper/vclunohelper.hxx> 34 #include <tools/diagnose_ex.h> 35 #include <vcl/window.hxx> 36 37 namespace dbaui 38 { 39 40 using namespace ::com::sun::star::uno; 41 using namespace ::com::sun::star::sdbc; 42 using namespace ::com::sun::star::sdb; 43 using namespace ::com::sun::star::sdb::application; 44 using namespace ::com::sun::star::ui::dialogs; 45 using namespace ::com::sun::star::frame; 46 using namespace ::com::sun::star::lang; 47 using namespace ::com::sun::star::beans; 48 using namespace ::com::sun::star::awt; 49 50 // DatabaseObjectView DatabaseObjectView(const Reference<XComponentContext> & _rxORB,const Reference<XDatabaseDocumentUI> & _rxApplication,const Reference<XFrame> & _rxParentFrame,const OUString & _rComponentURL)51 DatabaseObjectView::DatabaseObjectView( const Reference< XComponentContext >& _rxORB, 52 const Reference< XDatabaseDocumentUI >& _rxApplication, 53 const Reference< XFrame >& _rxParentFrame, 54 const OUString& _rComponentURL ) 55 :m_xORB ( _rxORB ) 56 ,m_xParentFrame ( _rxParentFrame ) 57 ,m_xFrameLoader ( ) 58 ,m_xApplication ( _rxApplication ) 59 ,m_sComponentURL ( _rComponentURL ) 60 { 61 OSL_ENSURE( m_xORB.is(), "DatabaseObjectView::DatabaseObjectView: invalid service factory!" ); 62 OSL_ENSURE( m_xApplication.is(), "DatabaseObjectView::DatabaseObjectView: invalid connection!" ); 63 } 64 getConnection() const65 Reference< XConnection > DatabaseObjectView::getConnection() const 66 { 67 Reference< XConnection > xConnection; 68 if ( m_xApplication.is() ) 69 xConnection = m_xApplication->getActiveConnection(); 70 return xConnection; 71 } 72 createNew(const Reference<XDataSource> & _xDataSource,const::comphelper::NamedValueCollection & i_rDispatchArgs)73 Reference< XComponent > DatabaseObjectView::createNew( const Reference< XDataSource >& _xDataSource, const ::comphelper::NamedValueCollection& i_rDispatchArgs ) 74 { 75 return doCreateView( makeAny( _xDataSource ), OUString(), i_rDispatchArgs ); 76 } 77 openExisting(const Any & _rDataSource,const OUString & _rName,const::comphelper::NamedValueCollection & i_rDispatchArgs)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 doCreateView(const Any & _rDataSource,const OUString & _rObjectName,const::comphelper::NamedValueCollection & i_rCreationArgs)84 Reference< XComponent > DatabaseObjectView::doCreateView( const Any& _rDataSource, const OUString& _rObjectName, 85 const ::comphelper::NamedValueCollection& i_rCreationArgs ) 86 { 87 ::comphelper::NamedValueCollection aDispatchArgs; 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 doDispatch(const::comphelper::NamedValueCollection & i_rDispatchArgs)96 Reference< XComponent > DatabaseObjectView::doDispatch( const ::comphelper::NamedValueCollection& i_rDispatchArgs ) 97 { 98 Reference< XComponent > xReturn; 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(3); 108 NamedValue aProp; 109 sal_Int32 nArg = 0; 110 111 aProp.Name = "ParentFrame"; 112 aProp.Value <<= m_xParentFrame; 113 lArgs[nArg++] <<= aProp; 114 115 aProp.Name = "TopWindow"; 116 aProp.Value <<= true; 117 lArgs[nArg++] <<= aProp; 118 119 aProp.Name = "SupportPersistentWindowState"; 120 aProp.Value <<= true; 121 lArgs[nArg++] <<= aProp; 122 123 m_xFrameLoader.set(xFact->createInstanceWithArguments(lArgs), UNO_QUERY_THROW); 124 125 // everything we load can be considered a "top level document", so set the respective bit at the window. 126 // This, amongst other things, triggers that the component in this task participates in the 127 // "ThisComponent"-game for the global application Basic. 128 const Reference< XFrame > xFrame( m_xFrameLoader, UNO_QUERY_THROW ); 129 const Reference< XWindow > xFrameWindow( xFrame->getContainerWindow(), UNO_SET_THROW ); 130 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xFrameWindow ); 131 ENSURE_OR_THROW( pContainerWindow, "no implementation access to the frame's container window!" ); 132 pContainerWindow->SetExtendedStyle( pContainerWindow->GetExtendedStyle() | WindowExtendedStyle::Document ); 133 } 134 135 Reference< XComponentLoader > xFrameLoader( m_xFrameLoader, UNO_SET_THROW ); 136 xReturn = xFrameLoader->loadComponentFromURL( 137 m_sComponentURL, 138 "_self", 139 0, 140 i_rDispatchArgs.getPropertyValues() 141 ); 142 } 143 catch( const Exception& ) 144 { 145 DBG_UNHANDLED_EXCEPTION("dbaccess"); 146 } 147 } 148 return xReturn; 149 } 150 fillDispatchArgs(::comphelper::NamedValueCollection & i_rDispatchArgs,const Any & _aDataSource,const OUString &)151 void DatabaseObjectView::fillDispatchArgs( 152 ::comphelper::NamedValueCollection& i_rDispatchArgs, 153 const Any& _aDataSource, 154 const OUString& /* _rName */ 155 ) 156 { 157 OUString sDataSource; 158 Reference<XDataSource> xDataSource; 159 if ( _aDataSource >>= sDataSource ) 160 { 161 i_rDispatchArgs.put( OUString(PROPERTY_DATASOURCENAME), sDataSource ); 162 } 163 else if ( _aDataSource >>= xDataSource ) 164 { 165 i_rDispatchArgs.put( OUString(PROPERTY_DATASOURCE), xDataSource ); 166 } 167 168 i_rDispatchArgs.put( OUString(PROPERTY_ACTIVE_CONNECTION), getConnection() ); 169 } 170 171 // QueryDesigner QueryDesigner(const Reference<XComponentContext> & _rxORB,const Reference<XDatabaseDocumentUI> & _rxApplication,const Reference<XFrame> & _rxParentFrame,bool _bCreateView)172 QueryDesigner::QueryDesigner( const Reference< XComponentContext >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, 173 const Reference< XFrame >& _rxParentFrame, bool _bCreateView ) 174 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, _bCreateView ? OUString(URL_COMPONENT_VIEWDESIGN) : OUString(URL_COMPONENT_QUERYDESIGN) ) 175 ,m_nCommandType( _bCreateView ? CommandType::TABLE : CommandType::QUERY ) 176 { 177 } 178 fillDispatchArgs(::comphelper::NamedValueCollection & i_rDispatchArgs,const Any & _aDataSource,const OUString & _rObjectName)179 void QueryDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource, 180 const OUString& _rObjectName ) 181 { 182 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName ); 183 184 const bool bIncludeQueryName = !_rObjectName.isEmpty(); 185 const bool bGraphicalDesign = i_rDispatchArgs.getOrDefault( PROPERTY_GRAPHICAL_DESIGN, true ); 186 const bool bEditViewAsSQLCommand = ( m_nCommandType == CommandType::TABLE ) && !bGraphicalDesign; 187 188 i_rDispatchArgs.put( OUString(PROPERTY_COMMAND_TYPE), m_nCommandType ); 189 190 if ( bIncludeQueryName ) 191 { 192 i_rDispatchArgs.put( OUString(PROPERTY_COMMAND), _rObjectName ); 193 } 194 195 if ( bEditViewAsSQLCommand ) 196 { 197 i_rDispatchArgs.put( OUString(PROPERTY_ESCAPE_PROCESSING), false ); 198 } 199 } 200 201 // TableDesigner TableDesigner(const Reference<XComponentContext> & _rxORB,const Reference<XDatabaseDocumentUI> & _rxApplication,const Reference<XFrame> & _rxParentFrame)202 TableDesigner::TableDesigner( const Reference< XComponentContext >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame ) 203 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< OUString >( URL_COMPONENT_TABLEDESIGN ) ) 204 { 205 } 206 fillDispatchArgs(::comphelper::NamedValueCollection & i_rDispatchArgs,const Any & _aDataSource,const OUString & _rObjectName)207 void TableDesigner::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource, 208 const OUString& _rObjectName ) 209 { 210 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rObjectName ); 211 212 if ( !_rObjectName.isEmpty() ) 213 { 214 i_rDispatchArgs.put( OUString(PROPERTY_CURRENTTABLE), _rObjectName ); 215 } 216 } 217 doCreateView(const Any & _rDataSource,const OUString & _rObjectName,const::comphelper::NamedValueCollection & i_rCreationArgs)218 Reference< XComponent > TableDesigner::doCreateView( const Any& _rDataSource, const OUString& _rObjectName, 219 const ::comphelper::NamedValueCollection& i_rCreationArgs ) 220 { 221 bool bIsNewDesign = _rObjectName.isEmpty(); 222 223 // let's see whether the connection can provide a dedicated table designer 224 Reference< XInterface > xDesigner; 225 if ( !bIsNewDesign ) 226 xDesigner = impl_getConnectionProvidedDesigner_nothrow( _rObjectName ); 227 228 if ( !xDesigner.is() ) 229 return DatabaseObjectView::doCreateView( _rDataSource, _rObjectName, i_rCreationArgs ); 230 231 // try whether the designer is a dialog 232 Reference< XExecutableDialog > xDialog( xDesigner, UNO_QUERY_THROW ); 233 try { AsyncDialogExecutor::executeModalDialogAsync( xDialog ); } 234 catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); } 235 return nullptr; 236 } 237 impl_getConnectionProvidedDesigner_nothrow(const OUString & _rTableName)238 Reference< XInterface > TableDesigner::impl_getConnectionProvidedDesigner_nothrow( const OUString& _rTableName ) 239 { 240 Reference< XInterface > xDesigner; 241 try 242 { 243 Reference< XTableUIProvider > xTableUIProv( getConnection(), UNO_QUERY ); 244 if ( xTableUIProv.is() ) 245 xDesigner = xTableUIProv->getTableEditor( getApplicationUI(), _rTableName ); 246 } 247 catch( const Exception& ) 248 { 249 DBG_UNHANDLED_EXCEPTION("dbaccess"); 250 } 251 return xDesigner; 252 } 253 254 // ResultSetBrowser ResultSetBrowser(const Reference<XComponentContext> & _rxORB,const Reference<XDatabaseDocumentUI> & _rxApplication,const Reference<XFrame> & _rxParentFrame,bool _bTable)255 ResultSetBrowser::ResultSetBrowser( const Reference< XComponentContext >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame, 256 bool _bTable ) 257 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast < OUString >( URL_COMPONENT_DATASOURCEBROWSER ) ) 258 ,m_bTable(_bTable) 259 { 260 } 261 fillDispatchArgs(::comphelper::NamedValueCollection & i_rDispatchArgs,const Any & _aDataSource,const OUString & _rQualifiedName)262 void ResultSetBrowser::fillDispatchArgs( ::comphelper::NamedValueCollection& i_rDispatchArgs, const Any& _aDataSource, 263 const OUString& _rQualifiedName) 264 { 265 DatabaseObjectView::fillDispatchArgs( i_rDispatchArgs, _aDataSource, _rQualifiedName ); 266 OSL_ENSURE( !_rQualifiedName.isEmpty(),"A Table name must be set"); 267 OUString sCatalog; 268 OUString sSchema; 269 OUString sTable; 270 if ( m_bTable ) 271 ::dbtools::qualifiedNameComponents( getConnection()->getMetaData(), _rQualifiedName, sCatalog, sSchema, sTable, ::dbtools::EComposeRule::InDataManipulation ); 272 273 i_rDispatchArgs.put( OUString(PROPERTY_COMMAND_TYPE), (m_bTable ? CommandType::TABLE : CommandType::QUERY) ); 274 i_rDispatchArgs.put( OUString(PROPERTY_COMMAND), _rQualifiedName ); 275 i_rDispatchArgs.put( OUString(PROPERTY_ENABLE_BROWSER), false ); 276 277 if ( m_bTable ) 278 { 279 i_rDispatchArgs.put( OUString(PROPERTY_UPDATE_CATALOGNAME), sCatalog ); 280 i_rDispatchArgs.put( OUString(PROPERTY_UPDATE_SCHEMANAME), sSchema ); 281 i_rDispatchArgs.put( OUString(PROPERTY_UPDATE_TABLENAME), sTable ); 282 } 283 } 284 285 // RelationDesigner RelationDesigner(const Reference<XComponentContext> & _rxORB,const Reference<XDatabaseDocumentUI> & _rxApplication,const Reference<XFrame> & _rxParentFrame)286 RelationDesigner::RelationDesigner( const Reference< XComponentContext >& _rxORB, const Reference< XDatabaseDocumentUI >& _rxApplication, const Reference< XFrame >& _rxParentFrame ) 287 :DatabaseObjectView( _rxORB, _rxApplication, _rxParentFrame, static_cast< OUString >( URL_COMPONENT_RELATIONDESIGN ) ) 288 { 289 } 290 } // namespace dbaui 291 292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 293